Browse Source

Add possibility to use global enums.

Tatyana Borisova 6 years ago
parent
commit
3d69945593

+ 2 - 1
src/generator/generator.cpp

@@ -155,7 +155,8 @@ bool QtGenerator::GenerateAll(const std::vector<const FileDescriptor *> &files,
         packageList[file->package()].push_back(file);
     }
 
-    GlobalEnumsGenerator enumGen(packageList, std::move(std::unique_ptr<io::ZeroCopyOutputStream>(generatorContext->Open(globalEnumsFilename))));
+    GlobalEnumsGenerator enumGen(packageList,
+                                 std::move(std::unique_ptr<io::ZeroCopyOutputStream>(generatorContext->Open(globalEnumsFilename))));
     enumGen.run();
 
     return CodeGenerator::GenerateAll(files, parameter, generatorContext, error);

+ 1 - 1
src/generator/globalenumsgenerator.cpp

@@ -33,7 +33,7 @@ using namespace ::google::protobuf::io;
 using namespace ::google::protobuf::compiler;
 
 GlobalEnumsGenerator::GlobalEnumsGenerator(const PackagesList &packageList, std::unique_ptr<io::ZeroCopyOutputStream> out) :
-    ClassGeneratorBase("GlobalEnums", std::move(out))
+    ClassGeneratorBase(Templates::EnumClassNameTemplate, std::move(out))
   , mPackageList(packageList) {}
 
 void GlobalEnumsGenerator::startEnum(const std::vector<std::string>& namespaces) {

+ 23 - 2
src/generator/protobufclassgenerator.cpp

@@ -1,7 +1,7 @@
 /*
  * MIT License
  *
- * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>, Tatyana Borisova <tanusshhka@mail.ru>
  *
  * This file is part of qtprotobuf project https://git.semlanik.org/semlanik/qtprotobuf
  *
@@ -42,7 +42,6 @@ ProtobufClassGenerator::ProtobufClassGenerator(const Descriptor *message, std::u
     : ClassGeneratorBase(message->full_name(), std::move(out))
     , mMessage(message)
 {
-
 }
 
 void ProtobufClassGenerator::printCopyFunctionality()
@@ -223,6 +222,10 @@ std::string ProtobufClassGenerator::getTypeName(const FieldDescriptor *field)
         }
     } else if (field->type() == FieldDescriptor::TYPE_ENUM) {
         typeName = field->enum_type()->name();
+        if (!isLocalMessageEnum(field)) {
+            std::string globEnum(Templates::EnumClassNameTemplate);
+            typeName = globEnum.append("::").append(typeName);
+        }
         if (field->is_repeated()) {
             return typeName.append("List");
         }
@@ -369,6 +372,24 @@ void ProtobufClassGenerator::printFieldsOrderingDefinition()
     Outdent();
 }
 
+bool ProtobufClassGenerator::isLocalMessageEnum(const ::google::protobuf::FieldDescriptor *field)
+{
+    if (field == nullptr)
+    {
+        return false;
+    }
+    for (int i = 0; i < mMessage->enum_type_count(); i++) {
+        const auto enumDescr = mMessage->enum_type(i);
+        if (enumDescr == nullptr || field->enum_type() == nullptr) {
+            return false;
+        }
+        if (enumDescr->name().compare(field->enum_type()->name()) == 0) {
+            return true;
+        }
+    }
+    return false;
+}
+
 void ProtobufClassGenerator::printClassMembers()
 {
     Indent();

+ 4 - 2
src/generator/protobufclassgenerator.h

@@ -64,10 +64,12 @@ public:
     void printConstructor();
     void printListType();
 
+    bool isLocalMessageEnum(const ::google::protobuf::FieldDescriptor *field);
+
     std::set<std::string> extractModels() const;
 
-    static std::string getTypeName(const ::google::protobuf::FieldDescriptor *field);
-    static bool producePropertyMap(const ::google::protobuf::FieldDescriptor *field, PropertyMap &propertyMap);
+    std::string getTypeName(const ::google::protobuf::FieldDescriptor *field);
+    bool producePropertyMap(const ::google::protobuf::FieldDescriptor *field, PropertyMap &propertyMap);
     static bool isComplexType(const ::google::protobuf::FieldDescriptor *field);
     static bool isListType(const ::google::protobuf::FieldDescriptor *field);
 };

+ 3 - 0
src/generator/templates.cpp

@@ -31,6 +31,8 @@ const char *Templates::DefaultProtobufIncludesTemplate = "#include <QMetaType>\n
                                                          "#include <protobufobject.h>\n"
                                                          "#include <unordered_map>\n\n";
 
+const char *Templates::EnumClassNameTemplate = "GlobalEnums";
+
 const char *Templates::PreambleTemplate = "/* This file is autogenerated. DO NOT CHANGE. All changes will be lost */\n\n"
                                       "#pragma once\n\n"
                                       "#include <QObject>\n";
@@ -67,6 +69,7 @@ const char *Templates::ClassDefinitionTemplate = "\nclass $classname$ final : pu
 const char *Templates::PropertyTemplate = "Q_PROPERTY($type$ $property_name$ READ $property_name$ WRITE set$property_name_cap$ NOTIFY $property_name$Changed)\n";
 const char *Templates::MessagePropertyTemplate = "Q_PROPERTY($type$ $property_name$ READ $property_name$ WRITE set$property_name_cap$ NOTIFY $property_name$Changed)\n";
 const char *Templates::MemberTemplate = "$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";
 const char *Templates::EnumDefinitionTemplate = "enum $enum$ {\n";

+ 2 - 0
src/generator/templates.h

@@ -35,6 +35,7 @@ namespace generator {
 class Templates {
 public:
     static const char *DefaultProtobufIncludesTemplate;
+    static const char *EnumClassNameTemplate;
     static const char *PreambleTemplate;
     static const char *InternalIncludeTemplate;
     static const char *ExternalIncludeTemplate;
@@ -51,6 +52,7 @@ public:
     static const char *PropertyTemplate;
     static const char *MessagePropertyTemplate;
     static const char *MemberTemplate;
+    static const char *EnumMemberTemplate;
     static const char *PublicBlockTemplate;
     static const char *PrivateBlockTemplate;
     static const char *EnumDefinitionTemplate;

+ 5 - 0
tests/proto/simpletest.proto

@@ -14,6 +14,11 @@ message SimpleEnumMessage {
   repeated LocalEnum localEnumList = 2;
 }
 
+message SimpleFileEnumMessage {
+  TestEnum globalEnum = 1;
+  repeated TestEnum globalEnumList = 2;
+}
+
 message SimpleIntMessage {
     int32 testFieldInt = 1;
 }