123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- /*
- * 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 "generatorbase.h"
- #include <google/protobuf/descriptor.h>
- #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 "utils.h"
- #include "templates.h"
- #include "generatoroptions.h"
- #include "generatorcommon.h"
- using namespace ::QtProtobuf::generator;
- using namespace ::google::protobuf;
- using namespace ::google::protobuf::compiler;
- GeneratorBase::GeneratorBase(Mode mode) : m_mode(mode)
- {
- }
- bool GeneratorBase::GenerateAll(const std::vector<const FileDescriptor *> &files, const string ¶meter, GeneratorContext *generatorContext, string *error) const
- {
- return CodeGenerator::GenerateAll(files, parameter, generatorContext, error);
- }
- std::string GeneratorBase::generateBaseName(const ::google::protobuf::FileDescriptor *file, std::string name)
- {
- std::vector<std::string> packages = utils::split(file->package(), '.');
- std::string outFileBasename = "";
- if (GeneratorOptions::instance().isFolder()) {
- for (auto package : packages) {
- outFileBasename += package + "/";
- }
- outFileBasename += name;
- } else {
- outFileBasename = name;
- }
- return outFileBasename;
- }
- void GeneratorBase::printDisclaimer(const std::shared_ptr<::google::protobuf::io::Printer> printer)
- {
- printer->Print(Templates::DisclaimerTemplate);
- }
- void GeneratorBase::printPreamble(const std::shared_ptr<::google::protobuf::io::Printer> printer)
- {
- printer->Print(Templates::PreambleTemplate);
- }
- void GeneratorBase::printInclude(const std::shared_ptr<::google::protobuf::io::Printer> printer, const google::protobuf::Descriptor *message, const FieldDescriptor *field, std::set<std::string> &existingIncludes)
- {
- assert(field != nullptr);
- std::string newInclude;
- const char *includeTemplate = "";
- switch (field->type()) {
- case FieldDescriptor::TYPE_MESSAGE:
- if (field->is_map()) {
- newInclude = "QMap";
- assert(field->message_type() != nullptr);
- assert(field->message_type()->field_count() == 2);
- printInclude(printer, message, field->message_type()->field(0), existingIncludes);
- printInclude(printer, message, field->message_type()->field(1), existingIncludes);
- includeTemplate = Templates::ExternalIncludeTemplate;
- } else if (common::isQtType(field)) {
- newInclude = field->message_type()->name();
- includeTemplate = Templates::ExternalIncludeTemplate;
- } else {
- if (!common::isNested(field->message_type())) {
- std::string outFileBasename = "";
- std::string fieldPackage = field->message_type()->file()->package();
- if (fieldPackage != message->file()->package()) {
- std::vector<std::string> packages = utils::split(fieldPackage, '.');
- for (auto package : packages) {
- outFileBasename += package + "/";
- }
- }
- std::string typeName = field->message_type()->name();
- utils::tolower(typeName);
- newInclude = outFileBasename + typeName;
- includeTemplate = Templates::InternalIncludeTemplate;
- } else if (!common::isNestedOf(field->message_type(), message)) {
- auto containingMessage = common::findHighestMessage(field->message_type());
- if (containingMessage != message) {
- std::string outFileBasename = "";
- std::string fieldPackage = containingMessage->file()->package();
- if (fieldPackage != message->file()->package()) {
- std::vector<std::string> packages = utils::split(fieldPackage, '.');
- for (auto package : packages) {
- outFileBasename += package + "/";
- }
- }
- std::string typeName = containingMessage->name();
- utils::tolower(typeName);
- newInclude = outFileBasename + typeName;
- includeTemplate = Templates::InternalIncludeTemplate;
- }
- }
- }
- break;
- case FieldDescriptor::TYPE_BYTES:
- newInclude = "QByteArray";
- includeTemplate = Templates::ExternalIncludeTemplate;
- break;
- case FieldDescriptor::TYPE_STRING:
- newInclude = "QString";
- includeTemplate = Templates::ExternalIncludeTemplate;
- break;
- case FieldDescriptor::TYPE_ENUM: {
- common::EnumVisibility enumVisibily = common::enumVisibility(field->enum_type(), message);
- if (enumVisibily == common::GLOBAL_ENUM) {
- includeTemplate = Templates::GlobalEnumIncludeTemplate;
- } else if (enumVisibily == common::NEIGHBOR_ENUM) {
- includeTemplate = Templates::InternalIncludeTemplate;
- std::string fullEnumName = field->enum_type()->full_name();
- std::vector<std::string> fullEnumNameParts = utils::split(fullEnumName, '.');
- std::string enumTypeOwner = fullEnumNameParts.at(fullEnumNameParts.size() - 2);
- utils::tolower(enumTypeOwner);
- newInclude = enumTypeOwner;
- } else {
- return;
- }
- }
- break;
- default:
- return;
- }
- if (existingIncludes.find(newInclude) == std::end(existingIncludes)) {
- printer->Print({{"include", newInclude}}, includeTemplate);
- existingIncludes.insert(newInclude);
- }
- }
- void GeneratorBase::printQtProtobufUsingNamespace(const std::shared_ptr<::google::protobuf::io::Printer> printer)
- {
- printer->Print({{"namespace", "QtProtobuf"}}, Templates::UsingNamespaceTemplate);
- }
- void GeneratorBase::printNamespaces(const std::shared_ptr<::google::protobuf::io::Printer> printer, const std::vector<std::string> namespaces) {
- printer->Print("\n");
- for (auto ns : namespaces) {
- printer->Print({{"namespace", ns}}, Templates::NamespaceTemplate);
- }
- }
|