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
16class QTextStream;
17
18namespace KWayland
19{
20namespace Tools
21{
22class Argument
23{
24public:
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
60private:
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
68class Request
69{
70public:
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
101private:
102 QString m_name;
103 QList<Argument> m_arguments;
104 bool m_destructor = false;
105};
106
107class Event
108{
109public:
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
129private:
130 QString m_name;
131 QList<Argument> m_arguments;
132};
133
134class Interface
135{
136public:
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
199private:
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
209class Generator : public QObject
210{
211 Q_OBJECT
212public:
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
226private:
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

source code of kwayland/src/tools/generator.h