Sfoglia il codice sorgente

Add ordering map field->property

- Add ordering map to generated classes
- Fix couple of templates
Alexey Edelev 6 anni fa
parent
commit
709c3c1bce

+ 8 - 2
src/generator/classgeneratorbase.cpp

@@ -175,9 +175,13 @@ void ClassGeneratorBase::printField(const FieldDescriptor *field, const char *fi
     }
 }
 
-void ClassGeneratorBase::enclose()
+void ClassGeneratorBase::encloseClass()
 {
     mPrinter.Print(SemicolonBlockEnclosureTemplate);
+}
+
+void ClassGeneratorBase::enclose()
+{
     while (mNamespaceCount > 0) {
         mPrinter.Print(SimpleBlockEnclosureTemplate);
         --mNamespaceCount;
@@ -232,6 +236,7 @@ void ClassGeneratorBase::printCopyFunctionality(const ::google::protobuf::Descri
     for (int i = 0; i < message->field_count(); i++) {
         printField(message->field(i), CopyFieldTemplate);
     }
+    mPrinter.Print(AssignmentOperatorReturnTemplate);
     Outdent();
 
     mPrinter.Print(SimpleBlockEnclosureTemplate);
@@ -257,6 +262,7 @@ void ClassGeneratorBase::printMoveSemantic(const ::google::protobuf::Descriptor
     for (int i = 0; i < message->field_count(); i++) {
         printField(message->field(i), CopyFieldTemplate);
     }
+    mPrinter.Print(AssignmentOperatorReturnTemplate);
     Outdent();
 
     mPrinter.Print(SimpleBlockEnclosureTemplate);
@@ -321,7 +327,7 @@ void ClassGeneratorBase::printEqualOperator(const Descriptor *message)
     bool isFirst = true;
     PropertyMap properties;
     mPrinter.Print({{"type", mClassName}}, EqualOperatorTemplate);
-    for (int i = 1; i < message->field_count(); i++) {
+    for (int i = 0; i < message->field_count(); i++) {
         const FieldDescriptor* field = message->field(i);
         if (producePropertyMap(field, properties)) {
             if (!isFirst) {

+ 1 - 0
src/generator/classgeneratorbase.h

@@ -57,6 +57,7 @@ protected:
     void printNamespaces(const std::string &package);
     void printClass();
     void printField(const ::google::protobuf::FieldDescriptor *field, const char *fieldTemplate);
+    void encloseClass();
     void enclose();
     std::string getTypeName(const ::google::protobuf::FieldDescriptor *field);
 

+ 25 - 0
src/generator/generator.cpp

@@ -77,6 +77,10 @@ public:
         printNamespaces(mPackage);
         printClass();
         printProperties(mMessage);
+        printPublic();
+        printFieldsOrderingDefinition();
+        encloseClass();
+        printFieldsOrdering();
         enclose();
     }
 
@@ -84,6 +88,26 @@ public:
         return mExtractedModels;
     }
 
+    void printFieldsOrderingDefinition() {
+        Indent();
+        mPrinter.Print(FieldsOrderingDefinitionContainerTemplate);
+        Outdent();
+    }
+
+    void printFieldsOrdering() {
+        mPrinter.Print({{"type", mClassName}}, FieldsOrderingContainerTemplate);
+        Indent();
+        for (int i = 0; i < mMessage->field_count(); i++) {
+            const FieldDescriptor* field = mMessage->field(i);
+            if (i != 0) {
+                mPrinter.Print("\n,");
+            }
+            mPrinter.Print({{"field_number", std::to_string(field->number())},
+                            {"property_number", std::to_string(i)}}, FieldOrderTemplate);
+        }
+        Outdent();
+        mPrinter.Print(SemicolonBlockEnclosureTemplate);
+    }
 };
 
 class GlobalEnumsGenerator : public ClassGeneratorBase
@@ -101,6 +125,7 @@ public:
         printNamespaces(mFile->package());
         printClass();
         printQEnums<FileDescriptor>(mFile);
+        encloseClass();
         enclose();
     }
 };

+ 13 - 7
src/generator/templates.h

@@ -33,15 +33,15 @@ namespace qtprotobuf {
 
 static const char *PreambleTemplate = "/* This file is autogenerated. DO NOT CHANGE. All changes will be lost */\n\n"
                                       "#pragma once\n\n"
-                                     "#include <QObject>\n";
+                                      "#include <QObject>\n"
+                                      "#include <unordered_map>\n\n";
 
 static const char *InternalIncludeTemplate =  "#include \"$type_lower$.h\"\n";
 static const char *ExternalIncludeTemplate = "#include <$type$>\n";
 static const char *ListModelsIncludeTemplate = "\n#include \"listmodels.h\"\n";
 static const char *UniversalListModelIncludeTemplate = "\n#include <universallistmodel.h>\n";
 
-static const char *NamespaceTemplate = "\nnamespace $namespace$\n"
-                                  "{\n";
+static const char *NamespaceTemplate = "\nnamespace $namespace$ {\n";
 
 static const char *ClassDefinitionTemplate = "\nclass $classname$ : public QObject\n"
                       "{\n"
@@ -53,10 +53,11 @@ static const char *PublicBlockTemplate = "\npublic:\n";
 static const char *EnumDefinitionTemplate = "enum $enum$ {\n";
 static const char *EnumFieldTemplate = "$enumvalue$ = $value$,\n";
 static const char *ConstructorTemplate = "$classname$(QObject *parent = nullptr) : QObject(parent)\n";
-static const char *CopyConstructorTemplate = "$classname$(const $classname$ &other) {\n";
-static const char *MoveConstructorTemplate = "$classname$(const $classname$ &&other) {\n";
+static const char *CopyConstructorTemplate = "$classname$(const $classname$ &other) : QObject() {\n";
+static const char *MoveConstructorTemplate = "$classname$(const $classname$ &&other) : QObject() {\n";
 static const char *CopyFieldTemplate = "m_$property_name$ = other.m_$property_name$;\n";
 static const char *AssignmentOperatorTemplate = "$classname$ &operator =(const $classname$ &other) {\n";
+static const char *AssignmentOperatorReturnTemplate = "return *this;\n";
 static const char *MoveAssignmentOperatorTemplate = "$classname$ &operator =(const $classname$ &&other) {\n";
 static const char *EqualOperatorTemplate = "bool operator ==(const $type$ &other) {\n"
                                           "    return ";
@@ -83,6 +84,11 @@ static const char *SetterTemplateComplexType = "void set$property_name_cap$(cons
 static const char *SignalsBlockTemplate = "\nsignals:\n";
 static const char *SignalTemplate = "void $property_name$Changed();\n";
 
+static const char *FieldsOrderingDefinitionContainerTemplate = "static const std::unordered_map<int/*field number*/, int/*property number*/> propertyOrdering;\n";
+
+static const char *FieldsOrderingContainerTemplate = "const std::unordered_map<int, int> $type$::propertyOrdering = {";
+static const char *FieldOrderTemplate = "{$field_number$,$property_number$}";
+
 static const char *EnumTemplate = "$type$";
 static const char *ModelClassTemplate = "using $type$Model = UniversalListModel<$type$>;\n";
 
@@ -101,10 +107,10 @@ static const std::unordered_map<::google::protobuf::FieldDescriptor::Type, std::
     {::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
+    //    {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
+    //    {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"},

+ 1 - 1
src/lib/CMakeLists.txt

@@ -11,7 +11,7 @@ if (Qt5_POSITION_INDEPENDENT_CODE)
   SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
 endif()
 
-add_library(qtprotobufsupport "universallistmodelbase.cpp" "universallistmodel.cpp")
+add_library(qtprotobufsupport "universallistmodelbase.cpp" "universallistmodel.cpp" "protobufobject.cpp")
 
 set_target_properties(qtprotobufsupport PROPERTIES PUBLIC_HEADER "universallistmodelbase.h;universallistmodel.h")
 

+ 33 - 0
src/lib/protobufobject.cpp

@@ -0,0 +1,33 @@
+/*
+ * 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 "protobufobject.h"
+
+using namespace qtprotobuf;
+
+ProtobufObject::ProtobufObject(QObject *parent) : QObject(parent)
+{
+
+}

+ 48 - 0
src/lib/protobufobject.h

@@ -0,0 +1,48 @@
+/*
+ * 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 <QObject>
+
+namespace qtprotobuf {
+
+class ProtobufObject : public QObject
+{
+public:
+    explicit ProtobufObject(QObject *parent = nullptr);
+
+    template <typename T>
+    QByteArray serialize() {
+
+    }
+
+    template <typename T>
+    void deserialize(const QByteArray& array) {
+
+    }
+};
+
+}

+ 1 - 0
src/lib/universallistmodel.cpp

@@ -20,4 +20,5 @@
  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
+
 #include "universallistmodel.h"