1 | /* |
2 | SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org> |
3 | |
4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL |
5 | */ |
6 | #ifndef KWAYLAND_TOOLS_GENERATOR_H |
7 | #define KWAYLAND_TOOLS_GENERATOR_H |
8 | |
9 | #include <QMap> |
10 | #include <QMutex> |
11 | #include <QObject> |
12 | #include <QThreadStorage> |
13 | #include <QWaitCondition> |
14 | #include <QXmlStreamReader> |
15 | |
16 | class QTextStream; |
17 | |
18 | namespace KWayland |
19 | { |
20 | namespace Tools |
21 | { |
22 | class Argument |
23 | { |
24 | public: |
25 | explicit Argument(); |
26 | explicit Argument(const QXmlStreamAttributes &attributes); |
27 | ~Argument(); |
28 | |
29 | enum class Type { |
30 | Unknown, |
31 | NewId, |
32 | Destructor, |
33 | Object, |
34 | FileDescriptor, |
35 | Fixed, |
36 | Uint, |
37 | Int, |
38 | String, |
39 | }; |
40 | |
41 | QString name() const |
42 | { |
43 | return m_name; |
44 | } |
45 | Type type() const |
46 | { |
47 | return m_type; |
48 | } |
49 | bool isNullAllowed() const |
50 | { |
51 | return m_allowNull; |
52 | } |
53 | QString interface() const |
54 | { |
55 | return m_inteface; |
56 | } |
57 | QString typeAsQt() const; |
58 | QString typeAsServerWl() const; |
59 | |
60 | private: |
61 | Type parseType(const QStringView type); |
62 | QString m_name; |
63 | Type m_type = Type::Unknown; |
64 | bool m_allowNull = false; |
65 | QString m_inteface; |
66 | }; |
67 | |
68 | class Request |
69 | { |
70 | public: |
71 | explicit Request(); |
72 | explicit Request(const QString &name); |
73 | ~Request(); |
74 | |
75 | void addArgument(const Argument &arg) |
76 | { |
77 | m_arguments << arg; |
78 | } |
79 | |
80 | QString name() const |
81 | { |
82 | return m_name; |
83 | } |
84 | |
85 | QList<Argument> arguments() const |
86 | { |
87 | return m_arguments; |
88 | } |
89 | |
90 | bool isDestructor() const |
91 | { |
92 | return m_destructor; |
93 | } |
94 | bool isFactory() const; |
95 | |
96 | void markAsDestructor() |
97 | { |
98 | m_destructor = true; |
99 | } |
100 | |
101 | private: |
102 | QString m_name; |
103 | QList<Argument> m_arguments; |
104 | bool m_destructor = false; |
105 | }; |
106 | |
107 | class Event |
108 | { |
109 | public: |
110 | explicit Event(); |
111 | explicit Event(const QString &name); |
112 | ~Event(); |
113 | |
114 | void addArgument(const Argument &arg) |
115 | { |
116 | m_arguments << arg; |
117 | } |
118 | |
119 | QString name() const |
120 | { |
121 | return m_name; |
122 | } |
123 | |
124 | QList<Argument> arguments() const |
125 | { |
126 | return m_arguments; |
127 | } |
128 | |
129 | private: |
130 | QString m_name; |
131 | QList<Argument> m_arguments; |
132 | }; |
133 | |
134 | class Interface |
135 | { |
136 | public: |
137 | explicit Interface(); |
138 | explicit Interface(const QXmlStreamAttributes &attributes); |
139 | virtual ~Interface(); |
140 | |
141 | void addRequest(const Request &request) |
142 | { |
143 | m_requests << request; |
144 | } |
145 | void addEvent(const Event &event) |
146 | { |
147 | m_events << event; |
148 | } |
149 | |
150 | QString name() const |
151 | { |
152 | return m_name; |
153 | } |
154 | quint32 version() const |
155 | { |
156 | return m_version; |
157 | } |
158 | QString kwaylandClientName() const |
159 | { |
160 | return m_clientName; |
161 | } |
162 | QString kwaylandServerName() const |
163 | { |
164 | return m_clientName + QStringLiteral("Interface" ); |
165 | } |
166 | |
167 | QList<Request> requests() const |
168 | { |
169 | return m_requests; |
170 | } |
171 | |
172 | QList<Event> events() const |
173 | { |
174 | return m_events; |
175 | } |
176 | |
177 | void markAsGlobal() |
178 | { |
179 | m_global = true; |
180 | } |
181 | bool isGlobal() const |
182 | { |
183 | return m_global; |
184 | } |
185 | void setFactory(Interface *factory) |
186 | { |
187 | m_factory = factory; |
188 | } |
189 | Interface *factory() const |
190 | { |
191 | return m_factory; |
192 | } |
193 | |
194 | bool isUnstableInterface() const |
195 | { |
196 | return m_name.startsWith(s: QLatin1String("zwp" )); |
197 | } |
198 | |
199 | private: |
200 | QString m_name; |
201 | QString m_clientName; |
202 | quint32 m_version; |
203 | QList<Request> m_requests; |
204 | QList<Event> m_events; |
205 | bool m_global = false; |
206 | Interface *m_factory; |
207 | }; |
208 | |
209 | class Generator : public QObject |
210 | { |
211 | Q_OBJECT |
212 | public: |
213 | explicit Generator(QObject *parent = nullptr); |
214 | ~Generator() override; |
215 | |
216 | void setXmlFileName(const QString &name) |
217 | { |
218 | m_xmlFileName = name; |
219 | } |
220 | void setBaseFileName(const QString &name) |
221 | { |
222 | m_baseFileName = name; |
223 | } |
224 | void start(); |
225 | |
226 | private: |
227 | void generateCopyrightHeader(); |
228 | void generateStartIncludeGuard(); |
229 | void generateEndIncludeGuard(); |
230 | void generateStartNamespace(); |
231 | void generateEndNamespace(); |
232 | void generateHeaderIncludes(); |
233 | void generateCppIncludes(); |
234 | void generatePrivateClass(const Interface &interface); |
235 | void generateClientPrivateClass(const Interface &interface); |
236 | void generateClientPrivateResourceClass(const Interface &interface); |
237 | void generateClientPrivateGlobalClass(const Interface &interface); |
238 | void generateServerPrivateGlobalClass(const Interface &interface); |
239 | void generateServerPrivateResourceClass(const Interface &interface); |
240 | void generateServerPrivateInterfaceClass(const Interface &interface); |
241 | void generateServerPrivateGlobalCtorBindClass(const Interface &interface); |
242 | void generateServerPrivateResourceCtorDtorClass(const Interface &interface); |
243 | void generateServerPrivateCallbackDefinitions(const Interface &interface); |
244 | void generateServerPrivateCallbackImpl(const Interface &interface); |
245 | void generateClientCpp(const Interface &interface); |
246 | void generateClass(const Interface &interface); |
247 | void generateClientGlobalClass(const Interface &interface); |
248 | void generateClientResourceClass(const Interface &interface); |
249 | void generateServerGlobalClass(const Interface &interface); |
250 | void generateServerGlobalClassUnstable(const Interface &interface); |
251 | void generateServerResourceClass(const Interface &interface); |
252 | void generateServerResourceClassUnstable(const Interface &interface); |
253 | void generateClientClassQObjectDerived(const Interface &interface); |
254 | void generateClientGlobalClassDoxy(const Interface &interface); |
255 | void generateClientGlobalClassCtor(const Interface &interface); |
256 | void generateClientGlobalClassSetup(const Interface &interface); |
257 | void generateClientResourceClassSetup(const Interface &interface); |
258 | void generateClientClassDtor(const Interface &interface); |
259 | void generateClientClassReleaseDestroy(const Interface &interface); |
260 | void generateClientClassStart(const Interface &interface); |
261 | void generateClientClassCasts(const Interface &interface); |
262 | void generateClientClassSignals(const Interface &interface); |
263 | void generateClientClassDptr(const Interface &interface); |
264 | void generateClientGlobalClassEnd(const Interface &interface); |
265 | void generateClientResourceClassEnd(const Interface &interface); |
266 | void generateClientClassRequests(const Interface &interface); |
267 | void generateClientCppRequests(const Interface &interface); |
268 | void generateWaylandForwardDeclarations(); |
269 | void generateNamespaceForwardDeclarations(); |
270 | void startParseXml(); |
271 | void startAuthorNameProcess(); |
272 | void startAuthorEmailProcess(); |
273 | void startGenerateHeaderFile(); |
274 | void startGenerateCppFile(); |
275 | void startGenerateServerHeaderFile(); |
276 | void startGenerateServerCppFile(); |
277 | |
278 | void checkEnd(); |
279 | |
280 | void parseProtocol(); |
281 | Interface parseInterface(); |
282 | Request parseRequest(); |
283 | Event parseEvent(); |
284 | |
285 | QString projectToName() const; |
286 | |
287 | QThreadStorage<QTextStream *> m_stream; |
288 | QString m_xmlFileName; |
289 | enum class Project { |
290 | Client, |
291 | Server, |
292 | }; |
293 | QThreadStorage<Project> m_project; |
294 | QString m_authorName; |
295 | QString m_authorEmail; |
296 | QString m_baseFileName; |
297 | |
298 | QMutex m_mutex; |
299 | QWaitCondition m_waitCondition; |
300 | QXmlStreamReader m_xmlReader; |
301 | QList<Interface> m_interfaces; |
302 | |
303 | int m_finishedCounter = 0; |
304 | }; |
305 | |
306 | } |
307 | } |
308 | |
309 | #endif |
310 | |