ソースを参照

Migrate to pointers for complex types

- Replace complex types objects fields in messages
  with pointers field
- THIS COMMIT SHOULD NOT BE USED BECAUSE OF COUPLE
  CRITICAL ISSUES IN GENERATED CODE
Alexey Edelev 5 年 前
コミット
3801e1ff93

+ 0 - 1
src/generator/main.cpp

@@ -39,7 +39,6 @@ int main(int argc, char *argv[])
         GeneratorOptions::instance().parseFromEnv(optionsPtr);
     }
     if (GeneratorOptions::instance().isMulti()) {
-        std::cerr << "Run multi generator" << std::endl;
         QtProtobuf::generator::QtGenerator generator;
         return ::google::protobuf::compiler::PluginMain(argc, argv, &generator);
     }

+ 41 - 11
src/generator/protobufclassgenerator.cpp

@@ -57,7 +57,12 @@ void ProtobufClassGenerator::printCopyFunctionality()
 
     Indent();
     for (int i = 0; i < mMessage->field_count(); i++) {
-        printField(mMessage->field(i), Templates::CopyFieldTemplate);
+        auto field = mMessage->field(i);
+        if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map() && !field->is_repeated()) {
+            printField(field, Templates::CopyComplexFieldTemplate);
+        } else {
+            printField(field, Templates::CopyFieldTemplate);
+        }
     }
     Outdent();
 
@@ -67,7 +72,12 @@ void ProtobufClassGenerator::printCopyFunctionality()
 
     Indent();
     for (int i = 0; i < mMessage->field_count(); i++) {
-        printField(mMessage->field(i), Templates::CopyFieldTemplate);
+        auto field = mMessage->field(i);
+        if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map() && !field->is_repeated()) {
+            printField(field, Templates::CopyComplexFieldTemplate);
+        } else {
+            printField(field, Templates::CopyFieldTemplate);
+        }
     }
     mPrinter->Print(Templates::AssignmentOperatorReturnTemplate);
     Outdent();
@@ -85,7 +95,11 @@ void ProtobufClassGenerator::printMoveSemantic()
     for (int i = 0; i < mMessage->field_count(); i++) {
         const FieldDescriptor *field = mMessage->field(i);
         if (isComplexType(field) || field->is_repeated()) {
-            printField(field, Templates::MoveComplexFieldTemplate);
+            if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map() && !field->is_repeated()) {
+                printField(field, Templates::MoveMessageFieldTemplate);
+            } else {
+                printField(field, Templates::MoveComplexFieldTemplate);
+            }
         } else {
             if (field->type() != FieldDescriptor::TYPE_ENUM) {
                 printField(field, Templates::MoveFieldTemplate);
@@ -105,7 +119,11 @@ void ProtobufClassGenerator::printMoveSemantic()
     for (int i = 0; i < mMessage->field_count(); i++) {
         const FieldDescriptor *field = mMessage->field(i);
         if (isComplexType(field) || field->is_repeated()) {
-            printField(field, Templates::MoveComplexFieldTemplate);
+            if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map() && !field->is_repeated()) {
+                printField(field, Templates::MoveMessageFieldTemplate);
+            } else {
+                printField(field, Templates::MoveComplexFieldTemplate);
+            }
         } else {
             if (field->type() != FieldDescriptor::TYPE_ENUM) {
                 printField(field, Templates::MoveFieldTemplate);
@@ -140,7 +158,12 @@ void ProtobufClassGenerator::printComparisonOperators()
                 Indent();
                 isFirst = false;
             }
-            mPrinter->Print(properties, Templates::EqualOperatorPropertyTemplate);
+            if (field->type() == FieldDescriptor::TYPE_MESSAGE
+                    && !field->is_map() && !field->is_repeated()) {
+                mPrinter->Print(properties, Templates::EqualOperatorMessagePropertyTemplate);
+            } else {
+                mPrinter->Print(properties, Templates::EqualOperatorPropertyTemplate);
+            }
         }
     }
 
@@ -424,12 +447,12 @@ void ProtobufClassGenerator::printProperties()
 
     for (int i = 0; i < mMessage->field_count(); i++) {
         const FieldDescriptor *field = mMessage->field(i);
-        if (field->type() == FieldDescriptor::TYPE_MESSAGE) {
-            if (!field->is_map() && !field->is_repeated()) {
+        if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map() && !field->is_repeated()) {
+                printField(field, Templates::GetterPrivateMessageTemplate);
                 printField(field, Templates::GetterMessageTemplate);
-            }
+        } else {
+            printField(field, Templates::GetterTemplate);
         }
-        printField(field, Templates::GetterTemplate);
         if (field->is_repeated()) {
             printField(field, Templates::GetterContainerExtraTemplate);
             if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map()
@@ -443,9 +466,11 @@ void ProtobufClassGenerator::printProperties()
         switch (field->type()) {
         case FieldDescriptor::TYPE_MESSAGE:
             if (!field->is_map() && !field->is_repeated()) {
+                printField(field, Templates::SetterPrivateTemplateMessageType);
                 printField(field, Templates::SetterTemplateMessageType);
+            } else {
+                printField(field, Templates::SetterTemplateComplexType);
             }
-            printField(field, Templates::SetterTemplateComplexType);
             break;
         case FieldDescriptor::FieldDescriptor::TYPE_STRING:
         case FieldDescriptor::FieldDescriptor::TYPE_BYTES:
@@ -481,7 +506,12 @@ void ProtobufClassGenerator::printClassMembers()
 {
     Indent();
     for (int i = 0; i < mMessage->field_count(); i++) {
-        printField(mMessage->field(i), Templates::MemberTemplate);
+        auto field = mMessage->field(i);
+        if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map() && !field->is_repeated()) {
+            printField(field, Templates::ComplexMemberTemplate);
+        } else {
+            printField(field, Templates::MemberTemplate);
+        }
     }
     Outdent();
 }

+ 8 - 1
src/generator/protobufsourcegenerator.cpp

@@ -158,8 +158,15 @@ void ProtobufSourceGenerator::printConstructor()
     for (int i = 0; i < mMessage->field_count(); i++) {
         const FieldDescriptor *field = mMessage->field(i);
         std::string fieldName = field->name();
+        auto fieldTypeName = getTypeName(field, mMessage);
         fieldName[0] =  static_cast<char>(::tolower(fieldName[0]));
-        mPrinter->Print({{"property_name", fieldName}}, Templates::PropertyInitializerTemplate);
+        if (field->type() == FieldDescriptor::TYPE_MESSAGE
+                && !field->is_map() && !field->is_repeated()) {
+            mPrinter->Print({{"property_name", fieldName}, {"type", fieldTypeName}}, Templates::MessagePropertyInitializerTemplate);
+        } else {
+            mPrinter->Print({{"property_name", fieldName}}, Templates::PropertyInitializerTemplate);
+        }
+
     }
     mPrinter->Print(Templates::ConstructorContentTemplate);
 }

+ 22 - 6
src/generator/templates.cpp

@@ -81,6 +81,7 @@ const char *Templates::MessagePropertyTemplate = "Q_PROPERTY($type$ *$property_n
 const char *Templates::QmlListPropertyTemplate = "Q_PROPERTY(QQmlListProperty<$type_nolist$> $property_name$Data READ $property_name$_l NOTIFY $property_name$Changed)\n";
 
 const char *Templates::MemberTemplate = "$type$ m_$property_name$;\n";
+const char *Templates::ComplexMemberTemplate = "$type$ *m_$property_name$;\n";
 const char *Templates::EnumMemberTemplate = "::$type$ m_$property_name$;\n";
 const char *Templates::PublicBlockTemplate = "\npublic:\n";
 const char *Templates::PrivateBlockTemplate = "\nprivate:\n";
@@ -96,6 +97,8 @@ const char *Templates::MoveConstructorTemplate = "$classname$($classname$ &&othe
 const char *Templates::DeletedCopyConstructorTemplate = "$classname$(const $classname$ &) = delete;\n";
 const char *Templates::DeletedMoveConstructorTemplate = "$classname$($classname$ &&) = delete;\n";
 const char *Templates::CopyFieldTemplate = "set$property_name_cap$(other.m_$property_name$);\n";
+const char *Templates::CopyComplexFieldTemplate = "set$property_name_cap$(*other.m_$property_name$);\n";
+const char *Templates::MoveMessageFieldTemplate = "*m_$property_name$ = std::move(*other.m_$property_name$);\n";
 const char *Templates::MoveComplexFieldTemplate = "m_$property_name$ = std::move(other.m_$property_name$);\n";
 const char *Templates::MoveFieldTemplate = "set$property_name_cap$(std::exchange(other.m_$property_name$, 0));\n"
                                            "other.$property_name$Changed();\n";
@@ -106,12 +109,17 @@ const char *Templates::MoveAssignmentOperatorTemplate = "$classname$ &operator =
 const char *Templates::EqualOperatorTemplate = "bool operator ==(const $type$ &other) const {\n"
                                                "    return ";
 const char *Templates::EqualOperatorPropertyTemplate = "m_$property_name$ == other.m_$property_name$";
+const char *Templates::EqualOperatorMessagePropertyTemplate = "*m_$property_name$ == *other.m_$property_name$";
 const char *Templates::NotEqualOperatorTemplate = "bool operator !=(const $type$ &other) const {\n"
                                                   "    return !this->operator ==(other);\n"
                                                   "}\n\n";
 
-const char *Templates::GetterMessageTemplate = "$type$ *$property_name$_p() const {\n" //formally const...
-                                        "    return const_cast<$type$*>(&m_$property_name$);\n"
+const char *Templates::GetterPrivateMessageTemplate = "$type$ *$property_name$_p() const {\n"
+                                        "    return m_$property_name$;\n"
+                                        "}\n\n";
+
+const char *Templates::GetterMessageTemplate = "$type$ $property_name$() const {\n"
+                                        "    return *m_$property_name$;\n"
                                         "}\n\n";
 
 const char *Templates::GetterTemplate = "$type$ $property_name$() const {\n"
@@ -126,19 +134,26 @@ const char *Templates::QmlListGetterTemplate = "QQmlListProperty<$type_nolist$>
                                                "    return QtProtobuf::constructQmlListProperty<$type_nolist$>(this, &m_$property_name$);\n"
                                                "}\n\n";
 
-const char *Templates::SetterTemplateMessageType = "void set$property_name_cap$_p($type$ *$property_name$) {\n"
+const char *Templates::SetterPrivateTemplateMessageType = "void set$property_name_cap$_p($type$ *$property_name$) {\n"
                                                    "    if ($property_name$ == nullptr) {\n"
-                                                   "        m_$property_name$ = {};\n"
+                                                   "        *m_$property_name$ = {};\n"
                                                    "        return;\n"
                                                    "    }\n"
-                                                   "    if (m_$property_name$ != *$property_name$) {\n"
-                                                   "        m_$property_name$ = *$property_name$;\n"
+                                                   "    if (*m_$property_name$ != *$property_name$) {\n"
+                                                   "        *m_$property_name$ = *$property_name$;\n"
                                                    "        $property_name$Changed();\n"
                                                    "    }\n"
                                                    "    //NOTE: take ownership of value\n"
                                                    "    delete $property_name$;\n"
                                                    "}\n\n";
 
+const char *Templates::SetterTemplateMessageType = "void set$property_name_cap$(const $type$ &$property_name$) {\n"
+                                                   "    if (*m_$property_name$ != $property_name$) {\n"
+                                                   "        *m_$property_name$ = $property_name$;\n"
+                                                   "        $property_name$Changed();\n"
+                                                   "    }\n"
+                                                   "}\n\n";
+
 const char *Templates::SetterTemplateComplexType = "void set$property_name_cap$(const $type$ &$property_name$) {\n"
                                                    "    if (m_$property_name$ != $property_name$) {\n"
                                                    "        m_$property_name$ = $property_name$;\n"
@@ -166,6 +181,7 @@ const char *Templates::SimpleBlockEnclosureTemplate = "}\n\n";
 const char *Templates::SemicolonBlockEnclosureTemplate = "};\n";
 const char *Templates::EmptyBlockTemplate = "{}\n\n";
 const char *Templates::PropertyInitializerTemplate = "\n    , m_$property_name$($property_name$)";
+const char *Templates::MessagePropertyInitializerTemplate = "\n    , m_$property_name$(new $type$($property_name$))";
 const char *Templates::ConstructorContentTemplate = "\n{\n}\n";
 
 const char *Templates::DeclareMetaTypeTemplate = "Q_DECLARE_METATYPE($namespaces$::$classname$)\n";

+ 7 - 0
src/generator/templates.h

@@ -64,6 +64,7 @@ public:
     static const char *QmlListPropertyTemplate;
     static const char *QmlListGetterTemplate;
     static const char *MemberTemplate;
+    static const char *ComplexMemberTemplate;
     static const char *EnumMemberTemplate;
     static const char *PublicBlockTemplate;
     static const char *PrivateBlockTemplate;
@@ -78,6 +79,8 @@ public:
     static const char *DeletedCopyConstructorTemplate;
     static const char *DeletedMoveConstructorTemplate;
     static const char *CopyFieldTemplate;
+    static const char *CopyComplexFieldTemplate;
+    static const char *MoveMessageFieldTemplate;
     static const char *MoveComplexFieldTemplate;
     static const char *MoveFieldTemplate;
     static const char *EnumMoveFieldTemplate;
@@ -86,12 +89,15 @@ public:
     static const char *MoveAssignmentOperatorTemplate;
     static const char *EqualOperatorTemplate;
     static const char *EqualOperatorPropertyTemplate;
+    static const char *EqualOperatorMessagePropertyTemplate;
     static const char *NotEqualOperatorTemplate;
     static const char *GetterTemplate;
     static const char *GetterContainerExtraTemplate;
+    static const char *GetterPrivateMessageTemplate;
     static const char *GetterMessageTemplate;
     static const char *SetterTemplateSimpleType;
     static const char *SetterTemplateComplexType;
+    static const char *SetterPrivateTemplateMessageType;
     static const char *SetterTemplateMessageType;
     static const char *SignalsBlockTemplate;
     static const char *SignalTemplate;
@@ -102,6 +108,7 @@ public:
     static const char *SemicolonBlockEnclosureTemplate;
     static const char *EmptyBlockTemplate;
     static const char *PropertyInitializerTemplate;
+    static const char *MessagePropertyInitializerTemplate;
     static const char *ConstructorContentTemplate;
     static const char *DeclareMetaTypeTemplate;
     static const char *DeclareMetaTypeListTemplate;