Browse Source

Make common class for class generation

- Fix issues with members generation
- Add GlobalEnums class generatino
Alexey Edelev 6 years ago
parent
commit
c73fe7a5cd

+ 2 - 1
CMakeLists.txt

@@ -4,7 +4,8 @@ project(qtprotobuf)
 
 find_package(Protobuf)
 
-add_executable(${PROJECT_NAME} "src/generator/main.cpp" "src/generator/generator.cpp" "src/generator/enumsgenerator.cpp")
+add_executable(${PROJECT_NAME} "src/generator/main.cpp" "src/generator/generator.cpp"
+    "src/generator/classgeneratorbase.cpp")
 target_link_libraries(${PROJECT_NAME} ${Protobuf_LIBRARIES} "-lprotoc")
 
 install(TARGETS ${PROJECT_NAME}

+ 201 - 0
src/generator/classgeneratorbase.cpp

@@ -0,0 +1,201 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of qtprotobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "classgeneratorbase.h"
+
+#include "templates.h"
+#include "utils.h"
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+
+using namespace qtprotobuf;
+using namespace ::google::protobuf;
+using namespace ::google::protobuf::io;
+using namespace ::google::protobuf::compiler;
+
+ClassGeneratorBase::ClassGeneratorBase(std::string mClassName, std::unique_ptr<::google::protobuf::io::ZeroCopyOutputStream> out) : mOutput(std::move(out))
+  , mPrinter(mOutput.get(), '$')
+  , mClassName(std::move(mClassName))
+  , mNamespaceCount(0)
+{
+
+}
+
+bool ClassGeneratorBase::producePropertyMap(const FieldDescriptor* field, PropertyMap& propertyMap) {
+    std::string typeName = getTypeName(field);
+
+    if (typeName.size() <= 0) {
+        std::cerr << "Type "
+                  << field->type_name()
+                  << " is not supported by Qt Generator"
+                     " please look at https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html"
+                     " for details" << std::endl;
+        return false;
+    }
+
+    std::string capProperty = field->camelcase_name();
+    capProperty[0] = ::toupper(capProperty[0]);
+
+    propertyMap = {{"type", typeName},
+        {"property_name", field->camelcase_name()},
+        {"property_name_cap", capProperty}};
+    return true;
+}
+
+void ClassGeneratorBase::printPreamble() {
+    mPrinter.Print("#pragma once\n"
+                   "#include <QObject>\n");
+}
+
+void ClassGeneratorBase::printNamespaces(const std::string& package) {
+    std::vector<std::string> namespaces;
+    utils::split(package, namespaces, '.');
+    mNamespaceCount = namespaces.size();
+    for (auto ns: namespaces) {
+        mPrinter.Print({{"namespace", ns}}, NamespaceTemplate);
+    }
+}
+
+void ClassGeneratorBase::printClass() {
+    mPrinter.Print({{"classname", mClassName}}, StartTemplate);
+}
+
+void ClassGeneratorBase::printProperties(const Descriptor* message) {
+    //private section
+    for (int i = 0; i < message->field_count(); i++) {
+        printField(message->field(i), PropertyTemplate);
+    }
+    for (int i = 0; i < message->field_count(); i++) {
+        printField(message->field(i), MemberTemplate);
+    }
+    printQEnums(message);
+
+    //public section
+    printPublic();
+    printConstructor();
+    for (int i = 0; i < message->field_count(); i++) {
+        printField(message->field(i), GetterTemplate);
+    }
+    for (int i = 0; i < message->field_count(); i++) {
+        auto field = message->field(i);
+        if (field->type() == FieldDescriptor::TYPE_MESSAGE
+                || field->type() == FieldDescriptor::TYPE_STRING) {
+            printField(field, SetterTemplateComplexType);
+        } else {
+            printField(field, SetterTemplateSimpleType);
+        }
+    }
+    mPrinter.Print("\nsignals:\n");
+    for (int i = 0; i < message->field_count(); i++) {
+        printField(message->field(i), SignalTemplate);
+    }
+}
+void ClassGeneratorBase::printField(const FieldDescriptor* field, const char* fieldTemplate) {
+    std::map<std::string, std::string> propertyMap;
+    if (producePropertyMap(field, propertyMap)) {
+        mPrinter.Print(propertyMap, fieldTemplate);
+    }
+}
+
+void ClassGeneratorBase::enclose() {
+    mPrinter.Print("};\n");
+    while (mNamespaceCount > 0) {
+        mPrinter.Print("}\n");
+        --mNamespaceCount;
+    }
+}
+
+std::string ClassGeneratorBase::getTypeName(const FieldDescriptor* field) {
+    std::string typeName;
+    if (field->type() == FieldDescriptor::TYPE_MESSAGE) {
+        typeName = field->message_type()->name();
+    } else if (field->type() == FieldDescriptor::TYPE_ENUM) {
+        typeName = field->enum_type()->name();
+    } else {
+        auto it = TypeReflection.find(field->type());
+        if (it != std::end(TypeReflection)) {
+            typeName = it->second;
+        }
+    }
+
+    if (field->is_repeated()) {
+        typeName = typeName.append("Model");
+    }
+
+    return typeName;
+}
+
+void ClassGeneratorBase::printConstructor() {
+    mPrinter.Print({{"classname", mClassName}},
+                   "    $classname$(QObject parent = nullptr) : QObject(parent)\n");
+
+    //FIXME: Explicit default values are not allowed in proto3 seems
+    //this function is useless
+//    for (int i = 0; i < mMessage->field_count(); i++) {
+//        const FieldDescriptor* field = mMessage->field(i);
+//        std::string defaultValue;
+//        if (field->has_default_value()) {
+//            switch (field->type()) {
+//            case FieldDescriptor::TYPE_DOUBLE:
+//                defaultValue = std::to_string(field->default_value_double());
+//                break;
+//            case FieldDescriptor::TYPE_FLOAT:
+//                defaultValue = std::to_string(field->default_value_float());
+//                break;
+//            case FieldDescriptor::TYPE_INT32:
+//            case FieldDescriptor::TYPE_UINT32:
+//            case FieldDescriptor::TYPE_SFIXED32:
+//            case FieldDescriptor::TYPE_SINT32:
+//                defaultValue = std::to_string(field->default_value_int32());
+//                break;
+//            case FieldDescriptor::TYPE_BOOL:
+//                defaultValue = field->default_value_bool() ? "true" : "false";
+//                break;
+//            case FieldDescriptor::TYPE_STRING:
+//                defaultValue = field->default_value_string();
+//                break;
+//            case FieldDescriptor::TYPE_ENUM:
+//                defaultValue = field->default_value_enum()->name();
+//                break;
+//            default:
+//                std::cerr << "Default value substitution"
+//                             " is not supported for type"
+//                          << field->type_name() << std::endl;
+//                break;
+//            }
+//            if (defaultValue.size() > 0) {
+//                mPrinter.Print({{"property_name", field->camelcase_name()},
+//                                {"default_value", defaultValue}},
+//                               "    , $m_property_name$($default_value$)\n");
+//            }
+//        }
+//    }
+    mPrinter.Print("    {}\n\n");
+}
+
+void ClassGeneratorBase::printPublic() {
+    mPrinter.Print("\npublic:\n");
+}

+ 88 - 0
src/generator/classgeneratorbase.h

@@ -0,0 +1,88 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of qtprotobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+#include <google/protobuf/io/printer.h>
+
+namespace google { namespace protobuf {
+class FieldDescriptor;
+class Descriptor;
+namespace io {
+class ZeroCopyOutputStream;
+}}}
+
+namespace qtprotobuf {
+
+using PropertyMap = std::map<std::string, std::string>;
+
+class ClassGeneratorBase
+{
+    std::unique_ptr<::google::protobuf::io::ZeroCopyOutputStream> mOutput;
+    ::google::protobuf::io::Printer mPrinter;
+    std::string mClassName;
+    int mNamespaceCount;
+public:
+    ClassGeneratorBase(std::string mClassName, std::unique_ptr<::google::protobuf::io::ZeroCopyOutputStream> out);
+
+protected:
+    bool producePropertyMap(const ::google::protobuf::FieldDescriptor* field, PropertyMap& propertyMap);
+    void printPreamble();
+    void printNamespaces(const std::string& package);
+    void printClass();
+    void printField(const ::google::protobuf::FieldDescriptor* field, const char* fieldTemplate);
+    void enclose();
+    std::string getTypeName(const ::google::protobuf::FieldDescriptor* field);
+
+    template<typename T>
+    void printQEnums(const T* message) {
+        if (message->enum_type_count() <= 0) {
+            return;
+        }
+
+        mPrinter.Print("    Q_ENUMS(");
+        for (int i = 0; i < message->enum_type_count(); i++) {
+            const auto enumDescr = message->enum_type(i);
+            mPrinter.Print(enumDescr->name().c_str());
+        }
+        mPrinter.Print(")\n");
+        printPublic();
+        for (int i = 0; i < message->enum_type_count(); i++) {
+            const auto enumDescr = message->enum_type(i);
+            mPrinter.Print({{"enum", enumDescr->name()}}, "    enum $enum$ {\n");
+            for (int j = 0; j < enumDescr->value_count(); j++) {
+                const auto valueDescr = enumDescr->value(j);
+                mPrinter.Print({{"enumvalue", valueDescr->name()},
+                                {"value", std::to_string(valueDescr->number())}}, "        $enumvalue$ = $value$,\n");
+            }
+            mPrinter.Print("    };\n");
+        }
+    }
+
+    void printProperties(const ::google::protobuf::Descriptor* message);
+    void printConstructor();
+    void printPublic();
+};
+
+}

+ 0 - 48
src/generator/enumsgenerator.cpp

@@ -1,48 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
- *
- * This file is part of qtprotobuf project https://git.semlanik.org/semlanik/qtprotobuf
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this
- * software and associated documentation files (the "Software"), to deal in the Software
- * without restriction, including without limitation the rights to use, copy, modify,
- * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
- * to permit persons to whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies
- * or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
- * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
- * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include "enumsgenerator.h"
-
-#include <google/protobuf/io/zero_copy_stream.h>
-
-using namespace qtprotobuf;
-using namespace google::protobuf;
-using namespace google::protobuf::io;
-
-GlobalEnumsGenerator::GlobalEnumsGenerator(std::unique_ptr<ZeroCopyOutputStream> out) : mOutput(std::move(out))
-  , mPrinter(mOutput.get(), '$')
-{
-}
-
-void GlobalEnumsGenerator::run(const FileDescriptor* file)
-{
-    if (file->enum_type_count() <= 0) {
-        return;
-    }
-//TODO:
-    for(int i = 0; i < file->enum_type_count(); i++) {
-
-    }
-}

+ 26 - 224
src/generator/generator.cpp

@@ -25,7 +25,7 @@
 
 #include "generator.h"
 #include "templates.h"
-#include "enumsgenerator.h"
+#include "classgeneratorbase.h"
 
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
@@ -44,240 +44,42 @@ using namespace ::google::protobuf::compiler;
 
 using namespace qtprotobuf;
 
-namespace utils {
-
-void split(const std::string& str, std::vector<std::string>& cont, char delim)
+class QtClassGenerator : public ClassGeneratorBase
 {
-    std::stringstream ss(str);
-    std::string token;
-    while (std::getline(ss, token, delim)) {
-        cont.push_back(token);
-    }
-}
-
-}
-
-static std::unordered_map<FieldDescriptor::Type, std::string> TypeReflection = {
-    {FieldDescriptor::TYPE_DOUBLE, "qreal"},
-    {FieldDescriptor::TYPE_FLOAT, "qreal"},
-    //        {FieldDescriptor::TYPE_INT64, "int"},//Not supported see https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html
-    //        {FieldDescriptor::TYPE_UINT64,"int"},//Not supported see https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html
-    {FieldDescriptor::TYPE_INT32, "int"},
-    //        {FieldDescriptor::TYPE_FIXED64, "int"},//Not supported see https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html
-    //        {FieldDescriptor::TYPE_FIXED32, "int"},//Not supported see https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html
-    {FieldDescriptor::TYPE_BOOL, "bool"},
-    {FieldDescriptor::TYPE_STRING, "QString"},
-    {FieldDescriptor::TYPE_GROUP, ""},//Not supported and deprecated in protobuf
-//    {FieldDescriptor::TYPE_MESSAGE, ""},//Custom typename
-    {FieldDescriptor::TYPE_BYTES, "QByteArray"},
-    {FieldDescriptor::TYPE_UINT32, "int"},//Limited usage see https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html
-//    {FieldDescriptor::TYPE_ENUM, ""},//Custom typename
-    {FieldDescriptor::TYPE_SFIXED32, "int"},
-    //        {FieldDescriptor::TYPE_SFIXED64, "int"},//Not supported see https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html
-    {FieldDescriptor::TYPE_SINT32, "int"},
-    //        {FieldDescriptor::TYPE_SINT64, "int"},//Not supported see https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html
-};
-
-class QtClassGenerator {
-    std::unique_ptr<io::ZeroCopyOutputStream> mOutput;
     std::string mPackage;
     const Descriptor* mMessage;
-    int mNamespaceCount;
-    io::Printer mPrinter;
 
 public:
-    QtClassGenerator(const std::string& package, const Descriptor* message, std::unique_ptr<io::ZeroCopyOutputStream> out) : mOutput(std::move(out))
-      , mPackage(package)
-      , mMessage(message)
-      , mNamespaceCount(0)
-      , mPrinter(mOutput.get(), '$')
-    {
-    }
+    QtClassGenerator(const std::string& package, const Descriptor* message, std::unique_ptr<io::ZeroCopyOutputStream> out) :
+        ClassGeneratorBase(message->name(), std::move(out))
+      , mPackage(std::move(package))
+      ,mMessage(message){}
 
     void run() {
         printPreamble();
-        printNamespaces();
+        printNamespaces(mPackage);
         printClass();
+        printProperties(mMessage);
         enclose();
     }
+};
 
-private:
-    bool producePropertyMap(const FieldDescriptor* field, std::map<string, string>& propertyMap) {
-        std::string typeName = getTypeName(field);
-
-        if (typeName.size() <= 0) {
-            std::cerr << "Type "
-                      << field->type_name()
-                      << " is not supported by Qt Generator"
-                         " please look at https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html"
-                         " for details" << std::endl;
-            return false;
-        }
-
-        std::string capProperty = field->camelcase_name();
-        capProperty[0] = ::toupper(capProperty[0]);
-
-        propertyMap = {{"type", typeName},
-            {"property_name", field->camelcase_name()},
-            {"property_name_cap", capProperty}};
-        return true;
-    }
-
-    void printPreamble() {
-        mPrinter.Print("#pragma once\n"
-                       "#include <QObject>\n");
-    }
-
-    void printNamespaces() {
-        std::vector<std::string> namespaces;
-        utils::split(mPackage, namespaces, '.');
-        mNamespaceCount = namespaces.size();
-        for(auto ns: namespaces) {
-            mPrinter.Print({{"namespace", ns}}, NamespaceTemplate);
-        }
-    }
-
-    void printClass() {
-        mPrinter.Print({{"classname", mMessage->name()}}, StartTemplate);
-
-        //private section
-        for(int i = 0; i < mMessage->field_count(); i++) {
-            printField(mMessage->field(i), PropertyTemplate);
-        }
-        for(int i = 0; i < mMessage->field_count(); i++) {
-            printField(mMessage->field(i), MemberTemplate);
-        }
-        printQEnums();
-
-        //public section
-        printPublic();
-        printConstructor();
-        for(int i = 0; i < mMessage->field_count(); i++) {
-            printField(mMessage->field(i), GetterTemplate);
-        }
-        for(int i = 0; i < mMessage->field_count(); i++) {
-            auto field = mMessage->field(i);
-            if (field->type() == FieldDescriptor::TYPE_MESSAGE
-                    || field->type() == FieldDescriptor::TYPE_STRING) {
-                printField(field, SetterTemplateComplexType);
-            } else {
-                printField(field, SetterTemplateSimpleType);
-            }
-        }
-        mPrinter.Print("\nsignals:\n");
-        for(int i = 0; i < mMessage->field_count(); i++) {
-            printField(mMessage->field(i), SignalTemplate);
-        }
-    }
-
-    void printField(const FieldDescriptor* field, const char* fieldTemplate) {
-        std::map<std::string, std::string> propertyMap;
-        if(producePropertyMap(field, propertyMap)) {
-            mPrinter.Print(propertyMap, fieldTemplate);
-        }
-    }
-
-    void enclose() {
-        mPrinter.Print("};\n");
-        while(mNamespaceCount > 0) {
-            mPrinter.Print("}\n");
-            --mNamespaceCount;
-        }
-    }
-
-    std::string getTypeName(const FieldDescriptor* field) {
-        string typeName;
-        if (field->type() == FieldDescriptor::TYPE_MESSAGE) {
-            typeName = field->message_type()->name();
-        } else if (field->type() == FieldDescriptor::TYPE_ENUM) {
-            typeName = field->enum_type()->name();
-        } else {
-            auto it = TypeReflection.find(field->type());
-            if(it != std::end(TypeReflection)) {
-                typeName = it->second;
-            }
-        }
-
-        if (field->is_repeated()) {
-            typeName = typeName.append("Model");
-        }
-
-        return typeName;
-    }
-
-    void printQEnums() {
-        if (mMessage->enum_type_count() <= 0) {
-            return;
-        }
-
-        mPrinter.Print("    Q_ENUMS(");
-        for(int i = 0; mMessage->enum_type_count(); i++) {
-            const auto enumDescr = mMessage->enum_type(i);
-            mPrinter.Print(enumDescr->name().c_str());
-        }
-        mPrinter.Print(")\n");
-        printPublic();
-        for(int i = 0; mMessage->enum_type_count(); i++) {
-            const auto enumDescr = mMessage->enum_type(i);
-            mPrinter.Print({{"enum", enumDescr->name()}}, "    enum $enum$ {\n");
-            for (int j = 0; j < enumDescr->value_count(); j++) {
-                const auto valueDescr = enumDescr->value(j);
-                mPrinter.Print({{"enumvalue", valueDescr->name()},
-                                {"value", std::to_string(valueDescr->number())}}, "        $enumvalue$ = $value$,\n");
-            }
-            mPrinter.Print("};\n");
-        }
-    }
+class GlobalEnumsGenerator : public ClassGeneratorBase
+{
+    const FileDescriptor* mFile;
 
-    void printConstructor() {
-        //FIXME: Explicit default values are not allowed in proto3 seems
-        //this function is useless
-        mPrinter.Print({{"classname", mMessage->name()}},
-                       "    $classname$(QObject parent = nullptr) : QObject(parent)\n");
-        for (int i = 0; i < mMessage->field_count(); i++) {
-            const FieldDescriptor* field = mMessage->field(i);
-            std::string defaultValue;
-            if (field->has_default_value()) {
-                switch(field->type()) {
-                case FieldDescriptor::TYPE_DOUBLE:
-                    defaultValue = std::to_string(field->default_value_double());
-                    break;
-                case FieldDescriptor::TYPE_FLOAT:
-                    defaultValue = std::to_string(field->default_value_float());
-                    break;
-                case FieldDescriptor::TYPE_INT32:
-                case FieldDescriptor::TYPE_UINT32:
-                case FieldDescriptor::TYPE_SFIXED32:
-                case FieldDescriptor::TYPE_SINT32:
-                    defaultValue = std::to_string(field->default_value_int32());
-                    break;
-                case FieldDescriptor::TYPE_BOOL:
-                    defaultValue = field->default_value_bool() ? "true" : "false";
-                    break;
-                case FieldDescriptor::TYPE_STRING:
-                    defaultValue = field->default_value_string();
-                    break;
-                case FieldDescriptor::TYPE_ENUM:
-                    defaultValue = field->default_value_enum()->name();
-                    break;
-                default:
-                    std::cerr << "Default value substitution"
-                                 " is not supported for type"
-                              << field->type_name() << std::endl;
-                    break;
-                }
-                if (defaultValue.size() > 0) {
-                    mPrinter.Print({{"property_name", field->camelcase_name()},
-                                    {"default_value", defaultValue}},
-                                   "    , $m_property_name$($default_value$)\n");
-                }
-            }
-        }
-        mPrinter.Print("    {}\n\n");
-    }
+public:
+    GlobalEnumsGenerator(const FileDescriptor* file, std::unique_ptr<io::ZeroCopyOutputStream> out) :
+        ClassGeneratorBase("GlobalEnums", std::move(out))
+    , mFile(file)
+    {}
 
-    void printPublic() {
-        mPrinter.Print("\npublic:\n");
+    void run() {
+        printPreamble();
+        printNamespaces(mFile->package());
+        printClass();
+        printQEnums<FileDescriptor>(mFile);
+        enclose();
     }
 };
 
@@ -300,8 +102,8 @@ bool QtGenerator::Generate(const FileDescriptor* file,
         classGen.run();
     }
 
-    std::string globalEnumsFilename = file->package() + "globalenums.h";
-    GlobalEnumsGenerator enumGen(std::move(std::unique_ptr<io::ZeroCopyOutputStream>(generator_context->Open(globalEnumsFilename))));
-    enumGen.run(file);
+    std::string globalEnumsFilename = "globalenums.h";
+    GlobalEnumsGenerator enumGen(file, std::move(std::unique_ptr<io::ZeroCopyOutputStream>(generator_context->Open(globalEnumsFilename))));
+    enumGen.run();
     return true;
 }

+ 24 - 1
src/generator/templates.h

@@ -25,7 +25,9 @@
 
 #pragma once
 
+#include <unordered_map>
 #include <string>
+#include <google/protobuf/descriptor.h>
 
 namespace qtprotobuf {
 
@@ -55,8 +57,29 @@ static const char* SetterTemplateComplexType = "    void set$property_name_cap$(
                                               "    }\n";
 
 static const char* SignalTemplate = "    void $property_name$Changed();\n";
-static const char* MemberTemplate = "    $type$ m_$property_name$Changed();\n";
+static const char* MemberTemplate = "    $type$ m_$property_name$;\n";
 
 static const char* EnumTemplate = "$type$";
 
+static const std::unordered_map<::google::protobuf::FieldDescriptor::Type, std::string> TypeReflection = {
+    {::google::protobuf::FieldDescriptor::TYPE_DOUBLE, "qreal"},
+    {::google::protobuf::FieldDescriptor::TYPE_FLOAT, "qreal"},
+    //        {FieldDescriptor::TYPE_INT64, "int"},//Not supported see https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html
+    //        {FieldDescriptor::TYPE_UINT64,"int"},//Not supported see https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html
+    {::google::protobuf::FieldDescriptor::TYPE_INT32, "int"},
+    //        {FieldDescriptor::TYPE_FIXED64, "int"},//Not supported see https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html
+    //        {FieldDescriptor::TYPE_FIXED32, "int"},//Not supported see https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html
+    {::google::protobuf::FieldDescriptor::TYPE_BOOL, "bool"},
+    {::google::protobuf::FieldDescriptor::TYPE_STRING, "QString"},
+    {::google::protobuf::FieldDescriptor::TYPE_GROUP, ""},//Not supported and deprecated in protobuf
+//    {FieldDescriptor::TYPE_MESSAGE, ""},//Custom typename
+    {::google::protobuf::FieldDescriptor::TYPE_BYTES, "QByteArray"},
+    {::google::protobuf::FieldDescriptor::TYPE_UINT32, "int"},//Limited usage see https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html
+//    {FieldDescriptor::TYPE_ENUM, ""},//Custom typename
+    {::google::protobuf::FieldDescriptor::TYPE_SFIXED32, "int"},
+    //        {FieldDescriptor::TYPE_SFIXED64, "int"},//Not supported see https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html
+    {::google::protobuf::FieldDescriptor::TYPE_SINT32, "int"},
+    //        {FieldDescriptor::TYPE_SINT64, "int"},//Not supported see https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html
+};
+
 }

+ 11 - 18
src/generator/enumsgenerator.h → src/generator/utils.h

@@ -23,28 +23,21 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#pragma once
-
 #include <string>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/io/printer.h>
-
-namespace google { namespace protobuf {
-class FileDescriptor;
-namespace io {
-class ZeroCopyOutputStream;
-}
-}}
+#include <vector>
+#include <sstream>
 
 namespace qtprotobuf {
+namespace utils {
 
-class GlobalEnumsGenerator
+void split(const std::string& str, std::vector<std::string>& container, char delim)
 {
-    std::unique_ptr<::google::protobuf::io::ZeroCopyOutputStream> mOutput;
-    ::google::protobuf::io::Printer mPrinter;
-public:
-    GlobalEnumsGenerator(std::unique_ptr<::google::protobuf::io::ZeroCopyOutputStream> out);
-    void run(const ::google::protobuf::FileDescriptor* file);
-};
+    std::stringstream stream(str);
+    std::string token;
+    while (std::getline(stream, token, delim)) {
+        container.push_back(token);
+    }
+}
 
 }
+}