Browse Source

Implement single-file generation approach

- Use single output file for all related to .proto
  file types
- Split grpc and proto parts
- Add package registration functions
- Update tests
Alexey Edelev 5 years ago
parent
commit
ea5d0738e3
45 changed files with 932 additions and 335 deletions
  1. 5 1
      examples/addressbook/addressbookengine.cpp
  2. 5 2
      examples/addressbook/addressbookengine.h
  3. 3 2
      examples/addressbook/main.cpp
  4. 5 3
      examples/simplechat/main.cpp
  5. 2 0
      examples/simplechat/simplechatengine.cpp
  6. 5 2
      examples/simplechat/simplechatengine.h
  7. 4 2
      src/generator/CMakeLists.txt
  8. 18 12
      src/generator/classgeneratorbase.cpp
  9. 13 11
      src/generator/classgeneratorbase.h
  10. 9 3
      src/generator/classsourcegeneratorbase.cpp
  11. 1 0
      src/generator/classsourcegeneratorbase.h
  12. 19 15
      src/generator/clientgenerator.cpp
  13. 3 1
      src/generator/clientgenerator.h
  14. 15 6
      src/generator/clientsourcegenerator.cpp
  15. 3 1
      src/generator/clientsourcegenerator.h
  16. 3 1
      src/generator/generator.cpp
  17. 11 6
      src/generator/globalenumsgenerator.cpp
  18. 1 0
      src/generator/globalenumsgenerator.h
  19. 12 7
      src/generator/globalenumssourcegenerator.cpp
  20. 1 0
      src/generator/globalenumssourcegenerator.h
  21. 2 1
      src/generator/main.cpp
  22. 34 27
      src/generator/protobufclassgenerator.cpp
  23. 1 0
      src/generator/protobufclassgenerator.h
  24. 24 18
      src/generator/protobufsourcegenerator.cpp
  25. 2 0
      src/generator/protobufsourcegenerator.h
  26. 11 5
      src/generator/servicegeneratorbase.cpp
  27. 2 0
      src/generator/servicegeneratorbase.h
  28. 359 0
      src/generator/singlefilegenerator.cpp
  29. 73 0
      src/generator/singlefilegenerator.h
  30. 1 0
      src/generator/templates.cpp
  31. 1 0
      src/generator/templates.h
  32. 6 0
      src/generator/utils.h
  33. 3 4
      src/protobuf/QtProtobufGen.cmake.in
  34. 31 3
      src/protobuf/parsemessages.go
  35. 4 2
      tests/test_grpc/clienttest.cpp
  36. 4 4
      tests/test_grpc/echoserver/main.cpp
  37. 3 2
      tests/test_grpc/sslclienttest.cpp
  38. 66 64
      tests/test_protobuf/deserializationtest.cpp
  39. 2 1
      tests/test_protobuf/jsonserializationtest.cpp
  40. 18 0
      tests/test_protobuf/proto/crossfiletest.proto_disabled
  41. 11 0
      tests/test_protobuf/proto/sequencetest.proto_disabled
  42. 15 13
      tests/test_protobuf/serializationcomplexmessagemap.cpp
  43. 53 52
      tests/test_protobuf/serializationtest.cpp
  44. 51 49
      tests/test_protobuf/simpletest.cpp
  45. 17 15
      tests/test_qml/main.cpp

+ 5 - 1
examples/addressbook/addressbookengine.cpp

@@ -24,7 +24,11 @@
  */
 
 #include "addressbookengine.h"
-#include "addressbookclient.h"
+
+#include "addressbook.pb.h"
+#include "addressbook_grpc.pb.h"
+
+//#include "addressbookclient.h"
 #include <QGrpcHttp2Channel>
 #include <InsecureCredentials>
 #include <SslCredentials>

+ 5 - 2
examples/addressbook/addressbookengine.h

@@ -26,9 +26,12 @@
 #pragma once
 
 #include <QObject>
-#include "contacts.h"
+#include "addressbook.pb.h"
+//#include "contacts.h"
+//#include "callstatus.h"
+
+
 #include "universallistmodel.h"
-#include "callstatus.h"
 
 namespace qtprotobuf { namespace examples {
 class AddressBookClient;

+ 3 - 2
examples/addressbook/main.cpp

@@ -30,8 +30,9 @@
 #include <QQmlContext>
 
 #include "addressbookengine.h"
-#include <contacts.h>
-#include <contact.h>
+#include "addressbook.pb.h"
+//#include <contacts.h>
+//#include <contact.h>
 
 #include <QMetaProperty>
 #include <QQmlPropertyMap>

+ 5 - 3
examples/simplechat/main.cpp

@@ -29,9 +29,11 @@
 #include <QQmlApplicationEngine>
 #include <QQmlContext>
 
-#include <chatmessage.h>
-#include <user.h>
-#include <chatmessages.h>
+#include "simplechat.pb.h"
+
+//#include <chatmessage.h>
+//#include <user.h>
+//#include <chatmessages.h>
 #include "simplechatengine.h"
 
 #include <QMetaProperty>

+ 2 - 0
examples/simplechat/simplechatengine.cpp

@@ -25,6 +25,8 @@
 
 #include "simplechatengine.h"
 
+#include "simplechat_grpc.pb.h"
+
 #include <QGrpcHttp2Channel>
 #include <InsecureCredentials>
 #include <SslCredentials>

+ 5 - 2
examples/simplechat/simplechatengine.h

@@ -27,8 +27,11 @@
 
 #include <QObject>
 
-#include <chatmessages.h>
-#include "simplechatclient.h"
+#include "simplechat.pb.h"
+#include "simplechat_grpc.pb.h"
+
+//#include <chatmessages.h>
+//#include "simplechatclient.h"
 
 #include "universallistmodel.h"
 

+ 4 - 2
src/generator/CMakeLists.txt

@@ -16,7 +16,8 @@ file(GLOB SOURCES main.cpp
     clientgenerator.cpp
     classsourcegeneratorbase.cpp
     protobufsourcegenerator.cpp
-    clientsourcegenerator.cpp)
+    clientsourcegenerator.cpp
+    singlefilegenerator.cpp)
 
 file(GLOB HEADERS classgeneratorbase.h
     classsourcegeneratorbase.h
@@ -30,7 +31,8 @@ file(GLOB HEADERS classgeneratorbase.h
     servergenerator.h
     servicegeneratorbase.h
     templates.h
-    utils.h)
+    utils.h
+    singlefilegenerator.h)
 
 add_executable(${TARGET} ${SOURCES})
 

+ 18 - 12
src/generator/classgeneratorbase.cpp

@@ -38,10 +38,10 @@ using namespace ::google::protobuf;
 using namespace ::google::protobuf::io;
 using namespace ::google::protobuf::compiler;
 
-ClassGeneratorBase::ClassGeneratorBase(const std::string &fullClassName, const std::shared_ptr<::google::protobuf::io::ZeroCopyOutputStream> &out) : mOutput(out)
-  , mPrinter(mOutput.get(), '$')
+ClassGeneratorBase::ClassGeneratorBase(const std::string &fullClassName, const std::shared_ptr<::google::protobuf::io::Printer> &printer) :
+    mPrinter(printer)
 {
-    mPrinter.Print(Templates::DisclaimerTemplate);
+    mPrinter->Print(Templates::DisclaimerTemplate);
     utils::split(fullClassName, mNamespaces, '.');
     assert(mNamespaces.size() > 0);
     mClassName = mNamespaces.back();
@@ -54,9 +54,15 @@ ClassGeneratorBase::ClassGeneratorBase(const std::string &fullClassName, const s
     }
 }
 
+ClassGeneratorBase::ClassGeneratorBase(const std::string &fullClassName, const std::shared_ptr<::google::protobuf::io::ZeroCopyOutputStream> &out) :
+  ClassGeneratorBase(fullClassName, std::shared_ptr<::google::protobuf::io::Printer>(new ::google::protobuf::io::Printer(out.get(), '$')))
+{
+    mOutput = out;
+}
+
 void ClassGeneratorBase::printPreamble()
 {
-    mPrinter.Print(Templates::PreambleTemplate);
+    mPrinter->Print(Templates::PreambleTemplate);
 }
 
 void ClassGeneratorBase::printNamespaces()
@@ -67,24 +73,24 @@ void ClassGeneratorBase::printNamespaces()
 void ClassGeneratorBase::printNamespaces(const std::vector<std::string> &namespaces)
 {
     for (auto ns: namespaces) {
-        mPrinter.Print({{"namespace", ns}}, Templates::NamespaceTemplate);
+        mPrinter->Print({{"namespace", ns}}, Templates::NamespaceTemplate);
     }
 }
 
 void ClassGeneratorBase::printClassDeclaration()
 {
-    mPrinter.Print({{"classname", mClassName}}, Templates::ProtoClassDefinitionTemplate);
+    mPrinter->Print({{"classname", mClassName}}, Templates::ProtoClassDefinitionTemplate);
 }
 
 void ClassGeneratorBase::encloseClass()
 {
-    mPrinter.Print(Templates::SemicolonBlockEnclosureTemplate);
+    mPrinter->Print(Templates::SemicolonBlockEnclosureTemplate);
 }
 
 void ClassGeneratorBase::encloseNamespaces(int count)
 {
     for (int i = 0; i < count; i++) {
-        mPrinter.Print(Templates::SimpleBlockEnclosureTemplate);
+        mPrinter->Print(Templates::SimpleBlockEnclosureTemplate);
     }
 }
 
@@ -95,19 +101,19 @@ void ClassGeneratorBase::encloseNamespaces()
 
 void ClassGeneratorBase::printPublic()
 {
-    mPrinter.Print(Templates::PublicBlockTemplate);
+    mPrinter->Print(Templates::PublicBlockTemplate);
 }
 
 void ClassGeneratorBase::printPrivate()
 {
-    mPrinter.Print(Templates::PrivateBlockTemplate);
+    mPrinter->Print(Templates::PrivateBlockTemplate);
 }
 
 void ClassGeneratorBase::printMetaTypeDeclaration()
 {
-    mPrinter.Print({{"classname", mClassName}, {"namespaces", mNamespacesColonDelimited}},
+    mPrinter->Print({{"classname", mClassName}, {"namespaces", mNamespacesColonDelimited}},
                    Templates::DeclareMetaTypeTemplate);
-    mPrinter.Print({{"classname", mClassName}, {"namespaces", mNamespacesColonDelimited}},
+    mPrinter->Print({{"classname", mClassName}, {"namespaces", mNamespacesColonDelimited}},
                    Templates::DeclareComplexListTypeTemplate);
 }
 

+ 13 - 11
src/generator/classgeneratorbase.h

@@ -47,7 +47,8 @@ using PropertyMap = std::map<std::string, std::string>;
 class ClassGeneratorBase
 {
 public:
-    ClassGeneratorBase(const std::string &className, const std::shared_ptr<google::protobuf::io::ZeroCopyOutputStream> &out);
+    ClassGeneratorBase(const std::string &fullClassName, const std::shared_ptr<google::protobuf::io::ZeroCopyOutputStream> &out);
+    ClassGeneratorBase(const std::string &fullClassName, const std::shared_ptr<::google::protobuf::io::Printer> &printer);
     virtual ~ClassGeneratorBase() = default;
     virtual void run() = 0;
 protected:
@@ -58,11 +59,12 @@ protected:
     };
 
     std::shared_ptr<::google::protobuf::io::ZeroCopyOutputStream> mOutput;
-    ::google::protobuf::io::Printer mPrinter;
+    std::shared_ptr<::google::protobuf::io::Printer> mPrinter;
     std::string mClassName;
     std::vector<std::string> mNamespaces;
     std::string mNamespacesColonDelimited;
 
+public:
     void printPreamble();
     void printNamespaces();
     void printNamespaces(const std::vector<std::string> &namespaces);
@@ -86,35 +88,35 @@ protected:
         Indent();
         for (int i = 0; i < message->enum_type_count(); i++) {
             const auto enumDescr = message->enum_type(i);
-            mPrinter.Print({{"enum", enumDescr->name()}}, Templates::EnumDefinitionTemplate);
+            mPrinter->Print({{"enum", enumDescr->name()}}, Templates::EnumDefinitionTemplate);
 
             Indent();
             for (int j = 0; j < enumDescr->value_count(); j++) {
                 const auto valueDescr = enumDescr->value(j);
-                mPrinter.Print({{"enumvalue", valueDescr->name()},
+                mPrinter->Print({{"enumvalue", valueDescr->name()},
                                 {"value", std::to_string(valueDescr->number())}}, Templates::EnumFieldTemplate);
             }
             Outdent();
-            mPrinter.Print(Templates::SemicolonBlockEnclosureTemplate);
-            mPrinter.Print({{"type", enumDescr->name().c_str()}}, Templates::QEnumTemplate);
+            mPrinter->Print(Templates::SemicolonBlockEnclosureTemplate);
+            mPrinter->Print({{"type", enumDescr->name().c_str()}}, Templates::QEnumTemplate);
         }
 
         for (int i = 0; i < message->enum_type_count(); i++) {
             const auto enumDescr = message->enum_type(i);
-            mPrinter.Print({{"enum", enumDescr->name()}}, Templates::EnumTypeUsingTemplate);
+            mPrinter->Print({{"enum", enumDescr->name()}}, Templates::EnumTypeUsingTemplate);
         }
         Outdent();
     }
 
 
     void Indent() {
-        mPrinter.Indent();
-        mPrinter.Indent();
+        mPrinter->Indent();
+        mPrinter->Indent();
     }
 
     void Outdent() {
-        mPrinter.Outdent();
-        mPrinter.Outdent();
+        mPrinter->Outdent();
+        mPrinter->Outdent();
     }
 
     std::string getTypeName(const ::google::protobuf::FieldDescriptor *field, const ::google::protobuf::Descriptor *messageFor);

+ 9 - 3
src/generator/classsourcegeneratorbase.cpp

@@ -42,17 +42,23 @@ ClassSourceGeneratorBase::ClassSourceGeneratorBase(const std::string &fullClassN
 
 }
 
+ClassSourceGeneratorBase::ClassSourceGeneratorBase(const std::string &fullClassName, const std::shared_ptr<::google::protobuf::io::Printer> &printer) :
+    ClassGeneratorBase(fullClassName, printer)
+{
+
+}
+
 void ClassSourceGeneratorBase::printClassHeaderInclude()
 {
     std::string includeFileName = mClassName;
     utils::tolower(includeFileName);
-    mPrinter.Print({{"include", includeFileName}}, Templates::InternalIncludeTemplate);
-    mPrinter.Print({{"include", "QQmlEngine"}}, Templates::ExternalIncludeTemplate);
+    mPrinter->Print({{"include", includeFileName}}, Templates::InternalIncludeTemplate);
+    mPrinter->Print({{"include", "QQmlEngine"}}, Templates::ExternalIncludeTemplate);
 }
 
 void ClassSourceGeneratorBase::printUsingNamespaces(const std::unordered_set<std::string> &namespaces)
 {
     for (auto ns : namespaces) {
-        mPrinter.Print({{"namespace", ns}}, Templates::UsingNamespaceTemplate);
+        mPrinter->Print({{"namespace", ns}}, Templates::UsingNamespaceTemplate);
     }
 }

+ 1 - 0
src/generator/classsourcegeneratorbase.h

@@ -37,6 +37,7 @@ class ClassSourceGeneratorBase : public ClassGeneratorBase
 {
 public:
     ClassSourceGeneratorBase(const std::string &className, const std::shared_ptr<google::protobuf::io::ZeroCopyOutputStream> &out);
+    ClassSourceGeneratorBase(const std::string &fullClassName, const std::shared_ptr<::google::protobuf::io::Printer> &printer);
     ~ClassSourceGeneratorBase() = default;
     virtual void run() = 0;
 

+ 19 - 15
src/generator/clientgenerator.cpp

@@ -46,28 +46,32 @@ ClientGenerator::ClientGenerator(const ServiceDescriptor *service, const std::sh
     mClassName += "Client";
 }
 
+ClientGenerator::ClientGenerator(const ::google::protobuf::ServiceDescriptor *service, const std::shared_ptr<::google::protobuf::io::Printer> &printer) :
+    ServiceGeneratorBase(service, printer)
+{
+    mClassName += "Client";
+}
+
 void ClientGenerator::printClientClass()
 {
-    mPrinter.Print({{"classname", mClassName}, {"parent_class", "QtProtobuf::QAbstractGrpcClient"}}, Templates::ClassDefinitionTemplate);
-    mPrinter.Print(Templates::QObjectMacro);
+    mPrinter->Print({{"classname", mClassName}, {"parent_class", "QtProtobuf::QAbstractGrpcClient"}}, Templates::ClassDefinitionTemplate);
+    mPrinter->Print(Templates::QObjectMacro);
 }
 
 void ClientGenerator::printConstructor()
 {
     Indent();
-    mPrinter.Print({{"classname", mClassName}}, Templates::QObjectConstructorTemplate);
+    mPrinter->Print({{"classname", mClassName}}, Templates::QObjectConstructorTemplate);
     Outdent();
 }
 
 void ClientGenerator::printClientIncludes()
 {
-    printIncludes();
-
     std::unordered_set<std::string> includeSet;
-    includeSet.insert("qabstractgrpcclient");
-    includeSet.insert("qgrpcasyncreply");
+    includeSet.insert("QAbstractGrpcClient");
+    includeSet.insert("QGrpcAsyncReply");
     for (auto type : includeSet) {
-        mPrinter.Print({{"include", type}}, Templates::InternalIncludeTemplate);
+        mPrinter->Print({{"include", type}}, Templates::ExternalIncludeTemplate);
     }
 }
 
@@ -80,15 +84,15 @@ void ClientGenerator::printClientMethodsDeclaration()
         getMethodParameters(method, parameters);
 
         if (method->server_streaming()) {
-            mPrinter.Print(parameters, Templates::ClientMethodSignalDeclarationTemplate);
-            mPrinter.Print(parameters, Templates::ClientMethodServerStreamDeclarationTemplate);
-            mPrinter.Print(parameters, Templates::ClientMethodServerStream2DeclarationTemplate);
+            mPrinter->Print(parameters, Templates::ClientMethodSignalDeclarationTemplate);
+            mPrinter->Print(parameters, Templates::ClientMethodServerStreamDeclarationTemplate);
+            mPrinter->Print(parameters, Templates::ClientMethodServerStream2DeclarationTemplate);
         } else {
-            mPrinter.Print(parameters, Templates::ClientMethodDeclarationSyncTemplate);
-            mPrinter.Print(parameters, Templates::ClientMethodDeclarationAsyncTemplate);
-            mPrinter.Print(parameters, Templates::ClientMethodDeclarationAsync2Template);
+            mPrinter->Print(parameters, Templates::ClientMethodDeclarationSyncTemplate);
+            mPrinter->Print(parameters, Templates::ClientMethodDeclarationAsyncTemplate);
+            mPrinter->Print(parameters, Templates::ClientMethodDeclarationAsync2Template);
         }
-        mPrinter.Print("\n");
+        mPrinter->Print("\n");
     }
     Outdent();
 }

+ 3 - 1
src/generator/clientgenerator.h

@@ -43,10 +43,13 @@ class ClientGenerator : public ServiceGeneratorBase
 public:
     ClientGenerator(const ::google::protobuf::ServiceDescriptor *service,
                     const std::shared_ptr<google::protobuf::io::ZeroCopyOutputStream> &out);
+    ClientGenerator(const ::google::protobuf::ServiceDescriptor *service,
+                    const std::shared_ptr<::google::protobuf::io::Printer> &printer);
     ~ClientGenerator() = default;
 
     void run() {
         printPreamble();
+        printIncludes();
         printClientIncludes();
         printNamespaces();
         printClientClass();
@@ -56,7 +59,6 @@ public:
         encloseClass();
         encloseNamespaces();
     }
-private:
     void printClientClass();
     void printConstructor();
     void printClientIncludes();

+ 15 - 6
src/generator/clientsourcegenerator.cpp

@@ -42,6 +42,15 @@ ClientSourceGenerator::ClientSourceGenerator(const google::protobuf::ServiceDesc
     mClassName += "Client";
 }
 
+
+ClientSourceGenerator::ClientSourceGenerator(const google::protobuf::ServiceDescriptor *service,
+                      const std::shared_ptr<::google::protobuf::io::Printer> &printer) :
+    ClassSourceGeneratorBase(service->full_name(), printer)
+  , mService(service)
+{
+    mClassName += "Client";
+}
+
 void ClientSourceGenerator::printMethods()
 {
     for (int i = 0; i < mService->method_count(); i++) {
@@ -49,19 +58,19 @@ void ClientSourceGenerator::printMethods()
         std::map<std::string, std::string> parameters;
         getMethodParameters(method, parameters);
         if (method->server_streaming()) {
-            mPrinter.Print(parameters, Templates::ClientMethodServerStreamDefinitionTemplate);
-            mPrinter.Print(parameters, Templates::ClientMethodServerStream2DefinitionTemplate);
+            mPrinter->Print(parameters, Templates::ClientMethodServerStreamDefinitionTemplate);
+            mPrinter->Print(parameters, Templates::ClientMethodServerStream2DefinitionTemplate);
         } else {
-            mPrinter.Print(parameters, Templates::ClientMethodDefinitionSyncTemplate);
-            mPrinter.Print(parameters, Templates::ClientMethodDefinitionAsyncTemplate);
-            mPrinter.Print(parameters, Templates::ClientMethodDefinitionAsync2Template);
+            mPrinter->Print(parameters, Templates::ClientMethodDefinitionSyncTemplate);
+            mPrinter->Print(parameters, Templates::ClientMethodDefinitionAsyncTemplate);
+            mPrinter->Print(parameters, Templates::ClientMethodDefinitionAsync2Template);
         }
     }
 }
 
 void ClientSourceGenerator::printConstructor()
 {
-    mPrinter.Print({ {"classname", mClassName},
+    mPrinter->Print({ {"classname", mClassName},
                      {"parent_class", "QAbstractGrpcClient"},
                      {"service_name", mService->full_name()} }, Templates::ClientConstructorDefinitionTemplate);
 }

+ 3 - 1
src/generator/clientsourcegenerator.h

@@ -35,6 +35,8 @@ class ClientSourceGenerator : public ClassSourceGeneratorBase
 public:
     ClientSourceGenerator(const google::protobuf::ServiceDescriptor *service,
                           const std::shared_ptr<google::protobuf::io::ZeroCopyOutputStream> &out);
+    ClientSourceGenerator(const google::protobuf::ServiceDescriptor *service,
+                          const std::shared_ptr<::google::protobuf::io::Printer> &printer);
     void run() override {
         printClassHeaderInclude();
         printUsingNamespaces({"QtProtobuf", mNamespacesColonDelimited});
@@ -42,9 +44,9 @@ public:
         printMethods();
     }
 
-protected:
     void printMethods();
     void printConstructor();
+protected:
     const ::google::protobuf::ServiceDescriptor *mService;
 };
 

+ 3 - 1
src/generator/generator.cpp

@@ -36,6 +36,7 @@
 #include "utils.h"
 
 #include <iostream>
+#include <set>
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/io/printer.h>
@@ -76,6 +77,7 @@ bool QtGenerator::Generate(const FileDescriptor *file,
             std::cerr << file->name() << ":" << (message->index() + 1) << ": " << " Error: Meta object features not supported for nested classes in " << message->full_name() << std::endl;
             continue;
         }
+
         std::string baseFilename(message->name());
         utils::tolower(baseFilename);
 
@@ -129,7 +131,7 @@ bool QtGenerator::GenerateAll(const std::vector<const FileDescriptor *> &files,
     GlobalEnumsSourceGenerator enumSourceGen(packageList,
                                              std::shared_ptr<io::ZeroCopyOutputStream>(generatorContext->Open(globalEnumsFilename + ".cpp")));
     enumSourceGen.run();
-    return CodeGenerator::GenerateAll(files, parameter, generatorContext, error);
 
+    return CodeGenerator::GenerateAll(files, parameter, generatorContext, error);
 }
 

+ 11 - 6
src/generator/globalenumsgenerator.cpp

@@ -36,12 +36,17 @@ GlobalEnumsGenerator::GlobalEnumsGenerator(const PackagesList &packageList, cons
     ClassGeneratorBase(Templates::GlobalEnumClassNameTemplate, out)
   , mPackageList(packageList) {}
 
+
+GlobalEnumsGenerator::GlobalEnumsGenerator(const PackagesList &packageList, const std::shared_ptr<::google::protobuf::io::Printer> &printer) :
+    ClassGeneratorBase(Templates::GlobalEnumClassNameTemplate, printer)
+  , mPackageList(packageList) {}
+
 void GlobalEnumsGenerator::startEnum(const std::vector<std::string>& namespaces) {
     printNamespaces(namespaces);
     printEnumClass();
     printPublic();
     Indent();
-    mPrinter.Print({{"classname", mClassName}}, Templates::ManualRegistrationDeclaration);
+    mPrinter->Print({{"classname", mClassName}}, Templates::ManualRegistrationDeclaration);
     Outdent();
     printPrivate();
     printConstructor();
@@ -50,9 +55,9 @@ void GlobalEnumsGenerator::startEnum(const std::vector<std::string>& namespaces)
 void GlobalEnumsGenerator::printConstructor()
 {
     Indent();
-    mPrinter.Print({{"classname", mClassName}}, Templates::ConstructorHeaderTemplate);
-    mPrinter.Print({{"classname", mClassName}}, Templates::DeletedCopyConstructorTemplate);
-    mPrinter.Print({{"classname", mClassName}}, Templates::DeletedMoveConstructorTemplate);
+    mPrinter->Print({{"classname", mClassName}}, Templates::ConstructorHeaderTemplate);
+    mPrinter->Print({{"classname", mClassName}}, Templates::DeletedCopyConstructorTemplate);
+    mPrinter->Print({{"classname", mClassName}}, Templates::DeletedMoveConstructorTemplate);
     Outdent();
 }
 
@@ -92,7 +97,7 @@ void GlobalEnumsGenerator::printMetatype(const google::protobuf::FileDescriptor
     fullNamespace.append("::").append(Templates::GlobalEnumClassNameTemplate);
     for (int i = 0; i < file->enum_type_count(); i++) {
         const auto enumDescr = file->enum_type(i);
-        mPrinter.Print({{"classname", enumDescr->name()}, {"namespaces", fullNamespace}},
+        mPrinter->Print({{"classname", enumDescr->name()}, {"namespaces", fullNamespace}},
                        Templates::DeclareMetaTypeListTemplate);
     }
 }
@@ -103,5 +108,5 @@ void GlobalEnumsGenerator::encloseEnum(const std::vector<std::string>& namespace
 }
 
 void GlobalEnumsGenerator::printEnumClass() {
-    mPrinter.Print({{"classname", mClassName}}, Templates::NonProtoClassDefinitionTemplate);
+    mPrinter->Print({{"classname", mClassName}}, Templates::NonProtoClassDefinitionTemplate);
 }

+ 1 - 0
src/generator/globalenumsgenerator.h

@@ -36,6 +36,7 @@ class GlobalEnumsGenerator : public ClassGeneratorBase
     PackagesList mPackageList;
 public:
     GlobalEnumsGenerator(const PackagesList &packageList, const std::shared_ptr<google::protobuf::io::ZeroCopyOutputStream> &out);
+    GlobalEnumsGenerator(const PackagesList &packageList, const std::shared_ptr<::google::protobuf::io::Printer> &printer);
     virtual ~GlobalEnumsGenerator() = default;
 
     void run();

+ 12 - 7
src/generator/globalenumssourcegenerator.cpp

@@ -36,8 +36,13 @@ GlobalEnumsSourceGenerator::GlobalEnumsSourceGenerator(const PackagesList &packa
     ClassGeneratorBase(Templates::GlobalEnumClassNameTemplate, out)
   , mPackageList(packageList) {}
 
+
+GlobalEnumsSourceGenerator::GlobalEnumsSourceGenerator(const PackagesList &packageList, const std::shared_ptr<::google::protobuf::io::Printer> &printer) :
+    ClassGeneratorBase(Templates::GlobalEnumClassNameTemplate, printer)
+  , mPackageList(packageList) {}
+
 void GlobalEnumsSourceGenerator::run() {
-    mPrinter.Print("#include <globalenums.h>\n"
+    mPrinter->Print("#include \"globaldeclarations.pb.h\"\n"
                    "#include <QProtobufObject>\n"
                    "\n"
                    "#include <QQmlEngine>");
@@ -74,9 +79,9 @@ void GlobalEnumsSourceGenerator::printRegisterBody(const std::list<const FileDes
                                                                        {"namespaces", fullNamespace},
                                                                        {"package", list.front()->package()}};
 
-    mPrinter.Print(registrationProperties, Templates::ManualRegistrationGlobalEnumDefinition);
+    mPrinter->Print(registrationProperties, Templates::ManualRegistrationGlobalEnumDefinition);
     Indent();
-    mPrinter.Print(registrationProperties, Templates::QmlRegisterTypeUncreatableTemplate);
+    mPrinter->Print(registrationProperties, Templates::QmlRegisterTypeUncreatableTemplate);
 
     for (auto file : list) {
         for (int i = 0; i < file->enum_type_count(); i++) {
@@ -85,11 +90,11 @@ void GlobalEnumsSourceGenerator::printRegisterBody(const std::list<const FileDes
                                                                    {"type", mClassName + "::" + enumDescr->name()},
                                                                    {"enum", enumDescr->name() + Templates::ListSuffix},
                                                                    {"namespaces", fullNamespace}};
-            mPrinter.Print(properties, Templates::ComplexGlobalEnumFieldRegistrationTemplate);
-            mPrinter.Print(properties, Templates::RegisterMetaTypeTemplate);
-            mPrinter.Print(properties, Templates::RegisterEnumSerializersTemplate);
+            mPrinter->Print(properties, Templates::ComplexGlobalEnumFieldRegistrationTemplate);
+            mPrinter->Print(properties, Templates::RegisterMetaTypeTemplate);
+            mPrinter->Print(properties, Templates::RegisterEnumSerializersTemplate);
         }
     }
     Outdent();
-    mPrinter.Print(Templates::SimpleBlockEnclosureTemplate);
+    mPrinter->Print(Templates::SimpleBlockEnclosureTemplate);
 }

+ 1 - 0
src/generator/globalenumssourcegenerator.h

@@ -36,6 +36,7 @@ class GlobalEnumsSourceGenerator : public ClassGeneratorBase
     PackagesList mPackageList;
 public:
     GlobalEnumsSourceGenerator(const PackagesList &packageList, const std::shared_ptr<google::protobuf::io::ZeroCopyOutputStream> &out);
+    GlobalEnumsSourceGenerator(const PackagesList &packageList, const std::shared_ptr<::google::protobuf::io::Printer> &printer);
     virtual ~GlobalEnumsSourceGenerator() = default;
 
     void run() override;

+ 2 - 1
src/generator/main.cpp

@@ -26,9 +26,10 @@
 #include <google/protobuf/compiler/plugin.h>
 
 #include "generator.h"
+#include "singlefilegenerator.h"
 
 int main(int argc, char *argv[])
 {
-    QtProtobuf::generator::QtGenerator generator;
+    QtProtobuf::generator::SingleFileGenerator generator;
     return ::google::protobuf::compiler::PluginMain(argc, argv, &generator);
 }

+ 34 - 27
src/generator/protobufclassgenerator.cpp

@@ -41,10 +41,17 @@ ProtobufClassGenerator::ProtobufClassGenerator(const Descriptor *message, const
 {
 }
 
+ProtobufClassGenerator::ProtobufClassGenerator(const ::google::protobuf::Descriptor *message, const std::shared_ptr<::google::protobuf::io::Printer> &printer)
+    : ClassGeneratorBase(message->full_name(), printer)
+    , mMessage(message)
+{
+
+}
+
 void ProtobufClassGenerator::printCopyFunctionality()
 {
     assert(mMessage != nullptr);
-    mPrinter.Print({{"classname", mClassName}},
+    mPrinter->Print({{"classname", mClassName}},
                    Templates::CopyConstructorTemplate);
 
     Indent();
@@ -53,24 +60,24 @@ void ProtobufClassGenerator::printCopyFunctionality()
     }
     Outdent();
 
-    mPrinter.Print(Templates::SimpleBlockEnclosureTemplate);
-    mPrinter.Print({{"classname", mClassName}},
+    mPrinter->Print(Templates::SimpleBlockEnclosureTemplate);
+    mPrinter->Print({{"classname", mClassName}},
                    Templates::AssignmentOperatorTemplate);
 
     Indent();
     for (int i = 0; i < mMessage->field_count(); i++) {
         printField(mMessage->field(i), Templates::CopyFieldTemplate);
     }
-    mPrinter.Print(Templates::AssignmentOperatorReturnTemplate);
+    mPrinter->Print(Templates::AssignmentOperatorReturnTemplate);
     Outdent();
 
-    mPrinter.Print(Templates::SimpleBlockEnclosureTemplate);
+    mPrinter->Print(Templates::SimpleBlockEnclosureTemplate);
 }
 
 void ProtobufClassGenerator::printMoveSemantic()
 {
     assert(mMessage != nullptr);
-    mPrinter.Print({{"classname", mClassName}},
+    mPrinter->Print({{"classname", mClassName}},
                    Templates::MoveConstructorTemplate);
 
     Indent();
@@ -89,8 +96,8 @@ void ProtobufClassGenerator::printMoveSemantic()
     }
     Outdent();
 
-    mPrinter.Print(Templates::SimpleBlockEnclosureTemplate);
-    mPrinter.Print({{"classname", mClassName}},
+    mPrinter->Print(Templates::SimpleBlockEnclosureTemplate);
+    mPrinter->Print({{"classname", mClassName}},
                    Templates::MoveAssignmentOperatorTemplate);
 
     Indent();
@@ -107,10 +114,10 @@ void ProtobufClassGenerator::printMoveSemantic()
             }
         }
     }
-    mPrinter.Print(Templates::AssignmentOperatorReturnTemplate);
+    mPrinter->Print(Templates::AssignmentOperatorReturnTemplate);
     Outdent();
 
-    mPrinter.Print(Templates::SimpleBlockEnclosureTemplate);
+    mPrinter->Print(Templates::SimpleBlockEnclosureTemplate);
 }
 
 void ProtobufClassGenerator::printComparisonOperators()
@@ -118,21 +125,21 @@ void ProtobufClassGenerator::printComparisonOperators()
     assert(mMessage != nullptr);
     bool isFirst = true;
     PropertyMap properties;
-    mPrinter.Print({{"type", mClassName}}, Templates::EqualOperatorTemplate);
+    mPrinter->Print({{"type", mClassName}}, Templates::EqualOperatorTemplate);
     if (mMessage->field_count() <= 0) {
-        mPrinter.Print("true");
+        mPrinter->Print("true");
     }
     for (int i = 0; i < mMessage->field_count(); i++) {
         const FieldDescriptor *field = mMessage->field(i);
         if (producePropertyMap(field, properties)) {
             if (!isFirst) {
-                mPrinter.Print("\n&& ");
+                mPrinter->Print("\n&& ");
             } else {
                 Indent();
                 Indent();
                 isFirst = false;
             }
-            mPrinter.Print(properties, Templates::EqualOperatorPropertyTemplate);
+            mPrinter->Print(properties, Templates::EqualOperatorPropertyTemplate);
         }
     }
 
@@ -142,17 +149,17 @@ void ProtobufClassGenerator::printComparisonOperators()
         Outdent();
     }
 
-    mPrinter.Print(";\n");
-    mPrinter.Print(Templates::SimpleBlockEnclosureTemplate);
+    mPrinter->Print(";\n");
+    mPrinter->Print(Templates::SimpleBlockEnclosureTemplate);
 
-    mPrinter.Print({{"type", mClassName}}, Templates::NotEqualOperatorTemplate);
+    mPrinter->Print({{"type", mClassName}}, Templates::NotEqualOperatorTemplate);
 }
 
 void ProtobufClassGenerator::printIncludes()
 {
     assert(mMessage != nullptr);
 
-    mPrinter.Print(Templates::DefaultProtobufIncludesTemplate);
+    mPrinter->Print(Templates::DefaultProtobufIncludesTemplate);
 
     std::set<std::string> existingIncludes;
     for (int i = 0; i < mMessage->field_count(); i++) {
@@ -211,7 +218,7 @@ void ProtobufClassGenerator::printInclude(const FieldDescriptor *field, std::set
     }
 
     if (existingIncludes.find(newInclude) == std::end(existingIncludes)) {
-        mPrinter.Print({{"include", newInclude}}, includeTemplate);
+        mPrinter->Print({{"include", newInclude}}, includeTemplate);
         existingIncludes.insert(newInclude);
     }
 }
@@ -221,7 +228,7 @@ void ProtobufClassGenerator::printField(const FieldDescriptor *field, const char
     assert(field != nullptr);
     std::map<std::string, std::string> propertyMap;
     if (producePropertyMap(field, propertyMap)) {
-        mPrinter.Print(propertyMap, fieldTemplate);
+        mPrinter->Print(propertyMap, fieldTemplate);
     }
 }
 
@@ -319,7 +326,7 @@ void ProtobufClassGenerator::printConstructor()
         }
         parameterList += ", ";
     }
-    mPrinter.Print({{"classname", mClassName},
+    mPrinter->Print({{"classname", mClassName},
                     {"parameter_list", parameterList}}, Templates::ProtoConstructorTemplate);
 
 }
@@ -339,7 +346,7 @@ void ProtobufClassGenerator::printMaps()
                 mapTemplate = Templates::MessageMapTypeUsingTemplate;
             }
 
-            mPrinter.Print({{"classname",field->message_type()->name()},
+            mPrinter->Print({{"classname",field->message_type()->name()},
                             {"key", keyType},
                             {"value", valueType}}, mapTemplate);
         }
@@ -356,7 +363,7 @@ void ProtobufClassGenerator::printLocalEmumsMetaTypesDeclaration()
 
         if (field->type() == FieldDescriptor::TYPE_ENUM
                 && isLocalMessageEnum(mMessage, field)) {
-             mPrinter.Print({{"classname", mClassName + "::" + field->enum_type()->name() + Templates::ListSuffix},
+             mPrinter->Print({{"classname", mClassName + "::" + field->enum_type()->name() + Templates::ListSuffix},
                              {"namespaces", mNamespacesColonDelimited}}, Templates::DeclareMetaTypeTemplate);
         }
     }
@@ -367,7 +374,7 @@ void ProtobufClassGenerator::printMapsMetaTypesDeclaration()
     for (int i = 0; i < mMessage->field_count(); i++) {
         const FieldDescriptor *field = mMessage->field(i);
         if (field->is_map()) {
-             mPrinter.Print({{"classname", field->message_type()->name()},
+             mPrinter->Print({{"classname", field->message_type()->name()},
                              {"namespaces", mNamespacesColonDelimited + "::" + mClassName}}, Templates::DeclareMetaTypeTemplate);
         }
     }
@@ -446,10 +453,10 @@ void ProtobufClassGenerator::printProperties()
     Outdent();
 
     Indent();
-    mPrinter.Print({{"classname", mClassName}}, Templates::ManualRegistrationDeclaration);
+    mPrinter->Print({{"classname", mClassName}}, Templates::ManualRegistrationDeclaration);
     Outdent();
 
-    mPrinter.Print(Templates::SignalsBlockTemplate);
+    mPrinter->Print(Templates::SignalsBlockTemplate);
 
     Indent();
     for (int i = 0; i < mMessage->field_count(); i++) {
@@ -460,7 +467,7 @@ void ProtobufClassGenerator::printProperties()
 
 void ProtobufClassGenerator::printListType()
 {
-    mPrinter.Print({{"classname", mClassName}}, Templates::ComplexListTypeUsingTemplate);
+    mPrinter->Print({{"classname", mClassName}}, Templates::ComplexListTypeUsingTemplate);
 
 }
 

+ 1 - 0
src/generator/protobufclassgenerator.h

@@ -48,6 +48,7 @@ class ProtobufClassGenerator : public ClassGeneratorBase
     const ::google::protobuf::Descriptor *mMessage;
 public:
     ProtobufClassGenerator(const ::google::protobuf::Descriptor *message, const std::shared_ptr<google::protobuf::io::ZeroCopyOutputStream> &out);
+    ProtobufClassGenerator(const ::google::protobuf::Descriptor *message, const std::shared_ptr<::google::protobuf::io::Printer> &printer);
     virtual ~ProtobufClassGenerator() = default;
 
     void run() override;

+ 24 - 18
src/generator/protobufsourcegenerator.cpp

@@ -40,39 +40,45 @@ ProtobufSourceGenerator::ProtobufSourceGenerator(const google::protobuf::Descrip
 {
 }
 
+ProtobufSourceGenerator::ProtobufSourceGenerator(const google::protobuf::Descriptor *message, const std::shared_ptr<::google::protobuf::io::Printer> &printer) :
+    ClassSourceGeneratorBase(message->full_name(), printer)
+  , mMessage(message)
+{
+}
+
 void ProtobufSourceGenerator::printRegisterBody()
 {
     const std::map<std::string, std::string> registrationProperties = {{"classname", mClassName},
                                                                        {"namespaces", mNamespacesColonDelimited},
                                                                        {"package", mMessage->file()->package()}
                                                                       };
-    mPrinter.Print(registrationProperties,
+    mPrinter->Print(registrationProperties,
                    Templates::ManualRegistrationComplexTypeDefinition);
     Indent();
-    mPrinter.Print(registrationProperties, Templates::RegisterQmlListPropertyMetaTypeTemplate);
-    mPrinter.Print(registrationProperties, Templates::QmlRegisterTypeTemplate);
+    mPrinter->Print(registrationProperties, Templates::RegisterQmlListPropertyMetaTypeTemplate);
+    mPrinter->Print(registrationProperties, Templates::QmlRegisterTypeTemplate);
 
     for (int i = 0; i < mMessage->field_count(); i++) {
         const FieldDescriptor *field = mMessage->field(i);
         if (field->type() == FieldDescriptor::TYPE_ENUM
                 && isLocalMessageEnum(mMessage, field)) {
-            mPrinter.Print({{"type", mClassName + "::" + field->enum_type()->name() + Templates::ListSuffix},
+            mPrinter->Print({{"type", mClassName + "::" + field->enum_type()->name() + Templates::ListSuffix},
                             {"namespaces", mNamespacesColonDelimited}},
                            Templates::RegisterMetaTypeTemplateNoNamespace);
-            mPrinter.Print({{"type", mClassName + "::" + field->enum_type()->name() + Templates::ListSuffix},
+            mPrinter->Print({{"type", mClassName + "::" + field->enum_type()->name() + Templates::ListSuffix},
                             {"namespaces", mNamespacesColonDelimited}},
                            Templates::RegisterMetaTypeTemplate);
-            mPrinter.Print({{"type", mClassName + "::" + field->enum_type()->name()}},
+            mPrinter->Print({{"type", mClassName + "::" + field->enum_type()->name()}},
                            Templates::RegisterEnumSerializersTemplate);
         } else if (field->is_map()) {
-            mPrinter.Print({{"type", field->message_type()->name()},
+            mPrinter->Print({{"type", field->message_type()->name()},
                             {"namespaces", mClassName}},
                            Templates::RegisterMetaTypeTemplate);
-            mPrinter.Print({{"type", field->message_type()->name()},
+            mPrinter->Print({{"type", field->message_type()->name()},
                             {"namespaces", mNamespacesColonDelimited + "::" + mClassName}},
                            Templates::RegisterMetaTypeTemplate);
 
-            mPrinter.Print({{"classname", mClassName},
+            mPrinter->Print({{"classname", mClassName},
                             {"type", field->message_type()->name()},
                             {"key_type", getTypeName(field->message_type()->field(0), mMessage)},
                             {"value_type", getTypeName(field->message_type()->field(1), mMessage)}},
@@ -81,25 +87,25 @@ void ProtobufSourceGenerator::printRegisterBody()
     }
 
     Outdent();
-    mPrinter.Print(Templates::SimpleBlockEnclosureTemplate);
+    mPrinter->Print(Templates::SimpleBlockEnclosureTemplate);
 }
 
 void ProtobufSourceGenerator::printFieldsOrdering() {
-    mPrinter.Print({{"type", mClassName}}, Templates::FieldsOrderingContainerTemplate);
+    mPrinter->Print({{"type", mClassName}}, Templates::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("\n,");
         }
         //property_number is incremented by 1 because user properties stating from 1.
         //Property with index 0 is "objectName"
-        mPrinter.Print({{"field_number", std::to_string(field->number())},
+        mPrinter->Print({{"field_number", std::to_string(field->number())},
                         {"property_number", std::to_string(i + 1)}}, Templates::FieldOrderTemplate);
     }
     Outdent();
-    mPrinter.Print(Templates::SemicolonBlockEnclosureTemplate);
-    mPrinter.Print("\n");
+    mPrinter->Print(Templates::SemicolonBlockEnclosureTemplate);
+    mPrinter->Print("\n");
 }
 
 void ProtobufSourceGenerator::printConstructor()
@@ -143,14 +149,14 @@ void ProtobufSourceGenerator::printConstructor()
         }
         parameterList += ", ";
     }
-    mPrinter.Print({{"classname", mClassName},
+    mPrinter->Print({{"classname", mClassName},
                     {"parameter_list", parameterList}}, Templates::ProtoConstructorDefinitionTemplate);
 
     for (int i = 0; i < mMessage->field_count(); i++) {
         const FieldDescriptor *field = mMessage->field(i);
         std::string fieldName = field->name();
         fieldName[0] =  static_cast<char>(::tolower(fieldName[0]));
-        mPrinter.Print({{"property_name", fieldName}}, Templates::PropertyInitializerTemplate);
+        mPrinter->Print({{"property_name", fieldName}}, Templates::PropertyInitializerTemplate);
     }
-    mPrinter.Print(Templates::ConstructorContentTemplate);
+    mPrinter->Print(Templates::ConstructorContentTemplate);
 }

+ 2 - 0
src/generator/protobufsourcegenerator.h

@@ -35,6 +35,8 @@ class ProtobufSourceGenerator : public ClassSourceGeneratorBase
     const google::protobuf::Descriptor *mMessage;
 public:
     ProtobufSourceGenerator(const google::protobuf::Descriptor *message, const std::shared_ptr<google::protobuf::io::ZeroCopyOutputStream> &out);
+    ProtobufSourceGenerator(const google::protobuf::Descriptor *message, const std::shared_ptr<::google::protobuf::io::Printer> &printer);
+
     void printRegisterBody();
     void printFieldsOrdering();
     void printConstructor();

+ 11 - 5
src/generator/servicegeneratorbase.cpp

@@ -48,6 +48,12 @@ ServiceGeneratorBase::ServiceGeneratorBase(const ::google::protobuf::ServiceDesc
 {
 }
 
+ServiceGeneratorBase::ServiceGeneratorBase(const ::google::protobuf::ServiceDescriptor *service,
+                const std::shared_ptr<::google::protobuf::io::Printer> &printer) :
+    ClassGeneratorBase(service->full_name(), printer)
+  , mService(service)
+{}
+
 void ServiceGeneratorBase::printIncludes()
 {
     std::unordered_set<std::string> includeSet;
@@ -63,13 +69,13 @@ void ServiceGeneratorBase::printIncludes()
     }
 
     for (auto type : includeSet) {
-        mPrinter.Print({{"include", type}}, Templates::InternalIncludeTemplate);
+        mPrinter->Print({{"include", type}}, Templates::InternalIncludeTemplate);
     }
 }
 
 void ServiceGeneratorBase::printClassName()
 {
-    mPrinter.Print({{"classname", mClassName}}, Templates::NonProtoClassDefinitionTemplate);
+    mPrinter->Print({{"classname", mClassName}}, Templates::NonProtoClassDefinitionTemplate);
 }
 
 void ServiceGeneratorBase::printMethodsDeclaration(const char *methodTemplate, const char *methodAsyncTemplate, const char *methodAsync2Template)
@@ -79,9 +85,9 @@ void ServiceGeneratorBase::printMethodsDeclaration(const char *methodTemplate, c
         const MethodDescriptor *method = mService->method(i);
         std::map<std::string, std::string> parameters;
         getMethodParameters(method, parameters);
-        mPrinter.Print(parameters, methodTemplate);
-        mPrinter.Print(parameters, methodAsyncTemplate);
-        mPrinter.Print(parameters, methodAsync2Template);
+        mPrinter->Print(parameters, methodTemplate);
+        mPrinter->Print(parameters, methodAsyncTemplate);
+        mPrinter->Print(parameters, methodAsync2Template);
     }
     Outdent();
 }

+ 2 - 0
src/generator/servicegeneratorbase.h

@@ -46,6 +46,8 @@ protected:
 public:
     ServiceGeneratorBase(const ::google::protobuf::ServiceDescriptor *service,
                          const std::shared_ptr<google::protobuf::io::ZeroCopyOutputStream> &out);
+    ServiceGeneratorBase(const ::google::protobuf::ServiceDescriptor *service,
+                    const std::shared_ptr<::google::protobuf::io::Printer> &printer);
     void run() = 0;
 
     void printIncludes();

+ 359 - 0
src/generator/singlefilegenerator.cpp

@@ -0,0 +1,359 @@
+/*
+ * 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 "singlefilegenerator.h"
+#include "templates.h"
+#include "classgeneratorbase.h"
+#include "protobufclassgenerator.h"
+#include "protobufsourcegenerator.h"
+#include "globalenumsgenerator.h"
+#include "globalenumssourcegenerator.h"
+#include "servergenerator.h"
+#include "clientgenerator.h"
+#include "clientsourcegenerator.h"
+#include "utils.h"
+
+#include <iostream>
+#include <set>
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor.h>
+
+static const char *protoFileSuffix = ".pb";
+static const char *grpcFileSuffix = "_grpc";
+static const std::string globalDeclarationsFilename = std::string("globaldeclarations") + protoFileSuffix;
+
+using namespace ::QtProtobuf::generator;
+using namespace ::google::protobuf;
+using namespace ::google::protobuf::compiler;
+
+bool SingleFileGenerator::Generate(const FileDescriptor *file,
+                                   const std::string &parameter,
+                                   GeneratorContext *generatorContext,
+                                   std::string *error) const
+{
+    if (file->syntax() != FileDescriptor::SYNTAX_PROTO3) {
+        *error = "Invalid proto used. This plugin only supports 'proto3' syntax";
+        return false;
+    }
+
+    return GenerateMessages(file, parameter, generatorContext, error)
+            && GenerateServices(file, parameter, generatorContext, error);
+}
+
+bool SingleFileGenerator::GenerateAll(const std::vector<const FileDescriptor *> &files, const string &parameter, GeneratorContext *generatorContext, string *error) const
+{
+    std::shared_ptr<io::ZeroCopyOutputStream> outHeader(generatorContext->Open(globalDeclarationsFilename + ".h"));
+    std::shared_ptr<io::ZeroCopyOutputStream> outSource(generatorContext->Open(globalDeclarationsFilename + ".cpp"));
+    std::shared_ptr<::google::protobuf::io::Printer> outHeaderPrinter(new ::google::protobuf::io::Printer(outHeader.get(), '$'));
+    std::shared_ptr<::google::protobuf::io::Printer> outSourcePrinter(new ::google::protobuf::io::Printer(outSource.get(), '$'));
+
+    PackagesList packageList;
+    for (auto file : files) {
+        packageList[file->package()].push_back(file);
+    }
+
+    GlobalEnumsGenerator enumGen(packageList,
+                                 outHeaderPrinter);
+    enumGen.run();
+
+    GlobalEnumsSourceGenerator enumSourceGen(packageList,
+                                             outSourcePrinter);
+    enumSourceGen.run();
+
+
+    std::shared_ptr<io::ZeroCopyOutputStream> outfHeader(generatorContext->Open(globalDeclarationsFilename + "_.h"));
+    std::shared_ptr<::google::protobuf::io::Printer> outfHeaderPrinter(new ::google::protobuf::io::Printer(outfHeader.get(), '$'));
+
+    outfHeaderPrinter->Print(Templates::DisclaimerTemplate);
+    outfHeaderPrinter->Print(Templates::PreambleTemplate);
+    outfHeaderPrinter->Print(Templates::DefaultProtobufIncludesTemplate);
+
+    for (auto file : files) {
+        if (file->message_type_count() > 0) {
+            outfHeaderPrinter->Print({{"include", utils::extractFileName(file->name()) + protoFileSuffix}}, Templates::InternalIncludeTemplate);
+        }
+    }
+
+    for (auto package : packageList) {
+        std::vector<std::string> namespaces;
+        utils::split(package.first, namespaces, '.');
+        for (auto ns : namespaces) {
+            outfHeaderPrinter->Print({{"namespace", ns}}, Templates::NamespaceTemplate);
+        }
+        outfHeaderPrinter->Print("inline void qRegisterProtobufTypes() {\n");
+        outfHeaderPrinter->Indent();
+        outfHeaderPrinter->Indent();
+        for (auto file : package.second) {
+            iterateNonNestedFileds(file, [&outfHeaderPrinter](const ::google::protobuf::Descriptor *message){
+                outfHeaderPrinter->Print({{"classname", message->name()}}, "qRegisterProtobufType<$classname$>();\n");
+            });
+        }
+        outfHeaderPrinter->Outdent();
+        outfHeaderPrinter->Outdent();
+        outfHeaderPrinter->Print("}\n");
+        for (size_t i = 0; i < namespaces.size(); i++) {
+            outfHeaderPrinter->Print("}\n");
+        }
+    }
+
+    return CodeGenerator::GenerateAll(files, parameter, generatorContext, error);
+}
+
+void SingleFileGenerator::iterateNonNestedFileds(const ::google::protobuf::FileDescriptor *file, std::function<void(const ::google::protobuf::Descriptor *)> callback) const
+{
+    for (int i = 0; i < file->message_type_count(); i++) {
+        const Descriptor *message = file->message_type(i);
+
+        //Detect nested fields and filter maps fields
+        int mapsFieldsCount = 0;
+        for (int j = 0; j < message->nested_type_count(); j++) {
+            for (int k = 0; k < message->field_count(); k++) {
+                if (message->field(k)->is_map() && message->field(k)->message_type() == message->nested_type(j)) {
+                    ++mapsFieldsCount;
+                }
+            }
+        }
+
+        if (message->nested_type_count() > 0 && message->nested_type_count() > mapsFieldsCount) {
+            std::cerr << file->name() << ":" << (message->index() + 1) << ": " << " Error: Meta object features not supported for nested classes in " << message->full_name() << std::endl;
+            continue;
+        }
+        callback(message);
+    }
+}
+
+bool SingleFileGenerator::GenerateMessages(const ::google::protobuf::FileDescriptor *file,
+                                           const std::string &,
+                                           ::google::protobuf::compiler::GeneratorContext *generatorContext,
+                                           std::string *) const {
+    if (file->message_type_count() <= 0) {
+        return true;
+    }
+
+    std::string outFileBasename = utils::extractFileName(file->name());
+    std::set<std::string> internalIncludes;
+    std::set<std::string> externalIncludes;
+    std::shared_ptr<io::ZeroCopyOutputStream> outHeader(generatorContext->Open(outFileBasename + protoFileSuffix + ".h"));
+    std::shared_ptr<io::ZeroCopyOutputStream> outSource(generatorContext->Open(outFileBasename + protoFileSuffix + ".cpp"));
+    std::shared_ptr<::google::protobuf::io::Printer> outHeaderPrinter(new ::google::protobuf::io::Printer(outHeader.get(), '$'));
+    std::shared_ptr<::google::protobuf::io::Printer> outSourcePrinter(new ::google::protobuf::io::Printer(outSource.get(), '$'));
+
+
+    outHeaderPrinter->Print(Templates::DisclaimerTemplate);
+    outHeaderPrinter->Print(Templates::PreambleTemplate);
+    outHeaderPrinter->Print(Templates::DefaultProtobufIncludesTemplate);
+
+    outSourcePrinter->Print(Templates::DisclaimerTemplate);
+    outSourcePrinter->Print({{"include", outFileBasename + protoFileSuffix}}, Templates::InternalIncludeTemplate);
+
+    for (int i = 0; i < file->message_type_count(); i++) {
+        const Descriptor *message = file->message_type(i);
+
+        for(int j = 0; j < message->field_count(); j++) {
+            const FieldDescriptor *field = message->field(j);
+            switch(field->type()) {
+            case FieldDescriptor::TYPE_MESSAGE:
+                if ( field->is_map() ) {
+                    externalIncludes.insert("QMap");
+                    assert(field->message_type() != nullptr);
+                    assert(field->message_type()->field_count() == 2);
+                } else if (field->message_type()->file() != file) {
+                    internalIncludes.insert(utils::extractFileName(field->message_type()->file()->name()) + protoFileSuffix);
+                }
+                break;
+            case FieldDescriptor::TYPE_BYTES:
+                externalIncludes.insert("QByteArray");
+                break;
+            case FieldDescriptor::TYPE_STRING:
+                externalIncludes.insert("QString");
+                break;
+            case FieldDescriptor::TYPE_ENUM:
+                if (field->enum_type()->file() != file) {
+                    internalIncludes.insert(utils::extractFileName(field->enum_type()->file()->name()) + protoFileSuffix);
+                }
+                break;
+            default:
+                break;
+            }
+        }
+    }
+
+    internalIncludes.insert(globalDeclarationsFilename);
+
+    for(auto include : externalIncludes) {
+        outHeaderPrinter->Print({{"include", include}}, Templates::ExternalIncludeTemplate);
+    }
+
+    for(auto include : internalIncludes) {
+        outHeaderPrinter->Print({{"include", include}}, Templates::InternalIncludeTemplate);
+    }
+
+    outSourcePrinter->Print({{"namespace", "QtProtobuf"}}, Templates::UsingNamespaceTemplate);
+
+    std::vector<std::string> namespaces;
+    std::string namespacesColonDelimited;
+
+    utils::split(file->package(), namespaces, '.');
+    assert(namespaces.size() > 0);
+    for (size_t i = 0; i < namespaces.size(); i++) {
+        if (i > 0) {
+            namespacesColonDelimited = namespacesColonDelimited.append("::");
+        }
+        namespacesColonDelimited = namespacesColonDelimited.append(namespaces[i]);
+        outHeaderPrinter->Print({{"namespace", namespaces[i]}}, Templates::NamespaceTemplate);
+    }
+
+    iterateNonNestedFileds(file, [&outHeaderPrinter](const ::google::protobuf::Descriptor *message){
+        outHeaderPrinter->Print({{"classname", message->name()}}, Templates::ProtoClassDeclarationTemplate);
+    });
+
+    for (size_t i = 0; i < namespaces.size(); i++) {
+        outHeaderPrinter->Print(Templates::SimpleBlockEnclosureTemplate);
+    }
+
+    iterateNonNestedFileds(file, [&outHeaderPrinter, &outSourcePrinter](const ::google::protobuf::Descriptor *message){
+        ProtobufClassGenerator classGen(message,
+                                        outHeaderPrinter);
+
+        classGen.printNamespaces();
+        classGen.printClassDeclaration();
+        classGen.printProperties();
+        classGen.printPrivate();
+        classGen.printClassMembers();
+        classGen.encloseClass();
+        classGen.printListType();
+        classGen.encloseNamespaces();
+        classGen.printMetaTypeDeclaration();
+        classGen.printMapsMetaTypesDeclaration();
+        classGen.printLocalEmumsMetaTypesDeclaration();
+
+        ProtobufSourceGenerator srcGen(message,
+                                       outSourcePrinter);
+        srcGen.printNamespaces();
+        srcGen.printFieldsOrdering();
+        srcGen.printRegisterBody();
+        srcGen.printConstructor();
+        srcGen.encloseNamespaces();
+
+    });
+
+    return true;
+}
+
+
+bool SingleFileGenerator::GenerateServices(const ::google::protobuf::FileDescriptor *file,
+                                           const std::string &,
+                                           ::google::protobuf::compiler::GeneratorContext *generatorContext,
+                                           std::string *) const
+{
+    if (file->service_count() <= 0) {
+        return true;
+    }
+
+    std::string outFileBasename = utils::extractFileName(file->name());
+    std::set<std::string> internalIncludes;
+    std::set<std::string> externalIncludes;
+    std::shared_ptr<io::ZeroCopyOutputStream> outHeader(generatorContext->Open(outFileBasename + grpcFileSuffix + protoFileSuffix + ".h"));
+    std::shared_ptr<io::ZeroCopyOutputStream> outSource(generatorContext->Open(outFileBasename + grpcFileSuffix + protoFileSuffix + ".cpp"));
+    std::shared_ptr<::google::protobuf::io::Printer> outHeaderPrinter(new ::google::protobuf::io::Printer(outHeader.get(), '$'));
+    std::shared_ptr<::google::protobuf::io::Printer> outSourcePrinter(new ::google::protobuf::io::Printer(outSource.get(), '$'));
+
+    outHeaderPrinter->Print(Templates::DisclaimerTemplate);
+    outHeaderPrinter->Print(Templates::PreambleTemplate);
+    outHeaderPrinter->Print(Templates::DefaultProtobufIncludesTemplate);
+
+    outSourcePrinter->Print(Templates::DisclaimerTemplate);
+    outSourcePrinter->Print({{"include", outFileBasename + grpcFileSuffix + protoFileSuffix}}, Templates::InternalIncludeTemplate);
+
+    for (int i = 0; i < file->service_count(); i++) {
+        const ServiceDescriptor *service = file->service(i);
+        for (int i = 0; i < service->method_count(); i++) {
+            const MethodDescriptor *method = service->method(i);
+            if (method->input_type()->file() != service->file()) {
+                internalIncludes.insert(utils::extractFileName(method->input_type()->file()->name()) + protoFileSuffix);
+            }
+
+            if (method->output_type()->file() != service->file()) {
+                internalIncludes.insert(utils::extractFileName(method->output_type()->file()->name()) + protoFileSuffix);
+            }
+        }
+    }
+
+
+    externalIncludes.insert("QAbstractGrpcClient");
+    externalIncludes.insert("QGrpcAsyncReply");
+
+    internalIncludes.insert(globalDeclarationsFilename);
+    if (file->message_type_count() > 0) {
+        internalIncludes.insert(outFileBasename + protoFileSuffix);
+    }
+    for(auto include : externalIncludes) {
+        outHeaderPrinter->Print({{"include", include}}, Templates::ExternalIncludeTemplate);
+    }
+
+    for(auto include : internalIncludes) {
+        outHeaderPrinter->Print({{"include", include}}, Templates::InternalIncludeTemplate);
+    }
+
+
+    outSourcePrinter->Print({{"namespace", "QtProtobuf"}}, Templates::UsingNamespaceTemplate);
+
+    for (int i = 0; i < file->service_count(); i++) {
+        const ServiceDescriptor *service = file->service(i);
+        // Serverside descriptor is not in use
+        //        std::string baseFilename(service->name());
+        //        utils::tolower(baseFilename);
+
+        //        std::string fullFilename = baseFilename + "server.h";
+        //        ServerGenerator serverGen(service,
+        //                                  std::shared_ptr<io::ZeroCopyOutputStream>(generatorContext->Open(fullFilename)));
+        //        serverGen.run();
+
+        ClientGenerator clientGen(service,
+                                  outHeaderPrinter);
+        clientGen.printNamespaces();
+        clientGen.printClientClass();
+        clientGen.printPublic();
+        clientGen.printConstructor();
+        clientGen.printClientMethodsDeclaration();
+        clientGen.encloseClass();
+        clientGen.encloseNamespaces();
+
+        ClientSourceGenerator clientSrcGen(service,
+                                           outSourcePrinter);
+        clientSrcGen.printNamespaces();
+        clientSrcGen.printConstructor();
+        clientSrcGen.printMethods();
+        clientSrcGen.encloseNamespaces();
+    }
+
+    return true;
+}
+
+
+

+ 73 - 0
src/generator/singlefilegenerator.h

@@ -0,0 +1,73 @@
+/*
+ * 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 <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <string>
+#include <memory>
+#include <functional>
+
+namespace google { namespace protobuf {
+class FileDescriptor;
+class Descriptor;
+namespace compiler {
+class GeneratorContext;
+}}}
+
+namespace QtProtobuf {
+namespace generator {
+
+class SingleFileGenerator : public ::google::protobuf::compiler::CodeGenerator
+{
+    bool Generate(const ::google::protobuf::FileDescriptor *file,
+                          const std::string &parameter,
+                          ::google::protobuf::compiler::GeneratorContext *generatorContext,
+                          std::string *error) const override;
+
+    bool GenerateAll(const std::vector<const ::google::protobuf::FileDescriptor *> &files,
+                             const std::string &parameter,
+                             ::google::protobuf::compiler::GeneratorContext *generatorContext,
+                             std::string *error) const override;
+    bool HasGenerateAll() const override { return true; }
+
+
+private:
+    void iterateNonNestedFileds(const ::google::protobuf::FileDescriptor *file, std::function<void(const ::google::protobuf::Descriptor *)> callback) const;
+
+    bool GenerateServices(const ::google::protobuf::FileDescriptor *file,
+                          const std::string &parameter,
+                          ::google::protobuf::compiler::GeneratorContext *generatorContext,
+                          std::string *error) const;
+
+    bool GenerateMessages(const ::google::protobuf::FileDescriptor *file,
+                          const std::string &parameter,
+                          ::google::protobuf::compiler::GeneratorContext *generatorContext,
+                          std::string *error) const;
+};
+
+} //namespace generator
+} // namespace QtProtobuf

+ 1 - 0
src/generator/templates.cpp

@@ -67,6 +67,7 @@ const char *Templates::UsingNamespaceTemplate = "using namespace $namespace$;\n"
 const char *Templates::NonProtoClassDefinitionTemplate = "\nclass $classname$ : public QObject\n"
                                                          "{\n"
                                                          "    Q_OBJECT\n";
+const char *Templates::ProtoClassDeclarationTemplate = "class $classname$;\n";
 const char *Templates::ProtoClassDefinitionTemplate = "\nclass $classname$ : public QObject\n"
                                                       "{\n"
                                                       "    Q_OBJECT\n"

+ 1 - 0
src/generator/templates.h

@@ -53,6 +53,7 @@ public:
     static const char *NamespaceTemplate;
     static const char *UsingNamespaceTemplate;
     static const char *NonProtoClassDefinitionTemplate;
+    static const char *ProtoClassDeclarationTemplate;
     static const char *ProtoClassDefinitionTemplate;
     static const char *ConstructorHeaderTemplate;
     static const char *ClassDefinitionTemplate;

+ 6 - 0
src/generator/utils.h

@@ -62,6 +62,12 @@ static void tolower(std::string &str) {
     std::transform(std::begin(str), std::end(str), std::begin(str), ::tolower);
 }
 
+static std::string extractFileName(std::string fileName) {
+    size_t index = fileName.rfind(".proto");
+    fileName.resize(index);
+    return fileName;
+}
+
 };
 
 #define UNUSED(expr) do { (void)(expr); } while (0)

+ 3 - 4
src/protobuf/QtProtobufGen.cmake.in

@@ -21,9 +21,7 @@ function(generate_qtprotobuf)
     endforeach()
 
     #TODO: add globalenums by default. But it's better to verify if proto file contains any global enum
-    set(GENERATED_HEADERS ${GENERATED_HEADERS} globalenums.h)
-
-    #message("${PARSER_ERROR} Generated files list: ${GENERATED_HEADERS} ${GENERATED_HEADERS_PART}")
+    set(GENERATED_HEADERS ${GENERATED_HEADERS} globaldeclarations.pb.h)
 
     if(DEFINED generate_qtprotobuf_GENERATED_HEADERS)
         set(GENERATED_HEADERS ${generate_qtprotobuf_GENERATED_HEADERS})
@@ -46,7 +44,8 @@ function(generate_qtprotobuf)
     unset(QTPROTOBUF_GENERATED_SOURCES)
     unset(QTPROTOBUF_GENERATED_HEADERS)
     foreach(GENERATED_HEADER IN LISTS GENERATED_HEADERS)
-        get_filename_component(GENERATED_BASENAME ${GENERATED_HEADER} NAME_WE)
+        get_filename_component(GENERATED_BASENAME ${GENERATED_HEADER} NAME)
+        string(REGEX REPLACE "\\.[^.]*$" "" GENERATED_BASENAME ${GENERATED_BASENAME})
 
         list(APPEND QTPROTOBUF_GENERATED_SOURCES ${OUT_DIR}/${GENERATED_BASENAME}.cpp)
         list(APPEND QTPROTOBUF_GENERATED_HEADERS ${OUT_DIR}/${GENERATED_BASENAME}.h)

+ 31 - 3
src/protobuf/parsemessages.go

@@ -7,6 +7,7 @@ import (
 	"os"
 	"regexp"
 	"strings"
+	filepath "path/filepath"
 )
 
 func main() {
@@ -26,20 +27,47 @@ func main() {
 	}
 	
     serviceFinder, err := regexp.Compile("^service\\s+([a-zA-Z0-9_]+)")
+	if err != nil {
+		log.Fatalf("Invalid regexp %s\n", err)
+	}
 
 	scanner := bufio.NewScanner(file)
+    //Multifile version
+// 	for scanner.Scan() {
+// 		capture := messageFinder.FindStringSubmatch(scanner.Text())
+// 		if len(capture) == 2 {
+//             fmt.Printf("%s.h;", strings.ToLower(capture[1]))
+// 		}
+// 
+//         
+// 		capture = serviceFinder.FindStringSubmatch(scanner.Text())
+// 		if len(capture) == 2 {
+//             fmt.Printf("%sclient.h;", strings.ToLower(capture[1]))
+// 		}
+// 	}
+    
+    //Signlefile version
+	basename := strings.TrimSuffix(os.Args[1], filepath.Ext(os.Args[1]))
+	messageFound := false
+	serviceFound := false
 	for scanner.Scan() {
 		capture := messageFinder.FindStringSubmatch(scanner.Text())
 		if len(capture) == 2 {
-            fmt.Printf("%s.h;", strings.ToLower(capture[1]))
+			messageFound = true
 		}
 
-        
 		capture = serviceFinder.FindStringSubmatch(scanner.Text())
 		if len(capture) == 2 {
-            fmt.Printf("%sclient.h;", strings.ToLower(capture[1]))
+			serviceFound = true
 		}
 	}
+	if messageFound {
+        fmt.Printf("%s.pb.h;", basename)
+    }
+    
+    if serviceFound {
+        fmt.Printf("%s_grpc.pb.h;", basename)
+    }
 
 	if err := scanner.Err(); err != nil {
 		log.Fatal(err)

+ 4 - 2
tests/test_grpc/clienttest.cpp

@@ -23,10 +23,12 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include "testserviceclient.h"
+#include "testservice_grpc.pb.h"
+
+//#include "testserviceclient.h"
 #include "qgrpchttp2channel.h"
 #include "insecurecredentials.h"
-#include "blobmessage.h"
+//#include "blobmessage.h"
 #include <sslcredentials.h>
 
 #include <QTimer>

+ 4 - 4
tests/test_grpc/echoserver/main.cpp

@@ -1,9 +1,9 @@
 #include <iostream>
 #include <grpc++/grpc++.h>
-#include <testservice.pb.h>
-#include <testservice.grpc.pb.h>
-#include <simpletest.pb.h>
-#include <simpletest.grpc.pb.h>
+#include "testservice.pb.h"
+#include "testservice.grpc.pb.h"
+#include "simpletest.pb.h"
+#include "simpletest.grpc.pb.h"
 #include <thread>
 
 class SimpleTestImpl final : public qtprotobufnamespace::tests::TestService::Service {

+ 3 - 2
tests/test_grpc/sslclienttest.cpp

@@ -23,9 +23,10 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include "testserviceclient.h"
+#include "testservice_grpc.pb.h"
+//#include "testserviceclient.h"
 #include "qgrpchttp2channel.h"
-#include "blobmessage.h"
+//#include "blobmessage.h"
 #include <sslcredentials.h>
 
 #include <QTimer>

+ 66 - 64
tests/test_protobuf/deserializationtest.cpp

@@ -24,70 +24,72 @@
  */
 
 #include "deserializationtest.h"
-#include "simpleboolmessage.h"
-#include "simplefixedint32message.h"
-#include "simplefixedint64message.h"
-#include "simplesfixedint32message.h"
-#include "simplesfixedint64message.h"
-#include "simplefloatmessage.h"
-#include "simpledoublemessage.h"
-#include "simpleintmessage.h"
-#include "simplesintmessage.h"
-#include "simpleuintmessage.h"
-#include "simplestringmessage.h"
-#include "complexmessage.h"
-#include "repeatedstringmessage.h"
-#include "repeatedbytesmessage.h"
-#include "repeateddoublemessage.h"
-#include "repeatedfloatmessage.h"
-#include "repeatedintmessage.h"
-#include "repeatedsintmessage.h"
-#include "repeateduintmessage.h"
-#include "repeatedint64message.h"
-#include "repeatedsint64message.h"
-#include "repeateduint64message.h"
-#include "repeatedfixedintmessage.h"
-#include "repeatedsfixedintmessage.h"
-#include "repeatedfixedint64message.h"
-#include "repeatedsfixedint64message.h"
-#include "simpleenummessage.h"
-#include "simplebytesmessage.h"
-#include "repeatedcomplexmessage.h"
-
-#include "simplefixed32stringmapmessage.h"
-#include "simplesfixed32stringmapmessage.h"
-#include "simpleint32stringmapmessage.h"
-#include "simplesint32stringmapmessage.h"
-#include "simpleuint32stringmapmessage.h"
-
-#include "simplefixed64stringmapmessage.h"
-#include "simplesfixed64stringmapmessage.h"
-#include "simpleint64stringmapmessage.h"
-#include "simplesint64stringmapmessage.h"
-#include "simpleuint64stringmapmessage.h"
-
-#include "simplestringstringmapmessage.h"
-
-#include "simplefixed32complexmessagemapmessage.h"
-#include "simplesfixed32complexmessagemapmessage.h"
-#include "simpleint32complexmessagemapmessage.h"
-#include "simplesint32complexmessagemapmessage.h"
-#include "simpleuint32complexmessagemapmessage.h"
-
-#include "simplefixed64complexmessagemapmessage.h"
-#include "simplesfixed64complexmessagemapmessage.h"
-#include "simpleint64complexmessagemapmessage.h"
-#include "simplesint64complexmessagemapmessage.h"
-#include "simpleuint64complexmessagemapmessage.h"
-
-#include "simplestringcomplexmessagemapmessage.h"
-
-#include "fieldindextest1message.h"
-#include "fieldindextest2message.h"
-#include "fieldindextest3message.h"
-#include "fieldindextest4message.h"
-
-#include "simpleenumlistmessage.h"
+
+#include "simpletest.pb.h"
+//#include "simpleboolmessage.h"
+//#include "simplefixedint32message.h"
+//#include "simplefixedint64message.h"
+//#include "simplesfixedint32message.h"
+//#include "simplesfixedint64message.h"
+//#include "simplefloatmessage.h"
+//#include "simpledoublemessage.h"
+//#include "simpleintmessage.h"
+//#include "simplesintmessage.h"
+//#include "simpleuintmessage.h"
+//#include "simplestringmessage.h"
+//#include "complexmessage.h"
+//#include "repeatedstringmessage.h"
+//#include "repeatedbytesmessage.h"
+//#include "repeateddoublemessage.h"
+//#include "repeatedfloatmessage.h"
+//#include "repeatedintmessage.h"
+//#include "repeatedsintmessage.h"
+//#include "repeateduintmessage.h"
+//#include "repeatedint64message.h"
+//#include "repeatedsint64message.h"
+//#include "repeateduint64message.h"
+//#include "repeatedfixedintmessage.h"
+//#include "repeatedsfixedintmessage.h"
+//#include "repeatedfixedint64message.h"
+//#include "repeatedsfixedint64message.h"
+//#include "simpleenummessage.h"
+//#include "simplebytesmessage.h"
+//#include "repeatedcomplexmessage.h"
+
+//#include "simplefixed32stringmapmessage.h"
+//#include "simplesfixed32stringmapmessage.h"
+//#include "simpleint32stringmapmessage.h"
+//#include "simplesint32stringmapmessage.h"
+//#include "simpleuint32stringmapmessage.h"
+
+//#include "simplefixed64stringmapmessage.h"
+//#include "simplesfixed64stringmapmessage.h"
+//#include "simpleint64stringmapmessage.h"
+//#include "simplesint64stringmapmessage.h"
+//#include "simpleuint64stringmapmessage.h"
+
+//#include "simplestringstringmapmessage.h"
+
+//#include "simplefixed32complexmessagemapmessage.h"
+//#include "simplesfixed32complexmessagemapmessage.h"
+//#include "simpleint32complexmessagemapmessage.h"
+//#include "simplesint32complexmessagemapmessage.h"
+//#include "simpleuint32complexmessagemapmessage.h"
+
+//#include "simplefixed64complexmessagemapmessage.h"
+//#include "simplesfixed64complexmessagemapmessage.h"
+//#include "simpleint64complexmessagemapmessage.h"
+//#include "simplesint64complexmessagemapmessage.h"
+//#include "simpleuint64complexmessagemapmessage.h"
+
+//#include "simplestringcomplexmessagemapmessage.h"
+
+//#include "fieldindextest1message.h"
+//#include "fieldindextest2message.h"
+//#include "fieldindextest3message.h"
+//#include "fieldindextest4message.h"
+
+//#include "simpleenumlistmessage.h"
 
 using namespace qtprotobufnamespace::tests;
 using namespace QtProtobuf::tests;

+ 2 - 1
tests/test_protobuf/jsonserializationtest.cpp

@@ -26,7 +26,8 @@
 #include <gtest/gtest.h>
 #include <QByteArray>
 #include <QString>
-#include <simplefixedint32message.h>
+#include "simpletest.pb.h"
+//#include <simplefixedint32message.h>
 #include <qprotobufjsonserializer.h>
 
 using namespace qtprotobufnamespace::tests;

+ 18 - 0
tests/test_protobuf/proto/crossfiletest.proto_disabled

@@ -0,0 +1,18 @@
+syntax = "proto3";
+
+package qtprotobufnamespace.tests;
+
+import "simpletest.proto";
+
+message CrossFileMessage {
+    SimpleBoolMessage testField = 1;
+}
+
+
+message SecondDependency {
+    FirstDependency testField = 1;
+}
+
+message FirstDependency {
+    SecondDependency testField = 1;
+}

+ 11 - 0
tests/test_protobuf/proto/sequencetest.proto_disabled

@@ -0,0 +1,11 @@
+syntax = "proto3";
+
+package qtprotobufnamespace.tests.sequence;
+
+message TestMessage {
+    TestMessage2 testField = 1;
+}
+
+message TestMessage2 {
+    bool testField = 1;
+}

+ 15 - 13
tests/test_protobuf/serializationcomplexmessagemap.cpp

@@ -25,19 +25,21 @@
 
 #include "serializationtest.h"
 
-#include "simplefixed32complexmessagemapmessage.h"
-#include "simplesfixed32complexmessagemapmessage.h"
-#include "simpleint32complexmessagemapmessage.h"
-#include "simplesint32complexmessagemapmessage.h"
-#include "simpleuint32complexmessagemapmessage.h"
-
-#include "simplefixed64complexmessagemapmessage.h"
-#include "simplesfixed64complexmessagemapmessage.h"
-#include "simpleint64complexmessagemapmessage.h"
-#include "simplesint64complexmessagemapmessage.h"
-#include "simpleuint64complexmessagemapmessage.h"
-
-#include "simplestringcomplexmessagemapmessage.h"
+#include "simpletest.pb.h"
+
+//#include "simplefixed32complexmessagemapmessage.h"
+//#include "simplesfixed32complexmessagemapmessage.h"
+//#include "simpleint32complexmessagemapmessage.h"
+//#include "simplesint32complexmessagemapmessage.h"
+//#include "simpleuint32complexmessagemapmessage.h"
+
+//#include "simplefixed64complexmessagemapmessage.h"
+//#include "simplesfixed64complexmessagemapmessage.h"
+//#include "simpleint64complexmessagemapmessage.h"
+//#include "simplesint64complexmessagemapmessage.h"
+//#include "simpleuint64complexmessagemapmessage.h"
+
+//#include "simplestringcomplexmessagemapmessage.h"
 
 using namespace qtprotobufnamespace::tests;
 using namespace QtProtobuf::tests;

+ 53 - 52
tests/test_protobuf/serializationtest.cpp

@@ -25,58 +25,59 @@
 
 #include "serializationtest.h"
 
-#include "simpleintmessage.h"
-#include "simpleuintmessage.h"
-#include "simplesintmessage.h"
-#include "simpleint64message.h"
-#include "simpleuint64message.h"
-#include "simplesint64message.h"
-#include "simplefixedint32message.h"
-#include "simplefixedint64message.h"
-#include "simplesfixedint32message.h"
-#include "simplesfixedint64message.h"
-#include "simplefloatmessage.h"
-#include "simpledoublemessage.h"
-#include "simplestringmessage.h"
-#include "complexmessage.h"
-#include "repeatedintmessage.h"
-#include "repeatedsintmessage.h"
-#include "repeateduintmessage.h"
-#include "repeatedint64message.h"
-#include "repeatedsint64message.h"
-#include "repeateduint64message.h"
-#include "repeatedfixedintmessage.h"
-#include "repeatedsfixedintmessage.h"
-#include "repeatedfixedint64message.h"
-#include "repeatedsfixedint64message.h"
-#include "repeatedstringmessage.h"
-#include "repeateddoublemessage.h"
-#include "repeatedbytesmessage.h"
-#include "repeatedfloatmessage.h"
-#include "repeatedcomplexmessage.h"
-#include "simpleboolmessage.h"
-#include "simpleenummessage.h"
-
-#include "simplefixed32stringmapmessage.h"
-#include "simplesfixed32stringmapmessage.h"
-#include "simpleint32stringmapmessage.h"
-#include "simplesint32stringmapmessage.h"
-#include "simpleuint32stringmapmessage.h"
-
-#include "simplefixed64stringmapmessage.h"
-#include "simplesfixed64stringmapmessage.h"
-#include "simpleint64stringmapmessage.h"
-#include "simplesint64stringmapmessage.h"
-#include "simpleuint64stringmapmessage.h"
-
-#include "simplestringstringmapmessage.h"
-
-#include "fieldindextest1message.h"
-#include "fieldindextest2message.h"
-#include "fieldindextest3message.h"
-#include "fieldindextest4message.h"
-#include "simpleenumlistmessage.h"
-#include "simplebytesmessage.h"
+#include "simpletest.pb.h"
+//#include "simpleintmessage.h"
+//#include "simpleuintmessage.h"
+//#include "simplesintmessage.h"
+//#include "simpleint64message.h"
+//#include "simpleuint64message.h"
+//#include "simplesint64message.h"
+//#include "simplefixedint32message.h"
+//#include "simplefixedint64message.h"
+//#include "simplesfixedint32message.h"
+//#include "simplesfixedint64message.h"
+//#include "simplefloatmessage.h"
+//#include "simpledoublemessage.h"
+//#include "simplestringmessage.h"
+//#include "complexmessage.h"
+//#include "repeatedintmessage.h"
+//#include "repeatedsintmessage.h"
+//#include "repeateduintmessage.h"
+//#include "repeatedint64message.h"
+//#include "repeatedsint64message.h"
+//#include "repeateduint64message.h"
+//#include "repeatedfixedintmessage.h"
+//#include "repeatedsfixedintmessage.h"
+//#include "repeatedfixedint64message.h"
+//#include "repeatedsfixedint64message.h"
+//#include "repeatedstringmessage.h"
+//#include "repeateddoublemessage.h"
+//#include "repeatedbytesmessage.h"
+//#include "repeatedfloatmessage.h"
+//#include "repeatedcomplexmessage.h"
+//#include "simpleboolmessage.h"
+//#include "simpleenummessage.h"
+
+//#include "simplefixed32stringmapmessage.h"
+//#include "simplesfixed32stringmapmessage.h"
+//#include "simpleint32stringmapmessage.h"
+//#include "simplesint32stringmapmessage.h"
+//#include "simpleuint32stringmapmessage.h"
+
+//#include "simplefixed64stringmapmessage.h"
+//#include "simplesfixed64stringmapmessage.h"
+//#include "simpleint64stringmapmessage.h"
+//#include "simplesint64stringmapmessage.h"
+//#include "simpleuint64stringmapmessage.h"
+
+//#include "simplestringstringmapmessage.h"
+
+//#include "fieldindextest1message.h"
+//#include "fieldindextest2message.h"
+//#include "fieldindextest3message.h"
+//#include "fieldindextest4message.h"
+//#include "simpleenumlistmessage.h"
+//#include "simplebytesmessage.h"
 
 using namespace qtprotobufnamespace::tests;
 using namespace QtProtobuf::tests;

+ 51 - 49
tests/test_protobuf/simpletest.cpp

@@ -23,55 +23,57 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include "stepchildenummessage.h"
-#include "simpleboolmessage.h"
-#include "simpleintmessage.h"
-#include "simplesintmessage.h"
-#include "simpleuintmessage.h"
-#include "simpleint64message.h"
-#include "simplesint64message.h"
-#include "simpleuint64message.h"
-#include "simplefixedint32message.h"
-#include "simplefixedint64message.h"
-#include "simplesfixedint32message.h"
-#include "simplesfixedint64message.h"
-#include "simplestringmessage.h"
-#include "simplefloatmessage.h"
-#include "simpledoublemessage.h"
-#include "simpleenummessage.h"
-#include "simpleenumlistmessage.h"
-#include "simplefileenummessage.h"
-#include "simpleexternalenummessage.h"
-#include "externalcomplexmessage.h"
-#include "complexmessage.h"
-#include "simplebytesmessage.h"
-#include "repeatedintmessage.h"
-#include "repeatedbytesmessage.h"
-#include "repeateddoublemessage.h"
-#include "repeatedcomplexmessage.h"
-#include "repeatedfloatmessage.h"
-#include "repeatedsintmessage.h"
-#include "repeatedstringmessage.h"
-#include "repeateduintmessage.h"
-#include "repeatedint64message.h"
-#include "repeatedsint64message.h"
-#include "repeateduint64message.h"
-#include "repeatedfixedintmessage.h"
-#include "repeatedsfixedintmessage.h"
-#include "repeatedfixedint64message.h"
-#include "repeatedsfixedint64message.h"
-#include "repeatedexternalcomplexmessage.h"
-#include "simplesint32stringmapmessage.h"
-#include "simplestringstringmapmessage.h"
-#include "emptymessage.h"
-#include "message_uderscore_name.h"
-#include "messageuderscorename.h"
-#include "messageunderscorefield.h"
-#include "priormessageunderscorefield.h"
-#include "followingmessageunderscorefield.h"
-#include "combinedmessageunderscorefield.h"
-
-#include "globalenums.h"
+#include "simpletest.pb.h"
+
+//#include "stepchildenummessage.h"
+//#include "simpleboolmessage.h"
+//#include "simpleintmessage.h"
+//#include "simplesintmessage.h"
+//#include "simpleuintmessage.h"
+//#include "simpleint64message.h"
+//#include "simplesint64message.h"
+//#include "simpleuint64message.h"
+//#include "simplefixedint32message.h"
+//#include "simplefixedint64message.h"
+//#include "simplesfixedint32message.h"
+//#include "simplesfixedint64message.h"
+//#include "simplestringmessage.h"
+//#include "simplefloatmessage.h"
+//#include "simpledoublemessage.h"
+//#include "simpleenummessage.h"
+//#include "simpleenumlistmessage.h"
+//#include "simplefileenummessage.h"
+//#include "simpleexternalenummessage.h"
+//#include "externalcomplexmessage.h"
+//#include "complexmessage.h"
+//#include "simplebytesmessage.h"
+//#include "repeatedintmessage.h"
+//#include "repeatedbytesmessage.h"
+//#include "repeateddoublemessage.h"
+//#include "repeatedcomplexmessage.h"
+//#include "repeatedfloatmessage.h"
+//#include "repeatedsintmessage.h"
+//#include "repeatedstringmessage.h"
+//#include "repeateduintmessage.h"
+//#include "repeatedint64message.h"
+//#include "repeatedsint64message.h"
+//#include "repeateduint64message.h"
+//#include "repeatedfixedintmessage.h"
+//#include "repeatedsfixedintmessage.h"
+//#include "repeatedfixedint64message.h"
+//#include "repeatedsfixedint64message.h"
+//#include "repeatedexternalcomplexmessage.h"
+//#include "simplesint32stringmapmessage.h"
+//#include "simplestringstringmapmessage.h"
+//#include "emptymessage.h"
+//#include "message_uderscore_name.h"
+//#include "messageuderscorename.h"
+//#include "messageunderscorefield.h"
+//#include "priormessageunderscorefield.h"
+//#include "followingmessageunderscorefield.h"
+//#include "combinedmessageunderscorefield.h"
+
+//#include "globalenums.h"
 #include <QVariantList>
 #include <QMetaProperty>
 #include <QSignalSpy>

+ 17 - 15
tests/test_qml/main.cpp

@@ -25,21 +25,23 @@
 
 #include <QtQuickTest/quicktest.h>
 
-#include "simpleboolmessage.h"
-#include "simplebytesmessage.h"
-#include "simpledoublemessage.h"
-#include "simplefloatmessage.h"
-#include "simplefixedint32message.h"
-#include "simplefixedint64message.h"
-#include "simplesfixedint32message.h"
-#include "simplesfixedint64message.h"
-#include "simpleintmessage.h"
-#include "simpleint64message.h"
-#include "simplesintmessage.h"
-#include "simplesint64message.h"
-#include "simpleuintmessage.h"
-#include "simpleuint64message.h"
-#include "simplestringmessage.h"
+#include "simpletest.pb.h"
+
+//#include "simpleboolmessage.h"
+//#include "simplebytesmessage.h"
+//#include "simpledoublemessage.h"
+//#include "simplefloatmessage.h"
+//#include "simplefixedint32message.h"
+//#include "simplefixedint64message.h"
+//#include "simplesfixedint32message.h"
+//#include "simplesfixedint64message.h"
+//#include "simpleintmessage.h"
+//#include "simpleint64message.h"
+//#include "simplesintmessage.h"
+//#include "simplesint64message.h"
+//#include "simpleuintmessage.h"
+//#include "simpleuint64message.h"
+//#include "simplestringmessage.h"
 
 using namespace qtprotobufnamespace::tests;