Browse Source

Refactor protobuf integral types

- Add generation of all protobuf integers
- Update existing test
Alexey Edelev 6 years ago
parent
commit
50b28dcf72

+ 14 - 6
src/generator/protobufclassgenerator.cpp

@@ -215,6 +215,7 @@ std::string ProtobufClassGenerator::getTypeName(const FieldDescriptor *field)
 {
     assert(field != nullptr);
     std::string typeName;
+    std::string namespaceDefinition("qtprotobuf::");
     if (field->type() == FieldDescriptor::TYPE_MESSAGE) {
         typeName = field->message_type()->name();
         if (field->is_repeated()) {
@@ -228,15 +229,22 @@ std::string ProtobufClassGenerator::getTypeName(const FieldDescriptor *field)
     } else {
         auto it = Templates::TypeReflection.find(field->type());
         if (it != std::end(Templates::TypeReflection)) {
-            typeName = it->second;
+            if (field->type() != FieldDescriptor::TYPE_STRING
+                    && field->type() != FieldDescriptor::TYPE_BYTES
+                    && field->type() != FieldDescriptor::TYPE_BOOL
+                    && field->type() != FieldDescriptor::TYPE_FLOAT
+                    && field->type() != FieldDescriptor::TYPE_DOUBLE) {
+                typeName = namespaceDefinition.append(it->second);
+            } else {
+                typeName = it->second;
+            }
             if (field->is_repeated()) {
-                std::string namespaceDefinition("qtprotobuf::");
-                typeName[0] = ::toupper(typeName[0]);
-                typeName.append("List");
-                if (typeName != "QStringList"
-                        && typeName != "QByteArrayList") {
+                if(field->type() == FieldDescriptor::TYPE_FLOAT
+                        || field->type() == FieldDescriptor::TYPE_DOUBLE) {
+                    typeName[0] = ::toupper(typeName[0]);
                     typeName = namespaceDefinition.append(typeName);
                 }
+                typeName.append("List");
             }
         }
     }

+ 10 - 14
src/generator/templates.cpp

@@ -125,24 +125,20 @@ const char *Templates::DeclareComplexListTypeTemplate = "Q_DECLARE_METATYPE($nam
 
 const char *Templates::QEnumTemplate = "Q_ENUM($type$)\n";
 
-
 const std::unordered_map<::google::protobuf::FieldDescriptor::Type, std::string> Templates::TypeReflection = {
     {::google::protobuf::FieldDescriptor::TYPE_DOUBLE, "double"},
     {::google::protobuf::FieldDescriptor::TYPE_FLOAT, "float"},
-    //        {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"},
-    {::google::protobuf::FieldDescriptor::TYPE_FIXED64, "qtprotobuf::FixedInt64"},
-    {::google::protobuf::FieldDescriptor::TYPE_FIXED32, "qtprotobuf::FixedInt32"},
+    {::google::protobuf::FieldDescriptor::TYPE_INT64, "int64"},
+    {::google::protobuf::FieldDescriptor::TYPE_UINT64,"uint64"},
+    {::google::protobuf::FieldDescriptor::TYPE_INT32, "int32"},
+    {::google::protobuf::FieldDescriptor::TYPE_FIXED64, "fint64"},
+    {::google::protobuf::FieldDescriptor::TYPE_FIXED32, "fint32"},
     {::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
+    {::google::protobuf::FieldDescriptor::TYPE_UINT32, "sint32"},//Limited usage see https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html
+    {::google::protobuf::FieldDescriptor::TYPE_SFIXED32, "sfint32"},
+    {::google::protobuf::FieldDescriptor::TYPE_SFIXED64, "sfint64"},
+    {::google::protobuf::FieldDescriptor::TYPE_SINT32, "sint32"},
+    {::google::protobuf::FieldDescriptor::TYPE_SINT64, "sint64"}
 };

+ 17 - 13
src/lib/protobufobject.h

@@ -91,8 +91,8 @@ public:
                                                       || wireType == LengthDelimited);
     }
 
-    QByteArray serializeValue(const QVariant& propertyValue, int fieldIndex, bool isFixed = false) const {
-        qProtoDebug() << __func__ << "propertyValue" << propertyValue << "fieldIndex" << fieldIndex << "isFixed" << isFixed;
+    QByteArray serializeValue(const QVariant& propertyValue, int fieldIndex, const QLatin1Literal& typeName) const {
+        qProtoDebug() << __func__ << "propertyValue" << propertyValue << "fieldIndex" << fieldIndex << "typeName" << typeName;
         QByteArray result;
         WireTypes type = UnknownWireType;
         switch (static_cast<QMetaType::Type>(propertyValue.type())) {
@@ -129,18 +129,22 @@ public:
             result.append(serializeUserType(propertyValue, fieldIndex));
             break;
         case QMetaType::UInt:
-            type = Fixed32;
-            if (isFixed) {
+            if (typeName == "fint32"
+                    || typeName == "qtprotobuf::fint32") {
+                type = Fixed32;
                 result.append(serializeFixed(propertyValue.toUInt()));
             } else {
+                type = Varint;
                 result.append(serializeVarint(propertyValue.toUInt()));
             }
             break;
         case QMetaType::ULongLong:
-            type = Fixed64;
-            if (isFixed) {
+            if (typeName == "fint64"
+                    || typeName == "qtprotobuf::fint64") {
+                type = Fixed64;
                 result.append(serializeFixed(propertyValue.toULongLong()));
             } else {
+                type = Varint;
                 result.append(serializeVarint(propertyValue.toULongLong()));
             }
             break;
@@ -173,8 +177,8 @@ public:
         }
 
         //Check if it's special list
-        if (userType == qMetaTypeId<IntList>()) {
-            return serializeListType(propertyValue.value<IntList>(), fieldIndex);
+        if (userType == qMetaTypeId<int32List>()) {
+            return serializeListType(propertyValue.value<int32List>(), fieldIndex);
         }
 
         if(userType == qMetaTypeId<FloatList>()) {
@@ -241,7 +245,7 @@ public:
 
         QByteArray serializedList;
         for(auto& value : listValue) {
-            serializedList.append(serializeValue(value, outFieldIndex));
+            serializedList.append(serializeValue(value, outFieldIndex, QLatin1Literal()));
         }
 
         outFieldIndex = NotUsedFieldIndex;
@@ -343,14 +347,14 @@ public:
         switch(type) {
         case QMetaType::UInt:
             if (wireType == Fixed32) {
-                newPropertyValue = deserializeFixed<FixedInt32>(it);
+                newPropertyValue = deserializeFixed<fint32>(it);
             } else {
                 newPropertyValue = deserializeVarint<unsigned int>(it);
             }
             break;
         case QMetaType::ULongLong:
             if (wireType == Fixed64) {
-                newPropertyValue = deserializeFixed<FixedInt64>(it);
+                newPropertyValue = deserializeFixed<fint64>(it);
             } else {
                 //TODO: deserialize varint
             }
@@ -453,7 +457,7 @@ public:
             return;
         }
 
-        if (userType == qMetaTypeId<IntList>()) {
+        if (userType == qMetaTypeId<int32List>()) {
             newValue = deserializeVarintListType<int>(it);
         } else if(userType == qMetaTypeId<FloatList>()) {
             newValue = deserializeListType<float>(it);
@@ -533,7 +537,7 @@ public:
             const QVariant &propertyValue = instance->property(propertyName);
             //TODO: flag isFixed looks ugly. Need to define more effective strategy
             //for type detection.
-            result.append(serializeValue(propertyValue, fieldIndex, QString(metaProperty.typeName()).contains("Fixed")));
+            result.append(serializeValue(propertyValue, fieldIndex, QLatin1Literal(metaProperty.typeName())));
         }
 
         return result;

+ 31 - 10
src/lib/qtprotobuf.h

@@ -26,6 +26,11 @@
 #pragma once
 
 #include <qtprotobuftypes.h>
+#include <QDebug>
+
+//registerProtobufType Not a part of API
+#define registerProtobufType(X) qDebug() << # X << "Type Id: " << qRegisterMetaType<X>(# X);\
+                              qDebug() << # X << "Type Id: " << qRegisterMetaType<X>("qtprotobuf::"# X);
 
 namespace qtprotobuf {
 
@@ -35,19 +40,35 @@ public:
         static bool registationDone = false;
         Q_ASSERT_X(!registationDone, "QtProtobuf", "Protobuf registation is already done");
         if (!registationDone) {
-            qRegisterMetaType<IntList>("IntList");
-            qRegisterMetaType<IntList>("qtprotobuf::IntList");
-            qRegisterMetaType<FloatList>("FloatList");
-            qRegisterMetaType<FloatList>("qtprotobuf::FloatList");
-            qRegisterMetaType<DoubleList>("DoubleList");
-            qRegisterMetaType<DoubleList>("qtprotobuf::DoubleList");
-            qRegisterMetaType<FixedInt32>("FixedInt32");
-            qRegisterMetaType<FixedInt32>("qtprotobuf::FixedInt32");
-            qRegisterMetaType<FixedInt64>("FixedInt64");
-            qRegisterMetaType<FixedInt64>("qtprotobuf::FixedInt64");
+            registerProtobufType(int32);
+            registerProtobufType(int64);
+            registerProtobufType(uint32);
+            registerProtobufType(uint64);
+            registerProtobufType(sint32);
+            registerProtobufType(sint64);
+            registerProtobufType(fint32);
+            registerProtobufType(fint64);
+            registerProtobufType(sfint32);
+            registerProtobufType(sfint64);
+
+            registerProtobufType(int32List);
+            registerProtobufType(int64List);
+            registerProtobufType(uint32List);
+            registerProtobufType(uint64List);
+            registerProtobufType(sint32List);
+            registerProtobufType(sint64List);
+            registerProtobufType(fint32List);
+            registerProtobufType(fint64List);
+            registerProtobufType(sfint32List);
+            registerProtobufType(sfint64List);
+
+            registerProtobufType(DoubleList);
+            registerProtobufType(FloatList);
             registationDone = true;
         }
     }
 };
 
 }
+
+#undef registerProtobufType

+ 31 - 7
src/lib/qtprotobuftypes.h

@@ -30,17 +30,41 @@
 #include <QMetaType>
 
 namespace qtprotobuf {
+using int32 = int;
+using int64 = qlonglong;
+using uint32 = unsigned int;
+using uint64 = qulonglong;
+using sint32 = int;
+using sint64 = qlonglong;
+using fint32 = unsigned int;
+using fint64 = qulonglong;
+using sfint32 = int;
+using sfint64 = qlonglong;
+
+using int32List = QList<int32>;
+using int64List = QList<int64>;
+using uint32List = QList<uint32>;
+using uint64List = QList<uint64>;
+using sint32List = QList<sint32>;
+using sint64List = QList<sint64>;
+using fint32List = QList<fint32>;
+using fint64List = QList<fint64>;
+using sfint32List = QList<sfint32>;
+using sfint64List = QList<sfint64>;
 
-using IntList = QList<int>;
 using FloatList = QList<float>;
 using DoubleList = QList<double>;
-
-using FixedInt32 = unsigned int;
-using FixedInt64 = qulonglong;
 }
 
-Q_DECLARE_METATYPE(qtprotobuf::IntList)
+Q_DECLARE_METATYPE(qtprotobuf::int32)
+Q_DECLARE_METATYPE(qtprotobuf::int64)
+Q_DECLARE_METATYPE(qtprotobuf::uint32)
+Q_DECLARE_METATYPE(qtprotobuf::uint64)
+
+Q_DECLARE_METATYPE(qtprotobuf::int32List)
+Q_DECLARE_METATYPE(qtprotobuf::int64List)
+Q_DECLARE_METATYPE(qtprotobuf::uint32List)
+Q_DECLARE_METATYPE(qtprotobuf::uint64List)
+
 Q_DECLARE_METATYPE(qtprotobuf::FloatList)
 Q_DECLARE_METATYPE(qtprotobuf::DoubleList)
-Q_DECLARE_METATYPE(qtprotobuf::FixedInt32)
-Q_DECLARE_METATYPE(qtprotobuf::FixedInt64)

+ 1 - 1
tests/deserializationtest.cpp

@@ -299,7 +299,7 @@ TEST_F(DeserializationTest, RepeatedIntMessageTest)
     RepeatedIntMessage test;
     test.deserialize(QByteArray::fromHex("0a0702a00606080a0c"));
     ASSERT_EQ(6, test.testRepeatedInt().count());
-    ASSERT_TRUE(test.testRepeatedInt() == IntList({1, 400, 3, 4, 5, 6}));
+    ASSERT_TRUE(test.testRepeatedInt() == int32List({1, 400, 3, 4, 5, 6}));
 }
 
 TEST_F(DeserializationTest, RepeatedComplexMessageTest)

+ 1 - 1
tests/serializationtest.cpp

@@ -465,7 +465,7 @@ TEST_F(SerializationTest, RepeatedIntMessageTest)
     //qDebug() << "result " << result.toHex();
     ASSERT_TRUE(result == QByteArray::fromHex("0a0702a00606080a0c"));
 
-    test.setTestRepeatedInt(IntList());
+    test.setTestRepeatedInt(int32List());
     result = test.serialize();
     ASSERT_TRUE(result.isEmpty());
 }

+ 10 - 9
tests/simpletest.cpp

@@ -55,7 +55,7 @@ TEST_F(SimpleTest, SimpleIntMessageTest)
     const char* propertyName = "testFieldInt";
     SimpleIntMessage test;
     int propertyNumber = SimpleIntMessage::propertyOrdering.at(1); //See simpletest.proto
-    ASSERT_EQ(SimpleIntMessage::staticMetaObject.property(propertyNumber).type(), QMetaType::Int);
+    ASSERT_EQ(SimpleIntMessage::staticMetaObject.property(propertyNumber).type(), qMetaTypeId<int32>());
     ASSERT_STREQ(SimpleIntMessage::staticMetaObject.property(propertyNumber).name(), propertyName);
     ASSERT_TRUE(test.setProperty(propertyName, QVariant::fromValue(1)));
     ASSERT_EQ(test.property(propertyName).toInt(), 1);
@@ -67,10 +67,10 @@ TEST_F(SimpleTest, SimpleFixedInt32MessageTest)
     const char* propertyName = "testFieldFixedInt32";
     SimpleFixedInt32Message test;
     int propertyNumber = SimpleFixedInt32Message::propertyOrdering.at(1); //See simpletest.proto
-    ASSERT_EQ(SimpleFixedInt32Message::staticMetaObject.property(propertyNumber).type(), qMetaTypeId<FixedInt32>());
+    ASSERT_EQ(SimpleFixedInt32Message::staticMetaObject.property(propertyNumber).type(), qMetaTypeId<fint32>());
     ASSERT_STREQ(SimpleFixedInt32Message::staticMetaObject.property(propertyNumber).name(), propertyName);
     ASSERT_TRUE(test.setProperty(propertyName, QVariant::fromValue(1)));
-    ASSERT_EQ(test.property(propertyName).value<FixedInt32>(), 1);
+    ASSERT_EQ(test.property(propertyName).value<fint32>(), 1);
     ASSERT_EQ(test.testFieldFixedInt32(), 1);
 }
 
@@ -79,10 +79,10 @@ TEST_F(SimpleTest, SimpleFixedInt64MessageTest)
     const char* propertyName = "testFieldFixedInt64";
     SimpleFixedInt64Message test;
     int propertyNumber = SimpleFixedInt64Message::propertyOrdering.at(1); //See simpletest.proto
-    ASSERT_EQ(SimpleFixedInt64Message::staticMetaObject.property(propertyNumber).type(), qMetaTypeId<FixedInt64>());
+    ASSERT_EQ(SimpleFixedInt64Message::staticMetaObject.property(propertyNumber).type(), qMetaTypeId<fint64>());
     ASSERT_STREQ(SimpleFixedInt64Message::staticMetaObject.property(propertyNumber).name(), propertyName);
     ASSERT_TRUE(test.setProperty(propertyName, QVariant::fromValue(1)));
-    ASSERT_EQ(test.property(propertyName).value<FixedInt64>(), 1);
+    ASSERT_EQ(test.property(propertyName).value<fint64>(), 1);
     ASSERT_EQ(test.testFieldFixedInt64(), 1);
 }
 
@@ -192,9 +192,10 @@ TEST_F(SimpleTest, RepeatedIntMessageTest)
     const char* propertyName = "testRepeatedInt";
     RepeatedIntMessage test;
     int propertyNumber = RepeatedIntMessage::propertyOrdering.at(1); //See simpletest.proto
-    ASSERT_EQ(RepeatedIntMessage::staticMetaObject.property(propertyNumber).type(), qMetaTypeId<IntList>());
+    ASSERT_STREQ(RepeatedIntMessage::staticMetaObject.property(propertyNumber).typeName(), "qtprotobuf::sint32List");
+    ASSERT_EQ(RepeatedIntMessage::staticMetaObject.property(propertyNumber).userType(), qMetaTypeId<qtprotobuf::sint32List>());
     ASSERT_STREQ(RepeatedIntMessage::staticMetaObject.property(propertyNumber).name(), propertyName);
-    ASSERT_TRUE(test.setProperty(propertyName, QVariant::fromValue<IntList>({1,2,3,4,5})));
-    ASSERT_TRUE(test.property(propertyName).value<IntList>() == IntList({1, 2, 3, 4, 5}));
-    ASSERT_TRUE(test.testRepeatedInt() == IntList({1, 2, 3, 4, 5}));
+    ASSERT_TRUE(test.setProperty(propertyName, QVariant::fromValue<sint32List>({1, 2, 3, 4, 5})));
+    ASSERT_TRUE(test.property(propertyName).value<sint32List>() == sint32List({1, 2, 3, 4, 5}));
+    ASSERT_TRUE(test.testRepeatedInt() == sint32List({1, 2, 3, 4, 5}));
 }