File indexing completed on 2025-02-02 05:18:49

0001 /*
0002     SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 #ifndef KWAYLAND_TOOLS_GENERATOR_H
0007 #define KWAYLAND_TOOLS_GENERATOR_H
0008 
0009 #include <QMap>
0010 #include <QMutex>
0011 #include <QObject>
0012 #include <QThreadStorage>
0013 #include <QWaitCondition>
0014 #include <QXmlStreamReader>
0015 
0016 class QTextStream;
0017 
0018 namespace KWayland
0019 {
0020 namespace Tools
0021 {
0022 class Argument
0023 {
0024 public:
0025     explicit Argument();
0026     explicit Argument(const QXmlStreamAttributes &attributes);
0027     ~Argument();
0028 
0029     enum class Type {
0030         Unknown,
0031         NewId,
0032         Destructor,
0033         Object,
0034         FileDescriptor,
0035         Fixed,
0036         Uint,
0037         Int,
0038         String,
0039     };
0040 
0041     QString name() const
0042     {
0043         return m_name;
0044     }
0045     Type type() const
0046     {
0047         return m_type;
0048     }
0049     bool isNullAllowed() const
0050     {
0051         return m_allowNull;
0052     }
0053     QString interface() const
0054     {
0055         return m_inteface;
0056     }
0057     QString typeAsQt() const;
0058     QString typeAsServerWl() const;
0059 
0060 private:
0061     Type parseType(const QStringView type);
0062     QString m_name;
0063     Type m_type = Type::Unknown;
0064     bool m_allowNull = false;
0065     QString m_inteface;
0066 };
0067 
0068 class Request
0069 {
0070 public:
0071     explicit Request();
0072     explicit Request(const QString &name);
0073     ~Request();
0074 
0075     void addArgument(const Argument &arg)
0076     {
0077         m_arguments << arg;
0078     }
0079 
0080     QString name() const
0081     {
0082         return m_name;
0083     }
0084 
0085     QList<Argument> arguments() const
0086     {
0087         return m_arguments;
0088     }
0089 
0090     bool isDestructor() const
0091     {
0092         return m_destructor;
0093     }
0094     bool isFactory() const;
0095 
0096     void markAsDestructor()
0097     {
0098         m_destructor = true;
0099     }
0100 
0101 private:
0102     QString m_name;
0103     QList<Argument> m_arguments;
0104     bool m_destructor = false;
0105 };
0106 
0107 class Event
0108 {
0109 public:
0110     explicit Event();
0111     explicit Event(const QString &name);
0112     ~Event();
0113 
0114     void addArgument(const Argument &arg)
0115     {
0116         m_arguments << arg;
0117     }
0118 
0119     QString name() const
0120     {
0121         return m_name;
0122     }
0123 
0124     QList<Argument> arguments() const
0125     {
0126         return m_arguments;
0127     }
0128 
0129 private:
0130     QString m_name;
0131     QList<Argument> m_arguments;
0132 };
0133 
0134 class Interface
0135 {
0136 public:
0137     explicit Interface();
0138     explicit Interface(const QXmlStreamAttributes &attributes);
0139     virtual ~Interface();
0140 
0141     void addRequest(const Request &request)
0142     {
0143         m_requests << request;
0144     }
0145     void addEvent(const Event &event)
0146     {
0147         m_events << event;
0148     }
0149 
0150     QString name() const
0151     {
0152         return m_name;
0153     }
0154     quint32 version() const
0155     {
0156         return m_version;
0157     }
0158     QString kwaylandClientName() const
0159     {
0160         return m_clientName;
0161     }
0162     QString kwaylandServerName() const
0163     {
0164         return m_clientName + QStringLiteral("Interface");
0165     }
0166 
0167     QList<Request> requests() const
0168     {
0169         return m_requests;
0170     }
0171 
0172     QList<Event> events() const
0173     {
0174         return m_events;
0175     }
0176 
0177     void markAsGlobal()
0178     {
0179         m_global = true;
0180     }
0181     bool isGlobal() const
0182     {
0183         return m_global;
0184     }
0185     void setFactory(Interface *factory)
0186     {
0187         m_factory = factory;
0188     }
0189     Interface *factory() const
0190     {
0191         return m_factory;
0192     }
0193 
0194     bool isUnstableInterface() const
0195     {
0196         return m_name.startsWith(QLatin1String("zwp"));
0197     }
0198 
0199 private:
0200     QString m_name;
0201     QString m_clientName;
0202     quint32 m_version;
0203     QList<Request> m_requests;
0204     QList<Event> m_events;
0205     bool m_global = false;
0206     Interface *m_factory;
0207 };
0208 
0209 class Generator : public QObject
0210 {
0211     Q_OBJECT
0212 public:
0213     explicit Generator(QObject *parent = nullptr);
0214     ~Generator() override;
0215 
0216     void setXmlFileName(const QString &name)
0217     {
0218         m_xmlFileName = name;
0219     }
0220     void setBaseFileName(const QString &name)
0221     {
0222         m_baseFileName = name;
0223     }
0224     void start();
0225 
0226 private:
0227     void generateCopyrightHeader();
0228     void generateStartIncludeGuard();
0229     void generateEndIncludeGuard();
0230     void generateStartNamespace();
0231     void generateEndNamespace();
0232     void generateHeaderIncludes();
0233     void generateCppIncludes();
0234     void generatePrivateClass(const Interface &interface);
0235     void generateClientPrivateClass(const Interface &interface);
0236     void generateClientPrivateResourceClass(const Interface &interface);
0237     void generateClientPrivateGlobalClass(const Interface &interface);
0238     void generateServerPrivateGlobalClass(const Interface &interface);
0239     void generateServerPrivateResourceClass(const Interface &interface);
0240     void generateServerPrivateInterfaceClass(const Interface &interface);
0241     void generateServerPrivateGlobalCtorBindClass(const Interface &interface);
0242     void generateServerPrivateResourceCtorDtorClass(const Interface &interface);
0243     void generateServerPrivateCallbackDefinitions(const Interface &interface);
0244     void generateServerPrivateCallbackImpl(const Interface &interface);
0245     void generateClientCpp(const Interface &interface);
0246     void generateClass(const Interface &interface);
0247     void generateClientGlobalClass(const Interface &interface);
0248     void generateClientResourceClass(const Interface &interface);
0249     void generateServerGlobalClass(const Interface &interface);
0250     void generateServerGlobalClassUnstable(const Interface &interface);
0251     void generateServerResourceClass(const Interface &interface);
0252     void generateServerResourceClassUnstable(const Interface &interface);
0253     void generateClientClassQObjectDerived(const Interface &interface);
0254     void generateClientGlobalClassDoxy(const Interface &interface);
0255     void generateClientGlobalClassCtor(const Interface &interface);
0256     void generateClientGlobalClassSetup(const Interface &interface);
0257     void generateClientResourceClassSetup(const Interface &interface);
0258     void generateClientClassDtor(const Interface &interface);
0259     void generateClientClassReleaseDestroy(const Interface &interface);
0260     void generateClientClassStart(const Interface &interface);
0261     void generateClientClassCasts(const Interface &interface);
0262     void generateClientClassSignals(const Interface &interface);
0263     void generateClientClassDptr(const Interface &interface);
0264     void generateClientGlobalClassEnd(const Interface &interface);
0265     void generateClientResourceClassEnd(const Interface &interface);
0266     void generateClientClassRequests(const Interface &interface);
0267     void generateClientCppRequests(const Interface &interface);
0268     void generateWaylandForwardDeclarations();
0269     void generateNamespaceForwardDeclarations();
0270     void startParseXml();
0271     void startAuthorNameProcess();
0272     void startAuthorEmailProcess();
0273     void startGenerateHeaderFile();
0274     void startGenerateCppFile();
0275     void startGenerateServerHeaderFile();
0276     void startGenerateServerCppFile();
0277 
0278     void checkEnd();
0279 
0280     void parseProtocol();
0281     Interface parseInterface();
0282     Request parseRequest();
0283     Event parseEvent();
0284 
0285     QString projectToName() const;
0286 
0287     QThreadStorage<QTextStream *> m_stream;
0288     QString m_xmlFileName;
0289     enum class Project {
0290         Client,
0291         Server,
0292     };
0293     QThreadStorage<Project> m_project;
0294     QString m_authorName;
0295     QString m_authorEmail;
0296     QString m_baseFileName;
0297 
0298     QMutex m_mutex;
0299     QWaitCondition m_waitCondition;
0300     QXmlStreamReader m_xmlReader;
0301     QList<Interface> m_interfaces;
0302 
0303     int m_finishedCounter = 0;
0304 };
0305 
0306 }
0307 }
0308 
0309 #endif