Browse Source

Add local enums lists registration

Tatyana Borisova 6 years ago
parent
commit
19a0eb404a

+ 12 - 0
src/generator/classgeneratorbase.cpp

@@ -110,3 +110,15 @@ void ClassGeneratorBase::printMetaTypeDeclaration()
                    Templates::DeclareComplexListTypeTemplate);
 }
 
+bool ClassGeneratorBase::isLocalMessageEnum(const google::protobuf::Descriptor *message,
+                                            const ::google::protobuf::FieldDescriptor *field)
+{
+    assert(field->enum_type() != nullptr);
+    for (int i = 0; i < message->enum_type_count(); i++) {
+        const auto enumDescr = message->enum_type(i);
+        if (enumDescr && enumDescr->full_name() == field->enum_type()->full_name()) {
+            return true;
+        }
+    }
+    return false;
+}

+ 2 - 1
src/generator/classgeneratorbase.h

@@ -65,7 +65,8 @@ protected:
     void printMetaTypeDeclaration();
     void encloseNamespaces();
     void encloseNamespaces(int count);
-
+    bool isLocalMessageEnum(const google::protobuf::Descriptor *message,
+                            const ::google::protobuf::FieldDescriptor *field);
 
     template<typename T>
     void printQEnums(const T *message) {

+ 22 - 14
src/generator/protobufclassgenerator.cpp

@@ -280,7 +280,11 @@ std::string ProtobufClassGenerator::getTypeName(const FieldDescriptor *field)
         namespaceTypeName = getNamespacesList(enumType, typeNamespace);
         EnumVisibility visibility = getEnumVisibility(field);
         if (visibility == LOCAL_ENUM) {
-            typeName = typeName.append(enumType->name());
+            if(field->is_repeated()) {
+                typeName = typeName.append(mClassName + "::" + enumType->name());
+            } else {
+                typeName = typeName.append(enumType->name());
+            }
         } else if (visibility == GLOBAL_ENUM) {
             typeName = namespaceTypeName.append(Templates::GlobalEnumClassNameTemplate)
                     .append("::").append(enumType->name());
@@ -407,6 +411,21 @@ void ProtobufClassGenerator::printMaps()
     Outdent();
 }
 
+void ProtobufClassGenerator::printLocalEmumsMetaTypesDeclaration()
+{
+    for (int i = 0; i < mMessage->field_count(); i++) {
+        const FieldDescriptor* field = mMessage->field(i);
+        if (field == nullptr || field->enum_type() == nullptr)
+            continue;
+
+        if (field->type() == FieldDescriptor::TYPE_ENUM
+                && isLocalMessageEnum(mMessage, field)) {
+             mPrinter.Print({{"classname", mClassName + "::" + field->enum_type()->name() + "List"},
+                             {"namespaces", mNamespacesColonDelimited}}, Templates::DeclareMetaTypeTemplate);
+        }
+    }
+}
+
 void ProtobufClassGenerator::printMapsMetaTypesDeclaration()
 {
     for (int i = 0; i < mMessage->field_count(); i++) {
@@ -492,7 +511,7 @@ ProtobufClassGenerator::EnumVisibility ProtobufClassGenerator::getEnumVisibility
 {
     assert(field->enum_type() != nullptr);
 
-    if (isLocalMessageEnum(field)) {
+    if (isLocalMessageEnum(mMessage, field)) {
         return LOCAL_ENUM;
     }
 
@@ -511,18 +530,6 @@ ProtobufClassGenerator::EnumVisibility ProtobufClassGenerator::getEnumVisibility
     return GLOBAL_ENUM;
 }
 
-bool ProtobufClassGenerator::isLocalMessageEnum(const ::google::protobuf::FieldDescriptor *field)
-{
-    assert(field->enum_type() != nullptr);
-    for (int i = 0; i < mMessage->enum_type_count(); i++) {
-        const auto enumDescr = mMessage->enum_type(i);
-        if (enumDescr->full_name() == field->enum_type()->full_name()) {
-            return true;
-        }
-    }
-    return false;
-}
-
 void ProtobufClassGenerator::printClassMembers()
 {
     Indent();
@@ -563,4 +570,5 @@ void ProtobufClassGenerator::run()
     encloseNamespaces();
     printMetaTypeDeclaration();
     printMapsMetaTypesDeclaration();
+    printLocalEmumsMetaTypesDeclaration();
 }

+ 1 - 1
src/generator/protobufclassgenerator.h

@@ -71,11 +71,11 @@ public:
     void printInclude(const google::protobuf::FieldDescriptor *field, std::set<std::string> &existingIncludes);
     void printMaps();
     void printMapsMetaTypesDeclaration();
+    void printLocalEmumsMetaTypesDeclaration();
 
     std::set<std::string> extractModels() const;
 
 private:
-    bool isLocalMessageEnum(const ::google::protobuf::FieldDescriptor *field);
     EnumVisibility getEnumVisibility(const ::google::protobuf::FieldDescriptor *field);
 
 

+ 9 - 2
src/generator/protobufsourcegenerator.cpp

@@ -38,7 +38,6 @@ ProtobufSourceGenerator::ProtobufSourceGenerator(const google::protobuf::Descrip
     ClassSourceGeneratorBase(message->full_name(), std::move(out))
   , mMessage(message)
 {
-
 }
 
 void ProtobufSourceGenerator::printRegisterBody()
@@ -48,7 +47,15 @@ void ProtobufSourceGenerator::printRegisterBody()
 
     for (int i = 0; i < mMessage->field_count(); i++) {
         const FieldDescriptor* field = mMessage->field(i);
-        if (field->is_map()) {
+        if (field->type() == FieldDescriptor::TYPE_ENUM
+                && isLocalMessageEnum(mMessage, field)) {
+            mPrinter.Print({{"classname", mClassName + "::" + field->enum_type()->name() + "List"},
+                            {"namespaces", mNamespacesColonDelimited}},
+                           Templates::RegisterMetaTypeTemplateNoNamespace);
+            mPrinter.Print({{"classname", mClassName+ "::" + field->enum_type()->name() + "List"},
+                            {"namespaces", mNamespacesColonDelimited}},
+                           Templates::RegisterMetaTypeTemplate);
+        } else if (field->is_map()) {
             mPrinter.Print({{"classname", field->message_type()->name()},
                             {"namespaces", mClassName}},
                            Templates::RegisterMetaTypeTemplate);

+ 1 - 1
src/generator/protobufsourcegenerator.h

@@ -32,7 +32,7 @@ namespace generator {
 
 class ProtobufSourceGenerator : public ClassSourceGeneratorBase
 {
-    const google::protobuf::Descriptor* mMessage;
+    const google::protobuf::Descriptor *mMessage;
 public:
     ProtobufSourceGenerator(const google::protobuf::Descriptor *message, std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> out);
     void printRegisterBody();

+ 1 - 0
src/generator/templates.cpp

@@ -128,6 +128,7 @@ const char *Templates::ConstructorContentTemplate = "\n{\n    registerTypes();\n
 
 const char *Templates::DeclareMetaTypeTemplate = "Q_DECLARE_METATYPE($namespaces$::$classname$)\n";
 const char *Templates::DeclareComplexListTypeTemplate = "Q_DECLARE_METATYPE($namespaces$::$classname$List)\n";
+const char *Templates::RegisterMetaTypeDefaultTemplate = "        qRegisterMetaType<$namespaces$::$classname$>();\n";
 const char *Templates::RegisterMetaTypeTemplateNoNamespace = "        qRegisterMetaType<$namespaces$::$classname$>(\"$classname$\");\n";
 const char *Templates::RegisterMetaTypeTemplate = "        qRegisterMetaType<$namespaces$::$classname$>(\"$namespaces$::$classname$\");\n";
 

+ 1 - 0
src/generator/templates.h

@@ -89,6 +89,7 @@ public:
     static const char *ConstructorContentTemplate;
     static const char *DeclareMetaTypeTemplate;
     static const char *DeclareComplexListTypeTemplate;
+    static const char *RegisterMetaTypeDefaultTemplate;
     static const char *RegisterMetaTypeTemplate;
     static const char *RegisterMetaTypeTemplateNoNamespace;
     static const char *QEnumTemplate;

+ 1 - 1
tests/proto/simpletest.proto

@@ -23,7 +23,7 @@ message SimpleEnumListMessage {
     LOCAL_ENUM_VALUE3 = 3;
   }
 
-  repeated LocalEnum localEnumList = 2;
+  repeated LocalEnum localEnumList = 1;
 }
 
 message SimpleFileEnumMessage {

+ 29 - 43
tests/simpletest.cpp

@@ -288,22 +288,19 @@ TEST_F(SimpleTest, SimpleLocalEnumListTest)
     ASSERT_GT(SimpleEnumListMessage::staticMetaObject.enumeratorCount(), 0);
     const char* propertyName = "localEnumList";
     SimpleEnumListMessage test;
-    int propertyNumber = SimpleEnumListMessage::propertyOrdering.at(2); //See simpletest.proto
-    ASSERT_STREQ(SimpleEnumListMessage::staticMetaObject.property(propertyNumber).typeName(), "LocalEnumList");
-    ASSERT_EQ(SimpleEnumListMessage::staticMetaObject.property(propertyNumber).userType(), qMetaTypeId<SimpleEnumListMessage::LocalEnumList>());
+    int propertyNumber = SimpleEnumListMessage::propertyOrdering.at(1); //See simpletest.proto
+    ASSERT_STREQ(SimpleEnumListMessage::staticMetaObject.property(propertyNumber).typeName(), "SimpleEnumListMessage::LocalEnumList");
+    ASSERT_EQ(SimpleEnumListMessage::staticMetaObject.property(propertyNumber).userType(), qMetaTypeId<qtprotobufnamespace::tests::SimpleEnumListMessage::LocalEnumList>());
     ASSERT_STREQ(SimpleEnumListMessage::staticMetaObject.property(propertyNumber).name(), propertyName);
-    ASSERT_TRUE(test.setProperty(propertyName, QVariant::fromValue<SimpleEnumListMessage::LocalEnumList>({SimpleEnumListMessage::LOCAL_ENUM_VALUE2,
-                                                                                                      SimpleEnumListMessage::LOCAL_ENUM_VALUE2,
-                                                                                                      SimpleEnumListMessage::LOCAL_ENUM_VALUE1,
-                                                                                                      SimpleEnumListMessage::LOCAL_ENUM_VALUE3})));
-    ASSERT_TRUE(test.property(propertyName).value<SimpleEnumListMessage::LocalEnum>() == QVariant::fromValue<SimpleEnumListMessage::LocalEnumList>({SimpleEnumListMessage::LOCAL_ENUM_VALUE2,
-                                                                                                                                            SimpleEnumListMessage::LOCAL_ENUM_VALUE2,
-                                                                                                                                            SimpleEnumListMessage::LOCAL_ENUM_VALUE1,
-                                                                                                                                            SimpleEnumListMessage::LOCAL_ENUM_VALUE3}));
-    ASSERT_TRUE(test.localEnumList() == SimpleEnumListMessage::LocalEnumList({SimpleEnumListMessage::LOCAL_ENUM_VALUE2,
-                                                                          SimpleEnumListMessage::LOCAL_ENUM_VALUE2,
-                                                                          SimpleEnumListMessage::LOCAL_ENUM_VALUE1,
-                                                                          SimpleEnumListMessage::LOCAL_ENUM_VALUE3}));
+
+    SimpleEnumListMessage::LocalEnumList value({SimpleEnumListMessage::LOCAL_ENUM_VALUE2,
+                                                SimpleEnumListMessage::LOCAL_ENUM_VALUE2,
+                                                SimpleEnumListMessage::LOCAL_ENUM_VALUE1,
+                                                SimpleEnumListMessage::LOCAL_ENUM_VALUE3});
+
+    ASSERT_TRUE(test.setProperty(propertyName, QVariant::fromValue<SimpleEnumListMessage::LocalEnumList>(value)));
+    ASSERT_TRUE(test.property(propertyName).value<SimpleEnumListMessage::LocalEnumList>() == value);
+    ASSERT_TRUE(test.localEnumList() == value);
 }
 
 TEST_F(SimpleTest, SimpleExternalEnumMessageTest)
@@ -353,22 +350,15 @@ TEST_F(SimpleTest, SimpleFileEnumsTest)
     ASSERT_STREQ(SimpleFileEnumMessage::staticMetaObject.property(propertyNumber).typeName(), "GlobalEnums::TestEnumList");
     ASSERT_EQ(SimpleFileEnumMessage::staticMetaObject.property(propertyNumber).userType(), qMetaTypeId<GlobalEnums::TestEnumList>());
     ASSERT_STREQ(SimpleFileEnumMessage::staticMetaObject.property(propertyNumber).name(), propertyName);
-    ASSERT_TRUE(test.setProperty(propertyName, QVariant::fromValue<GlobalEnums::TestEnumList>({GlobalEnums::TEST_ENUM_VALUE1,
-                                                                                               GlobalEnums::TEST_ENUM_VALUE3,
-                                                                                               GlobalEnums::TEST_ENUM_VALUE4,
-                                                                                               GlobalEnums::TEST_ENUM_VALUE2,
-                                                                                               GlobalEnums::TEST_ENUM_VALUE1})));
-
-    ASSERT_TRUE(test.property(propertyName).value<GlobalEnums::TestEnum>() == QVariant::fromValue<GlobalEnums::TestEnumList>({GlobalEnums::TEST_ENUM_VALUE1,
-                                                                                                                              GlobalEnums::TEST_ENUM_VALUE3,
-                                                                                                                              GlobalEnums::TEST_ENUM_VALUE4,
-                                                                                                                              GlobalEnums::TEST_ENUM_VALUE2,
-                                                                                                                              GlobalEnums::TEST_ENUM_VALUE1}));
-    ASSERT_TRUE(test.globalEnumList() == GlobalEnums::TestEnumList({GlobalEnums::TEST_ENUM_VALUE1,
-                                                                    GlobalEnums::TEST_ENUM_VALUE3,
-                                                                    GlobalEnums::TEST_ENUM_VALUE4,
-                                                                    GlobalEnums::TEST_ENUM_VALUE2,
-                                                                    GlobalEnums::TEST_ENUM_VALUE1}));
+
+    GlobalEnums::TestEnumList value({GlobalEnums::TEST_ENUM_VALUE1,
+                                     GlobalEnums::TEST_ENUM_VALUE3,
+                                     GlobalEnums::TEST_ENUM_VALUE4,
+                                     GlobalEnums::TEST_ENUM_VALUE2,
+                                     GlobalEnums::TEST_ENUM_VALUE1});
+    ASSERT_TRUE(test.setProperty(propertyName, QVariant::fromValue<GlobalEnums::TestEnumList>(value)));
+    ASSERT_TRUE(test.property(propertyName).value<GlobalEnums::TestEnumList>() == value);
+    ASSERT_TRUE(test.globalEnumList() == value);
 }
 
 TEST_F(SimpleTest, ComplexMessageTest)
@@ -631,18 +621,14 @@ TEST_F(SimpleTest, StepChildEnumListMessageTest)
     ASSERT_STREQ(StepChildEnumMessage::staticMetaObject.property(propertyNumber).typeName(), "qtprotobufnamespace::tests::SimpleEnumMessage::LocalEnumList");
     ASSERT_EQ(StepChildEnumMessage::staticMetaObject.property(propertyNumber).userType(), qMetaTypeId<qtprotobufnamespace::tests::SimpleEnumMessage::LocalEnumList>());
     ASSERT_STREQ(StepChildEnumMessage::staticMetaObject.property(propertyNumber).name(), propertyName);
-    ASSERT_TRUE(test.setProperty(propertyName, QVariant::fromValue<qtprotobufnamespace::tests::SimpleEnumMessage::LocalEnumList>({SimpleEnumMessage::LOCAL_ENUM_VALUE2,
-                                                                                                                                  SimpleEnumMessage::LOCAL_ENUM_VALUE2,
-                                                                                                                                  SimpleEnumMessage::LOCAL_ENUM_VALUE1,
-                                                                                                                                  SimpleEnumMessage::LOCAL_ENUM_VALUE3})));
-    ASSERT_TRUE(test.property(propertyName).value<SimpleEnumMessage::LocalEnum>() == QVariant::fromValue<SimpleEnumMessage::LocalEnumList>({SimpleEnumMessage::LOCAL_ENUM_VALUE2,
-                                                                                                                                            SimpleEnumMessage::LOCAL_ENUM_VALUE2,
-                                                                                                                                            SimpleEnumMessage::LOCAL_ENUM_VALUE1,
-                                                                                                                                            SimpleEnumMessage::LOCAL_ENUM_VALUE3}));
-    ASSERT_TRUE(test.localStepChildList() == SimpleEnumMessage::LocalEnumList({SimpleEnumMessage::LOCAL_ENUM_VALUE2,
-                                                                               SimpleEnumMessage::LOCAL_ENUM_VALUE2,
-                                                                               SimpleEnumMessage::LOCAL_ENUM_VALUE1,
-                                                                               SimpleEnumMessage::LOCAL_ENUM_VALUE3}));
+
+    qtprotobufnamespace::tests::SimpleEnumMessage::LocalEnumList value({SimpleEnumMessage::LOCAL_ENUM_VALUE2,
+                                                                        SimpleEnumMessage::LOCAL_ENUM_VALUE2,
+                                                                        SimpleEnumMessage::LOCAL_ENUM_VALUE1,
+                                                                        SimpleEnumMessage::LOCAL_ENUM_VALUE3});
+    ASSERT_TRUE(test.setProperty(propertyName, QVariant::fromValue<qtprotobufnamespace::tests::SimpleEnumMessage::LocalEnumList>(value)));
+    ASSERT_TRUE(test.property(propertyName).value<SimpleEnumMessage::LocalEnumList>() == value);
+    ASSERT_TRUE(test.localStepChildList() == value);
 }