mirror of https://github.com/qt/qtgrpc.git
QtGrpc: Update code generator to generate gRPC structures
Split the .proto files generator into QtProtobuf and QtGrpc parts. Pick-to: 6.5 Task-number: QTBUG-105496 Change-Id: Ib43abe4c1fb849ecf68952b82af9d3988e88e02a Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
This commit is contained in:
parent
c287697474
commit
326ebfaadb
|
|
@ -15,5 +15,7 @@ find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS BuildInternals Co
|
|||
find_package(Qt6 ${PROJECT_VERSION} CONFIG OPTIONAL_COMPONENTS Network)
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/cmake/QtProtobufBuildInternals.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/src/tools/qtprotobufgen/Qt6ProtobufToolsMacros.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/src/tools/qtgrpcgen/Qt6GrpcToolsMacros.cmake")
|
||||
|
||||
qt_build_repo()
|
||||
|
|
|
|||
|
|
@ -5,24 +5,25 @@ project(MyProject)
|
|||
find_package(Qt6 REQUIRED COMPONENTS Grpc Protobuf)
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_protobuf(MyMessages
|
||||
FOLDER
|
||||
qt_add_grpc(MyGrpcClient CLIENT
|
||||
PROTO_FILES
|
||||
path/to/service.proto
|
||||
path/to/message.proto
|
||||
path/to/other_message.proto
|
||||
PROTO_INCLUDES
|
||||
/path/to/proto/include
|
||||
)
|
||||
target_link_libraries(MyMessages PRIVATE Qt6::Grpc)
|
||||
target_link_libraries(MyGrpcClient PRIVATE Qt6::Grpc)
|
||||
|
||||
qt_add_executable(MyApp main.cpp)
|
||||
|
||||
target_link_libraries(MyApp PRIVATE MyMessages)
|
||||
target_link_libraries(MyApp PRIVATE MyGrpcClient)
|
||||
\endcode
|
||||
|
||||
In the example above we generate a library called \c{MyMessages}
|
||||
by calling the \l{qt_add_protobuf.html}{qt_add_protobuf()} CMake function.
|
||||
In the example above we generate a library called \c{MyGrpcClient}
|
||||
by calling the \l{qt_add_grpc.html}{qt_add_grpc()} CMake function.
|
||||
|
||||
Then we are linking generated library with \c{Qt6::Grpc} library.
|
||||
|
||||
We then create a target for an executable called \c{MyApp} which we link
|
||||
to the \c{MyMessages} library.
|
||||
to the \c{MyGrpcClient} library.
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ qhp.QtProtobuf.subprojects.classes.sortPages = true
|
|||
depends += qtdoc qtcore qtcmake
|
||||
|
||||
{headerdirs,sourcedirs} += ..
|
||||
sourcedirs += ../../tools/qtprotobufgen/doc/src
|
||||
sourcedirs += ../../tools/doc/src
|
||||
|
||||
exampledirs += ../../../examples/protobuf
|
||||
|
||||
|
|
|
|||
|
|
@ -2,5 +2,11 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
if(QT_FEATURE_qtprotobufgen)
|
||||
# Skip building qtprotoccommon when not building tools
|
||||
if((NOT CMAKE_CROSSCOMPILING OR QT_FORCE_BUILD_TOOLS)
|
||||
AND TARGET WrapProtobuf::WrapLibProtoc AND TARGET WrapProtobuf::WrapLibProtobuf)
|
||||
add_subdirectory(qtprotoccommon)
|
||||
endif()
|
||||
add_subdirectory(qtprotobufgen)
|
||||
add_subdirectory(qtgrpcgen)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
qt_get_tool_target_name(target_name qtgrpcgen)
|
||||
qt_internal_add_tool(${target_name}
|
||||
TARGET_DESCRIPTION "Qt gRPC generator"
|
||||
INSTALL_DIR "${INSTALL_LIBEXECDIR}"
|
||||
TOOLS_TARGET Grpc
|
||||
CORE_LIBRARY None
|
||||
SOURCES
|
||||
main.cpp
|
||||
qgrpcgenerator.cpp qgrpcgenerator.h
|
||||
grpctemplates.cpp grpctemplates.h
|
||||
serverdeclarationprinter.cpp serverdeclarationprinter.h
|
||||
clientdeclarationprinter.cpp clientdeclarationprinter.h
|
||||
clientdefinitionprinter.cpp clientdefinitionprinter.h
|
||||
EXTRA_CMAKE_FILES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${QT_CMAKE_EXPORT_NAMESPACE}GrpcToolsMacros.cmake"
|
||||
EXTRA_CMAKE_INCLUDES
|
||||
"${QT_CMAKE_EXPORT_NAMESPACE}GrpcToolsMacros.cmake"
|
||||
LIBRARIES
|
||||
WrapProtobuf::WrapLibProtoc
|
||||
QtProtocCommon
|
||||
)
|
||||
|
||||
qt_internal_return_unless_building_tools()
|
||||
|
||||
qt_record_extra_package_dependency(${target_name} WrapProtoc "")
|
||||
|
||||
if(MSVC)
|
||||
# Disable C4251:
|
||||
# `class 'type1' needs to have dll-interface to be used by clients of class 'type2'`
|
||||
# which can be generated from some of the protobuf headers on msvc.
|
||||
# This warning is also disabled globally in Qt in QtCore/qcompilerdetection.h
|
||||
target_compile_options(${target_name}
|
||||
PRIVATE "/wd4251"
|
||||
)
|
||||
target_compile_definitions(${target_name}
|
||||
PRIVATE "_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING"
|
||||
)
|
||||
endif()
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# The function looks for the service definitions inside provided PROTO_FILES and returns list of
|
||||
# the absolute .proto file paths, protobuf include paths and files that are expected to be generated
|
||||
# by qtgrpcgen.
|
||||
# Optional arguments:
|
||||
# GENERATE_PACKAGE_SUBFOLDERS - generated files will be located in package-base subdirectories.
|
||||
#
|
||||
# Multi-value arguments:
|
||||
# PROTO_FILES - input list of the proto files. May contain either absolute or relative paths.
|
||||
function(_qt_internal_grpc_preparse_proto_files type
|
||||
out_proto_files out_proto_includes out_generated_files base_dir)
|
||||
|
||||
cmake_parse_arguments(arg "GENERATE_PACKAGE_SUBFOLDERS" "" "PROTO_FILES" ${ARGN})
|
||||
|
||||
unset(proto_files)
|
||||
unset(proto_includes)
|
||||
unset(output_files)
|
||||
foreach(f IN LISTS arg_PROTO_FILES)
|
||||
if(NOT IS_ABSOLUTE "${f}")
|
||||
set(f "${base_dir}/${f}")
|
||||
get_filename_component(f "${f}" ABSOLUTE)
|
||||
endif()
|
||||
get_filename_component(f "${f}" REALPATH)
|
||||
list(APPEND proto_files "${f}")
|
||||
|
||||
_qt_internal_preparse_proto_file_common(result proto_package "${f}" "service")
|
||||
if(NOT result)
|
||||
message(NOTICE "No services found in ${f}. Skipping.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_filename_component(proto_file_base_dir "${f}" DIRECTORY)
|
||||
list(PREPEND proto_includes "${proto_file_base_dir}")
|
||||
|
||||
string(REPLACE "." "/" package_full_path "${proto_package}")
|
||||
set(folder_path "")
|
||||
if(arg_GENERATE_PACKAGE_SUBFOLDERS)
|
||||
set(folder_path "${package_full_path}/")
|
||||
endif()
|
||||
|
||||
get_filename_component(basename "${f}" NAME_WLE)
|
||||
if(type STREQUAL "SERVER")
|
||||
list(APPEND output_files
|
||||
"${folder_path}${basename}_service.grpc.qpb.h")
|
||||
elseif(type STREQUAL "CLIENT")
|
||||
list(APPEND output_files
|
||||
"${folder_path}${basename}_client.grpc.qpb.h"
|
||||
"${folder_path}${basename}_client.grpc.qpb.cpp")
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown gRPC target type: '${type}'.\n"
|
||||
"Supported types: CLIENT.")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
list(REMOVE_DUPLICATES proto_files)
|
||||
list(REMOVE_DUPLICATES proto_includes)
|
||||
list(REMOVE_DUPLICATES output_files)
|
||||
set(${out_proto_files} "${proto_files}" PARENT_SCOPE)
|
||||
set(${out_proto_includes} "${proto_includes}" PARENT_SCOPE)
|
||||
set(${out_generated_files} "${output_files}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# TODO Qt6:
|
||||
# - Collect PROTO_INCLUDES from the LINK_LIBRARIES property of TARGET
|
||||
# - Collect proto files from the source files of the ${TARGET}
|
||||
|
||||
# This function is currently in Technical Preview
|
||||
# Its signature and behavior might change.
|
||||
function(qt6_add_grpc target type)
|
||||
_qt_internal_get_protoc_common_options(protoc_option_opt protoc_single_opt protoc_multi_opt)
|
||||
_qt_internal_get_protoc_generate_arguments(protoc_option_arg protoc_single_arg protoc_multi_arg)
|
||||
|
||||
set(option_args
|
||||
${protoc_option_opt}
|
||||
${protoc_option_arg}
|
||||
)
|
||||
|
||||
set(single_args
|
||||
${protoc_single_opt}
|
||||
${protoc_single_arg}
|
||||
)
|
||||
|
||||
set(multi_args
|
||||
${protoc_multi_opt}
|
||||
${protoc_multi_arg}
|
||||
)
|
||||
cmake_parse_arguments(arg "${option_args}" "${single_args}" "${multi_args}" ${ARGN})
|
||||
|
||||
# TODO: Add the gRPC 'SERVER' target type support when implemented.
|
||||
set(supported_grpc_targets CLIENT)
|
||||
if(NOT type IN_LIST supported_grpc_targets)
|
||||
message(FATAL_ERROR "Unknown gRPC target type: '${type}'.\n"
|
||||
"Supported types: CLIENT.")
|
||||
endif()
|
||||
|
||||
_qt_internal_get_protoc_options(generation_options arg
|
||||
protoc_option_opt protoc_single_opt protoc_multi_opt)
|
||||
|
||||
if(arg_PROTO_FILES_BASE_DIR)
|
||||
set(base_dir "${arg_PROTO_FILES_BASE_DIR}")
|
||||
else()
|
||||
set(base_dir "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
endif()
|
||||
unset(extra_pre_parse_options)
|
||||
if(arg_GENERATE_PACKAGE_SUBFOLDERS)
|
||||
list(APPEND extra_pre_parse_options "GENERATE_PACKAGE_SUBFOLDERS")
|
||||
endif()
|
||||
|
||||
_qt_internal_grpc_preparse_proto_files(${type} proto_files proto_includes generated_files
|
||||
"${base_dir}"
|
||||
${extra_pre_parse_options}
|
||||
PROTO_FILES
|
||||
${arg_PROTO_FILES}
|
||||
)
|
||||
if(arg_PROTO_INCLUDES)
|
||||
list(APPEND proto_includes ${arg_PROTO_INCLUDES})
|
||||
endif()
|
||||
|
||||
set(is_shared FALSE)
|
||||
set(is_static FALSE)
|
||||
set(is_executable FALSE)
|
||||
if(TARGET ${target})
|
||||
get_target_property(target_type ${target} TYPE)
|
||||
if(target_type STREQUAL "SHARED_LIBRARY")
|
||||
set(is_shared TRUE)
|
||||
elseif(target_type STREQUAL "STATIC_LIBRARY")
|
||||
set(is_static TRUE)
|
||||
elseif(target_type STREQUAL "EXECUTABLE")
|
||||
set(is_executable TRUE)
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported target type '${target_type}'.")
|
||||
endif()
|
||||
else()
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(target_type "SHARED_LIBRARY")
|
||||
set(is_shared TRUE)
|
||||
else()
|
||||
set(target_type "STATIC_LIBRARY")
|
||||
set(is_static TRUE)
|
||||
endif()
|
||||
|
||||
_qt_internal_add_library(${target})
|
||||
if(DEFINED arg_OUTPUT_TARGETS)
|
||||
list(APPEND ${arg_OUTPUT_TARGETS} "${target}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(is_static OR is_shared)
|
||||
# Add EXPORT_MACRO if the target is, or we will create, a shared library
|
||||
string(TOUPPER "${target}" target_upper)
|
||||
if (is_shared)
|
||||
list(APPEND generation_options "EXPORT_MACRO=${target_upper}")
|
||||
endif()
|
||||
# Define this so we can conditionally set the export macro
|
||||
target_compile_definitions(${target}
|
||||
PRIVATE "QT_BUILD_${target_upper}_LIB")
|
||||
endif()
|
||||
|
||||
set(output_directory "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
if(DEFINED arg_OUTPUT_DIRECTORY)
|
||||
set(output_directory "${arg_OUTPUT_DIRECTORY}")
|
||||
endif()
|
||||
|
||||
list(TRANSFORM generated_files PREPEND "${output_directory}/")
|
||||
|
||||
_qt_internal_protoc_generate(${target} qtgrpcgen "${output_directory}"
|
||||
PROTO_FILES ${proto_files}
|
||||
PROTO_INCLUDES ${proto_includes}
|
||||
GENERATED_FILES ${generated_files}
|
||||
)
|
||||
|
||||
target_sources(${target} PRIVATE ${generated_files})
|
||||
|
||||
# Filter generated headers
|
||||
set(generated_headers "${generated_files}")
|
||||
list(FILTER generated_headers INCLUDE REGEX ".+\\.h$")
|
||||
|
||||
if(is_static OR is_shared)
|
||||
set_target_properties(${target}
|
||||
PROPERTIES
|
||||
PUBLIC_HEADER "${generated_headers}"
|
||||
AUTOMOC ON
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
target_compile_options(${target}
|
||||
PRIVATE "/Zc:__cplusplus" "/permissive-" "/bigobj")
|
||||
endif()
|
||||
|
||||
target_link_libraries(${target} PRIVATE
|
||||
${QT_CMAKE_EXPORT_NAMESPACE}::Grpc
|
||||
)
|
||||
|
||||
if(DEFINED arg_OUTPUT_HEADERS)
|
||||
set(${arg_OUTPUT_HEADERS} "${generated_headers}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if(DEFINED arg_OUTPUT_TARGETS)
|
||||
set(${arg_OUTPUT_TARGETS} "${${arg_OUTPUT_TARGETS}}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
|
||||
function(qt_add_grpc)
|
||||
if(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
|
||||
qt6_add_grpc(${ARGN})
|
||||
else()
|
||||
message(FATAL_ERROR "qt6_add_grpc() is only available in Qt 6. "
|
||||
"Please check the protobuf documentation for alternatives.")
|
||||
endif()
|
||||
endfunction()
|
||||
endif()
|
||||
|
|
@ -14,10 +14,11 @@
|
|||
#include <unordered_set>
|
||||
|
||||
#include "generatorcommon.h"
|
||||
#include "templates.h"
|
||||
#include "utils.h"
|
||||
#include "commontemplates.h"
|
||||
#include "grpctemplates.h"
|
||||
|
||||
using namespace ::QtProtobuf::generator;
|
||||
using namespace ::QtGrpc;
|
||||
using namespace ::qtprotoccommon;
|
||||
using namespace ::google::protobuf;
|
||||
using namespace ::google::protobuf::compiler;
|
||||
|
||||
|
|
@ -33,7 +34,7 @@ ClientDeclarationPrinter::ClientDeclarationPrinter(
|
|||
const ::google::protobuf::ServiceDescriptor *service,
|
||||
const std::shared_ptr<::google::protobuf::io::Printer> &printer)
|
||||
: DescriptorPrinterBase<::google::protobuf::ServiceDescriptor>(
|
||||
service, printer, common::produceClientTypeMap(service, nullptr))
|
||||
service, printer, common::produceClientTypeMap(service, nullptr))
|
||||
|
||||
{
|
||||
}
|
||||
|
|
@ -41,18 +42,18 @@ ClientDeclarationPrinter::ClientDeclarationPrinter(
|
|||
void ClientDeclarationPrinter::printOpenNamespace()
|
||||
{
|
||||
m_printer->Print({ { "scope_namespaces", m_typeMap["scope_type"] } },
|
||||
Templates::NamespaceTemplate());
|
||||
CommonTemplates::NamespaceTemplate());
|
||||
}
|
||||
|
||||
void ClientDeclarationPrinter::printClientClass()
|
||||
{
|
||||
m_printer->Print(m_typeMap, Templates::ChildClassDeclarationTemplate());
|
||||
m_printer->Print(m_typeMap, GrpcTemplates::ChildClassDeclarationTemplate());
|
||||
}
|
||||
|
||||
void ClientDeclarationPrinter::printConstructor()
|
||||
{
|
||||
Indent();
|
||||
m_printer->Print(m_typeMap, Templates::QObjectConstructorMessageDeclarationTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::QObjectConstructorMessageDeclarationTemplate());
|
||||
Outdent();
|
||||
}
|
||||
|
||||
|
|
@ -64,15 +65,15 @@ void ClientDeclarationPrinter::printClientMethodsDeclaration()
|
|||
MethodMap parameters = common::produceMethodMap(method, m_typeMap["classname"]);
|
||||
|
||||
if (method->server_streaming()) {
|
||||
m_printer->Print(parameters, Templates::ClientMethodServerStreamDeclarationTemplate());
|
||||
m_printer->Print(parameters, Templates::ClientMethodServerStream2DeclarationTemplate());
|
||||
m_printer->Print(parameters, GrpcTemplates::ClientMethodServerStreamDeclarationTemplate());
|
||||
m_printer->Print(parameters, GrpcTemplates::ClientMethodServerStream2DeclarationTemplate());
|
||||
} else {
|
||||
m_printer->Print(parameters, Templates::ClientMethodDeclarationSyncTemplate());
|
||||
m_printer->Print(parameters, Templates::ClientMethodDeclarationAsyncTemplate());
|
||||
m_printer->Print(parameters, Templates::ClientMethodDeclarationAsync2Template());
|
||||
m_printer->Print(parameters, GrpcTemplates::ClientMethodDeclarationSyncTemplate());
|
||||
m_printer->Print(parameters, GrpcTemplates::ClientMethodDeclarationAsyncTemplate());
|
||||
m_printer->Print(parameters, GrpcTemplates::ClientMethodDeclarationAsync2Template());
|
||||
if (Options::instance().hasQml()) {
|
||||
m_printer->Print(parameters, Templates::ClientMethodDeclarationQmlTemplate());
|
||||
m_printer->Print(parameters, Templates::ClientMethodDeclarationQml2Template());
|
||||
m_printer->Print(parameters, GrpcTemplates::ClientMethodDeclarationQmlTemplate());
|
||||
m_printer->Print(parameters, GrpcTemplates::ClientMethodDeclarationQml2Template());
|
||||
}
|
||||
}
|
||||
m_printer->Print("\n");
|
||||
|
|
@ -87,7 +88,7 @@ void ClientDeclarationPrinter::printClientMethodsDeclaration()
|
|||
if (method->server_streaming()) {
|
||||
if (Options::instance().hasQml()) {
|
||||
m_printer->Print(parameters,
|
||||
Templates::ClientMethodServerStreamQmlDeclarationTemplate());
|
||||
GrpcTemplates::ClientMethodServerStreamQmlDeclarationTemplate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -98,5 +99,5 @@ void ClientDeclarationPrinter::printClientMethodsDeclaration()
|
|||
void ClientDeclarationPrinter::printCloseNamespace()
|
||||
{
|
||||
m_printer->Print({ { "scope_namespaces", m_typeMap["scope_type"] } },
|
||||
Templates::NamespaceClosingTemplate());
|
||||
CommonTemplates::NamespaceClosingTemplate());
|
||||
}
|
||||
|
|
@ -5,19 +5,21 @@
|
|||
#pragma once
|
||||
|
||||
#include "descriptorprinterbase.h"
|
||||
#include <google/protobuf/io/printer.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace google::protobuf {
|
||||
class ServiceDescriptor;
|
||||
class Message;
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
}
|
||||
namespace io {
|
||||
class Printer;
|
||||
}
|
||||
|
||||
namespace QtProtobuf::generator {
|
||||
class ClientDeclarationPrinter : public DescriptorPrinterBase<::google::protobuf::ServiceDescriptor>
|
||||
namespace QtGrpc {
|
||||
|
||||
class ClientDeclarationPrinter :
|
||||
public qtprotoccommon::DescriptorPrinterBase<::google::protobuf::ServiceDescriptor>
|
||||
{
|
||||
public:
|
||||
ClientDeclarationPrinter(const ::google::protobuf::ServiceDescriptor *service,
|
||||
|
|
@ -43,4 +45,4 @@ private:
|
|||
void printCloseNamespace();
|
||||
};
|
||||
|
||||
} // namespace QtProtobuf::generator
|
||||
} // namespace QtGrpc
|
||||
|
|
@ -7,10 +7,11 @@
|
|||
#include <google/protobuf/io/zero_copy_stream.h>
|
||||
|
||||
#include "generatorcommon.h"
|
||||
#include "templates.h"
|
||||
#include "utils.h"
|
||||
#include "commontemplates.h"
|
||||
#include "grpctemplates.h"
|
||||
|
||||
using namespace ::QtProtobuf::generator;
|
||||
using namespace ::QtGrpc;
|
||||
using namespace ::qtprotoccommon;
|
||||
using namespace ::google::protobuf;
|
||||
using namespace ::google::protobuf::compiler;
|
||||
|
||||
|
|
@ -26,36 +27,43 @@ ClientDefinitionPrinter::ClientDefinitionPrinter(
|
|||
const google::protobuf::ServiceDescriptor *service,
|
||||
const std::shared_ptr<::google::protobuf::io::Printer> &printer)
|
||||
: DescriptorPrinterBase<google::protobuf::ServiceDescriptor>(
|
||||
service, printer, common::produceClientTypeMap(service, nullptr))
|
||||
service, printer, common::produceClientTypeMap(service, nullptr))
|
||||
{
|
||||
}
|
||||
|
||||
void ClientDefinitionPrinter::printOpenNamespace()
|
||||
{
|
||||
m_printer->Print({ { "scope_namespaces", m_typeMap["scope_type"] } },
|
||||
Templates::NamespaceTemplate());
|
||||
CommonTemplates::NamespaceTemplate());
|
||||
}
|
||||
|
||||
void ClientDefinitionPrinter::printMethods()
|
||||
{
|
||||
for (int i = 0; i < m_descriptor->method_count(); i++) {
|
||||
const MethodDescriptor *method = m_descriptor->method(i);
|
||||
MethodMap parameters = common::produceMethodMap(method, m_typeMap["classname"]);
|
||||
if (method->server_streaming()) {
|
||||
m_printer->Print(parameters, Templates::ClientMethodServerStreamDefinitionTemplate());
|
||||
m_printer->Print(parameters, Templates::ClientMethodServerStream2DefinitionTemplate());
|
||||
if (Options::instance().hasQml()) {
|
||||
m_printer->Print(parameters,
|
||||
Templates::ClientMethodServerStreamQmlDefinitionTemplate());
|
||||
}
|
||||
} else {
|
||||
m_printer->Print(parameters, Templates::ClientMethodDefinitionSyncTemplate());
|
||||
m_printer->Print(parameters, Templates::ClientMethodDefinitionAsyncTemplate());
|
||||
m_printer->Print(parameters, Templates::ClientMethodDefinitionAsync2Template());
|
||||
if (Options::instance().hasQml()) {
|
||||
m_printer->Print(parameters, Templates::ClientMethodDefinitionQmlTemplate());
|
||||
m_printer->Print(parameters, Templates::ClientMethodDefinitionQml2Template());
|
||||
}
|
||||
printMethod(method);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientDefinitionPrinter::printMethod(const MethodDescriptor *method)
|
||||
{
|
||||
MethodMap parameters = common::produceMethodMap(method, m_typeMap["classname"]);
|
||||
if (method->server_streaming()) {
|
||||
m_printer->Print(parameters,
|
||||
GrpcTemplates::ClientMethodServerStreamDefinitionTemplate());
|
||||
m_printer->Print(parameters,
|
||||
GrpcTemplates::ClientMethodServerStream2DefinitionTemplate());
|
||||
if (Options::instance().hasQml()) {
|
||||
m_printer->Print(parameters,
|
||||
GrpcTemplates::ClientMethodServerStreamQmlDefinitionTemplate());
|
||||
}
|
||||
} else {
|
||||
m_printer->Print(parameters, GrpcTemplates::ClientMethodDefinitionSyncTemplate());
|
||||
m_printer->Print(parameters, GrpcTemplates::ClientMethodDefinitionAsyncTemplate());
|
||||
m_printer->Print(parameters, GrpcTemplates::ClientMethodDefinitionAsync2Template());
|
||||
if (Options::instance().hasQml()) {
|
||||
m_printer->Print(parameters, GrpcTemplates::ClientMethodDefinitionQmlTemplate());
|
||||
m_printer->Print(parameters, GrpcTemplates::ClientMethodDefinitionQml2Template());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -65,11 +73,11 @@ void ClientDefinitionPrinter::printConstructor()
|
|||
m_printer->Print({ { "classname", m_typeMap["classname"] },
|
||||
{ "parent_class", m_typeMap["parent_class"] },
|
||||
{ "service_name", m_descriptor->full_name() } },
|
||||
Templates::ClientConstructorDefinitionTemplate());
|
||||
GrpcTemplates::ClientConstructorDefinitionTemplate());
|
||||
}
|
||||
|
||||
void ClientDefinitionPrinter::printCloseNamespace()
|
||||
{
|
||||
m_printer->Print({ { "scope_namespaces", m_typeMap["scope_type"] } },
|
||||
Templates::NamespaceClosingTemplate());
|
||||
CommonTemplates::NamespaceClosingTemplate());
|
||||
}
|
||||
|
|
@ -6,8 +6,10 @@
|
|||
|
||||
#include "descriptorprinterbase.h"
|
||||
|
||||
namespace QtProtobuf::generator {
|
||||
class ClientDefinitionPrinter : public DescriptorPrinterBase<google::protobuf::ServiceDescriptor>
|
||||
namespace QtGrpc {
|
||||
|
||||
class ClientDefinitionPrinter :
|
||||
public qtprotoccommon::DescriptorPrinterBase<google::protobuf::ServiceDescriptor>
|
||||
{
|
||||
public:
|
||||
ClientDefinitionPrinter(const google::protobuf::ServiceDescriptor *service,
|
||||
|
|
@ -23,6 +25,8 @@ public:
|
|||
void printConstructor();
|
||||
void printMethods();
|
||||
void printCloseNamespace();
|
||||
private:
|
||||
void printMethod(const ::google::protobuf::MethodDescriptor *method);
|
||||
};
|
||||
|
||||
} // namespace QtProtobuf::generator
|
||||
} // namespace QtGrpc
|
||||
|
|
@ -0,0 +1,221 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "grpctemplates.h"
|
||||
|
||||
using namespace ::QtGrpc;
|
||||
const char *GrpcTemplates::ChildClassDeclarationTemplate()
|
||||
{
|
||||
return "\nclass $export_macro$ $classname$ : public $parent_class$\n"
|
||||
"{\n"
|
||||
" Q_OBJECT\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientMethodDeclarationSyncTemplate()
|
||||
{
|
||||
return "QGrpcStatus $method_name$(const $param_type$ &$param_name$, "
|
||||
"$return_type$ *$return_name$);\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientMethodDeclarationAsyncTemplate()
|
||||
{
|
||||
return "std::shared_ptr<QGrpcCallReply> $method_name$(const $param_type$ &$param_name$);\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientMethodDeclarationAsync2Template()
|
||||
{
|
||||
return "Q_INVOKABLE void $method_name$(const $param_type$ &$param_name$, const QObject "
|
||||
"*context, "
|
||||
"const std::function<void(std::shared_ptr<QGrpcCallReply>)> &callback);\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientMethodDeclarationQmlTemplate()
|
||||
{
|
||||
return "Q_INVOKABLE void $method_name$($param_type$ *$param_name$, const QJSValue &callback, "
|
||||
"const QJSValue &errorCallback);\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientMethodDeclarationQml2Template()
|
||||
{
|
||||
return "Q_INVOKABLE void $method_name$($param_type$ *$param_name$, $return_type$ "
|
||||
"*$return_name$, const QJSValue &errorCallback);\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ServerMethodDeclarationTemplate()
|
||||
{
|
||||
return "Q_INVOKABLE virtual $return_type$ $method_name$(const $param_type$ &$param_name$) = "
|
||||
"0;\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientConstructorDefinitionTemplate()
|
||||
{
|
||||
return "\n$classname$::$classname$(QObject *parent) : $parent_class$(\"$service_name$\", "
|
||||
"parent)\n"
|
||||
"{\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientMethodDefinitionSyncTemplate()
|
||||
{
|
||||
return "\nQGrpcStatus $classname$::$method_name$(const $param_type$ &$param_name$, "
|
||||
"$return_type$ *$return_name$)\n"
|
||||
"{\n"
|
||||
" return call<$param_type$>(\"$method_name$\", $param_name$, $return_name$);\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientMethodDefinitionAsyncTemplate()
|
||||
{
|
||||
return "\nstd::shared_ptr<QGrpcCallReply> $classname$::$method_name$(const $param_type$ "
|
||||
"&$param_name$)\n"
|
||||
"{\n"
|
||||
" return call<$param_type$>(\"$method_name$\", $param_name$);\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientMethodDefinitionAsync2Template()
|
||||
{
|
||||
return "\nvoid $classname$::$method_name$(const $param_type$ &$param_name$, const QObject "
|
||||
"*context, const std::function<void(std::shared_ptr<QGrpcCallReply>)> &callback)\n"
|
||||
"{\n"
|
||||
" std::shared_ptr<QGrpcCallReply> reply = call<$param_type$>(\"$method_name$\", "
|
||||
"$param_name$);\n"
|
||||
" QObject::connect(reply.get(), &QGrpcCallReply::finished, context, [reply, "
|
||||
"callback]() "
|
||||
"{\n"
|
||||
" callback(reply);\n"
|
||||
" });\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientMethodDefinitionQmlTemplate()
|
||||
{
|
||||
return "\nvoid $classname$::$method_name$($param_type$ *$param_name$, const QJSValue "
|
||||
"&callback, "
|
||||
"const QJSValue &errorCallback)\n"
|
||||
"{\n"
|
||||
" if (!callback.isCallable()) {\n"
|
||||
" qWarning() << \"Unable to call $classname$::$method_name$, callback is not "
|
||||
"callable\";\n"
|
||||
" return;\n"
|
||||
" }\n\n"
|
||||
" if (arg == nullptr) {\n"
|
||||
" qWarning() << \"Invalid argument provided for method "
|
||||
"$classname$::$method_name$, "
|
||||
"argument of type '$param_type$ *' expected\";\n"
|
||||
" return;\n"
|
||||
" }\n\n"
|
||||
" QJSEngine *jsEngine = qjsEngine(this);\n"
|
||||
" if (jsEngine == nullptr) {\n"
|
||||
" qWarning() << \"Unable to call $classname$::$method_name$, it's only callable "
|
||||
"from JS engine context\";\n"
|
||||
" return;\n"
|
||||
" }\n\n"
|
||||
" std::shared_ptr<QGrpcCallReply> reply = call<$param_type$>(\"$method_name$\", "
|
||||
"*$param_name$);\n"
|
||||
" reply->subscribe(jsEngine, [this, reply, callback, jsEngine]() {\n"
|
||||
" auto result = new $return_type$(reply->read<$return_type$>());\n"
|
||||
" qmlEngine(this)->setObjectOwnership(result, QQmlEngine::JavaScriptOwnership);\n"
|
||||
" QJSValue(callback).call(QJSValueList{jsEngine->toScriptValue(result)});\n"
|
||||
" }, [errorCallback, jsEngine](const QGrpcStatus &status) {\n"
|
||||
" QJSValue(errorCallback).call(QJSValueList{jsEngine->toScriptValue(status)});\n"
|
||||
" });\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientMethodDefinitionQml2Template()
|
||||
{
|
||||
return "\nvoid $classname$::$method_name$($param_type$ *$param_name$, $return_type$ "
|
||||
"*$return_name$, const QJSValue &errorCallback)\n"
|
||||
"{\n"
|
||||
" if ($return_name$ == nullptr) {\n"
|
||||
" qWarning() << \"Invalid argument provided for method "
|
||||
"$classname$::$method_name$, "
|
||||
"argument of type '$return_type$ *' expected\";\n"
|
||||
" return;\n"
|
||||
" }\n\n"
|
||||
" QWeakPointer<$return_type$> safeReturn($return_name$);\n\n"
|
||||
" if ($param_name$ == nullptr) {\n"
|
||||
" qWarning() << \"Invalid argument provided for method "
|
||||
"$classname$::$method_name$, "
|
||||
"argument of type '$param_type$ *' expected\";\n"
|
||||
" return;\n"
|
||||
" }\n\n"
|
||||
" QJSEngine *jsEngine = qjsEngine(this);\n"
|
||||
" if (jsEngine == nullptr) {\n"
|
||||
" qWarning() << \"Unable to call $classname$::$method_name$, it's only callable "
|
||||
"from JS engine context\";\n"
|
||||
" return;\n"
|
||||
" }\n\n"
|
||||
" std::shared_ptr<QGrpcCallReply> reply = call<$param_type$>(\"$method_name$\", "
|
||||
"*$param_name$);\n"
|
||||
" reply->subscribe(jsEngine, [this, reply, jsEngine, safeReturn]() {\n"
|
||||
" if (safeReturn.isNull()) {\n"
|
||||
" qWarning() << \"Return value is destroyed. Ignore call result\";\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
" *safeReturn = $return_type$(reply->read<$return_type$>());\n"
|
||||
" }, [errorCallback, jsEngine](const QGrpcStatus &status) {\n"
|
||||
" QJSValue(errorCallback).call(QJSValueList{jsEngine->toScriptValue(status)});\n"
|
||||
" });\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientMethodServerStreamDeclarationTemplate()
|
||||
{
|
||||
return "std::shared_ptr<QGrpcStream> stream$method_name_upper$(const $param_type$ "
|
||||
"&$param_name$);\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientMethodServerStream2DeclarationTemplate()
|
||||
{
|
||||
return "std::shared_ptr<QGrpcStream> stream$method_name_upper$(const $param_type$ "
|
||||
"&$param_name$, const "
|
||||
"QWeakPointer<$return_type$> &$return_name$);\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientMethodServerStreamQmlDeclarationTemplate()
|
||||
{
|
||||
return "Q_INVOKABLE std::shared_ptr<QGrpcStream> qmlStream$method_name_upper$_p($param_type$ "
|
||||
"*$param_name$, "
|
||||
"$return_type$ *$return_name$);\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientMethodServerStreamDefinitionTemplate()
|
||||
{
|
||||
return "std::shared_ptr<QGrpcStream> $classname$::stream$method_name_upper$(const $param_type$ "
|
||||
"&$param_name$)\n"
|
||||
"{\n"
|
||||
" return stream<$param_type$>(\"$method_name$\", $param_name$);\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientMethodServerStream2DefinitionTemplate()
|
||||
{
|
||||
return "std::shared_ptr<QGrpcStream> $classname$::stream$method_name_upper$(const $param_type$ "
|
||||
"&$param_name$, const QWeakPointer<$return_type$> &$return_name$)\n"
|
||||
"{\n"
|
||||
" return stream<$param_type$>(\"$method_name$\", $param_name$, $return_name$);\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::GrpcClientFileSuffix()
|
||||
{
|
||||
return "_client.grpc";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::GrpcServiceFileSuffix()
|
||||
{
|
||||
return "_service.grpc";
|
||||
}
|
||||
|
||||
const char *GrpcTemplates::ClientMethodServerStreamQmlDefinitionTemplate()
|
||||
{
|
||||
return "std::shared_ptr<QGrpcStream> $classname$::qmlStream$method_name_upper$_p($param_type$ "
|
||||
"*$param_name$, "
|
||||
"$return_type$ *$return_name$)\n"
|
||||
"{\n"
|
||||
" return stream<$param_type$>(\"$method_name$\", *$param_name$, "
|
||||
"QWeakPointer<$return_type$>($return_name$));\n"
|
||||
"}\n";
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef GRPCTEMPLATES_H
|
||||
#define GRPCTEMPLATES_H
|
||||
|
||||
namespace QtGrpc {
|
||||
|
||||
class GrpcTemplates
|
||||
{
|
||||
public:
|
||||
// gRPC
|
||||
static const char *ChildClassDeclarationTemplate();
|
||||
|
||||
static const char *GrpcClientFileSuffix();
|
||||
static const char *GrpcServiceFileSuffix();
|
||||
|
||||
static const char *ClientConstructorDefinitionTemplate();
|
||||
|
||||
static const char *ClientMethodDeclarationSyncTemplate();
|
||||
static const char *ClientMethodDeclarationAsyncTemplate();
|
||||
static const char *ClientMethodDeclarationAsync2Template();
|
||||
static const char *ClientMethodDeclarationQmlTemplate();
|
||||
static const char *ClientMethodDeclarationQml2Template();
|
||||
|
||||
static const char *ServerMethodDeclarationTemplate();
|
||||
|
||||
static const char *ClientMethodDefinitionSyncTemplate();
|
||||
static const char *ClientMethodDefinitionAsyncTemplate();
|
||||
static const char *ClientMethodDefinitionAsync2Template();
|
||||
static const char *ClientMethodDefinitionQmlTemplate();
|
||||
static const char *ClientMethodDefinitionQml2Template();
|
||||
|
||||
static const char *ClientMethodServerStreamDeclarationTemplate();
|
||||
static const char *ClientMethodServerStream2DeclarationTemplate();
|
||||
static const char *ClientMethodServerStreamQmlDeclarationTemplate();
|
||||
|
||||
static const char *ClientMethodServerStreamDefinitionTemplate();
|
||||
static const char *ClientMethodServerStream2DefinitionTemplate();
|
||||
static const char *ClientMethodServerStreamQmlDefinitionTemplate();
|
||||
};
|
||||
|
||||
} // namespace QtGrpc
|
||||
|
||||
#endif // GRPCTEMPLATES_H
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <google/protobuf/compiler/plugin.h>
|
||||
|
||||
#include "qgrpcgenerator.h"
|
||||
#include "options.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace QtGrpc;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *optionsPtr = getenv("QT_GRPC_OPTIONS");
|
||||
if (optionsPtr != nullptr) {
|
||||
QT_PROTOBUF_DEBUG("QT_GRPC_OPTIONS: " << optionsPtr);
|
||||
qtprotoccommon::Options::setFromString(optionsPtr);
|
||||
}
|
||||
QGrpcGenerator generator;
|
||||
return ::google::protobuf::compiler::PluginMain(argc, argv, &generator);
|
||||
}
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "qgrpcgenerator.h"
|
||||
#include "clientdeclarationprinter.h"
|
||||
#include "clientdefinitionprinter.h"
|
||||
#include "serverdeclarationprinter.h"
|
||||
|
||||
#include "grpctemplates.h"
|
||||
#include "utils.h"
|
||||
#include "options.h"
|
||||
|
||||
#include <set>
|
||||
#include <google/protobuf/compiler/code_generator.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 <google/protobuf/descriptor.h>
|
||||
|
||||
using namespace ::QtGrpc;
|
||||
using namespace ::qtprotoccommon;
|
||||
using namespace ::google::protobuf;
|
||||
using namespace ::google::protobuf::io;
|
||||
using namespace ::google::protobuf::compiler;
|
||||
|
||||
QGrpcGenerator::QGrpcGenerator() : GeneratorBase()
|
||||
{}
|
||||
|
||||
QGrpcGenerator::~QGrpcGenerator() = default;
|
||||
|
||||
bool QGrpcGenerator::Generate(const FileDescriptor *file,
|
||||
[[maybe_unused]] const std::string ¶meter,
|
||||
GeneratorContext *generatorContext,
|
||||
std::string *error) const
|
||||
{
|
||||
assert(file != nullptr && generatorContext != nullptr);
|
||||
if (file->syntax() != FileDescriptor::SYNTAX_PROTO3) {
|
||||
*error = "Invalid proto used. qtgrpcgen only supports 'proto3' syntax";
|
||||
return false;
|
||||
}
|
||||
|
||||
return GenerateServices(file, generatorContext);
|
||||
}
|
||||
|
||||
void QGrpcGenerator::SetInternalIncludes(const FileDescriptor *file,
|
||||
std::set<std::string>& internalIncludes) const
|
||||
{
|
||||
assert(file != nullptr);
|
||||
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::removeFileSuffix(method->input_type()->file()->name())
|
||||
+ CommonTemplates::ProtoFileSuffix());
|
||||
}
|
||||
|
||||
if (method->output_type()->file() != service->file()) {
|
||||
internalIncludes.insert(
|
||||
utils::removeFileSuffix(method->output_type()->file()->name())
|
||||
+ CommonTemplates::ProtoFileSuffix());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (file->message_type_count() > 0) {
|
||||
internalIncludes.insert(generateBaseName(file, utils::extractFileBasename(file->name()))
|
||||
+ CommonTemplates::ProtoFileSuffix());
|
||||
}
|
||||
}
|
||||
|
||||
void QGrpcGenerator::RunPrinters(const FileDescriptor *file,
|
||||
std::shared_ptr<Printer> clientHeaderPrinter,
|
||||
std::shared_ptr<Printer> clientSourcePrinter,
|
||||
std::shared_ptr<Printer> serviceHeaderPrinter) const
|
||||
{
|
||||
assert(file != nullptr);
|
||||
for (int i = 0; i < file->service_count(); ++i) {
|
||||
const ServiceDescriptor *service = file->service(i);
|
||||
|
||||
ClientDeclarationPrinter clientDecl(service, clientHeaderPrinter);
|
||||
clientDecl.run();
|
||||
|
||||
ClientDefinitionPrinter clientDef(service, clientSourcePrinter);
|
||||
clientDef.run();
|
||||
|
||||
ServerDeclarationPrinter serverDecl(service, serviceHeaderPrinter);
|
||||
serverDecl.run();
|
||||
}
|
||||
}
|
||||
|
||||
bool QGrpcGenerator::GenerateServices(const FileDescriptor *file,
|
||||
GeneratorContext *generatorContext) const
|
||||
{
|
||||
assert(file != nullptr && generatorContext != nullptr);
|
||||
if (file->service_count() <= 0)
|
||||
return true;
|
||||
|
||||
std::set<std::string> internalIncludes;
|
||||
|
||||
const std::string filename = utils::extractFileBasename(file->name());
|
||||
const std::string basename = generateBaseName(file, filename);
|
||||
const std::string clientFileName = basename
|
||||
+ GrpcTemplates::GrpcClientFileSuffix() + CommonTemplates::ProtoFileSuffix();
|
||||
std::unique_ptr<ZeroCopyOutputStream> clientHeaderStream(
|
||||
generatorContext->Open(clientFileName + ".h"));
|
||||
std::unique_ptr<ZeroCopyOutputStream> clientSourceStream(
|
||||
generatorContext->Open(clientFileName + ".cpp"));
|
||||
std::unique_ptr<ZeroCopyOutputStream> serviceHeaderStream(
|
||||
generatorContext->Open(basename
|
||||
+ GrpcTemplates::GrpcServiceFileSuffix()
|
||||
+ CommonTemplates::ProtoFileSuffix() + ".h"));
|
||||
std::shared_ptr<Printer> clientHeaderPrinter(new Printer(clientHeaderStream.get(), '$'));
|
||||
std::shared_ptr<Printer> clientSourcePrinter(new Printer(clientSourceStream.get(), '$'));
|
||||
std::shared_ptr<Printer> serviceHeaderPrinter(new Printer(serviceHeaderStream.get(), '$'));
|
||||
|
||||
printDisclaimer(clientHeaderPrinter.get());
|
||||
clientHeaderPrinter->Print({ { "filename", filename + "_client" } },
|
||||
CommonTemplates::PreambleTemplate());
|
||||
|
||||
printDisclaimer(serviceHeaderPrinter.get());
|
||||
serviceHeaderPrinter->Print({ { "filename", filename + "_service" } },
|
||||
CommonTemplates::PreambleTemplate());
|
||||
|
||||
clientHeaderPrinter->Print(CommonTemplates::DefaultProtobufIncludesTemplate());
|
||||
if (Options::instance().hasQml())
|
||||
clientHeaderPrinter->Print(CommonTemplates::QmlProtobufIncludesTemplate());
|
||||
|
||||
serviceHeaderPrinter->Print(CommonTemplates::DefaultProtobufIncludesTemplate());
|
||||
if (Options::instance().hasQml())
|
||||
serviceHeaderPrinter->Print(CommonTemplates::QmlProtobufIncludesTemplate());
|
||||
|
||||
printDisclaimer(clientSourcePrinter.get());
|
||||
clientSourcePrinter->Print({ { "include", clientFileName } },
|
||||
CommonTemplates::InternalIncludeTemplate());
|
||||
|
||||
SetInternalIncludes(file, internalIncludes);
|
||||
|
||||
std::set<std::string> externalIncludes
|
||||
= {"QAbstractGrpcClient", "QGrpcCallReply", "QGrpcStream"};
|
||||
|
||||
for (const auto &include : externalIncludes) {
|
||||
clientHeaderPrinter->Print({ { "include", include } },
|
||||
CommonTemplates::ExternalIncludeTemplate());
|
||||
serviceHeaderPrinter->Print({ { "include", include } },
|
||||
CommonTemplates::ExternalIncludeTemplate());
|
||||
}
|
||||
|
||||
const std::string serviceIncludes = std::string("QAbstractGrpcService");
|
||||
serviceHeaderPrinter->Print({ { "include", serviceIncludes } },
|
||||
CommonTemplates::ExternalIncludeTemplate());
|
||||
|
||||
for (const auto &include : internalIncludes) {
|
||||
clientHeaderPrinter->Print({ { "include", include } },
|
||||
CommonTemplates::InternalIncludeTemplate());
|
||||
serviceHeaderPrinter->Print({ { "include", include } },
|
||||
CommonTemplates::InternalIncludeTemplate());
|
||||
}
|
||||
|
||||
if (Options::instance().hasQml()) {
|
||||
clientSourcePrinter->Print({ { "include", "QQmlEngine" } },
|
||||
CommonTemplates::ExternalIncludeTemplate());
|
||||
clientSourcePrinter->Print({ { "include", "QJSEngine" } },
|
||||
CommonTemplates::ExternalIncludeTemplate());
|
||||
clientSourcePrinter->Print({ { "include", "QJSValue" } },
|
||||
CommonTemplates::ExternalIncludeTemplate());
|
||||
}
|
||||
|
||||
clientHeaderPrinter->PrintRaw("\n");
|
||||
serviceHeaderPrinter->PrintRaw("\n");
|
||||
if (!Options::instance().exportMacro().empty()) {
|
||||
clientHeaderPrinter->Print({ { "export_macro", Options::instance().exportMacro() } },
|
||||
CommonTemplates::ExportMacroTemplate());
|
||||
serviceHeaderPrinter->Print({ { "export_macro", Options::instance().exportMacro() } },
|
||||
CommonTemplates::ExportMacroTemplate());
|
||||
}
|
||||
|
||||
OpenFileNamespaces(file, clientHeaderPrinter.get());
|
||||
OpenFileNamespaces(file, clientSourcePrinter.get());
|
||||
OpenFileNamespaces(file, serviceHeaderPrinter.get());
|
||||
|
||||
RunPrinters(file, clientHeaderPrinter, clientSourcePrinter, serviceHeaderPrinter);
|
||||
|
||||
CloseFileNamespaces(file, clientHeaderPrinter.get());
|
||||
CloseFileNamespaces(file, clientSourcePrinter.get());
|
||||
CloseFileNamespaces(file, serviceHeaderPrinter.get());
|
||||
|
||||
clientHeaderPrinter->Print({ { "filename", filename + "_client" } },
|
||||
CommonTemplates::FooterTemplate());
|
||||
serviceHeaderPrinter->Print({ { "filename", filename + "_service" } },
|
||||
CommonTemplates::FooterTemplate());
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef QGRPCGENERATOR_H
|
||||
#define QGRPCGENERATOR_H
|
||||
|
||||
#include <memory>
|
||||
#include "generatorbase.h"
|
||||
|
||||
namespace google::protobuf {
|
||||
class FileDescriptor;
|
||||
class Descriptor;
|
||||
namespace compiler {
|
||||
class GeneratorContext;
|
||||
} // namespace compiler
|
||||
namespace io {
|
||||
class Printer;
|
||||
}
|
||||
} // namespace google::protobuf
|
||||
|
||||
namespace QtGrpc {
|
||||
class QGrpcGenerator : public qtprotoccommon::GeneratorBase
|
||||
{
|
||||
public:
|
||||
QGrpcGenerator();
|
||||
~QGrpcGenerator();
|
||||
bool Generate(const ::google::protobuf::FileDescriptor *file,
|
||||
const std::string ¶meter,
|
||||
::google::protobuf::compiler::GeneratorContext *generatorContext,
|
||||
std::string *error) const override;
|
||||
private:
|
||||
bool GenerateServices(const ::google::protobuf::FileDescriptor *file,
|
||||
::google::protobuf::compiler::GeneratorContext *generatorContext) const;
|
||||
|
||||
void SetInternalIncludes(const ::google::protobuf::FileDescriptor *file,
|
||||
std::set<std::string> &internalIncludes) const;
|
||||
|
||||
void RunPrinters(const ::google::protobuf::FileDescriptor *file,
|
||||
std::shared_ptr<::google::protobuf::io::Printer> clientHeaderPrinter,
|
||||
std::shared_ptr<::google::protobuf::io::Printer> clientSourcePrinter,
|
||||
std::shared_ptr<::google::protobuf::io::Printer> serviceHeaderPrinter) const;
|
||||
};
|
||||
} // namespace QtGrpc
|
||||
|
||||
#endif // QGRPCGENERATOR_H
|
||||
|
|
@ -8,8 +8,10 @@
|
|||
#include <google/protobuf/io/printer.h>
|
||||
|
||||
#include "generatorcommon.h"
|
||||
#include "grpctemplates.h"
|
||||
|
||||
using namespace ::QtProtobuf::generator;
|
||||
using namespace ::QtGrpc;
|
||||
using namespace ::qtprotoccommon;
|
||||
using namespace ::google::protobuf;
|
||||
|
||||
/*!
|
||||
|
|
@ -24,19 +26,19 @@ ServerDeclarationPrinter::ServerDeclarationPrinter(
|
|||
const ::google::protobuf::ServiceDescriptor *service,
|
||||
const std::shared_ptr<::google::protobuf::io::Printer> &printer)
|
||||
: DescriptorPrinterBase<::google::protobuf::ServiceDescriptor>(
|
||||
service, printer, common::produceServiceTypeMap(service, nullptr))
|
||||
service, printer, common::produceServiceTypeMap(service, nullptr))
|
||||
{
|
||||
}
|
||||
|
||||
void ServerDeclarationPrinter::printOpenNamespace()
|
||||
{
|
||||
m_printer->Print({ { "scope_namespaces", m_typeMap["scope_type"] } },
|
||||
Templates::NamespaceTemplate());
|
||||
CommonTemplates::NamespaceTemplate());
|
||||
}
|
||||
|
||||
void ServerDeclarationPrinter::printClassName()
|
||||
{
|
||||
m_printer->Print(m_typeMap, Templates::ChildClassDeclarationTemplate());
|
||||
m_printer->Print(m_typeMap, GrpcTemplates::ChildClassDeclarationTemplate());
|
||||
}
|
||||
|
||||
void ServerDeclarationPrinter::printMethodsDeclaration(const char *methodTemplate,
|
||||
|
|
@ -58,5 +60,5 @@ void ServerDeclarationPrinter::printMethodsDeclaration(const char *methodTemplat
|
|||
void ServerDeclarationPrinter::printCloseNamespace()
|
||||
{
|
||||
m_printer->Print({ { "scope_namespaces", m_typeMap["scope_type"] } },
|
||||
Templates::NamespaceClosingTemplate());
|
||||
CommonTemplates::NamespaceClosingTemplate());
|
||||
}
|
||||
|
|
@ -6,20 +6,21 @@
|
|||
#define SERVERDECLARATIONPRINTER_H
|
||||
|
||||
#include "descriptorprinterbase.h"
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include "grpctemplates.h"
|
||||
#include <string>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace google::protobuf {
|
||||
class ServiceDescriptor;
|
||||
class Message;
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
}
|
||||
namespace io {
|
||||
class Printer;
|
||||
}
|
||||
|
||||
namespace QtProtobuf {
|
||||
namespace generator {
|
||||
namespace QtGrpc {
|
||||
|
||||
class ServerDeclarationPrinter : public DescriptorPrinterBase<::google::protobuf::ServiceDescriptor>
|
||||
class ServerDeclarationPrinter :
|
||||
public qtprotoccommon::DescriptorPrinterBase<::google::protobuf::ServiceDescriptor>
|
||||
{
|
||||
public:
|
||||
ServerDeclarationPrinter(const google::protobuf::ServiceDescriptor *service,
|
||||
|
|
@ -31,7 +32,7 @@ public:
|
|||
printOpenNamespace();
|
||||
printClassName();
|
||||
printPublicBlock();
|
||||
printMethodsDeclaration(Templates::ServerMethodDeclarationTemplate());
|
||||
printMethodsDeclaration(GrpcTemplates::ServerMethodDeclarationTemplate());
|
||||
encloseClass();
|
||||
printCloseNamespace();
|
||||
}
|
||||
|
|
@ -43,7 +44,5 @@ private:
|
|||
const char *methodAsync2Template = "");
|
||||
void printCloseNamespace();
|
||||
};
|
||||
|
||||
} // namespace generator
|
||||
} // namespace QtProtobuf
|
||||
} // namespace QtGrpc
|
||||
#endif // SERVERDECLARATIONPRINTER_H
|
||||
|
|
@ -1,10 +1,6 @@
|
|||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# The include is needed by Qt::Protobuf tests that use qt6_add_protobuf call to
|
||||
# generate the code of protobuf messages for testing.
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/${QT_CMAKE_EXPORT_NAMESPACE}ProtobufToolsMacros.cmake")
|
||||
|
||||
qt_get_tool_target_name(target_name qtprotobufgen)
|
||||
qt_internal_add_tool(${target_name}
|
||||
TARGET_DESCRIPTION "Qt protobuf generator"
|
||||
|
|
@ -12,22 +8,12 @@ qt_internal_add_tool(${target_name}
|
|||
TOOLS_TARGET Protobuf
|
||||
CORE_LIBRARY None
|
||||
SOURCES
|
||||
utils.cpp utils.h
|
||||
descriptorprinterbase.h
|
||||
main.cpp
|
||||
generatorcommon.cpp generatorcommon.h
|
||||
options.cpp options.h
|
||||
templates.cpp templates.h
|
||||
generatorbase.cpp generatorbase.h
|
||||
singlefilegenerator.cpp singlefilegenerator.h
|
||||
baseprinter.cpp baseprinter.h
|
||||
qprotobufgenerator.cpp qprotobufgenerator.h
|
||||
messagedeclarationprinter.cpp messagedeclarationprinter.h
|
||||
messagedefinitionprinter.cpp messagedefinitionprinter.h
|
||||
enumdeclarationprinter.cpp enumdeclarationprinter.h
|
||||
enumdefinitionprinter.cpp enumdefinitionprinter.h
|
||||
serverdeclarationprinter.cpp serverdeclarationprinter.h
|
||||
clientdeclarationprinter.cpp clientdeclarationprinter.h
|
||||
clientdefinitionprinter.cpp clientdefinitionprinter.h
|
||||
EXTRA_CMAKE_FILES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${QT_CMAKE_EXPORT_NAMESPACE}ProtobufToolsMacros.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/QtProtocCommandWrapper.cmake"
|
||||
|
|
@ -36,6 +22,7 @@ qt_internal_add_tool(${target_name}
|
|||
LIBRARIES
|
||||
WrapProtobuf::WrapLibProtobuf
|
||||
WrapProtobuf::WrapLibProtoc
|
||||
QtProtocCommon
|
||||
)
|
||||
|
||||
qt_internal_return_unless_building_tools()
|
||||
|
|
|
|||
|
|
@ -3,6 +3,189 @@
|
|||
|
||||
set(__qt_protobuf_macros_module_base_dir "${CMAKE_CURRENT_LIST_DIR}" CACHE INTERNAL "")
|
||||
|
||||
# List of the common protoc generator options.
|
||||
macro(_qt_internal_get_protoc_common_options option_args single_args multi_args)
|
||||
set(${option_args}
|
||||
COPY_COMMENTS
|
||||
GENERATE_PACKAGE_SUBFOLDERS
|
||||
)
|
||||
set(${single_args}
|
||||
EXTRA_NAMESPACE
|
||||
EXPORT_MACRO
|
||||
)
|
||||
|
||||
set(${multi_args} "")
|
||||
endmacro()
|
||||
|
||||
# List of arguments common for the protoc generating functions.
|
||||
macro(_qt_internal_get_protoc_generate_arguments option_args single_args multi_args)
|
||||
set(${option_args} "")
|
||||
set(${single_args}
|
||||
OUTPUT_DIRECTORY
|
||||
PROTO_FILES_BASE_DIR
|
||||
OUTPUT_HEADERS
|
||||
OUTPUT_TARGETS
|
||||
)
|
||||
set(${multi_args}
|
||||
PROTO_FILES
|
||||
PROTO_INCLUDES
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# The macro collects options in protoc compatible format. Options are written into out_var.
|
||||
# All input arguments are names of the lists containing the corresponding options.
|
||||
macro(_qt_internal_get_protoc_options out_var prefix option single multi)
|
||||
set(${out_var} "")
|
||||
foreach(opt IN LISTS ${option})
|
||||
if(${prefix}_${opt})
|
||||
list(APPEND ${out_var} ${opt})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(opt IN LISTS ${single} ${multi})
|
||||
if(${prefix}_${opt})
|
||||
list(APPEND ${out_var} "${opt}=${${prefix}_${opt}}")
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
# The base function that generates rules to call the protoc executable with the custom generator
|
||||
# plugin.
|
||||
# Multi-value Arguments:
|
||||
# PROTO_FILES - list of the .proto file paths. Paths should be absolute for the correct work of
|
||||
# this function.
|
||||
# PROTO_INCLUDES - list of the protobuf include paths.
|
||||
# GENERATED_FILES - list of files that are expected
|
||||
# to be genreated by the custom generator plugin.
|
||||
function(_qt_internal_protoc_generate target generator output_directory)
|
||||
cmake_parse_arguments(arg "" "" "PROTO_FILES;PROTO_INCLUDES;GENERATED_FILES" ${ARGN})
|
||||
|
||||
if(NOT arg_PROTO_FILES)
|
||||
message(FATAL_ERROR "PROTO_FILES list is empty.")
|
||||
endif()
|
||||
|
||||
unset(proto_includes)
|
||||
if(arg_PROTO_INCLUDES)
|
||||
set(proto_includes "${arg_PROTO_INCLUDES}")
|
||||
endif()
|
||||
|
||||
if(NOT arg_GENERATED_FILES)
|
||||
set(generated_files "${arg_GENERATED_FILES}")
|
||||
message(FATAL_ERROR
|
||||
"List of generated sources for target '${target}' is empty")
|
||||
endif()
|
||||
|
||||
get_filename_component(output_directory "${output_directory}" REALPATH)
|
||||
file(MAKE_DIRECTORY ${output_directory})
|
||||
|
||||
unset(num_deps)
|
||||
if(TARGET ${target})
|
||||
get_target_property(num_deps ${target} _qt_${generator}_deps_num)
|
||||
endif()
|
||||
if(NOT num_deps)
|
||||
set(num_deps 0)
|
||||
endif()
|
||||
set(deps_target ${target}_${generator}_deps_${num_deps})
|
||||
math(EXPR num_deps "${num_deps} + 1")
|
||||
|
||||
set(generator_file $<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::${generator}>)
|
||||
|
||||
unset(proto_includes_string)
|
||||
if(proto_includes)
|
||||
list(JOIN proto_includes "\\$<SEMICOLON>-I" proto_includes_string)
|
||||
set(proto_includes_string "-I${proto_includes_string}")
|
||||
endif()
|
||||
list(JOIN arg_PROTO_FILES "\\$<SEMICOLON>" proto_files_string)
|
||||
list(JOIN generation_options "\\\\$<SEMICOLON>" generation_options_string)
|
||||
string(JOIN "\\$<SEMICOLON>" protoc_arguments
|
||||
"--plugin=protoc-gen-${generator}=${generator_file}"
|
||||
"--${generator}_out=${output_directory}"
|
||||
"--${generator}_opt=${generation_options_string}"
|
||||
"${proto_files_string}"
|
||||
"${proto_includes_string}"
|
||||
)
|
||||
add_custom_command(OUTPUT ${generated_files}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DPROTOC_EXECUTABLE=$<TARGET_FILE:WrapProtoc::WrapProtoc>
|
||||
-DPROTOC_ARGS=${protoc_arguments}
|
||||
-DWORKING_DIRECTORY=${output_directory}
|
||||
-DGENERATOR_NAME=${generator}
|
||||
-P
|
||||
${__qt_protobuf_macros_module_base_dir}/QtProtocCommandWrapper.cmake
|
||||
WORKING_DIRECTORY ${output_directory}
|
||||
DEPENDS
|
||||
${QT_CMAKE_EXPORT_NAMESPACE}::${generator}
|
||||
${proto_files}
|
||||
COMMENT "Generating QtProtobuf ${target} sources for ${generator}..."
|
||||
COMMAND_EXPAND_LISTS
|
||||
VERBATIM
|
||||
)
|
||||
add_custom_target(${deps_target} DEPENDS ${generated_files})
|
||||
set_property(TARGET ${target} APPEND PROPERTY
|
||||
AUTOGEN_TARGET_DEPENDS "${deps_target}")
|
||||
set_property(TARGET ${target} PROPERTY _qt_${generator}_deps_num "${num_deps}")
|
||||
set_source_files_properties(${generated_files} PROPERTIES
|
||||
GENERATED TRUE
|
||||
)
|
||||
|
||||
target_include_directories(${target} PUBLIC "$<BUILD_INTERFACE:${output_directory}>")
|
||||
endfunction()
|
||||
|
||||
# The function looks for the enum and message definitions inside provided PROTO_FILES and returns
|
||||
# list of the absolute .proto file paths, protobuf include paths and files that are expected to be
|
||||
# generated by qtprotobufgen.
|
||||
# Optional arguments:
|
||||
# GENERATE_PACKAGE_SUBFOLDERS - generated files will be located in package-base subdirectories.
|
||||
#
|
||||
# Multi-value arguments:
|
||||
# PROTO_FILES - input list of the proto files. May contain either absolute or relative paths.
|
||||
function(_qt_internal_protobuf_preparse_proto_files
|
||||
out_proto_files out_proto_includes out_generated_files base_dir)
|
||||
|
||||
cmake_parse_arguments(arg "GENERATE_PACKAGE_SUBFOLDERS" "" "PROTO_FILES" ${ARGN})
|
||||
|
||||
unset(proto_files)
|
||||
unset(proto_includes)
|
||||
unset(output_files)
|
||||
foreach(f IN LISTS arg_PROTO_FILES)
|
||||
if(NOT IS_ABSOLUTE "${f}")
|
||||
set(f "${base_dir}/${f}")
|
||||
get_filename_component(f "${f}" ABSOLUTE)
|
||||
endif()
|
||||
get_filename_component(f "${f}" REALPATH)
|
||||
list(APPEND proto_files "${f}")
|
||||
|
||||
_qt_internal_preparse_proto_file_common(result proto_package "${f}" "message;enum")
|
||||
if(NOT result)
|
||||
message(STATUS "No messages or enums found in ${f}. Skipping.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_filename_component(proto_file_base_dir "${f}" DIRECTORY)
|
||||
list(PREPEND proto_includes "${proto_file_base_dir}")
|
||||
|
||||
string(REPLACE "." "/" package_full_path "${proto_package}")
|
||||
set(folder_path "")
|
||||
if(arg_GENERATE_PACKAGE_SUBFOLDERS)
|
||||
set(folder_path "${package_full_path}/")
|
||||
endif()
|
||||
|
||||
get_filename_component(basename "${f}" NAME_WLE)
|
||||
list(APPEND output_files
|
||||
"${folder_path}${basename}.qpb.h"
|
||||
"${folder_path}${basename}.qpb.cpp"
|
||||
"${folder_path}${basename}_protobuftyperegistrations.cpp"
|
||||
)
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES proto_files)
|
||||
list(REMOVE_DUPLICATES proto_includes)
|
||||
list(REMOVE_DUPLICATES output_files)
|
||||
|
||||
set(${out_proto_files} "${proto_files}" PARENT_SCOPE)
|
||||
set(${out_proto_includes} "${proto_includes}" PARENT_SCOPE)
|
||||
set(${out_generated_files} "${output_files}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# TODO Qt6:
|
||||
# - Collect PROTO_INCLUDES from the LINK_LIBRARIES property of TARGET
|
||||
# - Collect proto files from the source files of the ${TARGET}
|
||||
|
|
@ -10,107 +193,98 @@ set(__qt_protobuf_macros_module_base_dir "${CMAKE_CURRENT_LIST_DIR}" CACHE INTER
|
|||
# This function is currently in Technical Preview
|
||||
# Its signature and behavior might change.
|
||||
function(qt6_add_protobuf target)
|
||||
set(options COPY_COMMENTS GENERATE_PACKAGE_SUBFOLDERS)
|
||||
set(oneValueArgs
|
||||
OUTPUT_DIRECTORY
|
||||
EXTRA_NAMESPACE
|
||||
PROTO_FILES_BASE_DIR
|
||||
OUTPUT_HEADERS
|
||||
OUTPUT_TARGETS
|
||||
_qt_internal_get_protoc_common_options(protoc_option_opt protoc_single_opt protoc_multi_opt)
|
||||
_qt_internal_get_protoc_generate_arguments(protoc_option_arg protoc_single_arg protoc_multi_arg)
|
||||
|
||||
set(option_args
|
||||
${protoc_option_opt}
|
||||
${protoc_option_arg}
|
||||
)
|
||||
set(multiValueArgs PROTO_FILES PROTO_INCLUDES)
|
||||
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
unset(proto_files)
|
||||
foreach(proto_file IN LISTS arg_PROTO_FILES)
|
||||
if(NOT IS_ABSOLUTE "${proto_file}")
|
||||
if(arg_PROTO_FILES_BASE_DIR)
|
||||
set(proto_file "${arg_PROTO_FILES_BASE_DIR}/${proto_file}")
|
||||
endif()
|
||||
get_filename_component(proto_file "${proto_file}" ABSOLUTE)
|
||||
endif()
|
||||
get_filename_component(proto_file "${proto_file}" REALPATH)
|
||||
list(APPEND proto_files "${proto_file}")
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES proto_files)
|
||||
set(single_args
|
||||
${protoc_single_opt}
|
||||
${protoc_single_arg}
|
||||
)
|
||||
|
||||
if(DEFINED arg_OUTPUT_TARGETS)
|
||||
set(${arg_OUTPUT_TARGETS} "")
|
||||
set(multi_args
|
||||
${protoc_multi_opt}
|
||||
${protoc_multi_arg}
|
||||
)
|
||||
cmake_parse_arguments(arg "${option_args}" "${single_args}" "${multi_args}" ${ARGN})
|
||||
|
||||
_qt_internal_get_protoc_options(generation_options arg
|
||||
protoc_option_opt protoc_single_opt protoc_multi_opt)
|
||||
|
||||
if(arg_PROTO_FILES_BASE_DIR)
|
||||
set(base_dir "${arg_PROTO_FILES_BASE_DIR}")
|
||||
else()
|
||||
set(base_dir "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
endif()
|
||||
|
||||
if(DEFINED arg_OUTPUT_HEADERS)
|
||||
set(${arg_OUTPUT_HEADERS} "")
|
||||
endif()
|
||||
|
||||
if("${proto_files}" STREQUAL "")
|
||||
message(FATAL_ERROR "PROTO_FILES list is empty.")
|
||||
endif()
|
||||
|
||||
string(TOUPPER "${target}" target_upper)
|
||||
|
||||
set(generation_options "")
|
||||
set(extra_pre_parse_options "")
|
||||
|
||||
if(arg_COPY_COMMENTS)
|
||||
list(APPEND generation_options "COPY_COMMENTS")
|
||||
endif()
|
||||
|
||||
unset(extra_pre_parse_options)
|
||||
if(arg_GENERATE_PACKAGE_SUBFOLDERS)
|
||||
list(APPEND generation_options "GENERATE_PACKAGE_SUBFOLDERS")
|
||||
list(APPEND extra_pre_parse_options "GENERATE_PACKAGE_SUBFOLDERS")
|
||||
endif()
|
||||
|
||||
if(arg_EXTRA_NAMESPACE)
|
||||
list(APPEND generation_options "EXTRA_NAMESPACE=${arg_EXTRA_NAMESPACE}")
|
||||
_qt_internal_protobuf_preparse_proto_files(proto_files proto_includes generated_files
|
||||
"${base_dir}"
|
||||
${extra_pre_parse_options}
|
||||
PROTO_FILES
|
||||
${arg_PROTO_FILES}
|
||||
)
|
||||
if(arg_PROTO_INCLUDES)
|
||||
list(APPEND proto_includes ${arg_PROTO_INCLUDES})
|
||||
endif()
|
||||
|
||||
set(is_shared FALSE)
|
||||
set(is_static FALSE)
|
||||
set(is_executable FALSE)
|
||||
if(TARGET ${target})
|
||||
get_target_property(target_type ${target} TYPE)
|
||||
elseif(BUILD_SHARED_LIBS)
|
||||
set(target_type "SHARED_LIBRARY")
|
||||
if(target_type STREQUAL "SHARED_LIBRARY" OR target_type STREQUAL "MODULE_LIBRARY")
|
||||
set(is_shared TRUE)
|
||||
elseif(target_type STREQUAL "STATIC_LIBRARY")
|
||||
set(is_static TRUE)
|
||||
elseif(target_type STREQUAL "EXECUTABLE")
|
||||
set(is_executable TRUE)
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported target type '${target_type}'.")
|
||||
endif()
|
||||
else()
|
||||
set(target_type "STATIC_LIBRARY")
|
||||
endif()
|
||||
# Add EXPORT_MACRO if the target is, or we will create, a shared library
|
||||
if (target_type STREQUAL SHARED_LIBRARY)
|
||||
list(APPEND generation_options "EXPORT_MACRO=${target_upper}")
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(target_type "SHARED_LIBRARY")
|
||||
set(is_shared TRUE)
|
||||
else()
|
||||
set(target_type "STATIC_LIBRARY")
|
||||
set(is_static TRUE)
|
||||
endif()
|
||||
|
||||
_qt_internal_add_library(${target})
|
||||
if(DEFINED arg_OUTPUT_TARGETS)
|
||||
list(APPEND ${arg_OUTPUT_TARGETS} "${target}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(proto_includes "")
|
||||
foreach(proto_include IN LISTS arg_PROTO_INCLUDES)
|
||||
get_filename_component(proto_include "${proto_include}" REALPATH)
|
||||
list(APPEND proto_includes "${proto_include}")
|
||||
endforeach()
|
||||
|
||||
unset(generated_files)
|
||||
foreach(proto_file IN LISTS proto_files)
|
||||
get_filename_component(proto_file_base_dir "${proto_file}" DIRECTORY)
|
||||
list(PREPEND proto_includes "-I${proto_file_base_dir}")
|
||||
_qt_internal_preparse_proto_file(preparsed_files "${proto_file}" ${extra_pre_parse_options})
|
||||
list(APPEND generated_files ${preparsed_files})
|
||||
endforeach()
|
||||
|
||||
if(NOT generated_files)
|
||||
message(FATAL_ERROR
|
||||
"Unable to get the list of generated sources for target '${target}'")
|
||||
if(is_static OR is_shared)
|
||||
# Add EXPORT_MACRO if the target is, or we will create, a shared library
|
||||
string(TOUPPER "${target}" target_upper)
|
||||
if (is_shared)
|
||||
list(APPEND generation_options "EXPORT_MACRO=${target_upper}")
|
||||
endif()
|
||||
# Define this so we can conditionally set the export macro
|
||||
target_compile_definitions(${target}
|
||||
PRIVATE "QT_BUILD_${target_upper}_LIB")
|
||||
endif()
|
||||
|
||||
list(REMOVE_DUPLICATES generated_files)
|
||||
|
||||
if(NOT DEFINED arg_OUTPUT_DIRECTORY OR "${arg_OUTPUT_DIRECTORY}" STREQUAL "")
|
||||
set(out_dir ${CMAKE_CURRENT_BINARY_DIR})
|
||||
else()
|
||||
set(out_dir ${arg_OUTPUT_DIRECTORY})
|
||||
set(output_directory "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
if(DEFINED arg_OUTPUT_DIRECTORY)
|
||||
set(output_directory "${arg_OUTPUT_DIRECTORY}")
|
||||
endif()
|
||||
|
||||
get_filename_component(out_dir "${out_dir}" REALPATH)
|
||||
list(TRANSFORM generated_files PREPEND "${output_directory}/")
|
||||
|
||||
file(MAKE_DIRECTORY ${out_dir})
|
||||
|
||||
list(TRANSFORM generated_files PREPEND "${out_dir}/")
|
||||
|
||||
set_source_files_properties(${generated_files} PROPERTIES
|
||||
GENERATED TRUE
|
||||
_qt_internal_protoc_generate(${target} qtprotobufgen "${output_directory}"
|
||||
PROTO_FILES ${proto_files}
|
||||
PROTO_INCLUDES ${proto_includes}
|
||||
GENERATED_FILES ${generated_files}
|
||||
)
|
||||
|
||||
# Filter generated headers
|
||||
|
|
@ -128,80 +302,26 @@ function(qt6_add_protobuf target)
|
|||
endif()
|
||||
endforeach()
|
||||
|
||||
unset(num_deps)
|
||||
if(TARGET ${target})
|
||||
get_target_property(num_deps ${target} _qt_protobufgen_deps_num)
|
||||
target_sources(${target} PRIVATE ${generated_headers} ${generated_sources})
|
||||
|
||||
if(is_static OR is_shared)
|
||||
set_target_properties(${target}
|
||||
PROPERTIES
|
||||
PUBLIC_HEADER "${generated_headers}"
|
||||
AUTOMOC ON
|
||||
)
|
||||
endif()
|
||||
if(NOT num_deps)
|
||||
set(num_deps 0)
|
||||
endif()
|
||||
set(deps_target ${target}_protobufgen_deps_${num_deps})
|
||||
math(EXPR num_deps "${num_deps} + 1")
|
||||
|
||||
set(qtprotobufgen_file $<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qtprotobufgen>)
|
||||
|
||||
list(REMOVE_DUPLICATES proto_includes)
|
||||
list(JOIN proto_files "\\$<SEMICOLON>" proto_files_string)
|
||||
list(JOIN proto_includes "\\$<SEMICOLON>" proto_includes_string)
|
||||
list(JOIN generation_options "\\\\$<SEMICOLON>" generation_options_string)
|
||||
string(JOIN "\\$<SEMICOLON>" protoc_arguments
|
||||
"--plugin=protoc-gen-qtprotobufgen=${qtprotobufgen_file}"
|
||||
"--qtprotobufgen_out=${out_dir}"
|
||||
"--qtprotobufgen_opt=${generation_options_string}"
|
||||
"${proto_files_string}"
|
||||
"${proto_includes_string}"
|
||||
)
|
||||
add_custom_command(OUTPUT ${generated_files}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DPROTOC_EXECUTABLE=$<TARGET_FILE:WrapProtoc::WrapProtoc>
|
||||
-DPROTOC_ARGS=${protoc_arguments}
|
||||
-DWORKING_DIRECTORY=${out_dir}
|
||||
-P
|
||||
${__qt_protobuf_macros_module_base_dir}/QtProtocCommandWrapper.cmake
|
||||
WORKING_DIRECTORY ${out_dir}
|
||||
DEPENDS
|
||||
${QT_CMAKE_EXPORT_NAMESPACE}::qtprotobufgen
|
||||
${proto_files}
|
||||
COMMENT "Generating QtProtobuf ${target} sources..."
|
||||
COMMAND_EXPAND_LISTS
|
||||
VERBATIM
|
||||
)
|
||||
add_custom_target(${deps_target} DEPENDS ${generated_files})
|
||||
|
||||
if(TARGET ${target})
|
||||
target_sources(${target} PRIVATE ${generated_headers} ${generated_sources})
|
||||
else()
|
||||
if(DEFINED arg_OUTPUT_TARGETS)
|
||||
list(APPEND arg_OUTPUT_TARGETS "${target}")
|
||||
endif()
|
||||
_qt_internal_add_library(${target} ${generated_headers} ${generated_sources})
|
||||
endif()
|
||||
set_property(TARGET ${target} APPEND PROPERTY
|
||||
AUTOGEN_TARGET_DEPENDS "${deps_target}")
|
||||
|
||||
set_property(TARGET ${target} PROPERTY _qt_protobufgen_deps_num "${num_deps}")
|
||||
|
||||
set_target_properties(${target}
|
||||
PROPERTIES
|
||||
PUBLIC_HEADER "${generated_headers}"
|
||||
AUTOMOC ON
|
||||
)
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
target_compile_options(${target}
|
||||
PRIVATE "/Zc:__cplusplus" "/permissive-" "/bigobj")
|
||||
endif()
|
||||
if(NOT target_type STREQUAL "EXECUTABLE")
|
||||
# Define this so we can conditionally set the export macro
|
||||
target_compile_definitions(${target}
|
||||
PRIVATE "QT_BUILD_${target_upper}_LIB")
|
||||
endif()
|
||||
|
||||
|
||||
target_link_libraries(${target} PRIVATE
|
||||
${QT_CMAKE_EXPORT_NAMESPACE}::Protobuf
|
||||
)
|
||||
|
||||
if(target_type STREQUAL "STATIC_LIBRARY" OR (WIN32 AND NOT target_type STREQUAL "EXECUTABLE"))
|
||||
if(is_static OR (WIN32 AND NOT is_executable))
|
||||
if(TARGET ${target}_protobuf_registration)
|
||||
target_sources(${target}_protobuf_registration PRIVATE ${generated_typeregistrations})
|
||||
else()
|
||||
|
|
@ -232,8 +352,6 @@ function(qt6_add_protobuf target)
|
|||
target_sources(${target} PRIVATE ${generated_typeregistrations})
|
||||
endif()
|
||||
|
||||
target_include_directories(${target} PUBLIC "$<BUILD_INTERFACE:${out_dir}>")
|
||||
|
||||
if(DEFINED arg_OUTPUT_HEADERS)
|
||||
set(${arg_OUTPUT_HEADERS} "${generated_headers}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
|
@ -254,9 +372,10 @@ if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
|
|||
endfunction()
|
||||
endif()
|
||||
|
||||
function(_qt_internal_preparse_proto_file out_generated_files proto_file)
|
||||
cmake_parse_arguments(arg "GENERATE_PACKAGE_SUBFOLDERS" "" "" ${ARGN})
|
||||
|
||||
# The common parsing function looking for the 'lookup_keys' definitions inside the 'proto_file'.
|
||||
# The function sets the 'out_result' variable to true if one of 'lookup_keys' is found. Also the
|
||||
# function writes to the 'out_package' variable the package name that the .proto file belongs to.
|
||||
function(_qt_internal_preparse_proto_file_common out_result out_package proto_file lookup_keys)
|
||||
if(NOT proto_file OR NOT EXISTS "${proto_file}")
|
||||
message(FATAL_ERROR "Unable to scan '${proto_file}': file doesn't exist.")
|
||||
endif()
|
||||
|
|
@ -275,19 +394,14 @@ function(_qt_internal_preparse_proto_file out_generated_files proto_file)
|
|||
set(unclosed_braces 0)
|
||||
set(in_message_scope FALSE)
|
||||
|
||||
set(found_key FALSE)
|
||||
list(JOIN lookup_keys "|" lookup_keys_regex)
|
||||
foreach(item IN LISTS file_content)
|
||||
if(item MATCHES "^[\t ]*package[\t ]+([a-zA-Z0-9_.-]+)")
|
||||
set(proto_package "${CMAKE_MATCH_1}")
|
||||
elseif(item MATCHES "^[\t ]*message${proto_key_common_regex}")
|
||||
# Skip adding nested messages to the list.
|
||||
if(unclosed_braces EQUAL 0)
|
||||
list(APPEND proto_messages "${CMAKE_MATCH_1}")
|
||||
set(in_message_scope TRUE)
|
||||
endif()
|
||||
elseif(item MATCHES "^[\t ]*service${proto_key_common_regex}")
|
||||
list(APPEND proto_services "${CMAKE_MATCH_1}")
|
||||
elseif(item MATCHES "^[\t ]*enum${proto_key_common_regex}")
|
||||
list(APPEND proto_enums "${CMAKE_MATCH_1}")
|
||||
elseif(item MATCHES "^[\t ]*(${lookup_keys_regex})${proto_key_common_regex}")
|
||||
set(found_key TRUE)
|
||||
break()
|
||||
endif()
|
||||
if(in_message_scope)
|
||||
if(item MATCHES "[^/]*\\{")
|
||||
|
|
@ -302,31 +416,6 @@ function(_qt_internal_preparse_proto_file out_generated_files proto_file)
|
|||
endif()
|
||||
endforeach()
|
||||
|
||||
unset(output_files)
|
||||
string(REPLACE "." "/" package_full_path "${proto_package}")
|
||||
get_filename_component(basename "${proto_file}" NAME_WLE)
|
||||
|
||||
set(folder_path "")
|
||||
if(arg_GENERATE_PACKAGE_SUBFOLDERS)
|
||||
set(folder_path "${package_full_path}/")
|
||||
endif()
|
||||
if(proto_messages OR proto_enums)
|
||||
list(APPEND output_files
|
||||
"${folder_path}${basename}.qpb.h"
|
||||
"${folder_path}${basename}.qpb.cpp"
|
||||
"${folder_path}${basename}_protobuftyperegistrations.cpp"
|
||||
)
|
||||
endif()
|
||||
if(proto_services)
|
||||
if(QT_FEATURE_native_grpc)
|
||||
list(APPEND output_files
|
||||
"${folder_path}${basename}_service.grpc.qpb.h"
|
||||
)
|
||||
endif()
|
||||
list(APPEND output_files
|
||||
"${folder_path}${basename}_client.grpc.qpb.h"
|
||||
"${folder_path}${basename}_client.grpc.qpb.cpp"
|
||||
)
|
||||
endif()
|
||||
set(${out_generated_files} "${output_files}" PARENT_SCOPE)
|
||||
set(${out_package} "${proto_package}" PARENT_SCOPE)
|
||||
set(${out_result} "${found_key}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,12 @@
|
|||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
set(ENV{QT_PROTOBUF_OPTIONS} "${QT_PROTOBUF_OPTIONS}")
|
||||
if(GENERATOR_NAME EQUAL "qtgrpc")
|
||||
set(ENV{QT_GRPC_OPTIONS} "${QT_GRPC_OPTIONS}")
|
||||
elseif(GENERATOR_NAME EQUAL "qtprotobuf")
|
||||
set(ENV{QT_PROTOBUF_OPTIONS} "${QT_PROTOBUF_OPTIONS}")
|
||||
endif()
|
||||
|
||||
|
||||
execute_process(COMMAND
|
||||
${PROTOC_EXECUTABLE}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,11 @@
|
|||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "enumdeclarationprinter.h"
|
||||
#include "utils.h"
|
||||
#include "generatorcommon.h"
|
||||
|
||||
using namespace ::QtProtobuf::generator;
|
||||
using namespace ::QtProtobuf;
|
||||
using namespace ::qtprotoccommon;
|
||||
using namespace ::google::protobuf;
|
||||
using namespace ::google::protobuf::io;
|
||||
|
||||
|
|
@ -21,14 +23,14 @@ EnumDeclarationPrinter::~EnumDeclarationPrinter() = default;
|
|||
void EnumDeclarationPrinter::startEnum()
|
||||
{
|
||||
printEnumClass();
|
||||
m_printer->Print(m_typeMap, Templates::EnumRegistrationDeclaration());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::EnumRegistrationDeclaration());
|
||||
}
|
||||
|
||||
void EnumDeclarationPrinter::printEnum()
|
||||
{
|
||||
auto typeMap = common::produceEnumTypeMap(m_descriptor, nullptr);
|
||||
|
||||
m_printer->Print(typeMap, Templates::EnumDefinitionTemplate());
|
||||
m_printer->Print(typeMap, CommonTemplates::EnumDefinitionTemplate());
|
||||
|
||||
Indent();
|
||||
int numValues = m_descriptor->value_count();
|
||||
|
|
@ -36,15 +38,15 @@ void EnumDeclarationPrinter::printEnum()
|
|||
const EnumValueDescriptor *valueDescr = m_descriptor->value(j);
|
||||
m_printer->Print({ { "enumvalue", utils::capitalizeAsciiName(valueDescr->name()) },
|
||||
{ "value", std::to_string(valueDescr->number()) } },
|
||||
Templates::EnumFieldTemplate());
|
||||
CommonTemplates::EnumFieldTemplate());
|
||||
}
|
||||
Outdent();
|
||||
m_printer->Print(Templates::SemicolonBlockEnclosureTemplate());
|
||||
m_printer->Print(typeMap, Templates::QEnumNSTemplate());
|
||||
m_printer->Print(typeMap, Templates::UsingRepeatedEnumTemplate());
|
||||
m_printer->Print(CommonTemplates::SemicolonBlockEnclosureTemplate());
|
||||
m_printer->Print(typeMap, CommonTemplates::QEnumNSTemplate());
|
||||
m_printer->Print(typeMap, CommonTemplates::UsingRepeatedEnumTemplate());
|
||||
}
|
||||
|
||||
void EnumDeclarationPrinter::printEnumClass()
|
||||
{
|
||||
m_printer->Print(m_typeMap, Templates::EnumDeclarationTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::EnumDeclarationTemplate());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@
|
|||
|
||||
#include "descriptorprinterbase.h"
|
||||
|
||||
namespace QtProtobuf::generator {
|
||||
class EnumDeclarationPrinter final : public DescriptorPrinterBase<google::protobuf::EnumDescriptor>
|
||||
namespace QtProtobuf {
|
||||
class EnumDeclarationPrinter final
|
||||
: public qtprotoccommon::DescriptorPrinterBase<google::protobuf::EnumDescriptor>
|
||||
{
|
||||
public:
|
||||
explicit EnumDeclarationPrinter(
|
||||
|
|
@ -30,6 +31,6 @@ private:
|
|||
void printEnumClass();
|
||||
};
|
||||
|
||||
} // namespace QtProtobuf::generator
|
||||
} // namespace QtProtobuf
|
||||
|
||||
#endif // ENUMDECLARATIONPRINTER_H
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
|
||||
#include "options.h"
|
||||
|
||||
using namespace ::QtProtobuf::generator;
|
||||
using namespace ::QtProtobuf;
|
||||
using namespace ::qtprotoccommon;
|
||||
using namespace ::google::protobuf;
|
||||
using namespace ::google::protobuf::io;
|
||||
|
||||
|
|
@ -21,14 +22,14 @@ EnumDefinitionPrinter::~EnumDefinitionPrinter() = default;
|
|||
|
||||
void EnumDefinitionPrinter::printRegisterBody()
|
||||
{
|
||||
m_printer->Print(m_typeMap, Templates::RegistrarEnumTemplate());
|
||||
m_printer->Print(m_typeMap, Templates::MetaTypeRegistrationGlobalEnumDefinition());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::RegistrarEnumTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::MetaTypeRegistrationGlobalEnumDefinition());
|
||||
Indent();
|
||||
if (Options::instance().hasQml())
|
||||
m_printer->Print(m_typeMap, Templates::QmlRegisterTypeEnumTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::QmlRegisterTypeEnumTemplate());
|
||||
|
||||
m_printer->Print(m_typeMap, Templates::MetaTypeRegistrationGlobalEnumTemplate());
|
||||
m_printer->Print(m_typeMap, Templates::RegisterEnumSerializersTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::MetaTypeRegistrationGlobalEnumTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::RegisterEnumSerializersTemplate());
|
||||
Outdent();
|
||||
m_printer->Print(Templates::SimpleBlockEnclosureTemplate());
|
||||
m_printer->Print(CommonTemplates::SimpleBlockEnclosureTemplate());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
#include "descriptorprinterbase.h"
|
||||
|
||||
namespace QtProtobuf::generator {
|
||||
|
||||
class EnumDefinitionPrinter final : public DescriptorPrinterBase<google::protobuf::EnumDescriptor>
|
||||
namespace QtProtobuf {
|
||||
class EnumDefinitionPrinter final
|
||||
: public qtprotoccommon::DescriptorPrinterBase<google::protobuf::EnumDescriptor>
|
||||
{
|
||||
public:
|
||||
explicit EnumDefinitionPrinter(const google::protobuf::EnumDescriptor *descriptor,
|
||||
|
|
@ -21,6 +21,6 @@ public:
|
|||
void printRegisterBody();
|
||||
};
|
||||
|
||||
} // namespace QtProtobuf::generator
|
||||
} // namespace QtProtobuf
|
||||
|
||||
#endif // ENUMDEFINITIONPRINTER_H
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#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 "options.h"
|
||||
#include "generatorcommon.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
using namespace ::google::protobuf;
|
||||
using namespace ::google::protobuf::io;
|
||||
using namespace ::google::protobuf::compiler;
|
||||
using namespace ::QtProtobuf::generator;
|
||||
|
||||
bool GeneratorBase::GenerateAll(const std::vector<const FileDescriptor *> &files,
|
||||
const std::string ¶meter, GeneratorContext *generatorContext,
|
||||
std::string *error) const
|
||||
{
|
||||
Options::setFromString(parameter);
|
||||
return CodeGenerator::GenerateAll(files, parameter, generatorContext, error);
|
||||
}
|
||||
|
||||
std::string GeneratorBase::generateBaseName(const FileDescriptor *file, const std::string &name)
|
||||
{
|
||||
std::string outFileBasename;
|
||||
if (Options::instance().isFolder()) {
|
||||
outFileBasename = file->package();
|
||||
outFileBasename = utils::replace(outFileBasename, ".", "/");
|
||||
outFileBasename += '/';
|
||||
}
|
||||
outFileBasename += name;
|
||||
|
||||
return outFileBasename;
|
||||
}
|
||||
|
||||
void GeneratorBase::printDisclaimer(Printer *printer)
|
||||
{
|
||||
printer->Print(Templates::DisclaimerTemplate());
|
||||
}
|
||||
|
|
@ -4,18 +4,18 @@
|
|||
|
||||
#include <google/protobuf/compiler/plugin.h>
|
||||
|
||||
#include "singlefilegenerator.h"
|
||||
#include "qprotobufgenerator.h"
|
||||
#include "options.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace ::QtProtobuf::generator;
|
||||
using namespace ::QtProtobuf;
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *optionsPtr = getenv("QT_PROTOBUF_OPTIONS");
|
||||
if (optionsPtr != nullptr) {
|
||||
QT_PROTOBUF_DEBUG("QT_PROTOBUF_OPTIONS: " << optionsPtr);
|
||||
Options::setFromString(optionsPtr);
|
||||
qtprotoccommon::Options::setFromString(optionsPtr);
|
||||
}
|
||||
SingleFileGenerator generator;
|
||||
QProtobufGenerator generator;
|
||||
return ::google::protobuf::compiler::PluginMain(argc, argv, &generator);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// Copyright (C) 2020 Alexey Edelev <semlanik@gmail.com>, Tatyana Borisova <tanusshhka@mail.ru>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
|
@ -12,14 +12,16 @@
|
|||
|
||||
#include <cassert>
|
||||
|
||||
using namespace ::QtProtobuf::generator;
|
||||
using namespace ::QtProtobuf;
|
||||
using namespace ::qtprotoccommon;
|
||||
using namespace ::google::protobuf;
|
||||
using namespace ::google::protobuf::io;
|
||||
using namespace ::google::protobuf::compiler;
|
||||
|
||||
MessageDeclarationPrinter::MessageDeclarationPrinter(const Descriptor *message,
|
||||
std::shared_ptr<Printer> printer)
|
||||
: DescriptorPrinterBase<Descriptor>(message, std::move(printer),
|
||||
: DescriptorPrinterBase<Descriptor>(message,
|
||||
std::move(printer),
|
||||
common::produceMessageTypeMap(message, nullptr))
|
||||
{
|
||||
}
|
||||
|
|
@ -30,16 +32,16 @@ void MessageDeclarationPrinter::printClassForwardDeclarationPrivate()
|
|||
{
|
||||
if (common::hasNestedMessages(m_descriptor)) {
|
||||
auto scopeNamespaces = common::getNestedScopeNamespace(m_typeMap["classname"]);
|
||||
m_printer->Print(scopeNamespaces, Templates::NamespaceTemplate());
|
||||
m_printer->Print(scopeNamespaces, CommonTemplates::NamespaceTemplate());
|
||||
common::iterateNestedMessages(m_descriptor, [this](const Descriptor *nestedMessage) {
|
||||
MessageDeclarationPrinter nesterPrinter(nestedMessage, m_printer);
|
||||
nesterPrinter.printClassForwardDeclarationPrivate();
|
||||
});
|
||||
m_printer->Print(scopeNamespaces, Templates::NamespaceClosingTemplate());
|
||||
m_printer->Print(scopeNamespaces, CommonTemplates::NamespaceClosingTemplate());
|
||||
}
|
||||
|
||||
m_printer->Print(m_typeMap, Templates::ClassMessageForwardDeclarationTemplate());
|
||||
m_printer->Print(m_typeMap, Templates::UsingMessageTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::ClassMessageForwardDeclarationTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::UsingMessageTemplate());
|
||||
}
|
||||
|
||||
void MessageDeclarationPrinter::printClassForwardDeclaration()
|
||||
|
|
@ -56,12 +58,12 @@ void MessageDeclarationPrinter::printClassDeclarationPrivate()
|
|||
{
|
||||
if (common::hasNestedMessages(m_descriptor)) {
|
||||
auto scopeNamespaces = common::getNestedScopeNamespace(m_typeMap["classname"]);
|
||||
m_printer->Print(scopeNamespaces, Templates::NamespaceTemplate());
|
||||
m_printer->Print(scopeNamespaces, CommonTemplates::NamespaceTemplate());
|
||||
common::iterateNestedMessages(m_descriptor, [this](const Descriptor *nestedMessage) {
|
||||
MessageDeclarationPrinter nesterPrinter(nestedMessage, m_printer);
|
||||
nesterPrinter.printClassDeclarationPrivate();
|
||||
});
|
||||
m_printer->Print(scopeNamespaces, Templates::NamespaceClosingTemplate());
|
||||
m_printer->Print(scopeNamespaces, CommonTemplates::NamespaceClosingTemplate());
|
||||
}
|
||||
printComments(m_descriptor);
|
||||
printClassDeclarationBegin();
|
||||
|
|
@ -72,30 +74,30 @@ void MessageDeclarationPrinter::printClassDeclarationPrivate()
|
|||
void MessageDeclarationPrinter::printCopyFunctionality()
|
||||
{
|
||||
assert(m_descriptor != nullptr);
|
||||
m_printer->Print(m_typeMap, Templates::CopyConstructorDeclarationTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::CopyConstructorDeclarationTemplate());
|
||||
|
||||
m_printer->Print(m_typeMap, Templates::AssignmentOperatorDeclarationTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::AssignmentOperatorDeclarationTemplate());
|
||||
}
|
||||
|
||||
void MessageDeclarationPrinter::printMoveSemantic()
|
||||
{
|
||||
assert(m_descriptor != nullptr);
|
||||
m_printer->Print(m_typeMap, Templates::MoveConstructorDeclarationTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::MoveConstructorDeclarationTemplate());
|
||||
|
||||
m_printer->Print(m_typeMap, Templates::MoveAssignmentOperatorDeclarationTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::MoveAssignmentOperatorDeclarationTemplate());
|
||||
}
|
||||
|
||||
void MessageDeclarationPrinter::printComparisonOperators()
|
||||
{
|
||||
assert(m_descriptor != nullptr);
|
||||
m_printer->Print(m_typeMap, Templates::EqualOperatorDeclarationTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::EqualOperatorDeclarationTemplate());
|
||||
|
||||
m_printer->Print(m_typeMap, Templates::NotEqualOperatorDeclarationTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::NotEqualOperatorDeclarationTemplate());
|
||||
}
|
||||
|
||||
void MessageDeclarationPrinter::printConstructors()
|
||||
{
|
||||
m_printer->Print(m_typeMap, Templates::ConstructorMessageDeclarationTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::ConstructorMessageDeclarationTemplate());
|
||||
|
||||
if (m_descriptor->full_name() == "google.protobuf.Timestamp") {
|
||||
m_printer->Print("Timestamp(const QDateTime &datetime);\n"
|
||||
|
|
@ -112,8 +114,8 @@ void MessageDeclarationPrinter::printMaps()
|
|||
if (field->is_map()) {
|
||||
const Descriptor *type = field->message_type();
|
||||
const char *mapTemplate = type->field(1)->type() == FieldDescriptor::TYPE_MESSAGE
|
||||
? Templates::UsingMapMessageTemplate()
|
||||
: Templates::UsingMapTemplate();
|
||||
? CommonTemplates::UsingMapMessageTemplate()
|
||||
: CommonTemplates::UsingMapTemplate();
|
||||
m_printer->Print(common::producePropertyMap(field, m_descriptor), mapTemplate);
|
||||
}
|
||||
}
|
||||
|
|
@ -125,22 +127,22 @@ void MessageDeclarationPrinter::printNested()
|
|||
Indent();
|
||||
common::iterateNestedMessages(m_descriptor, [&](const Descriptor *nestedMessage) {
|
||||
m_printer->Print(common::produceMessageTypeMap(nestedMessage, m_descriptor),
|
||||
Templates::UsingNestedMessageTemplate());
|
||||
CommonTemplates::UsingNestedMessageTemplate());
|
||||
});
|
||||
Outdent();
|
||||
}
|
||||
|
||||
void MessageDeclarationPrinter::printClassDeclarationBegin()
|
||||
{
|
||||
m_printer->Print(m_typeMap, Templates::ClassMessageBeginDeclarationTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::ClassMessageBeginDeclarationTemplate());
|
||||
}
|
||||
|
||||
void MessageDeclarationPrinter::printMetaTypesDeclaration()
|
||||
{
|
||||
m_printer->Print(m_typeMap, Templates::DeclareMetaTypeTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::DeclareMetaTypeTemplate());
|
||||
|
||||
if (Options::instance().hasQml()) {
|
||||
m_printer->Print(m_typeMap, Templates::DeclareMetaTypeQmlListTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::DeclareMetaTypeQmlListTemplate());
|
||||
}
|
||||
|
||||
common::iterateNestedMessages(m_descriptor, [&](const Descriptor *nestedMessage) {
|
||||
|
|
@ -158,18 +160,18 @@ void MessageDeclarationPrinter::printProperties()
|
|||
const int numFields = m_descriptor->field_count();
|
||||
for (int i = 0; i < numFields; ++i) {
|
||||
const FieldDescriptor *field = m_descriptor->field(i);
|
||||
const char *propertyTemplate = Templates::PropertyTemplate();
|
||||
const char *propertyTemplate = CommonTemplates::PropertyTemplate();
|
||||
if (common::isPureMessage(field)) {
|
||||
propertyTemplate = Templates::PropertyMessageTemplate();
|
||||
propertyTemplate = CommonTemplates::PropertyMessageTemplate();
|
||||
} else if (common::hasQmlAlias(field)) {
|
||||
propertyTemplate = Templates::PropertyNonScriptableTemplate();
|
||||
propertyTemplate = CommonTemplates::PropertyNonScriptableTemplate();
|
||||
} else if (field->is_repeated() && !field->is_map()) {
|
||||
// Non-message list properties don't require an extra QQmlListProperty to access
|
||||
// their data, so the property name should not contain the 'Data' suffix
|
||||
if (field->type() == FieldDescriptor::TYPE_MESSAGE)
|
||||
propertyTemplate = Templates::PropertyRepeatedMessageTemplate();
|
||||
propertyTemplate = CommonTemplates::PropertyRepeatedMessageTemplate();
|
||||
else
|
||||
propertyTemplate = Templates::PropertyRepeatedTemplate();
|
||||
propertyTemplate = CommonTemplates::PropertyRepeatedTemplate();
|
||||
}
|
||||
m_printer->Print(common::producePropertyMap(field, m_descriptor), propertyTemplate);
|
||||
}
|
||||
|
|
@ -180,10 +182,10 @@ void MessageDeclarationPrinter::printProperties()
|
|||
if (field->type() == FieldDescriptor::TYPE_MESSAGE && field->is_repeated()
|
||||
&& !field->is_map() && Options::instance().hasQml()) {
|
||||
m_printer->Print(common::producePropertyMap(field, m_descriptor),
|
||||
Templates::PropertyQmlListTemplate());
|
||||
CommonTemplates::PropertyQmlListTemplate());
|
||||
} else if (common::hasQmlAlias(field)) {
|
||||
m_printer->Print(common::producePropertyMap(field, m_descriptor),
|
||||
Templates::PropertyNonScriptableAliasTemplate());
|
||||
CommonTemplates::PropertyNonScriptableAliasTemplate());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -197,16 +199,17 @@ void MessageDeclarationPrinter::printGetters()
|
|||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
printComments(field);
|
||||
m_printer->Print("\n");
|
||||
if (common::isPureMessage(field))
|
||||
m_printer->Print(propertyMap, Templates::GetterMessageDeclarationTemplate());
|
||||
else
|
||||
m_printer->Print(propertyMap, Templates::GetterTemplate());
|
||||
m_printer->Print(propertyMap,
|
||||
common::isPureMessage(field) ?
|
||||
CommonTemplates::GetterMessageDeclarationTemplate() :
|
||||
CommonTemplates::GetterTemplate());
|
||||
|
||||
if (field->is_repeated()) {
|
||||
m_printer->Print(propertyMap, Templates::GetterComplexTemplate());
|
||||
m_printer->Print(propertyMap, CommonTemplates::GetterComplexTemplate());
|
||||
if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map()
|
||||
&& Options::instance().hasQml()) {
|
||||
m_printer->Print(propertyMap, Templates::GetterQmlListDeclarationTemplate());
|
||||
m_printer->Print(propertyMap,
|
||||
CommonTemplates::GetterQmlListDeclarationTemplate());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -220,19 +223,21 @@ void MessageDeclarationPrinter::printSetters()
|
|||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
switch (field->type()) {
|
||||
case FieldDescriptor::TYPE_MESSAGE:
|
||||
if (!field->is_map() && !field->is_repeated() && !common::isQtType(field))
|
||||
if (!field->is_map() && !field->is_repeated() && !common::isQtType(field)) {
|
||||
m_printer->Print(propertyMap,
|
||||
Templates::SetterMessageDeclarationTemplate());
|
||||
else
|
||||
CommonTemplates::SetterMessageDeclarationTemplate());
|
||||
} else {
|
||||
m_printer->Print(propertyMap,
|
||||
Templates::SetterComplexDeclarationTemplate());
|
||||
CommonTemplates::SetterComplexDeclarationTemplate());
|
||||
}
|
||||
break;
|
||||
case FieldDescriptor::FieldDescriptor::TYPE_STRING:
|
||||
case FieldDescriptor::FieldDescriptor::TYPE_BYTES:
|
||||
m_printer->Print(propertyMap, Templates::SetterComplexDeclarationTemplate());
|
||||
m_printer->Print(propertyMap,
|
||||
CommonTemplates::SetterComplexDeclarationTemplate());
|
||||
break;
|
||||
default:
|
||||
m_printer->Print(propertyMap, Templates::SetterTemplate());
|
||||
m_printer->Print(propertyMap, CommonTemplates::SetterTemplate());
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
|
@ -244,9 +249,10 @@ void MessageDeclarationPrinter::printPrivateGetters()
|
|||
Indent();
|
||||
common::iterateMessageFields(
|
||||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
if (common::isPureMessage(field))
|
||||
if (common::isPureMessage(field)) {
|
||||
m_printer->Print(propertyMap,
|
||||
Templates::PrivateGetterMessageDeclarationTemplate());
|
||||
CommonTemplates::PrivateGetterMessageDeclarationTemplate());
|
||||
}
|
||||
});
|
||||
Outdent();
|
||||
}
|
||||
|
|
@ -256,9 +262,10 @@ void MessageDeclarationPrinter::printPrivateSetters()
|
|||
Indent();
|
||||
common::iterateMessageFields(
|
||||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
if (common::isPureMessage(field))
|
||||
if (common::isPureMessage(field)) {
|
||||
m_printer->Print(propertyMap,
|
||||
Templates::PrivateSetterMessageDeclarationTemplate());
|
||||
CommonTemplates::PrivateSetterMessageDeclarationTemplate());
|
||||
}
|
||||
});
|
||||
Outdent();
|
||||
}
|
||||
|
|
@ -269,8 +276,8 @@ void MessageDeclarationPrinter::printPrivateMethods()
|
|||
common::iterateMessageFields(
|
||||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
if (common::hasQmlAlias(field)) {
|
||||
m_printer->Print(propertyMap, Templates::GetterNonScriptableTemplate());
|
||||
m_printer->Print(propertyMap, Templates::SetterNonScriptableTemplate());
|
||||
m_printer->Print(propertyMap, CommonTemplates::GetterNonScriptableTemplate());
|
||||
m_printer->Print(propertyMap, CommonTemplates::SetterNonScriptableTemplate());
|
||||
}
|
||||
});
|
||||
Outdent();
|
||||
|
|
@ -289,24 +296,24 @@ void MessageDeclarationPrinter::printQEnums()
|
|||
for (int i = 0; i < m_descriptor->enum_type_count(); ++i) {
|
||||
const auto *enumDescr = m_descriptor->enum_type(i);
|
||||
auto typeMap = common::produceEnumTypeMap(enumDescr, m_descriptor);
|
||||
m_printer->Print(typeMap, Templates::EnumDefinitionTemplate());
|
||||
m_printer->Print(typeMap, CommonTemplates::EnumDefinitionTemplate());
|
||||
|
||||
Indent();
|
||||
for (int j = 0; j < enumDescr->value_count(); ++j) {
|
||||
const auto *valueDescr = enumDescr->value(j);
|
||||
m_printer->Print({ { "enumvalue", utils::capitalizeAsciiName(valueDescr->name()) },
|
||||
{ "value", std::to_string(valueDescr->number()) } },
|
||||
Templates::EnumFieldTemplate());
|
||||
CommonTemplates::EnumFieldTemplate());
|
||||
}
|
||||
Outdent();
|
||||
m_printer->Print(Templates::SemicolonBlockEnclosureTemplate());
|
||||
m_printer->Print(typeMap, Templates::QEnumTemplate());
|
||||
m_printer->Print(CommonTemplates::SemicolonBlockEnclosureTemplate());
|
||||
m_printer->Print(typeMap, CommonTemplates::QEnumTemplate());
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_descriptor->enum_type_count(); ++i) {
|
||||
const auto *enumDescr = m_descriptor->enum_type(i);
|
||||
auto typeMap = common::produceEnumTypeMap(enumDescr, m_descriptor);
|
||||
m_printer->Print(typeMap, Templates::UsingRepeatedEnumTemplate());
|
||||
m_printer->Print(typeMap, CommonTemplates::UsingRepeatedEnumTemplate());
|
||||
}
|
||||
Outdent();
|
||||
}
|
||||
|
|
@ -334,7 +341,7 @@ void MessageDeclarationPrinter::printClassBody()
|
|||
printSetters();
|
||||
|
||||
Indent();
|
||||
m_printer->Print(m_typeMap, Templates::MetaTypeRegistrationDeclaration());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::MetaTypeRegistrationDeclaration());
|
||||
Outdent();
|
||||
|
||||
printPrivateBlock();
|
||||
|
|
@ -351,11 +358,11 @@ void MessageDeclarationPrinter::printClassMembers()
|
|||
common::iterateMessageFields(
|
||||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
if (common::isPureMessage(field)) {
|
||||
m_printer->Print(propertyMap, Templates::MemberMessageTemplate());
|
||||
m_printer->Print(propertyMap, CommonTemplates::MemberMessageTemplate());
|
||||
} else if (field->is_repeated() && !field->is_map()) {
|
||||
m_printer->Print(propertyMap, Templates::MemberRepeatedTemplate());
|
||||
m_printer->Print(propertyMap, CommonTemplates::MemberRepeatedTemplate());
|
||||
} else {
|
||||
m_printer->Print(propertyMap, Templates::MemberTemplate());
|
||||
m_printer->Print(propertyMap, CommonTemplates::MemberTemplate());
|
||||
}
|
||||
});
|
||||
Outdent();
|
||||
|
|
@ -363,22 +370,24 @@ void MessageDeclarationPrinter::printClassMembers()
|
|||
|
||||
void MessageDeclarationPrinter::printDestructor()
|
||||
{
|
||||
m_printer->Print(m_typeMap, Templates::DestructorMessageDeclarationTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::DestructorMessageDeclarationTemplate());
|
||||
}
|
||||
|
||||
void MessageDeclarationPrinter::printFieldEnum()
|
||||
{
|
||||
if (m_descriptor->field_count() > 0) {
|
||||
Indent();
|
||||
m_printer->Print(Templates::FieldEnumTemplate());
|
||||
m_printer->Print(CommonTemplates::FieldEnumTemplate());
|
||||
Indent();
|
||||
common::iterateMessageFields(m_descriptor,
|
||||
[&](const FieldDescriptor *, const PropertyMap &propertyMap) {
|
||||
m_printer->Print(propertyMap, Templates::FieldNumberTemplate());
|
||||
m_printer->Print(propertyMap,
|
||||
CommonTemplates::FieldNumberTemplate());
|
||||
});
|
||||
Outdent();
|
||||
m_printer->Print(Templates::SemicolonBlockEnclosureTemplate());
|
||||
m_printer->Print({ { "type", Templates::QtProtobufFieldEnum() } }, Templates::QEnumTemplate());
|
||||
m_printer->Print(CommonTemplates::SemicolonBlockEnclosureTemplate());
|
||||
m_printer->Print({ { "type", CommonTemplates::QtProtobufFieldEnum() } },
|
||||
CommonTemplates::QEnumTemplate());
|
||||
Outdent();
|
||||
m_printer->Print("\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@
|
|||
|
||||
#include "descriptorprinterbase.h"
|
||||
|
||||
namespace QtProtobuf::generator {
|
||||
namespace QtProtobuf {
|
||||
|
||||
class MessageDeclarationPrinter final : public DescriptorPrinterBase<google::protobuf::Descriptor>
|
||||
class MessageDeclarationPrinter final
|
||||
: public qtprotoccommon::DescriptorPrinterBase<google::protobuf::Descriptor>
|
||||
{
|
||||
public:
|
||||
explicit MessageDeclarationPrinter(const ::google::protobuf::Descriptor *message,
|
||||
|
|
@ -45,6 +46,7 @@ private:
|
|||
void printClassDeclarationPrivate();
|
||||
void printClassForwardDeclarationPrivate();
|
||||
};
|
||||
} // namespace QtProtobuf::generator
|
||||
|
||||
} // namespace QtProtobuf
|
||||
|
||||
#endif // MESSAGEDECLARATIONPRINTER_H
|
||||
|
|
|
|||
|
|
@ -1,17 +1,19 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>, Tatyana Borisova <tanusshhka@mail.ru>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "messagedefinitionprinter.h"
|
||||
|
||||
#include "generatorcommon.h"
|
||||
#include "options.h"
|
||||
#include "templates.h"
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include "utils.h"
|
||||
#include "options.h"
|
||||
#include "commontemplates.h"
|
||||
#include "generatorcommon.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
using namespace ::QtProtobuf::generator;
|
||||
using namespace ::QtProtobuf;
|
||||
using namespace ::qtprotoccommon;
|
||||
using namespace ::google::protobuf;
|
||||
using namespace ::google::protobuf::io;
|
||||
|
||||
|
|
@ -22,10 +24,10 @@ using namespace ::google::protobuf::io;
|
|||
|
||||
\brief Generates gRPC message class definition.
|
||||
*/
|
||||
|
||||
MessageDefinitionPrinter::MessageDefinitionPrinter(const Descriptor *message,
|
||||
std::shared_ptr<Printer> printer)
|
||||
: DescriptorPrinterBase<Descriptor>(message, std::move(printer),
|
||||
: DescriptorPrinterBase<Descriptor>(message,
|
||||
std::move(printer),
|
||||
common::produceMessageTypeMap(message, nullptr))
|
||||
{
|
||||
}
|
||||
|
|
@ -35,13 +37,13 @@ MessageDefinitionPrinter::~MessageDefinitionPrinter() = default;
|
|||
void MessageDefinitionPrinter::printClassDefinitionPrivate()
|
||||
{
|
||||
if (common::hasNestedMessages(m_descriptor)) {
|
||||
auto scopeNamespaces = common::getNestedScopeNamespace(m_typeMap["classname"]);
|
||||
m_printer->Print(scopeNamespaces, Templates::NamespaceTemplate());
|
||||
auto scopeNamespaces = qtprotoccommon::common::getNestedScopeNamespace(m_typeMap["classname"]);
|
||||
m_printer->Print(scopeNamespaces, CommonTemplates::NamespaceTemplate());
|
||||
common::iterateNestedMessages(m_descriptor, [this](const Descriptor *nestedMessage) {
|
||||
MessageDefinitionPrinter nestedPrinter(nestedMessage, m_printer);
|
||||
nestedPrinter.printClassDefinitionPrivate();
|
||||
});
|
||||
m_printer->Print(scopeNamespaces, Templates::NamespaceClosingTemplate());
|
||||
m_printer->Print(scopeNamespaces, CommonTemplates::NamespaceClosingTemplate());
|
||||
}
|
||||
|
||||
printDestructor();
|
||||
|
|
@ -63,11 +65,11 @@ void MessageDefinitionPrinter::printRegisterBody()
|
|||
{
|
||||
std::vector<std::string> registredMetaTypes;
|
||||
|
||||
m_printer->Print(m_typeMap, Templates::MetaTypeRegistrationMessageDefinition());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::MetaTypeRegistrationMessageDefinition());
|
||||
Indent();
|
||||
if (Options::instance().hasQml()) {
|
||||
m_printer->Print(m_typeMap, Templates::MetaTypeRegistrationQmlListTemplate());
|
||||
m_printer->Print(m_typeMap, Templates::QmlRegisterTypeTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::MetaTypeRegistrationQmlListTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::QmlRegisterTypeTemplate());
|
||||
}
|
||||
|
||||
common::iterateMessageFields(
|
||||
|
|
@ -83,14 +85,15 @@ void MessageDefinitionPrinter::printRegisterBody()
|
|||
if (field->type() == FieldDescriptor::TYPE_ENUM
|
||||
&& common::isLocalEnum(field->enum_type(), m_descriptor)) {
|
||||
m_printer->Print(propertyMap,
|
||||
Templates::MetaTypeRegistrationLocalEnumTemplate());
|
||||
CommonTemplates::MetaTypeRegistrationLocalEnumTemplate());
|
||||
} else if (field->is_map()) {
|
||||
m_printer->Print(propertyMap, Templates::MetaTypeRegistrationMapTemplate());
|
||||
m_printer->Print(propertyMap,
|
||||
CommonTemplates::MetaTypeRegistrationMapTemplate());
|
||||
}
|
||||
});
|
||||
|
||||
Outdent();
|
||||
m_printer->Print(Templates::SimpleBlockEnclosureTemplate());
|
||||
m_printer->Print(CommonTemplates::SimpleBlockEnclosureTemplate());
|
||||
}
|
||||
|
||||
void MessageDefinitionPrinter::printFieldsOrdering()
|
||||
|
|
@ -113,35 +116,35 @@ void MessageDefinitionPrinter::printFieldsOrdering()
|
|||
std::to_string(fieldCount * (uint_dataOffset++) + NullTerminator) },
|
||||
{ "property_index_offset",
|
||||
std::to_string(fieldCount * (uint_dataOffset++) + NullTerminator) },
|
||||
{ "field_flags_offset", std::to_string(fieldCount * (uint_dataOffset++) + NullTerminator) },
|
||||
{ "field_flags_offset", std::to_string(fieldCount * (uint_dataOffset++) + NullTerminator)},
|
||||
{ "uint_size", std::to_string(fieldCount * MetaFieldsCount + FakeJsonNameOffset) },
|
||||
{ "char_size", std::to_string(char_dataSizeTotal) },
|
||||
{ "message_full_name_size", std::to_string(metadataCharSize) },
|
||||
};
|
||||
assert(uint_dataOffset == MetaFieldsCount);
|
||||
|
||||
m_printer->Print(dataVariables, Templates::PropertyOrderingDataOpeningTemplate());
|
||||
m_printer->Print(dataVariables, CommonTemplates::PropertyOrderingDataOpeningTemplate());
|
||||
Indent();
|
||||
// uint_data
|
||||
m_printer->Print("// uint_data\n{\n");
|
||||
Indent();
|
||||
|
||||
m_printer->Print("// JSON name offsets:\n");
|
||||
printUintData(Templates::JsonNameOffsetsUintDataTemplate());
|
||||
printUintData(CommonTemplates::JsonNameOffsetsUintDataTemplate());
|
||||
// Include an extra offset which points to the end-of-string, so we can efficiently get the
|
||||
// length of all the strings by subtracting adjacent offsets:
|
||||
m_printer->Print({ { "json_name_offset", std::to_string(char_dataSizeTotal - NullTerminator) },
|
||||
{ "json_name", "end-of-string-marker" } },
|
||||
Templates::JsonNameOffsetsUintDataTemplate());
|
||||
CommonTemplates::JsonNameOffsetsUintDataTemplate());
|
||||
|
||||
m_printer->Print("// Field numbers:\n");
|
||||
printUintData(Templates::FieldNumbersUintDataTemplate());
|
||||
printUintData(CommonTemplates::FieldNumbersUintDataTemplate());
|
||||
|
||||
m_printer->Print("// Property indices:\n");
|
||||
printUintData(Templates::QtPropertyIndicesUintDataTemplate());
|
||||
printUintData(CommonTemplates::QtPropertyIndicesUintDataTemplate());
|
||||
|
||||
m_printer->Print("// Field flags:\n");
|
||||
printUintData(Templates::FieldFlagsUintDataTemplate());
|
||||
printUintData(CommonTemplates::FieldFlagsUintDataTemplate());
|
||||
|
||||
Outdent();
|
||||
m_printer->Print("},\n");
|
||||
|
|
@ -150,9 +153,9 @@ void MessageDefinitionPrinter::printFieldsOrdering()
|
|||
printCharData();
|
||||
Outdent();
|
||||
|
||||
m_printer->Print(m_typeMap, Templates::PropertyOrderingDataClosingTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::PropertyOrderingDataClosingTemplate());
|
||||
|
||||
m_printer->Print(m_typeMap, Templates::PropertyOrderingDefinitionTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::PropertyOrderingDefinitionTemplate());
|
||||
}
|
||||
|
||||
void MessageDefinitionPrinter::printUintData(const char *templateString)
|
||||
|
|
@ -214,9 +217,9 @@ size_t MessageDefinitionPrinter::charDataSize() const
|
|||
|
||||
void MessageDefinitionPrinter::printConstructors()
|
||||
{
|
||||
m_printer->Print(m_typeMap, Templates::ConstructorMessageDefinitionTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::ConstructorMessageDefinitionTemplate());
|
||||
printInitializationList();
|
||||
m_printer->Print(Templates::EmptyBracesTemplate());
|
||||
m_printer->Print(CommonTemplates::EmptyBracesTemplate());
|
||||
|
||||
if (m_descriptor->full_name() == "google.protobuf.Timestamp") {
|
||||
m_printer->Print(
|
||||
|
|
@ -270,11 +273,11 @@ void MessageDefinitionPrinter::printInitializationList()
|
|||
|
||||
if (common::isPureMessage(field)) {
|
||||
m_printer->Print(",\n");
|
||||
m_printer->Print(propertyMap, Templates::InitializerMemberMessageTemplate());
|
||||
m_printer->Print(propertyMap, CommonTemplates::InitializerMemberMessageTemplate());
|
||||
} else {
|
||||
if (!propertyMap["initializer"].empty()) {
|
||||
m_printer->Print(",\n");
|
||||
m_printer->Print(propertyMap, Templates::InitializerMemberTemplate());
|
||||
m_printer->Print(propertyMap, CommonTemplates::InitializerMemberTemplate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -284,169 +287,173 @@ void MessageDefinitionPrinter::printInitializationList()
|
|||
void MessageDefinitionPrinter::printCopyFunctionality()
|
||||
{
|
||||
assert(m_descriptor != nullptr);
|
||||
m_printer->Print(m_typeMap, Templates::CopyConstructorDefinitionTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::CopyConstructorDefinitionTemplate());
|
||||
common::iterateMessageFields(
|
||||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
if (common::isPureMessage(field)) {
|
||||
m_printer->Print(",\n");
|
||||
m_printer->Print(propertyMap, Templates::InitializerMemberMessageTemplate());
|
||||
}
|
||||
});
|
||||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
if (common::isPureMessage(field)) {
|
||||
m_printer->Print(",\n");
|
||||
m_printer->Print(propertyMap,
|
||||
CommonTemplates::InitializerMemberMessageTemplate());
|
||||
}
|
||||
});
|
||||
m_printer->Print("\n{\n");
|
||||
|
||||
Indent();
|
||||
common::iterateMessageFields(
|
||||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
if (common::isPureMessage(field)) {
|
||||
m_printer->Print(propertyMap, Templates::CopyMemberMessageTemplate());
|
||||
} else {
|
||||
m_printer->Print(propertyMap, Templates::CopyMemberTemplate());
|
||||
}
|
||||
});
|
||||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
m_printer->Print(propertyMap,
|
||||
common::isPureMessage(field) ?
|
||||
CommonTemplates::CopyMemberMessageTemplate() :
|
||||
CommonTemplates::CopyMemberTemplate());
|
||||
});
|
||||
Outdent();
|
||||
m_printer->Print(Templates::SimpleBlockEnclosureTemplate());
|
||||
m_printer->Print(CommonTemplates::SimpleBlockEnclosureTemplate());
|
||||
|
||||
m_printer->Print(m_typeMap, Templates::AssignmentOperatorDefinitionTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::AssignmentOperatorDefinitionTemplate());
|
||||
Indent();
|
||||
common::iterateMessageFields(
|
||||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
if (common::isPureMessage(field)) {
|
||||
m_printer->Print(propertyMap, Templates::AssignMemberMessageTemplate());
|
||||
} else {
|
||||
m_printer->Print(propertyMap, Templates::CopyMemberTemplate());
|
||||
}
|
||||
});
|
||||
m_printer->Print(Templates::AssignmentOperatorReturnTemplate());
|
||||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
m_printer->Print(propertyMap,
|
||||
common::isPureMessage(field) ?
|
||||
CommonTemplates::AssignMemberMessageTemplate() :
|
||||
CommonTemplates::CopyMemberTemplate());
|
||||
});
|
||||
m_printer->Print(CommonTemplates::AssignmentOperatorReturnTemplate());
|
||||
Outdent();
|
||||
m_printer->Print(Templates::SimpleBlockEnclosureTemplate());
|
||||
m_printer->Print(CommonTemplates::SimpleBlockEnclosureTemplate());
|
||||
}
|
||||
|
||||
void MessageDefinitionPrinter::printMoveSemantic()
|
||||
{
|
||||
assert(m_descriptor != nullptr);
|
||||
m_printer->Print(m_typeMap, Templates::MoveConstructorDefinitionTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::MoveConstructorDefinitionTemplate());
|
||||
common::iterateMessageFields(
|
||||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
if (common::isPureMessage(field)) {
|
||||
m_printer->Print(",\n");
|
||||
m_printer->Print(propertyMap, Templates::InitializerMemberMessageTemplate());
|
||||
}
|
||||
});
|
||||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
if (common::isPureMessage(field)) {
|
||||
m_printer->Print(",\n");
|
||||
m_printer->Print(propertyMap,
|
||||
CommonTemplates::InitializerMemberMessageTemplate());
|
||||
}
|
||||
});
|
||||
m_printer->Print("\n{\n");
|
||||
|
||||
Indent();
|
||||
common::iterateMessageFields(
|
||||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
if (field->type() == FieldDescriptor::TYPE_MESSAGE
|
||||
|| field->type() == FieldDescriptor::TYPE_STRING
|
||||
|| field->type() == FieldDescriptor::TYPE_BYTES || field->is_repeated()) {
|
||||
if (common::isPureMessage(field)) {
|
||||
m_printer->Print(propertyMap, Templates::MoveMemberMessageTemplate());
|
||||
} else {
|
||||
m_printer->Print(propertyMap,
|
||||
Templates::MoveConstructorMemberComplexTemplate());
|
||||
}
|
||||
} else {
|
||||
if (field->type() != FieldDescriptor::TYPE_ENUM) {
|
||||
m_printer->Print(propertyMap, Templates::MoveMemberTemplate());
|
||||
} else {
|
||||
m_printer->Print(propertyMap, Templates::MoveMemberEnumTemplate());
|
||||
}
|
||||
}
|
||||
});
|
||||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
if (field->type() == FieldDescriptor::TYPE_MESSAGE
|
||||
|| field->type() == FieldDescriptor::TYPE_STRING
|
||||
|| field->type() == FieldDescriptor::TYPE_BYTES || field->is_repeated()) {
|
||||
m_printer->Print(propertyMap,
|
||||
common::isPureMessage(field) ?
|
||||
CommonTemplates::MoveMemberMessageTemplate() :
|
||||
CommonTemplates::MoveConstructorMemberComplexTemplate());
|
||||
} else {
|
||||
m_printer->Print(propertyMap,
|
||||
(field->type() != FieldDescriptor::TYPE_ENUM) ?
|
||||
CommonTemplates::MoveMemberTemplate() :
|
||||
CommonTemplates::MoveMemberEnumTemplate());
|
||||
}
|
||||
});
|
||||
Outdent();
|
||||
m_printer->Print(Templates::SimpleBlockEnclosureTemplate());
|
||||
m_printer->Print(CommonTemplates::SimpleBlockEnclosureTemplate());
|
||||
|
||||
m_printer->Print(m_typeMap, Templates::MoveAssignmentOperatorDefinitionTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::MoveAssignmentOperatorDefinitionTemplate());
|
||||
Indent();
|
||||
common::iterateMessageFields(
|
||||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
if (field->type() == FieldDescriptor::TYPE_MESSAGE
|
||||
|| field->type() == FieldDescriptor::TYPE_STRING
|
||||
|| field->type() == FieldDescriptor::TYPE_BYTES || field->is_repeated()) {
|
||||
if (common::isPureMessage(field)) {
|
||||
m_printer->Print(propertyMap, Templates::MoveAssignMemberMessageTemplate());
|
||||
} else {
|
||||
m_printer->Print(propertyMap, Templates::MoveAssignMemberComplexTemplate());
|
||||
}
|
||||
} else {
|
||||
if (field->type() != FieldDescriptor::TYPE_ENUM) {
|
||||
m_printer->Print(propertyMap, Templates::MoveMemberTemplate());
|
||||
} else {
|
||||
m_printer->Print(propertyMap, Templates::MoveMemberEnumTemplate());
|
||||
}
|
||||
}
|
||||
});
|
||||
m_printer->Print(Templates::AssignmentOperatorReturnTemplate());
|
||||
m_descriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
|
||||
if (field->type() == FieldDescriptor::TYPE_MESSAGE
|
||||
|| field->type() == FieldDescriptor::TYPE_STRING
|
||||
|| field->type() == FieldDescriptor::TYPE_BYTES || field->is_repeated()) {
|
||||
m_printer->Print(propertyMap,
|
||||
common::isPureMessage(field) ?
|
||||
CommonTemplates::MoveAssignMemberMessageTemplate() :
|
||||
CommonTemplates::MoveAssignMemberComplexTemplate());
|
||||
} else {
|
||||
m_printer->Print(propertyMap,
|
||||
(field->type() != FieldDescriptor::TYPE_ENUM) ?
|
||||
CommonTemplates::MoveMemberTemplate() :
|
||||
CommonTemplates::MoveMemberEnumTemplate());
|
||||
}
|
||||
});
|
||||
m_printer->Print(CommonTemplates::AssignmentOperatorReturnTemplate());
|
||||
Outdent();
|
||||
m_printer->Print(Templates::SimpleBlockEnclosureTemplate());
|
||||
m_printer->Print(CommonTemplates::SimpleBlockEnclosureTemplate());
|
||||
}
|
||||
|
||||
void MessageDefinitionPrinter::printComparisonOperators()
|
||||
{
|
||||
assert(m_descriptor != nullptr);
|
||||
|
||||
m_printer->Print(m_typeMap, Templates::EqualOperatorDefinitionTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::EqualOperatorDefinitionTemplate());
|
||||
|
||||
Indent();
|
||||
Indent();
|
||||
common::iterateMessageFields(
|
||||
m_descriptor, [&](const FieldDescriptor *field, PropertyMap &propertyMap) {
|
||||
m_printer->Print("\n&& ");
|
||||
if (common::isPureMessage(field)) {
|
||||
m_printer->Print(propertyMap, Templates::EqualOperatorMemberMessageTemplate());
|
||||
} else if (field->type() == FieldDescriptor::TYPE_MESSAGE && field->is_repeated()) {
|
||||
m_printer->Print(propertyMap, Templates::EqualOperatorMemberRepeatedTemplate());
|
||||
} else {
|
||||
m_printer->Print(propertyMap, Templates::EqualOperatorMemberTemplate());
|
||||
}
|
||||
});
|
||||
m_descriptor, [&](const FieldDescriptor *field, PropertyMap &propertyMap) {
|
||||
m_printer->Print("\n&& ");
|
||||
if (common::isPureMessage(field)) {
|
||||
m_printer->Print(propertyMap,
|
||||
CommonTemplates::EqualOperatorMemberMessageTemplate());
|
||||
} else if (field->type() == FieldDescriptor::TYPE_MESSAGE
|
||||
&& field->is_repeated()) {
|
||||
m_printer->Print(propertyMap,
|
||||
CommonTemplates::EqualOperatorMemberRepeatedTemplate());
|
||||
} else {
|
||||
m_printer->Print(propertyMap,
|
||||
CommonTemplates::EqualOperatorMemberTemplate());
|
||||
}
|
||||
});
|
||||
Outdent();
|
||||
Outdent();
|
||||
|
||||
m_printer->Print(";\n");
|
||||
m_printer->Print(Templates::SimpleBlockEnclosureTemplate());
|
||||
m_printer->Print(CommonTemplates::SimpleBlockEnclosureTemplate());
|
||||
|
||||
m_printer->Print(m_typeMap, Templates::NotEqualOperatorDefinitionTemplate());
|
||||
m_printer->Print(m_typeMap, CommonTemplates::NotEqualOperatorDefinitionTemplate());
|
||||
}
|
||||
|
||||
void MessageDefinitionPrinter::printGetters()
|
||||
{
|
||||
common::iterateMessageFields(
|
||||
m_descriptor, [&](const FieldDescriptor *field, PropertyMap &propertyMap) {
|
||||
if (common::isPureMessage(field)) {
|
||||
m_printer->Print(propertyMap,
|
||||
Templates::PrivateGetterMessageDefinitionTemplate());
|
||||
m_printer->Print(propertyMap, Templates::GetterMessageDefinitionTemplate());
|
||||
}
|
||||
if (field->is_repeated()) {
|
||||
if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map()
|
||||
&& !common::isQtType(field) && Options::instance().hasQml()) {
|
||||
m_printer->Print(propertyMap, Templates::GetterQmlListDefinitionTemplate());
|
||||
}
|
||||
}
|
||||
});
|
||||
m_descriptor, [&](const FieldDescriptor *field, PropertyMap &propertyMap) {
|
||||
if (common::isPureMessage(field)) {
|
||||
m_printer->Print(propertyMap,
|
||||
CommonTemplates::PrivateGetterMessageDefinitionTemplate());
|
||||
m_printer->Print(propertyMap,
|
||||
CommonTemplates::GetterMessageDefinitionTemplate());
|
||||
}
|
||||
if (field->is_repeated()) {
|
||||
if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map()
|
||||
&& !common::isQtType(field) && Options::instance().hasQml()) {
|
||||
m_printer->Print(propertyMap,
|
||||
CommonTemplates::GetterQmlListDefinitionTemplate());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
common::iterateMessageFields(
|
||||
m_descriptor, [&](const FieldDescriptor *field, PropertyMap &propertyMap) {
|
||||
switch (field->type()) {
|
||||
case FieldDescriptor::TYPE_MESSAGE:
|
||||
if (!field->is_map() && !field->is_repeated() && !common::isQtType(field)) {
|
||||
m_printer->Print(propertyMap,
|
||||
Templates::PrivateSetterMessageDefinitionTemplate());
|
||||
m_printer->Print(propertyMap, Templates::SetterMessageDefinitionTemplate());
|
||||
} else {
|
||||
m_printer->Print(propertyMap, Templates::SetterComplexDefinitionTemplate());
|
||||
}
|
||||
break;
|
||||
case FieldDescriptor::FieldDescriptor::TYPE_STRING:
|
||||
case FieldDescriptor::FieldDescriptor::TYPE_BYTES:
|
||||
m_printer->Print(propertyMap, Templates::SetterComplexDefinitionTemplate());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
m_descriptor, [&](const FieldDescriptor *field, PropertyMap &propertyMap) {
|
||||
switch (field->type()) {
|
||||
case FieldDescriptor::TYPE_MESSAGE:
|
||||
if (!field->is_map() && !field->is_repeated() && !common::isQtType(field)) {
|
||||
m_printer->Print(propertyMap,
|
||||
CommonTemplates::PrivateSetterMessageDefinitionTemplate());
|
||||
m_printer->Print(propertyMap,
|
||||
CommonTemplates::SetterMessageDefinitionTemplate());
|
||||
} else {
|
||||
m_printer->Print(propertyMap,
|
||||
CommonTemplates::SetterComplexDefinitionTemplate());
|
||||
}
|
||||
break;
|
||||
case FieldDescriptor::FieldDescriptor::TYPE_STRING:
|
||||
case FieldDescriptor::FieldDescriptor::TYPE_BYTES:
|
||||
m_printer->Print(propertyMap,
|
||||
CommonTemplates::SetterComplexDefinitionTemplate());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MessageDefinitionPrinter::printDestructor()
|
||||
|
|
@ -458,15 +465,14 @@ void MessageDefinitionPrinter::printClassRegistration(Printer *printer)
|
|||
{
|
||||
if (common::hasNestedMessages(m_descriptor)) {
|
||||
auto scopeNamespaces = common::getNestedScopeNamespace(m_typeMap["classname"]);
|
||||
printer->Print(scopeNamespaces, Templates::NamespaceTemplate());
|
||||
common::iterateNestedMessages(m_descriptor,
|
||||
[this, &printer](const Descriptor *nestedMessage) {
|
||||
MessageDefinitionPrinter nestedPrinter(nestedMessage,
|
||||
m_printer);
|
||||
nestedPrinter.printClassRegistration(printer);
|
||||
});
|
||||
printer->Print(scopeNamespaces, Templates::NamespaceClosingTemplate());
|
||||
printer->Print(scopeNamespaces, CommonTemplates::NamespaceTemplate());
|
||||
common::iterateNestedMessages(
|
||||
m_descriptor, [this, &printer](const Descriptor *nestedMessage) {
|
||||
MessageDefinitionPrinter nestedPrinter(nestedMessage, m_printer);
|
||||
nestedPrinter.printClassRegistration(printer);
|
||||
});
|
||||
printer->Print(scopeNamespaces, CommonTemplates::NamespaceClosingTemplate());
|
||||
}
|
||||
|
||||
printer->Print(m_typeMap, Templates::RegistrarTemplate());
|
||||
printer->Print(m_typeMap, CommonTemplates::RegistrarTemplate());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,10 @@
|
|||
|
||||
#include "descriptorprinterbase.h"
|
||||
|
||||
#include <stddef.h>
|
||||
namespace QtProtobuf {
|
||||
|
||||
namespace QtProtobuf::generator {
|
||||
|
||||
class MessageDefinitionPrinter final : public DescriptorPrinterBase<google::protobuf::Descriptor>
|
||||
class MessageDefinitionPrinter final
|
||||
: public qtprotoccommon::DescriptorPrinterBase<google::protobuf::Descriptor>
|
||||
{
|
||||
public:
|
||||
explicit MessageDefinitionPrinter(const google::protobuf::Descriptor *message,
|
||||
|
|
@ -40,5 +39,5 @@ private:
|
|||
void printClassDefinitionPrivate();
|
||||
};
|
||||
|
||||
} // namespace QtProtobuf::generator
|
||||
} // namespace QtProtobuf
|
||||
#endif // MESSAGEDEFINITIONPRINTER_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,219 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "qprotobufgenerator.h"
|
||||
#include "enumdeclarationprinter.h"
|
||||
#include "enumdefinitionprinter.h"
|
||||
#include "messagedeclarationprinter.h"
|
||||
#include "messagedefinitionprinter.h"
|
||||
|
||||
#include "commontemplates.h"
|
||||
#include "utils.h"
|
||||
#include "options.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <array>
|
||||
#include <numeric>
|
||||
#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>
|
||||
|
||||
using namespace ::QtProtobuf;
|
||||
using namespace ::qtprotoccommon;
|
||||
using namespace ::google::protobuf;
|
||||
using namespace ::google::protobuf::io;
|
||||
using namespace ::google::protobuf::compiler;
|
||||
|
||||
QProtobufGenerator::QProtobufGenerator() : GeneratorBase()
|
||||
{}
|
||||
|
||||
QProtobufGenerator::~QProtobufGenerator() = default;
|
||||
|
||||
bool QProtobufGenerator::Generate(const FileDescriptor *file,
|
||||
[[maybe_unused]] const std::string ¶meter,
|
||||
GeneratorContext *generatorContext,
|
||||
std::string *error) const
|
||||
{
|
||||
assert(file != nullptr && generatorContext != nullptr);
|
||||
|
||||
if (file->syntax() != FileDescriptor::SYNTAX_PROTO3) {
|
||||
*error = "Invalid proto used. qtprotobufgen only supports 'proto3' syntax";
|
||||
return false;
|
||||
}
|
||||
|
||||
return GenerateMessages(file, generatorContext);
|
||||
}
|
||||
|
||||
void QProtobufGenerator::GenerateSources(const FileDescriptor *file,
|
||||
GeneratorContext *generatorContext) const
|
||||
{
|
||||
assert(file != nullptr && generatorContext != nullptr);
|
||||
|
||||
std::string filename = utils::extractFileBasename(file->name());
|
||||
std::string basename = generateBaseName(file, filename);
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> sourceStream(
|
||||
generatorContext->Open(basename + CommonTemplates::ProtoFileSuffix() + ".cpp"));
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> registrationStream(
|
||||
generatorContext->Open(basename + "_protobuftyperegistrations.cpp"));
|
||||
|
||||
std::shared_ptr<Printer> sourcePrinter(new Printer(sourceStream.get(), '$'));
|
||||
std::shared_ptr<Printer> registrationPrinter(new Printer(registrationStream.get(), '$'));
|
||||
|
||||
printDisclaimer(sourcePrinter.get());
|
||||
sourcePrinter->Print({{"include", basename + CommonTemplates::ProtoFileSuffix()}},
|
||||
CommonTemplates::InternalIncludeTemplate());
|
||||
|
||||
std::array<std::string, 2> registrationPrinterExternalIncludes {"QProtobufSerializer",
|
||||
"array"};
|
||||
for (const auto &include : registrationPrinterExternalIncludes) {
|
||||
registrationPrinter->Print({{"include", include}},
|
||||
CommonTemplates::ExternalIncludeTemplate());
|
||||
}
|
||||
registrationPrinter->Print({{"include", basename + CommonTemplates::ProtoFileSuffix()}},
|
||||
CommonTemplates::InternalIncludeTemplate());
|
||||
|
||||
sourcePrinter->Print({{"include", "QProtobufSerializer"}},
|
||||
CommonTemplates::ExternalIncludeTemplate());
|
||||
if (Options::instance().hasQml()) {
|
||||
sourcePrinter->Print({{"include", "QQmlEngine"}},
|
||||
CommonTemplates::ExternalIncludeTemplate());
|
||||
}
|
||||
|
||||
OpenFileNamespaces(file, sourcePrinter.get());
|
||||
OpenFileNamespaces(file, registrationPrinter.get());
|
||||
|
||||
for (int i = 0; i < file->enum_type_count(); ++i) {
|
||||
EnumDefinitionPrinter enumSourceDef(file->enum_type(i), sourcePrinter);
|
||||
enumSourceDef.run();
|
||||
}
|
||||
|
||||
common::iterateMessages(
|
||||
file,
|
||||
[&sourcePrinter, ®istrationPrinter](const Descriptor *message) {
|
||||
MessageDefinitionPrinter messageDef(message, sourcePrinter);
|
||||
messageDef.printClassDefinition();
|
||||
messageDef.printClassRegistration(registrationPrinter.get());
|
||||
});
|
||||
|
||||
CloseFileNamespaces(file, registrationPrinter.get());
|
||||
CloseFileNamespaces(file, sourcePrinter.get());
|
||||
|
||||
// Include the moc file:
|
||||
sourcePrinter->Print({{"source_file", filename + CommonTemplates::ProtoFileSuffix()}},
|
||||
"#include \"moc_$source_file$.cpp\"\n");
|
||||
|
||||
}
|
||||
|
||||
void QProtobufGenerator::GenerateHeader(const FileDescriptor *file,
|
||||
GeneratorContext *generatorContext) const
|
||||
{
|
||||
assert(file != nullptr && generatorContext != nullptr);
|
||||
|
||||
std::string filename = utils::extractFileBasename(file->name());
|
||||
std::string basename = generateBaseName(file, filename);
|
||||
std::set<std::string> internalIncludes;
|
||||
std::set<std::string> externalIncludes;
|
||||
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> headerStream(
|
||||
generatorContext->Open(basename
|
||||
+ CommonTemplates::ProtoFileSuffix() + ".h"));
|
||||
std::shared_ptr<Printer> headerPrinter(new Printer(headerStream.get(), '$'));
|
||||
|
||||
printDisclaimer(headerPrinter.get());
|
||||
headerPrinter->Print({{"filename", filename}}, CommonTemplates::PreambleTemplate());
|
||||
|
||||
headerPrinter->Print(CommonTemplates::DefaultProtobufIncludesTemplate());
|
||||
if (Options::instance().hasQml()) {
|
||||
headerPrinter->Print(CommonTemplates::QmlProtobufIncludesTemplate());
|
||||
}
|
||||
|
||||
externalIncludes.insert("QByteArray");
|
||||
externalIncludes.insert("QString");
|
||||
|
||||
bool hasQtTypes = false;
|
||||
common::iterateMessages(file, [&externalIncludes, &hasQtTypes](const Descriptor *message) {
|
||||
for (int i = 0; i < message->field_count(); ++i) {
|
||||
const auto *field = message->field(i);
|
||||
if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map()
|
||||
&& !field->is_repeated() && common::isQtType(field)) {
|
||||
externalIncludes.insert(field->message_type()->name());
|
||||
hasQtTypes = true;
|
||||
}
|
||||
}
|
||||
if (message->full_name() == "google.protobuf.Timestamp") {
|
||||
externalIncludes.insert("QDateTime");
|
||||
}
|
||||
});
|
||||
|
||||
if (hasQtTypes) {
|
||||
externalIncludes.insert("QtProtobufQtTypes");
|
||||
}
|
||||
|
||||
for (int i = 0; i < file->dependency_count(); ++i) {
|
||||
if (file->dependency(i)->name() == "QtProtobuf/QtCore.proto"
|
||||
|| file->dependency(i)->name() == "QtProtobuf/QtGui.proto") {
|
||||
continue;
|
||||
}
|
||||
internalIncludes.insert(utils::removeFileSuffix(file->dependency(i)->name())
|
||||
+ CommonTemplates::ProtoFileSuffix());
|
||||
}
|
||||
|
||||
for (const auto &include : externalIncludes) {
|
||||
headerPrinter->Print({{"include", include}}, CommonTemplates::ExternalIncludeTemplate());
|
||||
}
|
||||
|
||||
for (const auto &include : internalIncludes) {
|
||||
headerPrinter->Print({{"include", include}}, CommonTemplates::InternalIncludeTemplate());
|
||||
}
|
||||
|
||||
headerPrinter->PrintRaw("\n");
|
||||
if (!Options::instance().exportMacro().empty()) {
|
||||
headerPrinter->Print({ { "export_macro", Options::instance().exportMacro() } },
|
||||
CommonTemplates::ExportMacroTemplate());
|
||||
}
|
||||
OpenFileNamespaces(file, headerPrinter.get());
|
||||
|
||||
for (int i = 0; i < file->enum_type_count(); ++i) {
|
||||
EnumDeclarationPrinter enumDecl(file->enum_type(i), headerPrinter);
|
||||
enumDecl.run();
|
||||
}
|
||||
|
||||
common::iterateMessages(file, [&headerPrinter](const Descriptor *message) {
|
||||
MessageDeclarationPrinter messageDecl(message, headerPrinter);
|
||||
messageDecl.printClassForwardDeclaration();
|
||||
});
|
||||
|
||||
common::iterateMessages(
|
||||
file,
|
||||
[&headerPrinter](const Descriptor *message) {
|
||||
MessageDeclarationPrinter messageDecl(message, headerPrinter);
|
||||
messageDecl.printClassDeclaration();
|
||||
});
|
||||
|
||||
CloseFileNamespaces(file, headerPrinter.get());
|
||||
|
||||
common::iterateMessages(file, [&headerPrinter](const Descriptor *message) {
|
||||
MessageDeclarationPrinter messageDef(message, headerPrinter);
|
||||
messageDef.printMetaTypesDeclaration();
|
||||
});
|
||||
|
||||
headerPrinter->Print({{"filename", filename}}, CommonTemplates::FooterTemplate());
|
||||
}
|
||||
|
||||
bool QProtobufGenerator::GenerateMessages(const FileDescriptor *file,
|
||||
GeneratorContext *generatorContext) const
|
||||
{
|
||||
assert(file != nullptr && generatorContext != nullptr);
|
||||
|
||||
if (file->message_type_count() <= 0 && file->enum_type_count() <= 0) {
|
||||
return false;
|
||||
}
|
||||
GenerateHeader(file, generatorContext);
|
||||
GenerateSources(file, generatorContext);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef QPROTOBUFGENERATOR_H
|
||||
#define QPROTOBUFGENERATOR_H
|
||||
|
||||
#include "generatorbase.h"
|
||||
|
||||
namespace google::protobuf {
|
||||
class FileDescriptor;
|
||||
class Descriptor;
|
||||
namespace compiler {
|
||||
class GeneratorContext;
|
||||
} // namespace compiler
|
||||
} // namespace google::protobuf
|
||||
|
||||
namespace QtProtobuf {
|
||||
class QProtobufGenerator : public qtprotoccommon::GeneratorBase
|
||||
{
|
||||
public:
|
||||
QProtobufGenerator();
|
||||
~QProtobufGenerator();
|
||||
bool Generate(const ::google::protobuf::FileDescriptor *file,
|
||||
const std::string ¶meter,
|
||||
::google::protobuf::compiler::GeneratorContext *generatorContext,
|
||||
std::string *error) const override;
|
||||
private:
|
||||
bool GenerateMessages(const ::google::protobuf::FileDescriptor *file,
|
||||
::google::protobuf::compiler::GeneratorContext *generatorContext) const;
|
||||
void GenerateHeader(const ::google::protobuf::FileDescriptor *file,
|
||||
::google::protobuf::compiler::GeneratorContext *generatorContext) const;
|
||||
void GenerateSources(const ::google::protobuf::FileDescriptor *file,
|
||||
::google::protobuf::compiler::GeneratorContext *generatorContext) const;
|
||||
};
|
||||
} // namespace QtProtobuf
|
||||
|
||||
#endif // QPROTOBUFGENERATOR_H
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef SINGLEFILEGENERATOR_H
|
||||
#define SINGLEFILEGENERATOR_H
|
||||
|
||||
#include <google/protobuf/compiler/code_generator.h>
|
||||
#include <google/protobuf/io/zero_copy_stream.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include "generatorbase.h"
|
||||
|
||||
namespace google::protobuf {
|
||||
class FileDescriptor;
|
||||
class Descriptor;
|
||||
namespace compiler {
|
||||
class GeneratorContext;
|
||||
} // namespace compiler
|
||||
} // namespace google::protobuf
|
||||
|
||||
namespace QtProtobuf::generator {
|
||||
class SingleFileGenerator : public GeneratorBase
|
||||
{
|
||||
public:
|
||||
SingleFileGenerator();
|
||||
~SingleFileGenerator();
|
||||
bool Generate(const ::google::protobuf::FileDescriptor *file,
|
||||
const std::string ¶meter,
|
||||
::google::protobuf::compiler::GeneratorContext *generatorContext,
|
||||
std::string *error) const override;
|
||||
private:
|
||||
bool GenerateMessages(const ::google::protobuf::FileDescriptor *file,
|
||||
::google::protobuf::compiler::GeneratorContext *generatorContext) const;
|
||||
bool GenerateServices(const ::google::protobuf::FileDescriptor *file,
|
||||
::google::protobuf::compiler::GeneratorContext *generatorContext) const;
|
||||
};
|
||||
} // namespace QtProtobuf
|
||||
|
||||
#endif // SINGLEFILEGENERATOR_H
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
qt_add_library(QtProtocCommon STATIC
|
||||
baseprinter.cpp baseprinter.h
|
||||
descriptorprinterbase.h
|
||||
generatorbase.cpp generatorbase.h
|
||||
generatorcommon.cpp generatorcommon.h
|
||||
options.cpp options.h
|
||||
commontemplates.cpp commontemplates.h
|
||||
utils.cpp utils.h
|
||||
)
|
||||
|
||||
target_link_libraries(QtProtocCommon
|
||||
PUBLIC
|
||||
WrapProtobuf::WrapLibProtobuf
|
||||
WrapProtobuf::WrapLibProtoc
|
||||
)
|
||||
|
||||
target_include_directories(QtProtocCommon PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
)
|
||||
|
|
@ -2,16 +2,15 @@
|
|||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "baseprinter.h"
|
||||
|
||||
#include "templates.h"
|
||||
#include "generatorcommon.h"
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include "utils.h"
|
||||
#include "commontemplates.h"
|
||||
#include <google/protobuf/io/printer.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
using namespace ::google::protobuf;
|
||||
using namespace ::google::protobuf::io;
|
||||
using namespace ::QtProtobuf::generator;
|
||||
using namespace ::qtprotoccommon;
|
||||
|
||||
BasePrinter::BasePrinter(std::shared_ptr<Printer> printer) : m_printer(std::move(printer)) { }
|
||||
|
||||
|
|
@ -19,12 +18,12 @@ BasePrinter::~BasePrinter() = default;
|
|||
|
||||
void BasePrinter::printPublicBlock()
|
||||
{
|
||||
m_printer->Print(Templates::PublicBlockTemplate());
|
||||
m_printer->Print(CommonTemplates::PublicBlockTemplate());
|
||||
}
|
||||
|
||||
void BasePrinter::printPrivateBlock()
|
||||
{
|
||||
m_printer->Print(Templates::PrivateBlockTemplate());
|
||||
m_printer->Print(CommonTemplates::PrivateBlockTemplate());
|
||||
}
|
||||
|
||||
void BasePrinter::printCommentsImpl(std::string comments)
|
||||
|
|
@ -55,3 +54,16 @@ void BasePrinter::printCommentsImpl(std::string comments)
|
|||
m_printer->Print(" */");
|
||||
}
|
||||
}
|
||||
|
||||
void BasePrinter::Indent()
|
||||
{
|
||||
// The protoc printer prints 2 spaces, so we call it twice
|
||||
m_printer->Indent();
|
||||
m_printer->Indent();
|
||||
}
|
||||
|
||||
void BasePrinter::Outdent()
|
||||
{
|
||||
m_printer->Outdent();
|
||||
m_printer->Outdent();
|
||||
}
|
||||
|
|
@ -1,19 +1,20 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>, Tatyana Borisova <tanusshhka@mail.ru>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef BASEPRINTER_H
|
||||
#define BASEPRINTER_H
|
||||
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <memory>
|
||||
|
||||
#include "utils.h"
|
||||
#include "options.h"
|
||||
#include "generatorcommon.h"
|
||||
|
||||
namespace QtProtobuf::generator {
|
||||
namespace google::protobuf::io {
|
||||
class Printer;
|
||||
} // google::protobuf::io
|
||||
|
||||
namespace qtprotoccommon {
|
||||
|
||||
using PropertyMap = std::map<std::string, std::string>;
|
||||
|
||||
|
|
@ -39,19 +40,8 @@ public:
|
|||
descriptor->GetSourceLocation(&loc);
|
||||
printCommentsImpl(loc.leading_comments);
|
||||
}
|
||||
|
||||
void Indent()
|
||||
{
|
||||
// The protoc printer prints 2 spaces, so we call it twice
|
||||
m_printer->Indent();
|
||||
m_printer->Indent();
|
||||
}
|
||||
|
||||
void Outdent()
|
||||
{
|
||||
m_printer->Outdent();
|
||||
m_printer->Outdent();
|
||||
}
|
||||
void Indent();
|
||||
void Outdent();
|
||||
|
||||
private:
|
||||
void printCommentsImpl(std::string comments);
|
||||
|
|
@ -62,5 +52,5 @@ protected:
|
|||
std::shared_ptr<::google::protobuf::io::Printer> m_printer;
|
||||
};
|
||||
|
||||
} // namespace QtProtobuf::generator
|
||||
} // namespace qtprotoccommon
|
||||
#endif // BASEPRINTER_H
|
||||
|
|
@ -2,10 +2,9 @@
|
|||
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>, Tatyana Borisova <tanusshhka@mail.ru>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "templates.h"
|
||||
#include <unordered_map>
|
||||
#include "commontemplates.h"
|
||||
|
||||
// Templates navigation map:
|
||||
// CommonTemplates navigation map:
|
||||
// All template functions are named as following(with some exceptions):
|
||||
// <CommonTemplateType>[TemplateSubject][Declaration|Definition]Template
|
||||
//
|
||||
|
|
@ -27,20 +26,20 @@
|
|||
// Map and Repeated can be combined with one of Complex, Message or Enum keywords, that indicates
|
||||
// the specialization of the template.
|
||||
|
||||
using namespace ::QtProtobuf::generator;
|
||||
using namespace ::qtprotoccommon;
|
||||
|
||||
const char *Templates::ProtoSuffix()
|
||||
const char *CommonTemplates::ProtoSuffix()
|
||||
{
|
||||
return "_proto";
|
||||
}
|
||||
|
||||
const std::vector<std::string> &Templates::ListOfQmlExceptions()
|
||||
const std::vector<std::string> &CommonTemplates::ListOfQmlExceptions()
|
||||
{
|
||||
static std::vector<std::string> vec{ { "id", "property", "import" } };
|
||||
return vec;
|
||||
}
|
||||
|
||||
const char *Templates::DefaultProtobufIncludesTemplate()
|
||||
const char *CommonTemplates::DefaultProtobufIncludesTemplate()
|
||||
{
|
||||
return "#include <QtCore/QMetaType>\n"
|
||||
"#include <QtCore/QList>\n"
|
||||
|
|
@ -52,107 +51,107 @@ const char *Templates::DefaultProtobufIncludesTemplate()
|
|||
"\n";
|
||||
}
|
||||
|
||||
const char *Templates::QmlProtobufIncludesTemplate()
|
||||
const char *CommonTemplates::QmlProtobufIncludesTemplate()
|
||||
{
|
||||
return "#include <QtQml/QQmlListProperty>\n"
|
||||
"#include <QtProtobufQuick/qtprotobufqmllistpropertyconstructor.h>\n\n";
|
||||
}
|
||||
|
||||
const char *Templates::DisclaimerTemplate()
|
||||
const char *CommonTemplates::DisclaimerTemplate()
|
||||
{
|
||||
return "/* This file is autogenerated. DO NOT CHANGE. All changes will be lost */\n\n";
|
||||
}
|
||||
|
||||
const char *Templates::PreambleTemplate()
|
||||
const char *CommonTemplates::PreambleTemplate()
|
||||
{
|
||||
return "#ifndef Q_PROTOBUF_$filename$_H\n"
|
||||
"#define Q_PROTOBUF_$filename$_H\n\n"
|
||||
"#include <QtProtobuf/QProtobufMessage>\n";
|
||||
}
|
||||
|
||||
const char *Templates::FooterTemplate()
|
||||
const char *CommonTemplates::FooterTemplate()
|
||||
{
|
||||
return "#endif // Q_PROTOBUF_$filename$_H\n";
|
||||
}
|
||||
|
||||
const char *Templates::InternalIncludeTemplate()
|
||||
const char *CommonTemplates::InternalIncludeTemplate()
|
||||
{
|
||||
return "#include \"$include$.h\"\n";
|
||||
}
|
||||
const char *Templates::ExternalIncludeTemplate()
|
||||
const char *CommonTemplates::ExternalIncludeTemplate()
|
||||
{
|
||||
return "#include <$include$>\n";
|
||||
}
|
||||
const char *Templates::GlobalEnumIncludeTemplate()
|
||||
const char *CommonTemplates::GlobalEnumIncludeTemplate()
|
||||
{
|
||||
return "#include <globalenums.h>\n";
|
||||
}
|
||||
|
||||
const char *Templates::EnumRegistrationDeclaration()
|
||||
const char *CommonTemplates::EnumRegistrationDeclaration()
|
||||
{
|
||||
return "$export_macro$ void registerTypes();\n";
|
||||
}
|
||||
|
||||
const char *Templates::MetaTypeRegistrationDeclaration()
|
||||
const char *CommonTemplates::MetaTypeRegistrationDeclaration()
|
||||
{
|
||||
return "static void registerTypes();\n";
|
||||
}
|
||||
const char *Templates::MetaTypeRegistrationMessageDefinition()
|
||||
const char *CommonTemplates::MetaTypeRegistrationMessageDefinition()
|
||||
{
|
||||
return "void $type$::registerTypes()\n{\n"
|
||||
" qRegisterMetaType<$type$>();\n"
|
||||
" qRegisterMetaType<$list_type$>();\n";
|
||||
}
|
||||
const char *Templates::MetaTypeRegistrationGlobalEnumDefinition()
|
||||
const char *CommonTemplates::MetaTypeRegistrationGlobalEnumDefinition()
|
||||
{
|
||||
return "void $enum_gadget$::registerTypes()\n{\n";
|
||||
}
|
||||
const char *Templates::MetaTypeRegistrationGlobalEnumTemplate()
|
||||
const char *CommonTemplates::MetaTypeRegistrationGlobalEnumTemplate()
|
||||
{
|
||||
return "qRegisterMetaType<$type$>();\n"
|
||||
"qRegisterMetaType<$full_type$>();\n";
|
||||
}
|
||||
const char *Templates::UsingMessageTemplate()
|
||||
const char *CommonTemplates::UsingMessageTemplate()
|
||||
{
|
||||
return "using $classname$Repeated = QList<std::shared_ptr<$classname$>>;\n";
|
||||
}
|
||||
const char *Templates::UsingMapTemplate()
|
||||
const char *CommonTemplates::UsingMapTemplate()
|
||||
{
|
||||
return "using $type$ = QHash<$key_type$, $value_type$>;\n";
|
||||
}
|
||||
const char *Templates::UsingMapMessageTemplate()
|
||||
const char *CommonTemplates::UsingMapMessageTemplate()
|
||||
{
|
||||
return "using $type$ = QHash<$key_type$, std::shared_ptr<$value_type$>>;\n";
|
||||
}
|
||||
const char *Templates::UsingNestedMessageTemplate()
|
||||
const char *CommonTemplates::UsingNestedMessageTemplate()
|
||||
{
|
||||
return "using $type$ = $scope_namespaces$::$type$;\n"
|
||||
"using $list_type$ = $scope_namespaces$::$list_type$;\n";
|
||||
}
|
||||
|
||||
const char *Templates::UsingRepeatedEnumTemplate()
|
||||
const char *CommonTemplates::UsingRepeatedEnumTemplate()
|
||||
{
|
||||
return "using $list_type$ = QList<$type$>;\n";
|
||||
}
|
||||
|
||||
const char *Templates::NamespaceTemplate()
|
||||
const char *CommonTemplates::NamespaceTemplate()
|
||||
{
|
||||
return "namespace $scope_namespaces$ {\n";
|
||||
}
|
||||
const char *Templates::NamespaceClosingTemplate()
|
||||
const char *CommonTemplates::NamespaceClosingTemplate()
|
||||
{
|
||||
return "} // namespace $scope_namespaces$\n";
|
||||
}
|
||||
const char *Templates::EnumDeclarationTemplate()
|
||||
const char *CommonTemplates::EnumDeclarationTemplate()
|
||||
{
|
||||
return "\nnamespace $classname$ {\n"
|
||||
"Q_NAMESPACE_EXPORT($export_macro$)\n";
|
||||
}
|
||||
const char *Templates::ClassMessageForwardDeclarationTemplate()
|
||||
const char *CommonTemplates::ClassMessageForwardDeclarationTemplate()
|
||||
{
|
||||
return "class $classname$;\n";
|
||||
}
|
||||
const char *Templates::ClassMessageBeginDeclarationTemplate()
|
||||
const char *CommonTemplates::ClassMessageBeginDeclarationTemplate()
|
||||
{
|
||||
return "\nclass $export_macro$ $classname$ : public QProtobufMessage\n"
|
||||
"{\n"
|
||||
|
|
@ -161,286 +160,286 @@ const char *Templates::ClassMessageBeginDeclarationTemplate()
|
|||
" Q_DECLARE_PROTOBUF_SERIALIZERS($classname$)\n";
|
||||
}
|
||||
|
||||
const char *Templates::PropertyTemplate()
|
||||
const char *CommonTemplates::PropertyTemplate()
|
||||
{
|
||||
return "Q_PROPERTY($property_type$ $property_name$ READ $property_name$ WRITE "
|
||||
"set$property_name_cap$ SCRIPTABLE $scriptable$)\n";
|
||||
}
|
||||
const char *Templates::PropertyRepeatedTemplate()
|
||||
const char *CommonTemplates::PropertyRepeatedTemplate()
|
||||
{
|
||||
return "Q_PROPERTY($property_list_type$ $property_name$ READ $property_name$ WRITE "
|
||||
"set$property_name_cap$ SCRIPTABLE $scriptable$)\n";
|
||||
}
|
||||
const char *Templates::PropertyRepeatedMessageTemplate()
|
||||
const char *CommonTemplates::PropertyRepeatedMessageTemplate()
|
||||
{
|
||||
return "Q_PROPERTY($property_list_type$ $property_name$Data READ $property_name$ WRITE "
|
||||
"set$property_name_cap$ SCRIPTABLE $scriptable$)\n";
|
||||
}
|
||||
const char *Templates::PropertyNonScriptableTemplate()
|
||||
const char *CommonTemplates::PropertyNonScriptableTemplate()
|
||||
{
|
||||
return "Q_PROPERTY($property_type$ $property_name$_p READ $property_name$ WRITE "
|
||||
"set$property_name_cap$ SCRIPTABLE false)\n";
|
||||
}
|
||||
const char *Templates::PropertyNonScriptableAliasTemplate()
|
||||
const char *CommonTemplates::PropertyNonScriptableAliasTemplate()
|
||||
{
|
||||
return "Q_PROPERTY($qml_alias_type$ $property_name$ READ $property_name$_p WRITE "
|
||||
"set$property_name_cap$_p SCRIPTABLE true)\n";
|
||||
}
|
||||
const char *Templates::PropertyMessageTemplate()
|
||||
const char *CommonTemplates::PropertyMessageTemplate()
|
||||
{
|
||||
return "Q_PROPERTY($property_type$ *$property_name$ READ $property_name$_p WRITE "
|
||||
"set$property_name_cap$_p)\n";
|
||||
}
|
||||
const char *Templates::PropertyQmlListTemplate()
|
||||
const char *CommonTemplates::PropertyQmlListTemplate()
|
||||
{
|
||||
return "Q_PROPERTY(QQmlListProperty<$property_type$> $property_name$ READ $property_name$_l)\n";
|
||||
}
|
||||
|
||||
const char *Templates::ConstructorMessageDeclarationTemplate()
|
||||
const char *CommonTemplates::ConstructorMessageDeclarationTemplate()
|
||||
{
|
||||
return "$classname$();\n";
|
||||
}
|
||||
|
||||
const char *Templates::DestructorMessageDeclarationTemplate()
|
||||
const char *CommonTemplates::DestructorMessageDeclarationTemplate()
|
||||
{
|
||||
return "~$classname$() override;\n";
|
||||
}
|
||||
|
||||
const char *Templates::MemberTemplate()
|
||||
const char *CommonTemplates::MemberTemplate()
|
||||
{
|
||||
return "$scope_type$ m_$property_name$;\n";
|
||||
}
|
||||
const char *Templates::MemberRepeatedTemplate()
|
||||
const char *CommonTemplates::MemberRepeatedTemplate()
|
||||
{
|
||||
return "$scope_list_type$ m_$property_name$;\n";
|
||||
}
|
||||
const char *Templates::MemberMessageTemplate()
|
||||
const char *CommonTemplates::MemberMessageTemplate()
|
||||
{
|
||||
return "QtProtobufPrivate::QProtobufLazyMessagePointer<$scope_type$> m_$property_name$;\n";
|
||||
}
|
||||
const char *Templates::PublicBlockTemplate()
|
||||
const char *CommonTemplates::PublicBlockTemplate()
|
||||
{
|
||||
return "\npublic:\n";
|
||||
}
|
||||
const char *Templates::PrivateBlockTemplate()
|
||||
const char *CommonTemplates::PrivateBlockTemplate()
|
||||
{
|
||||
return "\nprivate:\n";
|
||||
}
|
||||
const char *Templates::EnumDefinitionTemplate()
|
||||
const char *CommonTemplates::EnumDefinitionTemplate()
|
||||
{
|
||||
return "enum $type$ {\n";
|
||||
}
|
||||
const char *Templates::EnumFieldTemplate()
|
||||
const char *CommonTemplates::EnumFieldTemplate()
|
||||
{
|
||||
return "$enumvalue$ = $value$,\n";
|
||||
}
|
||||
|
||||
const char *Templates::ConstructorMessageDefinitionTemplate()
|
||||
const char *CommonTemplates::ConstructorMessageDefinitionTemplate()
|
||||
{
|
||||
return "$type$::$type$() : QProtobufMessage(&$type$::staticMetaObject)";
|
||||
}
|
||||
|
||||
const char *Templates::EmptyConstructorTemplate()
|
||||
const char *CommonTemplates::EmptyConstructorTemplate()
|
||||
{
|
||||
return "$classname$() {}\n";
|
||||
}
|
||||
|
||||
const char *Templates::QObjectConstructorMessageDeclarationTemplate()
|
||||
const char *CommonTemplates::QObjectConstructorMessageDeclarationTemplate()
|
||||
{
|
||||
return "explicit $classname$(QObject *parent = nullptr);\n";
|
||||
}
|
||||
|
||||
const char *Templates::CopyConstructorDeclarationTemplate()
|
||||
const char *CommonTemplates::CopyConstructorDeclarationTemplate()
|
||||
{
|
||||
return "$classname$(const $classname$ &other);\n";
|
||||
}
|
||||
const char *Templates::MoveConstructorDeclarationTemplate()
|
||||
const char *CommonTemplates::MoveConstructorDeclarationTemplate()
|
||||
{
|
||||
return "$classname$($classname$ &&other) noexcept;\n";
|
||||
}
|
||||
const char *Templates::CopyConstructorDefinitionTemplate()
|
||||
const char *CommonTemplates::CopyConstructorDefinitionTemplate()
|
||||
{
|
||||
return "$classname$::$classname$(const $classname$ &other) : "
|
||||
"QProtobufMessage(other)";
|
||||
}
|
||||
const char *Templates::MoveConstructorDefinitionTemplate()
|
||||
const char *CommonTemplates::MoveConstructorDefinitionTemplate()
|
||||
{
|
||||
return "$classname$::$classname$($classname$ &&other) noexcept : "
|
||||
"QProtobufMessage(std::move(other))";
|
||||
}
|
||||
const char *Templates::DeletedCopyConstructorTemplate()
|
||||
const char *CommonTemplates::DeletedCopyConstructorTemplate()
|
||||
{
|
||||
return "$classname$(const $classname$ &) = delete;\n";
|
||||
}
|
||||
const char *Templates::DeletedMoveConstructorTemplate()
|
||||
const char *CommonTemplates::DeletedMoveConstructorTemplate()
|
||||
{
|
||||
return "$classname$($classname$ &&) = delete;\n";
|
||||
}
|
||||
const char *Templates::CopyMemberTemplate()
|
||||
const char *CommonTemplates::CopyMemberTemplate()
|
||||
{
|
||||
return "set$property_name_cap$(other.m_$property_name$);\n";
|
||||
}
|
||||
const char *Templates::CopyMemberMessageTemplate()
|
||||
const char *CommonTemplates::CopyMemberMessageTemplate()
|
||||
{
|
||||
return "if (m_$property_name$ != other.m_$property_name$) {\n"
|
||||
" *m_$property_name$ = *other.m_$property_name$;\n"
|
||||
"}\n";
|
||||
}
|
||||
const char *Templates::AssignMemberMessageTemplate()
|
||||
const char *CommonTemplates::AssignMemberMessageTemplate()
|
||||
{
|
||||
return "if (m_$property_name$ != other.m_$property_name$)\n"
|
||||
" *m_$property_name$ = *other.m_$property_name$;\n";
|
||||
}
|
||||
const char *Templates::MoveMemberMessageTemplate()
|
||||
const char *CommonTemplates::MoveMemberMessageTemplate()
|
||||
{
|
||||
return "if (m_$property_name$ != other.m_$property_name$) {\n"
|
||||
" *m_$property_name$ = std::move(*other.m_$property_name$);\n"
|
||||
"}\n";
|
||||
}
|
||||
const char *Templates::MoveAssignMemberMessageTemplate()
|
||||
const char *CommonTemplates::MoveAssignMemberMessageTemplate()
|
||||
{
|
||||
return "if (m_$property_name$ != other.m_$property_name$)\n"
|
||||
" *m_$property_name$ = std::move(*other.m_$property_name$);\n";
|
||||
}
|
||||
const char *Templates::MoveAssignMemberComplexTemplate()
|
||||
const char *CommonTemplates::MoveAssignMemberComplexTemplate()
|
||||
{
|
||||
return "if (m_$property_name$ != other.m_$property_name$)\n"
|
||||
" m_$property_name$ = std::move(other.m_$property_name$);\n";
|
||||
}
|
||||
|
||||
const char *Templates::MoveConstructorMemberComplexTemplate()
|
||||
const char *CommonTemplates::MoveConstructorMemberComplexTemplate()
|
||||
{
|
||||
return "m_$property_name$ = std::move(other.m_$property_name$);\n";
|
||||
}
|
||||
|
||||
const char *Templates::MoveMemberTemplate()
|
||||
const char *CommonTemplates::MoveMemberTemplate()
|
||||
{
|
||||
return "set$property_name_cap$(std::exchange(other.m_$property_name$, 0));\n";
|
||||
}
|
||||
const char *Templates::MoveMemberEnumTemplate()
|
||||
const char *CommonTemplates::MoveMemberEnumTemplate()
|
||||
{
|
||||
return "m_$property_name$ = other.m_$property_name$;\n";
|
||||
}
|
||||
|
||||
const char *Templates::AssignmentOperatorDeclarationTemplate()
|
||||
const char *CommonTemplates::AssignmentOperatorDeclarationTemplate()
|
||||
{
|
||||
return "$classname$ &operator =(const $classname$ &other);\n";
|
||||
}
|
||||
const char *Templates::AssignmentOperatorDefinitionTemplate()
|
||||
const char *CommonTemplates::AssignmentOperatorDefinitionTemplate()
|
||||
{
|
||||
return "$classname$ &$classname$::operator =(const $classname$ &other)\n"
|
||||
"{\n"
|
||||
" QProtobufMessage::operator=(other);\n";
|
||||
}
|
||||
const char *Templates::AssignmentOperatorReturnTemplate()
|
||||
const char *CommonTemplates::AssignmentOperatorReturnTemplate()
|
||||
{
|
||||
return "return *this;\n";
|
||||
}
|
||||
|
||||
const char *Templates::MoveAssignmentOperatorDeclarationTemplate()
|
||||
const char *CommonTemplates::MoveAssignmentOperatorDeclarationTemplate()
|
||||
{
|
||||
return "$classname$ &operator =($classname$ &&other) noexcept;\n";
|
||||
}
|
||||
const char *Templates::MoveAssignmentOperatorDefinitionTemplate()
|
||||
const char *CommonTemplates::MoveAssignmentOperatorDefinitionTemplate()
|
||||
{
|
||||
return "$classname$ &$classname$::operator =($classname$ &&other) noexcept\n"
|
||||
"{\n"
|
||||
" QProtobufMessage::operator=(std::move(other));\n";
|
||||
}
|
||||
|
||||
const char *Templates::EqualOperatorDeclarationTemplate()
|
||||
const char *CommonTemplates::EqualOperatorDeclarationTemplate()
|
||||
{
|
||||
return "bool operator ==(const $classname$ &other) const;\n";
|
||||
}
|
||||
const char *Templates::EqualOperatorDefinitionTemplate()
|
||||
const char *CommonTemplates::EqualOperatorDefinitionTemplate()
|
||||
{
|
||||
return "bool $classname$::operator ==(const $classname$ &other) const\n{\n"
|
||||
" return QProtobufMessage::isEqual(*this, other)";
|
||||
}
|
||||
const char *Templates::EqualOperatorMemberTemplate()
|
||||
const char *CommonTemplates::EqualOperatorMemberTemplate()
|
||||
{
|
||||
return "m_$property_name$ == other.m_$property_name$";
|
||||
}
|
||||
const char *Templates::EqualOperatorMemberMessageTemplate()
|
||||
const char *CommonTemplates::EqualOperatorMemberMessageTemplate()
|
||||
{
|
||||
return "(m_$property_name$ == other.m_$property_name$\n"
|
||||
" || *m_$property_name$ == *other.m_$property_name$)\n";
|
||||
}
|
||||
const char *Templates::EqualOperatorMemberRepeatedTemplate()
|
||||
const char *CommonTemplates::EqualOperatorMemberRepeatedTemplate()
|
||||
{
|
||||
return "QtProtobuf::repeatedValueCompare(m_$property_name$, other.m_$property_name$)";
|
||||
}
|
||||
|
||||
const char *Templates::NotEqualOperatorDeclarationTemplate()
|
||||
const char *CommonTemplates::NotEqualOperatorDeclarationTemplate()
|
||||
{
|
||||
return "bool operator !=(const $classname$ &other) const;\n";
|
||||
}
|
||||
const char *Templates::NotEqualOperatorDefinitionTemplate()
|
||||
const char *CommonTemplates::NotEqualOperatorDefinitionTemplate()
|
||||
{
|
||||
return "bool $classname$::operator !=(const $classname$ &other) const\n{\n"
|
||||
" return !this->operator ==(other);\n"
|
||||
"}\n\n";
|
||||
}
|
||||
|
||||
const char *Templates::PrivateGetterMessageDeclarationTemplate()
|
||||
const char *CommonTemplates::PrivateGetterMessageDeclarationTemplate()
|
||||
{
|
||||
return "$getter_type$ *$property_name$_p() const;\n";
|
||||
}
|
||||
const char *Templates::PrivateGetterMessageDefinitionTemplate()
|
||||
const char *CommonTemplates::PrivateGetterMessageDefinitionTemplate()
|
||||
{
|
||||
return "$getter_type$ *$classname$::$property_name$_p() const\n{\n"
|
||||
" return m_$property_name$.get();\n"
|
||||
"}\n\n";
|
||||
}
|
||||
|
||||
const char *Templates::GetterMessageDeclarationTemplate()
|
||||
const char *CommonTemplates::GetterMessageDeclarationTemplate()
|
||||
{
|
||||
return "$getter_type$ &$property_name$() const;\n";
|
||||
}
|
||||
const char *Templates::GetterMessageDefinitionTemplate()
|
||||
const char *CommonTemplates::GetterMessageDefinitionTemplate()
|
||||
{
|
||||
return "$getter_type$ &$classname$::$property_name$() const\n{\n"
|
||||
" return *m_$property_name$;\n"
|
||||
"}\n\n";
|
||||
}
|
||||
|
||||
const char *Templates::GetterTemplate()
|
||||
const char *CommonTemplates::GetterTemplate()
|
||||
{
|
||||
return "$getter_type$ $property_name$() const {\n"
|
||||
" return m_$property_name$;\n"
|
||||
"}\n\n";
|
||||
}
|
||||
|
||||
const char *Templates::GetterNonScriptableTemplate()
|
||||
const char *CommonTemplates::GetterNonScriptableTemplate()
|
||||
{
|
||||
return "$qml_alias_type$ $property_name$_p() const {\n"
|
||||
" return m_$property_name$;\n"
|
||||
"}\n\n";
|
||||
}
|
||||
|
||||
const char *Templates::GetterComplexTemplate()
|
||||
const char *CommonTemplates::GetterComplexTemplate()
|
||||
{
|
||||
return "$getter_type$ &$property_name$() {\n"
|
||||
" return m_$property_name$;\n"
|
||||
"}\n\n";
|
||||
}
|
||||
|
||||
const char *Templates::GetterQmlListDeclarationTemplate()
|
||||
const char *CommonTemplates::GetterQmlListDeclarationTemplate()
|
||||
{
|
||||
return "QQmlListProperty<$scope_type$> $property_name$_l();\n";
|
||||
}
|
||||
const char *Templates::GetterQmlListDefinitionTemplate()
|
||||
const char *CommonTemplates::GetterQmlListDefinitionTemplate()
|
||||
{
|
||||
return "QQmlListProperty<$full_type$> $classname$::$property_name$_l()\n{\n"
|
||||
" return qProtobufConstructQmlListProperty<$scope_type$>(this, &m_$property_name$);\n"
|
||||
"}\n\n";
|
||||
}
|
||||
|
||||
const char *Templates::PrivateSetterMessageDeclarationTemplate()
|
||||
const char *CommonTemplates::PrivateSetterMessageDeclarationTemplate()
|
||||
{
|
||||
return "void set$property_name_cap$_p($setter_type$ *$property_name$);\n";
|
||||
}
|
||||
const char *Templates::PrivateSetterMessageDefinitionTemplate()
|
||||
const char *CommonTemplates::PrivateSetterMessageDefinitionTemplate()
|
||||
{
|
||||
return "void $classname$::set$property_name_cap$_p($setter_type$ *$property_name$)\n{\n"
|
||||
" if (m_$property_name$.get() != $property_name$)\n"
|
||||
|
|
@ -448,11 +447,11 @@ const char *Templates::PrivateSetterMessageDefinitionTemplate()
|
|||
"}\n\n";
|
||||
}
|
||||
|
||||
const char *Templates::SetterMessageDeclarationTemplate()
|
||||
const char *CommonTemplates::SetterMessageDeclarationTemplate()
|
||||
{
|
||||
return "void set$property_name_cap$(const $setter_type$ &$property_name$);\n";
|
||||
}
|
||||
const char *Templates::SetterMessageDefinitionTemplate()
|
||||
const char *CommonTemplates::SetterMessageDefinitionTemplate()
|
||||
{
|
||||
return "void $classname$::set$property_name_cap$(const $setter_type$ &$property_name$)\n{\n"
|
||||
" if (*m_$property_name$ != $property_name$)\n"
|
||||
|
|
@ -460,11 +459,11 @@ const char *Templates::SetterMessageDefinitionTemplate()
|
|||
"}\n\n";
|
||||
}
|
||||
|
||||
const char *Templates::SetterComplexDeclarationTemplate()
|
||||
const char *CommonTemplates::SetterComplexDeclarationTemplate()
|
||||
{
|
||||
return "void set$property_name_cap$(const $setter_type$ &$property_name$);\n";
|
||||
}
|
||||
const char *Templates::SetterComplexDefinitionTemplate()
|
||||
const char *CommonTemplates::SetterComplexDefinitionTemplate()
|
||||
{
|
||||
return "void $classname$::set$property_name_cap$(const $setter_type$ &$property_name$)\n{\n"
|
||||
" if (m_$property_name$ != $property_name$)\n"
|
||||
|
|
@ -472,14 +471,14 @@ const char *Templates::SetterComplexDefinitionTemplate()
|
|||
"}\n\n";
|
||||
}
|
||||
|
||||
const char *Templates::SetterTemplate()
|
||||
const char *CommonTemplates::SetterTemplate()
|
||||
{
|
||||
return "void set$property_name_cap$(const $setter_type$ &$property_name$) {\n"
|
||||
" if (m_$property_name$ != $property_name$)\n"
|
||||
" m_$property_name$ = $property_name$;\n"
|
||||
"}\n\n";
|
||||
}
|
||||
const char *Templates::SetterNonScriptableTemplate()
|
||||
const char *CommonTemplates::SetterNonScriptableTemplate()
|
||||
{
|
||||
return "void set$property_name_cap$_p(const $qml_alias_type$ &$property_name$) {\n"
|
||||
" if (m_$property_name$ != $property_name$)\n"
|
||||
|
|
@ -487,46 +486,46 @@ const char *Templates::SetterNonScriptableTemplate()
|
|||
"}\n\n";
|
||||
}
|
||||
|
||||
const char *Templates::SignalsBlockTemplate()
|
||||
const char *CommonTemplates::SignalsBlockTemplate()
|
||||
{
|
||||
return "\nQ_SIGNALS:\n";
|
||||
}
|
||||
const char *Templates::SignalTemplate()
|
||||
const char *CommonTemplates::SignalTemplate()
|
||||
{
|
||||
return "void $property_name$Changed();\n";
|
||||
}
|
||||
|
||||
const char *Templates::MetaDataUintDataEntryTemplate()
|
||||
const char *CommonTemplates::MetaDataUintDataEntryTemplate()
|
||||
{
|
||||
return "const std::array<uint, $size$> qt_protobuf_$classname$_uint_data =";
|
||||
}
|
||||
|
||||
const char *Templates::MetaDataCharDataEntryTemplate()
|
||||
const char *CommonTemplates::MetaDataCharDataEntryTemplate()
|
||||
{
|
||||
return "const char qt_protobuf_$classname$_char_data[$size$] =";
|
||||
}
|
||||
|
||||
const char *Templates::JsonNameOffsetsUintDataTemplate()
|
||||
const char *CommonTemplates::JsonNameOffsetsUintDataTemplate()
|
||||
{
|
||||
return "$json_name_offset$, /* = $json_name$ */\n";
|
||||
}
|
||||
|
||||
const char *Templates::FieldNumbersUintDataTemplate()
|
||||
const char *CommonTemplates::FieldNumbersUintDataTemplate()
|
||||
{
|
||||
return "$field_number$, /* = $json_name$ */\n";
|
||||
}
|
||||
|
||||
const char *Templates::QtPropertyIndicesUintDataTemplate()
|
||||
const char *CommonTemplates::QtPropertyIndicesUintDataTemplate()
|
||||
{
|
||||
return "$property_index$, /* = $json_name$ */\n";
|
||||
}
|
||||
|
||||
const char *Templates::FieldFlagsUintDataTemplate()
|
||||
const char *CommonTemplates::FieldFlagsUintDataTemplate()
|
||||
{
|
||||
return "$field_flags$, /* = $json_name$ */\n";
|
||||
}
|
||||
|
||||
const char *Templates::PropertyOrderingDataOpeningTemplate()
|
||||
const char *CommonTemplates::PropertyOrderingDataOpeningTemplate()
|
||||
{
|
||||
return "static constexpr struct {\n"
|
||||
" QtProtobufPrivate::QProtobufPropertyOrdering::Data data;\n"
|
||||
|
|
@ -544,101 +543,101 @@ const char *Templates::PropertyOrderingDataOpeningTemplate()
|
|||
" },\n";
|
||||
}
|
||||
|
||||
const char *Templates::PropertyOrderingDataClosingTemplate()
|
||||
const char *CommonTemplates::PropertyOrderingDataClosingTemplate()
|
||||
{
|
||||
return "};\n\n";
|
||||
}
|
||||
const char *Templates::PropertyOrderingDefinitionTemplate()
|
||||
const char *CommonTemplates::PropertyOrderingDefinitionTemplate()
|
||||
{
|
||||
return "const QtProtobufPrivate::QProtobufPropertyOrdering $type$::propertyOrdering = {\n"
|
||||
" &qt_protobuf_$classname$_metadata.data\n"
|
||||
"};\n\n";
|
||||
}
|
||||
|
||||
const char *Templates::SimpleBlockEnclosureTemplate()
|
||||
const char *CommonTemplates::SimpleBlockEnclosureTemplate()
|
||||
{
|
||||
return "}\n";
|
||||
}
|
||||
const char *Templates::SemicolonBlockEnclosureTemplate()
|
||||
const char *CommonTemplates::SemicolonBlockEnclosureTemplate()
|
||||
{
|
||||
return "};\n";
|
||||
}
|
||||
const char *Templates::InitializerMemberTemplate()
|
||||
const char *CommonTemplates::InitializerMemberTemplate()
|
||||
{
|
||||
return "m_$property_name$($initializer$)";
|
||||
}
|
||||
const char *Templates::InitializerMemberMessageTemplate()
|
||||
const char *CommonTemplates::InitializerMemberMessageTemplate()
|
||||
{
|
||||
return "m_$property_name$(nullptr)";
|
||||
}
|
||||
const char *Templates::EmptyBracesTemplate()
|
||||
const char *CommonTemplates::EmptyBracesTemplate()
|
||||
{
|
||||
return "\n{\n}\n";
|
||||
}
|
||||
|
||||
const char *Templates::DeclareMetaTypeTemplate()
|
||||
const char *CommonTemplates::DeclareMetaTypeTemplate()
|
||||
{
|
||||
return "Q_DECLARE_METATYPE($full_type$)\n";
|
||||
}
|
||||
|
||||
const char *Templates::DeclareMetaTypeQmlListTemplate()
|
||||
const char *CommonTemplates::DeclareMetaTypeQmlListTemplate()
|
||||
{
|
||||
return "Q_DECLARE_METATYPE(QQmlListProperty<$full_type$>)\n";
|
||||
}
|
||||
|
||||
const char *Templates::MetaTypeRegistrationLocalEnumTemplate()
|
||||
const char *CommonTemplates::MetaTypeRegistrationLocalEnumTemplate()
|
||||
{
|
||||
return "qRegisterProtobufEnumType<$scope_type$>();\n"
|
||||
"qRegisterMetaType<$scope_type$>();\n"
|
||||
"qRegisterMetaType<$scope_type$>();\n"
|
||||
"qRegisterMetaType<$scope_list_type$>();\n";
|
||||
}
|
||||
const char *Templates::MetaTypeRegistrationMapTemplate()
|
||||
const char *CommonTemplates::MetaTypeRegistrationMapTemplate()
|
||||
{
|
||||
return "qRegisterMetaType<$scope_type$>();\n"
|
||||
"qRegisterProtobufMapType<$key_type$, $value_type$>();\n";
|
||||
}
|
||||
|
||||
const char *Templates::MetaTypeRegistrationQmlListTemplate()
|
||||
const char *CommonTemplates::MetaTypeRegistrationQmlListTemplate()
|
||||
{
|
||||
return "qRegisterMetaType<QQmlListProperty<$full_type$>>();\n";
|
||||
}
|
||||
|
||||
const char *Templates::QEnumTemplate()
|
||||
const char *CommonTemplates::QEnumTemplate()
|
||||
{
|
||||
return "Q_ENUM($type$)\n";
|
||||
}
|
||||
|
||||
const char *Templates::QEnumNSTemplate()
|
||||
const char *CommonTemplates::QEnumNSTemplate()
|
||||
{
|
||||
return "Q_ENUM_NS($type$)\n";
|
||||
}
|
||||
|
||||
const char *Templates::RegisterEnumSerializersTemplate()
|
||||
const char *CommonTemplates::RegisterEnumSerializersTemplate()
|
||||
{
|
||||
return "qRegisterProtobufEnumType<$full_type$>();\n";
|
||||
}
|
||||
const char *Templates::RegistrarTemplate()
|
||||
const char *CommonTemplates::RegistrarTemplate()
|
||||
{
|
||||
return "static QtProtobuf::ProtoTypeRegistrar "
|
||||
"ProtoTypeRegistrar$classname$(qRegisterProtobufType<$classname$>);\n";
|
||||
}
|
||||
const char *Templates::RegistrarEnumTemplate()
|
||||
const char *CommonTemplates::RegistrarEnumTemplate()
|
||||
{
|
||||
return "static QtProtobuf::ProtoTypeRegistrar "
|
||||
"ProtoTypeRegistrar$enum_gadget$($enum_gadget$::registerTypes);\n";
|
||||
}
|
||||
const char *Templates::QmlRegisterTypeTemplate()
|
||||
const char *CommonTemplates::QmlRegisterTypeTemplate()
|
||||
{
|
||||
return "qmlRegisterType<$scope_type$>(\"$qml_package$\", 1, 0, \"$type$\");\n";
|
||||
}
|
||||
const char *Templates::QmlRegisterTypeEnumTemplate()
|
||||
const char *CommonTemplates::QmlRegisterTypeEnumTemplate()
|
||||
{
|
||||
return "qmlRegisterUncreatableType<$enum_gadget$>(\"$qml_package$\", 1, 0, \"$type$\", "
|
||||
"QStringLiteral(\"$full_type$ Could not be created from qml context\"));\n";
|
||||
}
|
||||
|
||||
const char *Templates::RepeatedSuffix()
|
||||
const char *CommonTemplates::RepeatedSuffix()
|
||||
{
|
||||
return "Repeated";
|
||||
}
|
||||
|
|
@ -647,7 +646,7 @@ const char *Templates::RepeatedSuffix()
|
|||
// See https://doc.qt.io/qt-6/qtqml-typesystem-valuetypes.html for types that are supported by the
|
||||
// QML JS engine.
|
||||
const std::unordered_map<::google::protobuf::FieldDescriptor::Type, std::string>
|
||||
&Templates::TypeReflection()
|
||||
&CommonTemplates::TypeReflection()
|
||||
{
|
||||
static std::unordered_map<::google::protobuf::FieldDescriptor::Type, std::string> map{
|
||||
{ ::google::protobuf::FieldDescriptor::TYPE_DOUBLE, "double" },
|
||||
|
|
@ -669,49 +668,39 @@ const std::unordered_map<::google::protobuf::FieldDescriptor::Type, std::string>
|
|||
return map;
|
||||
}
|
||||
|
||||
const char *Templates::ProtoFileSuffix()
|
||||
const char *CommonTemplates::ProtoFileSuffix()
|
||||
{
|
||||
return ".qpb";
|
||||
}
|
||||
|
||||
const char *Templates::GrpcClientFileSuffix()
|
||||
{
|
||||
return "_client.grpc";
|
||||
}
|
||||
|
||||
const char *Templates::GrpcServiceFileSuffix()
|
||||
{
|
||||
return "_service.grpc";
|
||||
}
|
||||
|
||||
const char *Templates::EnumClassSuffix()
|
||||
const char *CommonTemplates::EnumClassSuffix()
|
||||
{
|
||||
return "Gadget";
|
||||
}
|
||||
|
||||
const char *Templates::QtProtobufNamespace()
|
||||
const char *CommonTemplates::QtProtobufNamespace()
|
||||
{
|
||||
return "QtProtobuf";
|
||||
}
|
||||
const char *Templates::QtProtobufNestedNamespace()
|
||||
const char *CommonTemplates::QtProtobufNestedNamespace()
|
||||
{
|
||||
return "_QtProtobufNested";
|
||||
}
|
||||
|
||||
const char *Templates::QtProtobufFieldEnum()
|
||||
const char *CommonTemplates::QtProtobufFieldEnum()
|
||||
{
|
||||
return "QtProtobufFieldEnum";
|
||||
}
|
||||
const char *Templates::FieldEnumTemplate()
|
||||
const char *CommonTemplates::FieldEnumTemplate()
|
||||
{
|
||||
return "enum QtProtobufFieldEnum {\n";
|
||||
}
|
||||
const char *Templates::FieldNumberTemplate()
|
||||
const char *CommonTemplates::FieldNumberTemplate()
|
||||
{
|
||||
return "$property_name_cap$ProtoFieldNumber = $number$,\n";
|
||||
}
|
||||
|
||||
const char *Templates::ExportMacroTemplate()
|
||||
const char *CommonTemplates::ExportMacroTemplate()
|
||||
{
|
||||
return "#if defined(QT_SHARED) || !defined(QT_STATIC)\n"
|
||||
"# if defined(QT_BUILD_$export_macro$_LIB)\n"
|
||||
|
|
@ -724,208 +713,3 @@ const char *Templates::ExportMacroTemplate()
|
|||
"#endif\n";
|
||||
}
|
||||
|
||||
const char *Templates::ChildClassDeclarationTemplate()
|
||||
{
|
||||
return "\nclass $export_macro$ $classname$ : public $parent_class$\n"
|
||||
"{\n"
|
||||
" Q_OBJECT\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientMethodDeclarationSyncTemplate()
|
||||
{
|
||||
return "QGrpcStatus $method_name$(const $param_type$ &$param_name$, "
|
||||
"$return_type$ *$return_name$);\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientMethodDeclarationAsyncTemplate()
|
||||
{
|
||||
return "std::shared_ptr<QGrpcCallReply> $method_name$(const $param_type$ &$param_name$);\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientMethodDeclarationAsync2Template()
|
||||
{
|
||||
return "Q_INVOKABLE void $method_name$(const $param_type$ &$param_name$, const QObject "
|
||||
"*context, "
|
||||
"const std::function<void(std::shared_ptr<QGrpcCallReply>)> &callback);\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientMethodDeclarationQmlTemplate()
|
||||
{
|
||||
return "Q_INVOKABLE void $method_name$($param_type$ *$param_name$, const QJSValue &callback, "
|
||||
"const QJSValue &errorCallback);\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientMethodDeclarationQml2Template()
|
||||
{
|
||||
return "Q_INVOKABLE void $method_name$($param_type$ *$param_name$, $return_type$ "
|
||||
"*$return_name$, const QJSValue &errorCallback);\n";
|
||||
}
|
||||
|
||||
const char *Templates::ServerMethodDeclarationTemplate()
|
||||
{
|
||||
return "Q_INVOKABLE virtual $return_type$ $method_name$(const $param_type$ &$param_name$) = "
|
||||
"0;\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientConstructorDefinitionTemplate()
|
||||
{
|
||||
return "\n$classname$::$classname$(QObject *parent) : $parent_class$(\"$service_name$\", "
|
||||
"parent)\n"
|
||||
"{\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientMethodDefinitionSyncTemplate()
|
||||
{
|
||||
return "\nQGrpcStatus $classname$::$method_name$(const $param_type$ &$param_name$, "
|
||||
"$return_type$ *$return_name$)\n"
|
||||
"{\n"
|
||||
" return call<$param_type$>(\"$method_name$\", $param_name$, $return_name$);\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientMethodDefinitionAsyncTemplate()
|
||||
{
|
||||
return "\nstd::shared_ptr<QGrpcCallReply> $classname$::$method_name$(const $param_type$ "
|
||||
"&$param_name$)\n"
|
||||
"{\n"
|
||||
" return call<$param_type$>(\"$method_name$\", $param_name$);\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientMethodDefinitionAsync2Template()
|
||||
{
|
||||
return "\nvoid $classname$::$method_name$(const $param_type$ &$param_name$, const QObject "
|
||||
"*context, const std::function<void(std::shared_ptr<QGrpcCallReply>)> &callback)\n"
|
||||
"{\n"
|
||||
" std::shared_ptr<QGrpcCallReply> reply = call<$param_type$>(\"$method_name$\", "
|
||||
"$param_name$);\n"
|
||||
" QObject::connect(reply.get(), &QGrpcCallReply::finished, context, [reply, "
|
||||
"callback]() "
|
||||
"{\n"
|
||||
" callback(reply);\n"
|
||||
" });\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientMethodDefinitionQmlTemplate()
|
||||
{
|
||||
return "\nvoid $classname$::$method_name$($param_type$ *$param_name$, const QJSValue "
|
||||
"&callback, "
|
||||
"const QJSValue &errorCallback)\n"
|
||||
"{\n"
|
||||
" if (!callback.isCallable()) {\n"
|
||||
" qWarning() << \"Unable to call $classname$::$method_name$, callback is not "
|
||||
"callable\";\n"
|
||||
" return;\n"
|
||||
" }\n\n"
|
||||
" if (arg == nullptr) {\n"
|
||||
" qWarning() << \"Invalid argument provided for method "
|
||||
"$classname$::$method_name$, "
|
||||
"argument of type '$param_type$ *' expected\";\n"
|
||||
" return;\n"
|
||||
" }\n\n"
|
||||
" QJSEngine *jsEngine = qjsEngine(this);\n"
|
||||
" if (jsEngine == nullptr) {\n"
|
||||
" qWarning() << \"Unable to call $classname$::$method_name$, it's only callable "
|
||||
"from JS engine context\";\n"
|
||||
" return;\n"
|
||||
" }\n\n"
|
||||
" std::shared_ptr<QGrpcCallReply> reply = call<$param_type$>(\"$method_name$\", "
|
||||
"*$param_name$);\n"
|
||||
" reply->subscribe(jsEngine, [this, reply, callback, jsEngine]() {\n"
|
||||
" auto result = new $return_type$(reply->read<$return_type$>());\n"
|
||||
" qmlEngine(this)->setObjectOwnership(result, QQmlEngine::JavaScriptOwnership);\n"
|
||||
" QJSValue(callback).call(QJSValueList{jsEngine->toScriptValue(result)});\n"
|
||||
" }, [errorCallback, jsEngine](const QGrpcStatus &status) {\n"
|
||||
" QJSValue(errorCallback).call(QJSValueList{jsEngine->toScriptValue(status)});\n"
|
||||
" });\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientMethodDefinitionQml2Template()
|
||||
{
|
||||
return "\nvoid $classname$::$method_name$($param_type$ *$param_name$, $return_type$ "
|
||||
"*$return_name$, const QJSValue &errorCallback)\n"
|
||||
"{\n"
|
||||
" if ($return_name$ == nullptr) {\n"
|
||||
" qWarning() << \"Invalid argument provided for method "
|
||||
"$classname$::$method_name$, "
|
||||
"argument of type '$return_type$ *' expected\";\n"
|
||||
" return;\n"
|
||||
" }\n\n"
|
||||
" QWeakPointer<$return_type$> safeReturn($return_name$);\n\n"
|
||||
" if ($param_name$ == nullptr) {\n"
|
||||
" qWarning() << \"Invalid argument provided for method "
|
||||
"$classname$::$method_name$, "
|
||||
"argument of type '$param_type$ *' expected\";\n"
|
||||
" return;\n"
|
||||
" }\n\n"
|
||||
" QJSEngine *jsEngine = qjsEngine(this);\n"
|
||||
" if (jsEngine == nullptr) {\n"
|
||||
" qWarning() << \"Unable to call $classname$::$method_name$, it's only callable "
|
||||
"from JS engine context\";\n"
|
||||
" return;\n"
|
||||
" }\n\n"
|
||||
" std::shared_ptr<QGrpcCallReply> reply = call<$param_type$>(\"$method_name$\", "
|
||||
"*$param_name$);\n"
|
||||
" reply->subscribe(jsEngine, [this, reply, jsEngine, safeReturn]() {\n"
|
||||
" if (safeReturn.isNull()) {\n"
|
||||
" qWarning() << \"Return value is destroyed. Ignore call result\";\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
" *safeReturn = $return_type$(reply->read<$return_type$>());\n"
|
||||
" }, [errorCallback, jsEngine](const QGrpcStatus &status) {\n"
|
||||
" QJSValue(errorCallback).call(QJSValueList{jsEngine->toScriptValue(status)});\n"
|
||||
" });\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientMethodServerStreamDeclarationTemplate()
|
||||
{
|
||||
return "std::shared_ptr<QGrpcStream> stream$method_name_upper$(const $param_type$ "
|
||||
"&$param_name$);\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientMethodServerStream2DeclarationTemplate()
|
||||
{
|
||||
return "std::shared_ptr<QGrpcStream> stream$method_name_upper$(const $param_type$ "
|
||||
"&$param_name$, const "
|
||||
"QWeakPointer<$return_type$> &$return_name$);\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientMethodServerStreamQmlDeclarationTemplate()
|
||||
{
|
||||
return "Q_INVOKABLE std::shared_ptr<QGrpcStream> qmlStream$method_name_upper$_p($param_type$ "
|
||||
"*$param_name$, "
|
||||
"$return_type$ *$return_name$);\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientMethodServerStreamDefinitionTemplate()
|
||||
{
|
||||
return "std::shared_ptr<QGrpcStream> $classname$::stream$method_name_upper$(const $param_type$ "
|
||||
"&$param_name$)\n"
|
||||
"{\n"
|
||||
" return stream<$param_type$>(\"$method_name$\", $param_name$);\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientMethodServerStream2DefinitionTemplate()
|
||||
{
|
||||
return "std::shared_ptr<QGrpcStream> $classname$::stream$method_name_upper$(const $param_type$ "
|
||||
"&$param_name$, const QWeakPointer<$return_type$> &$return_name$)\n"
|
||||
"{\n"
|
||||
" return stream<$param_type$>(\"$method_name$\", $param_name$, $return_name$);\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
const char *Templates::ClientMethodServerStreamQmlDefinitionTemplate()
|
||||
{
|
||||
return "std::shared_ptr<QGrpcStream> $classname$::qmlStream$method_name_upper$_p($param_type$ "
|
||||
"*$param_name$, "
|
||||
"$return_type$ *$return_name$)\n"
|
||||
"{\n"
|
||||
" return stream<$param_type$>(\"$method_name$\", *$param_name$, "
|
||||
"QWeakPointer<$return_type$>($return_name$));\n"
|
||||
"}\n";
|
||||
}
|
||||
|
|
@ -2,16 +2,16 @@
|
|||
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>, Tatyana Borisova <tanusshhka@mail.ru>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef QTPROTOBUFGEN_TEMPLATES_H
|
||||
#define QTPROTOBUFGEN_TEMPLATES_H
|
||||
#ifndef QTPROTOCCOMMON_TEMPLATES_H
|
||||
#define QTPROTOCCOMMON_TEMPLATES_H
|
||||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
namespace QtProtobuf::generator {
|
||||
namespace qtprotoccommon {
|
||||
|
||||
class Templates
|
||||
class CommonTemplates
|
||||
{
|
||||
public:
|
||||
static const std::vector<std::string> &ListOfQmlExceptions();
|
||||
|
|
@ -150,38 +150,8 @@ public:
|
|||
static const char *QtProtobufFieldEnum();
|
||||
|
||||
static const char *ExportMacroTemplate();
|
||||
|
||||
// gRPC
|
||||
static const char *ChildClassDeclarationTemplate();
|
||||
|
||||
static const char *GrpcClientFileSuffix();
|
||||
static const char *GrpcServiceFileSuffix();
|
||||
|
||||
static const char *ClientConstructorDefinitionTemplate();
|
||||
static const char *QObjectConstructorMessageDeclarationTemplate();
|
||||
|
||||
static const char *ClientMethodDeclarationSyncTemplate();
|
||||
static const char *ClientMethodDeclarationAsyncTemplate();
|
||||
static const char *ClientMethodDeclarationAsync2Template();
|
||||
static const char *ClientMethodDeclarationQmlTemplate();
|
||||
static const char *ClientMethodDeclarationQml2Template();
|
||||
|
||||
static const char *ServerMethodDeclarationTemplate();
|
||||
|
||||
static const char *ClientMethodDefinitionSyncTemplate();
|
||||
static const char *ClientMethodDefinitionAsyncTemplate();
|
||||
static const char *ClientMethodDefinitionAsync2Template();
|
||||
static const char *ClientMethodDefinitionQmlTemplate();
|
||||
static const char *ClientMethodDefinitionQml2Template();
|
||||
|
||||
static const char *ClientMethodServerStreamDeclarationTemplate();
|
||||
static const char *ClientMethodServerStream2DeclarationTemplate();
|
||||
static const char *ClientMethodServerStreamQmlDeclarationTemplate();
|
||||
|
||||
static const char *ClientMethodServerStreamDefinitionTemplate();
|
||||
static const char *ClientMethodServerStream2DefinitionTemplate();
|
||||
static const char *ClientMethodServerStreamQmlDefinitionTemplate();
|
||||
};
|
||||
|
||||
} // namespace QtProtobuf::generator
|
||||
#endif // QTPROTOBUFGEN_TEMPLATES_H
|
||||
} // namespace qtprotoccommon
|
||||
#endif // QTPROTOCCOMMON_TEMPLATES_H
|
||||
|
|
@ -7,11 +7,10 @@
|
|||
|
||||
#include "baseprinter.h"
|
||||
|
||||
#include "templates.h"
|
||||
#include "options.h"
|
||||
#include "commontemplates.h"
|
||||
#include "generatorcommon.h"
|
||||
|
||||
namespace QtProtobuf::generator {
|
||||
namespace qtprotoccommon {
|
||||
|
||||
template<typename T>
|
||||
class DescriptorPrinterBase : public BasePrinter
|
||||
|
|
@ -27,7 +26,7 @@ public:
|
|||
|
||||
void encloseClass()
|
||||
{
|
||||
m_printer->Print(Templates::SemicolonBlockEnclosureTemplate());
|
||||
m_printer->Print(CommonTemplates::SemicolonBlockEnclosureTemplate());
|
||||
m_printer->Print("\n");
|
||||
}
|
||||
|
||||
|
|
@ -35,6 +34,6 @@ protected:
|
|||
const T *m_descriptor;
|
||||
TypeMap m_typeMap;
|
||||
};
|
||||
} // namespace QtProtobuf::generator
|
||||
} // namespace qtprotoccommon
|
||||
|
||||
#endif // DESCRIPTORPRINTERBASE_H
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#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 "commontemplates.h"
|
||||
#include "generatorcommon.h"
|
||||
#include "options.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
using namespace ::google::protobuf;
|
||||
using namespace ::google::protobuf::io;
|
||||
using namespace ::google::protobuf::compiler;
|
||||
using namespace ::qtprotoccommon;
|
||||
|
||||
bool GeneratorBase::GenerateAll(const std::vector<const FileDescriptor *> &files,
|
||||
const std::string ¶meter, GeneratorContext *generatorContext,
|
||||
std::string *error) const
|
||||
{
|
||||
Options::setFromString(parameter);
|
||||
return CodeGenerator::GenerateAll(files, parameter, generatorContext, error);
|
||||
}
|
||||
|
||||
std::string GeneratorBase::generateBaseName(const FileDescriptor *file, const std::string &name)
|
||||
{
|
||||
std::string outFileBasename;
|
||||
if (Options::instance().isFolder()) {
|
||||
outFileBasename = file->package();
|
||||
outFileBasename = utils::replace(outFileBasename, ".", "/");
|
||||
outFileBasename += '/';
|
||||
}
|
||||
outFileBasename += name;
|
||||
|
||||
return outFileBasename;
|
||||
}
|
||||
|
||||
void GeneratorBase::printDisclaimer(Printer *printer)
|
||||
{
|
||||
printer->Print(CommonTemplates::DisclaimerTemplate());
|
||||
}
|
||||
|
||||
void GeneratorBase::OpenFileNamespaces(
|
||||
const FileDescriptor *file,
|
||||
google::protobuf::io::Printer *printer) const
|
||||
{
|
||||
assert(printer != nullptr);
|
||||
const bool hasQtNamespace = (Options::instance().extraNamespace() == "QT_NAMESPACE");
|
||||
const std::string scopeNamespaces = file->message_type_count() > 0
|
||||
? common::getFullNamespace(file->message_type(0), "::")
|
||||
: common::getFullNamespace(file->enum_type(0), "::");
|
||||
printer->Print("\n");
|
||||
if (hasQtNamespace)
|
||||
printer->PrintRaw("QT_BEGIN_NAMESPACE\n");
|
||||
if (!scopeNamespaces.empty()) {
|
||||
printer->Print({ { "scope_namespaces", scopeNamespaces } },
|
||||
CommonTemplates::NamespaceTemplate());
|
||||
}
|
||||
}
|
||||
|
||||
void GeneratorBase::CloseFileNamespaces(
|
||||
const ::google::protobuf::FileDescriptor *file,
|
||||
google::protobuf::io::Printer *printer) const
|
||||
{
|
||||
assert(printer != nullptr);
|
||||
const bool hasQtNamespace = (Options::instance().extraNamespace() == "QT_NAMESPACE");
|
||||
const std::string scopeNamespaces = file->message_type_count() > 0
|
||||
? common::getFullNamespace(file->message_type(0), "::")
|
||||
: common::getFullNamespace(file->enum_type(0), "::");
|
||||
if (!scopeNamespaces.empty()) {
|
||||
printer->Print({ { "scope_namespaces", scopeNamespaces } },
|
||||
CommonTemplates::NamespaceClosingTemplate());
|
||||
}
|
||||
if (hasQtNamespace)
|
||||
printer->PrintRaw("QT_END_NAMESPACE\n");
|
||||
printer->Print("\n");
|
||||
}
|
||||
|
|
@ -6,11 +6,9 @@
|
|||
#define GENERATORBASE_H
|
||||
|
||||
#include <google/protobuf/compiler/code_generator.h>
|
||||
#include <google/protobuf/io/zero_copy_stream.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
namespace google::protobuf {
|
||||
class FileDescriptor;
|
||||
|
|
@ -18,9 +16,12 @@ class Descriptor;
|
|||
namespace compiler {
|
||||
class GeneratorContext;
|
||||
} // namespace compiler
|
||||
namespace io {
|
||||
class Printer;
|
||||
} // namespace io
|
||||
} // namespace google::protobuf
|
||||
|
||||
namespace QtProtobuf::generator {
|
||||
namespace qtprotoccommon {
|
||||
class GeneratorBase : public ::google::protobuf::compiler::CodeGenerator
|
||||
{
|
||||
GeneratorBase(const GeneratorBase &) = delete;
|
||||
|
|
@ -37,11 +38,15 @@ public:
|
|||
bool HasGenerateAll() const override { return true; }
|
||||
|
||||
static void printDisclaimer(::google::protobuf::io::Printer *printer);
|
||||
void OpenFileNamespaces(const ::google::protobuf::FileDescriptor *file,
|
||||
google::protobuf::io::Printer *printer) const;
|
||||
void CloseFileNamespaces(const ::google::protobuf::FileDescriptor *file,
|
||||
google::protobuf::io::Printer *printer) const;
|
||||
|
||||
protected:
|
||||
static std::string generateBaseName(const ::google::protobuf::FileDescriptor *file,
|
||||
const std::string &name);
|
||||
};
|
||||
} // namespace QtProtobuf::generator
|
||||
} // namespace qtprotoccommon
|
||||
|
||||
#endif // GENERATORBASE_H
|
||||
|
|
@ -5,13 +5,14 @@
|
|||
#include "generatorcommon.h"
|
||||
#include "options.h"
|
||||
#include "utils.h"
|
||||
#include "commontemplates.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace ::google::protobuf;
|
||||
using namespace ::google::protobuf::io;
|
||||
using namespace ::QtProtobuf::generator;
|
||||
using namespace ::qtprotoccommon;
|
||||
|
||||
/*
|
||||
Constructs a C++ namespace from the full protobuf descriptor name. E.g. for
|
||||
|
|
@ -41,7 +42,7 @@ std::string common::getFullNamespace(std::string_view fullDescriptorName,
|
|||
*/
|
||||
std::string common::getNestedNamespace(const Descriptor *type, std::string_view separator)
|
||||
{
|
||||
static const std::string nestedSuffix = Templates::QtProtobufNestedNamespace();
|
||||
static const std::string nestedSuffix = CommonTemplates::QtProtobufNestedNamespace();
|
||||
|
||||
const std::size_t packageSize =
|
||||
type->file()->package().size() > 0 ? type->file()->package().size() + 1 : 0;
|
||||
|
|
@ -89,7 +90,7 @@ std::string common::getScopeNamespace(std::string_view original, std::string_vie
|
|||
|
||||
std::map<std::string, std::string> common::getNestedScopeNamespace(const std::string &className)
|
||||
{
|
||||
return { { "scope_namespaces", className + Templates::QtProtobufNestedNamespace() } };
|
||||
return { { "scope_namespaces", className + CommonTemplates::QtProtobufNestedNamespace() } };
|
||||
}
|
||||
|
||||
TypeMap common::produceQtTypeMap(const Descriptor *type, const Descriptor *scope)
|
||||
|
|
@ -102,7 +103,7 @@ TypeMap common::produceQtTypeMap(const Descriptor *type, const Descriptor *scope
|
|||
std::string fullName = name;
|
||||
std::string scopeName = name;
|
||||
|
||||
std::string listName = std::string("QList<") + Templates::RepeatedSuffix() + ">";
|
||||
std::string listName = std::string("QList<") + CommonTemplates::RepeatedSuffix() + ">";
|
||||
std::string fullListName = listName;
|
||||
std::string scopeListName = listName;
|
||||
|
||||
|
|
@ -133,7 +134,7 @@ TypeMap common::produceMessageTypeMap(const Descriptor *type, const Descriptor *
|
|||
std::string fullName = namespaces.empty() ? name : (namespaces + "::" + name);
|
||||
std::string scopeName = scopeNamespaces.empty() ? name : (scopeNamespaces + "::" + name);
|
||||
|
||||
std::string listName = name + Templates::RepeatedSuffix();
|
||||
std::string listName = name + CommonTemplates::RepeatedSuffix();
|
||||
std::string fullListName = namespaces.empty() ? listName : (namespaces + "::" + listName);
|
||||
std::string scopeListName =
|
||||
scopeNamespaces.empty() ? listName : (scopeNamespaces + "::" + listName);
|
||||
|
|
@ -172,7 +173,7 @@ TypeMap common::produceEnumTypeMap(const EnumDescriptor *type, const Descriptor
|
|||
// Not used:
|
||||
std::string enumGadget = scope != nullptr ? utils::capitalizeAsciiName(scope->name()) : "";
|
||||
if (visibility == GLOBAL_ENUM) {
|
||||
enumGadget = name + Templates::EnumClassSuffix();
|
||||
enumGadget = name + CommonTemplates::EnumClassSuffix();
|
||||
namespaces += "::";
|
||||
namespaces += enumGadget; // Global enums are stored in helper Gadget
|
||||
}
|
||||
|
|
@ -182,7 +183,7 @@ TypeMap common::produceEnumTypeMap(const EnumDescriptor *type, const Descriptor
|
|||
std::string fullName = namespaces.empty() ? name : (namespaces + "::" + name);
|
||||
std::string scopeName = scopeNamespaces.empty() ? name : (scopeNamespaces + "::" + name);
|
||||
|
||||
std::string listName = name + Templates::RepeatedSuffix();
|
||||
std::string listName = name + CommonTemplates::RepeatedSuffix();
|
||||
std::string fullListName = namespaces.empty() ? listName : (namespaces + "::" + listName);
|
||||
std::string scopeListName =
|
||||
scopeNamespaces.empty() ? listName : (scopeNamespaces + "::" + listName);
|
||||
|
|
@ -218,14 +219,14 @@ TypeMap common::produceSimpleTypeMap(FieldDescriptor::Type type)
|
|||
if (type != FieldDescriptor::TYPE_STRING && type != FieldDescriptor::TYPE_BYTES
|
||||
&& type != FieldDescriptor::TYPE_BOOL && type != FieldDescriptor::TYPE_FLOAT
|
||||
&& type != FieldDescriptor::TYPE_DOUBLE) {
|
||||
namespaces = Templates::QtProtobufNamespace();
|
||||
namespaces = CommonTemplates::QtProtobufNamespace();
|
||||
}
|
||||
|
||||
std::string name;
|
||||
std::string qmlPackage = Templates::QtProtobufNamespace();
|
||||
std::string qmlPackage = CommonTemplates::QtProtobufNamespace();
|
||||
|
||||
auto it = Templates::TypeReflection().find(type);
|
||||
if (it != std::end(Templates::TypeReflection()))
|
||||
auto it = CommonTemplates::TypeReflection().find(type);
|
||||
if (it != std::end(CommonTemplates::TypeReflection()))
|
||||
name = it->second;
|
||||
else
|
||||
assert(name.empty());
|
||||
|
|
@ -235,7 +236,7 @@ TypeMap common::produceSimpleTypeMap(FieldDescriptor::Type type)
|
|||
using namespace std::string_literals;
|
||||
std::string fullListName = listName;
|
||||
if (type != FieldDescriptor::TYPE_STRING && type != FieldDescriptor::TYPE_BYTES)
|
||||
fullListName = Templates::QtProtobufNamespace() + "::"s + listName;
|
||||
fullListName = CommonTemplates::QtProtobufNamespace() + "::"s + listName;
|
||||
std::string scopeListName = fullListName;
|
||||
|
||||
std::string qmlAliasType;
|
||||
|
|
@ -406,10 +407,10 @@ PropertyMap common::producePropertyMap(const FieldDescriptor *field, const Descr
|
|||
std::string common::qualifiedName(const std::string &name)
|
||||
{
|
||||
std::string fieldName(name);
|
||||
const std::vector<std::string> &searchExceptions = Templates::ListOfQmlExceptions();
|
||||
const std::vector<std::string> &searchExceptions = CommonTemplates::ListOfQmlExceptions();
|
||||
|
||||
if (utils::contains(searchExceptions, fieldName))
|
||||
return fieldName.append(Templates::ProtoSuffix());
|
||||
return fieldName.append(CommonTemplates::ProtoSuffix());
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
|
|
@ -6,19 +6,15 @@
|
|||
#define GENERATORCOMMON_H
|
||||
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <vector>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <functional>
|
||||
|
||||
#include "utils.h"
|
||||
#include "templates.h"
|
||||
#include "options.h"
|
||||
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
namespace QtProtobuf::generator {
|
||||
namespace qtprotoccommon {
|
||||
|
||||
using TypeMap = std::map<std::string, std::string>;
|
||||
using PropertyMap = std::map<std::string, std::string>;
|
||||
|
|
@ -89,6 +85,6 @@ struct common {
|
|||
|
||||
static std::string collectFieldFlags(const google::protobuf::FieldDescriptor *field);
|
||||
};
|
||||
} // namespace QtProtobuf::generator
|
||||
} // namespace qtprotoccommon
|
||||
|
||||
#endif // GENERATORCOMMON_H
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "utils.h"
|
||||
|
||||
using namespace ::QtProtobuf::generator;
|
||||
using namespace ::qtprotoccommon;
|
||||
|
||||
static const char QmlPluginOption[] = "QML";
|
||||
static const char CommentsGenerationOption[] = "COPY_COMMENTS";
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
namespace QtProtobuf::generator {
|
||||
namespace qtprotoccommon {
|
||||
|
||||
/*!
|
||||
\ingroup generator
|
||||
|
|
@ -5,8 +5,6 @@
|
|||
#include "utils.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <ctype.h>
|
||||
|
|
@ -16,7 +14,7 @@ namespace {
|
|||
const std::string_view asciiSpacing = " \t\n\r\f\v";
|
||||
}
|
||||
|
||||
namespace QtProtobuf::generator::utils {
|
||||
namespace qtprotoccommon::utils {
|
||||
|
||||
bool isAsciiAlpha(char c)
|
||||
{
|
||||
|
|
@ -177,4 +175,4 @@ size_t count(std::string_view s, char c)
|
|||
{
|
||||
return std::count(s.begin(), s.end(), c);
|
||||
}
|
||||
} // namespace QtProtobuf::generator::utils
|
||||
} // namespace qtprotoccommon::utils
|
||||
|
|
@ -7,8 +7,6 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef QT_PROTOBUF_DEBUG_GENERATOR
|
||||
|
|
@ -22,7 +20,7 @@ namespace google::protobuf {
|
|||
class FileDescriptor;
|
||||
}
|
||||
|
||||
namespace QtProtobuf::generator {
|
||||
namespace qtprotoccommon {
|
||||
namespace utils {
|
||||
std::vector<std::string> split(std::string_view s, std::string_view c, bool keepEmpty = false);
|
||||
std::string replace(std::string_view where, std::string_view from, std::string_view to);
|
||||
|
|
@ -68,6 +66,5 @@ std::string join(const T &container, std::string_view separator, std::string_vie
|
|||
size_t count(std::string_view s, char c);
|
||||
|
||||
} // namespace utils
|
||||
|
||||
} // namespace QtProtobuf::generator
|
||||
} // namespace qtprotoccommon
|
||||
#endif // QTPROTOBUFGEN_UTILS_H
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
add_subdirectory(protobuf)
|
||||
if(QT_FEATURE_qtprotobufgen AND NOT CMAKE_CROSSCOMPILING)
|
||||
add_subdirectory(protobufgen)
|
||||
add_subdirectory(grpcgen)
|
||||
endif()
|
||||
|
||||
if(QT_FEATURE_grpc)
|
||||
|
|
|
|||
|
|
@ -11,10 +11,14 @@ qt6_add_protobuf(tst_grpc_client_qtgrpc_gen
|
|||
PROTO_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../shared/proto/testservice.proto
|
||||
)
|
||||
target_link_libraries(tst_grpc_client_qtgrpc_gen PRIVATE Qt::Grpc)
|
||||
|
||||
qt6_add_grpc(tst_grpc_client_qtgrpc_gen CLIENT
|
||||
PROTO_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../shared/proto/testservice.proto
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/qt_grpc_generated"
|
||||
)
|
||||
|
||||
qt_autogen_tools_initial_setup(tst_grpc_client_qtgrpc_gen)
|
||||
|
||||
qt_internal_add_test(tst_grpc_client
|
||||
SOURCES
|
||||
tst_grpc_client.cpp
|
||||
|
|
@ -24,7 +28,6 @@ qt_internal_add_test(tst_grpc_client
|
|||
Qt::Test
|
||||
Qt::Core
|
||||
Qt::Grpc
|
||||
WrapgRPC::WrapLibgRPC
|
||||
tst_grpc_client_qtgrpc_gen
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,18 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
qt6_add_protobuf(tst_grpc_server_qtgrpc_gen
|
||||
OUTPUT_DIRECTORY
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/qt_grpc_generated"
|
||||
PROTO_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../shared/proto/testservice.proto
|
||||
OUTPUT_DIRECTORY
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/qt_grpc_generated"
|
||||
)
|
||||
|
||||
qt6_add_grpc(tst_grpc_server_qtgrpc_gen CLIENT
|
||||
PROTO_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../shared/proto/testservice.proto
|
||||
OUTPUT_DIRECTORY
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/qt_grpc_generated"
|
||||
)
|
||||
target_link_libraries(tst_grpc_server_qtgrpc_gen PRIVATE Qt::Grpc)
|
||||
|
||||
qt_autogen_tools_initial_setup(tst_grpc_server_qtgrpc_gen)
|
||||
|
||||
|
|
|
|||
|
|
@ -6,12 +6,17 @@ if(NOT TARGET securetestserver)
|
|||
endif()
|
||||
|
||||
qt6_add_protobuf(tst_grpc_ssl_client_qtgrpc_gen
|
||||
OUTPUT_DIRECTORY
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/qt_grpc_generated"
|
||||
PROTO_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../shared/proto/testservice.proto
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/qt_grpc_generated"
|
||||
)
|
||||
|
||||
qt6_add_grpc(tst_grpc_ssl_client_qtgrpc_gen CLIENT
|
||||
PROTO_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../shared/proto/testservice.proto
|
||||
OUTPUT_DIRECTORY
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/qt_grpc_generated"
|
||||
)
|
||||
target_link_libraries(tst_grpc_ssl_client_qtgrpc_gen PRIVATE Qt::Grpc)
|
||||
|
||||
qt_autogen_tools_initial_setup(tst_grpc_ssl_client_qtgrpc_gen)
|
||||
|
||||
|
|
@ -25,7 +30,6 @@ qt_internal_add_test(tst_grpc_ssl_client
|
|||
Qt::Core
|
||||
Qt::Grpc
|
||||
Qt::Network
|
||||
WrapgRPC::WrapLibgRPC
|
||||
tst_grpc_ssl_client_qtgrpc_gen
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,17 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
qt6_add_protobuf(tst_grpc_unattached_channel_qtgrpc_gen
|
||||
PROTO_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../shared/proto/testservice.proto
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/qt_grpc_generated"
|
||||
)
|
||||
|
||||
qt6_add_grpc(tst_grpc_unattached_channel_qtgrpc_gen CLIENT
|
||||
PROTO_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../shared/proto/testservice.proto
|
||||
OUTPUT_DIRECTORY
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/qt_grpc_generated"
|
||||
PROTO_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../shared/proto/testservice.proto
|
||||
)
|
||||
target_link_libraries(tst_grpc_unattached_channel_qtgrpc_gen PRIVATE Qt::Grpc)
|
||||
|
||||
qt_autogen_tools_initial_setup(tst_grpc_unattached_channel_qtgrpc_gen)
|
||||
|
||||
qt_internal_add_test(tst_grpc_unattached_channel
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
# Blacklist for testing on ARM macos due to QTBUG-109130
|
||||
[initTestCase]
|
||||
macos arm ci
|
||||
[cmakeGeneratedFile_data]
|
||||
macos arm ci
|
||||
[cmakeGeneratedFile]
|
||||
macos arm ci
|
||||
[cmdLineGeneratedFile_data]
|
||||
macos arm ci
|
||||
[cmdLineGeneratedFile]
|
||||
macos arm ci
|
||||
[cmdLineGeneratedNoOptions_data]
|
||||
macos arm ci
|
||||
[cmdLineGeneratedNoOptions]
|
||||
macos arm ci
|
||||
[cleanupTestCase]
|
||||
macos arm ci
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
qt_internal_add_test(tst_qtgrpcgen
|
||||
SOURCES
|
||||
tst_qtgrpcgen.cpp
|
||||
LIBRARIES
|
||||
Qt::Test
|
||||
Qt::Protobuf
|
||||
Qt::Grpc
|
||||
DEFINES
|
||||
PROTOC_EXECUTABLE="$<TARGET_FILE:WrapProtoc::WrapProtoc>"
|
||||
)
|
||||
|
||||
qt_add_protobuf(tst_qtgrpcgen
|
||||
OUTPUT_DIRECTORY
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/qt_grpc_generated/folder"
|
||||
GENERATE_PACKAGE_SUBFOLDERS
|
||||
PROTO_FILES
|
||||
../shared/data/proto/testservice.proto
|
||||
)
|
||||
|
||||
qt_add_grpc(tst_qtgrpcgen CLIENT
|
||||
PROTO_FILES
|
||||
../shared/data/proto/testservice.proto
|
||||
GENERATE_PACKAGE_SUBFOLDERS
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/qt_grpc_generated/folder"
|
||||
)
|
||||
|
||||
qt_autogen_tools_initial_setup(tst_qtgrpcgen)
|
||||
|
|
@ -0,0 +1,255 @@
|
|||
/* This file is autogenerated. DO NOT CHANGE. All changes will be lost */
|
||||
|
||||
#include "qtgrpc/tests/testservice.qpb.h"
|
||||
#include <QProtobufSerializer>
|
||||
|
||||
namespace qtgrpc::tests {
|
||||
SimpleStringMessage::~SimpleStringMessage() = default;
|
||||
|
||||
static constexpr struct {
|
||||
QtProtobufPrivate::QProtobufPropertyOrdering::Data data;
|
||||
const std::array<uint, 5> qt_protobuf_SimpleStringMessage_uint_data;
|
||||
const char qt_protobuf_SimpleStringMessage_char_data[50];
|
||||
} qt_protobuf_SimpleStringMessage_metadata {
|
||||
// data
|
||||
{
|
||||
0, /* = version */
|
||||
1, /* = num fields */
|
||||
2, /* = field number offset */
|
||||
3, /* = property index offset */
|
||||
4, /* = field flags offset */
|
||||
32, /* = message full name length */
|
||||
},
|
||||
// uint_data
|
||||
{
|
||||
// JSON name offsets:
|
||||
33, /* = testFieldString */
|
||||
49, /* = end-of-string-marker */
|
||||
// Field numbers:
|
||||
6, /* = testFieldString */
|
||||
// Property indices:
|
||||
0, /* = testFieldString */
|
||||
// Field flags:
|
||||
QtProtobufPrivate::NoFlags, /* = testFieldString */
|
||||
},
|
||||
// char_data
|
||||
/* metadata char_data: */
|
||||
"qtgrpc.tests.SimpleStringMessage\0" /* = full message name */
|
||||
/* field char_data: */
|
||||
"testFieldString\0"
|
||||
};
|
||||
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering SimpleStringMessage::propertyOrdering = {
|
||||
&qt_protobuf_SimpleStringMessage_metadata.data
|
||||
};
|
||||
|
||||
void SimpleStringMessage::registerTypes()
|
||||
{
|
||||
qRegisterMetaType<SimpleStringMessage>();
|
||||
qRegisterMetaType<SimpleStringMessageRepeated>();
|
||||
}
|
||||
SimpleStringMessage::SimpleStringMessage() : QProtobufMessage(&SimpleStringMessage::staticMetaObject)
|
||||
{
|
||||
}
|
||||
SimpleStringMessage::SimpleStringMessage(const SimpleStringMessage &other) : QProtobufMessage(other)
|
||||
{
|
||||
setTestFieldString(other.m_testFieldString);
|
||||
}
|
||||
SimpleStringMessage &SimpleStringMessage::operator =(const SimpleStringMessage &other)
|
||||
{
|
||||
QProtobufMessage::operator=(other);
|
||||
setTestFieldString(other.m_testFieldString);
|
||||
return *this;
|
||||
}
|
||||
SimpleStringMessage::SimpleStringMessage(SimpleStringMessage &&other) noexcept : QProtobufMessage(std::move(other))
|
||||
{
|
||||
m_testFieldString = std::move(other.m_testFieldString);
|
||||
}
|
||||
SimpleStringMessage &SimpleStringMessage::operator =(SimpleStringMessage &&other) noexcept
|
||||
{
|
||||
QProtobufMessage::operator=(std::move(other));
|
||||
if (m_testFieldString != other.m_testFieldString)
|
||||
m_testFieldString = std::move(other.m_testFieldString);
|
||||
return *this;
|
||||
}
|
||||
bool SimpleStringMessage::operator ==(const SimpleStringMessage &other) const
|
||||
{
|
||||
return QProtobufMessage::isEqual(*this, other)
|
||||
&& m_testFieldString == other.m_testFieldString;
|
||||
}
|
||||
bool SimpleStringMessage::operator !=(const SimpleStringMessage &other) const
|
||||
{
|
||||
return !this->operator ==(other);
|
||||
}
|
||||
|
||||
void SimpleStringMessage::setTestFieldString(const QString &testFieldString)
|
||||
{
|
||||
if (m_testFieldString != testFieldString)
|
||||
m_testFieldString = testFieldString;
|
||||
}
|
||||
|
||||
SimpleIntMessage::~SimpleIntMessage() = default;
|
||||
|
||||
static constexpr struct {
|
||||
QtProtobufPrivate::QProtobufPropertyOrdering::Data data;
|
||||
const std::array<uint, 5> qt_protobuf_SimpleIntMessage_uint_data;
|
||||
const char qt_protobuf_SimpleIntMessage_char_data[41];
|
||||
} qt_protobuf_SimpleIntMessage_metadata {
|
||||
// data
|
||||
{
|
||||
0, /* = version */
|
||||
1, /* = num fields */
|
||||
2, /* = field number offset */
|
||||
3, /* = property index offset */
|
||||
4, /* = field flags offset */
|
||||
29, /* = message full name length */
|
||||
},
|
||||
// uint_data
|
||||
{
|
||||
// JSON name offsets:
|
||||
30, /* = testField */
|
||||
40, /* = end-of-string-marker */
|
||||
// Field numbers:
|
||||
1, /* = testField */
|
||||
// Property indices:
|
||||
0, /* = testField */
|
||||
// Field flags:
|
||||
QtProtobufPrivate::NoFlags, /* = testField */
|
||||
},
|
||||
// char_data
|
||||
/* metadata char_data: */
|
||||
"qtgrpc.tests.SimpleIntMessage\0" /* = full message name */
|
||||
/* field char_data: */
|
||||
"testField\0"
|
||||
};
|
||||
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering SimpleIntMessage::propertyOrdering = {
|
||||
&qt_protobuf_SimpleIntMessage_metadata.data
|
||||
};
|
||||
|
||||
void SimpleIntMessage::registerTypes()
|
||||
{
|
||||
qRegisterMetaType<SimpleIntMessage>();
|
||||
qRegisterMetaType<SimpleIntMessageRepeated>();
|
||||
}
|
||||
SimpleIntMessage::SimpleIntMessage() : QProtobufMessage(&SimpleIntMessage::staticMetaObject),
|
||||
m_testField(0)
|
||||
{
|
||||
}
|
||||
SimpleIntMessage::SimpleIntMessage(const SimpleIntMessage &other) : QProtobufMessage(other)
|
||||
{
|
||||
setTestField(other.m_testField);
|
||||
}
|
||||
SimpleIntMessage &SimpleIntMessage::operator =(const SimpleIntMessage &other)
|
||||
{
|
||||
QProtobufMessage::operator=(other);
|
||||
setTestField(other.m_testField);
|
||||
return *this;
|
||||
}
|
||||
SimpleIntMessage::SimpleIntMessage(SimpleIntMessage &&other) noexcept : QProtobufMessage(std::move(other))
|
||||
{
|
||||
setTestField(std::exchange(other.m_testField, 0));
|
||||
}
|
||||
SimpleIntMessage &SimpleIntMessage::operator =(SimpleIntMessage &&other) noexcept
|
||||
{
|
||||
QProtobufMessage::operator=(std::move(other));
|
||||
setTestField(std::exchange(other.m_testField, 0));
|
||||
return *this;
|
||||
}
|
||||
bool SimpleIntMessage::operator ==(const SimpleIntMessage &other) const
|
||||
{
|
||||
return QProtobufMessage::isEqual(*this, other)
|
||||
&& m_testField == other.m_testField;
|
||||
}
|
||||
bool SimpleIntMessage::operator !=(const SimpleIntMessage &other) const
|
||||
{
|
||||
return !this->operator ==(other);
|
||||
}
|
||||
|
||||
BlobMessage::~BlobMessage() = default;
|
||||
|
||||
static constexpr struct {
|
||||
QtProtobufPrivate::QProtobufPropertyOrdering::Data data;
|
||||
const std::array<uint, 5> qt_protobuf_BlobMessage_uint_data;
|
||||
const char qt_protobuf_BlobMessage_char_data[36];
|
||||
} qt_protobuf_BlobMessage_metadata {
|
||||
// data
|
||||
{
|
||||
0, /* = version */
|
||||
1, /* = num fields */
|
||||
2, /* = field number offset */
|
||||
3, /* = property index offset */
|
||||
4, /* = field flags offset */
|
||||
24, /* = message full name length */
|
||||
},
|
||||
// uint_data
|
||||
{
|
||||
// JSON name offsets:
|
||||
25, /* = testBytes */
|
||||
35, /* = end-of-string-marker */
|
||||
// Field numbers:
|
||||
1, /* = testBytes */
|
||||
// Property indices:
|
||||
0, /* = testBytes */
|
||||
// Field flags:
|
||||
QtProtobufPrivate::NoFlags, /* = testBytes */
|
||||
},
|
||||
// char_data
|
||||
/* metadata char_data: */
|
||||
"qtgrpc.tests.BlobMessage\0" /* = full message name */
|
||||
/* field char_data: */
|
||||
"testBytes\0"
|
||||
};
|
||||
|
||||
const QtProtobufPrivate::QProtobufPropertyOrdering BlobMessage::propertyOrdering = {
|
||||
&qt_protobuf_BlobMessage_metadata.data
|
||||
};
|
||||
|
||||
void BlobMessage::registerTypes()
|
||||
{
|
||||
qRegisterMetaType<BlobMessage>();
|
||||
qRegisterMetaType<BlobMessageRepeated>();
|
||||
}
|
||||
BlobMessage::BlobMessage() : QProtobufMessage(&BlobMessage::staticMetaObject)
|
||||
{
|
||||
}
|
||||
BlobMessage::BlobMessage(const BlobMessage &other) : QProtobufMessage(other)
|
||||
{
|
||||
setTestBytes(other.m_testBytes);
|
||||
}
|
||||
BlobMessage &BlobMessage::operator =(const BlobMessage &other)
|
||||
{
|
||||
QProtobufMessage::operator=(other);
|
||||
setTestBytes(other.m_testBytes);
|
||||
return *this;
|
||||
}
|
||||
BlobMessage::BlobMessage(BlobMessage &&other) noexcept : QProtobufMessage(std::move(other))
|
||||
{
|
||||
m_testBytes = std::move(other.m_testBytes);
|
||||
}
|
||||
BlobMessage &BlobMessage::operator =(BlobMessage &&other) noexcept
|
||||
{
|
||||
QProtobufMessage::operator=(std::move(other));
|
||||
if (m_testBytes != other.m_testBytes)
|
||||
m_testBytes = std::move(other.m_testBytes);
|
||||
return *this;
|
||||
}
|
||||
bool BlobMessage::operator ==(const BlobMessage &other) const
|
||||
{
|
||||
return QProtobufMessage::isEqual(*this, other)
|
||||
&& m_testBytes == other.m_testBytes;
|
||||
}
|
||||
bool BlobMessage::operator !=(const BlobMessage &other) const
|
||||
{
|
||||
return !this->operator ==(other);
|
||||
}
|
||||
|
||||
void BlobMessage::setTestBytes(const QByteArray &testBytes)
|
||||
{
|
||||
if (m_testBytes != testBytes)
|
||||
m_testBytes = testBytes;
|
||||
}
|
||||
|
||||
} // namespace qtgrpc::tests
|
||||
|
||||
#include "moc_testservice.qpb.cpp"
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
/* This file is autogenerated. DO NOT CHANGE. All changes will be lost */
|
||||
|
||||
#ifndef Q_PROTOBUF_testservice_H
|
||||
#define Q_PROTOBUF_testservice_H
|
||||
|
||||
#include <QtProtobuf/QProtobufMessage>
|
||||
#include <QtCore/QMetaType>
|
||||
#include <QtCore/QList>
|
||||
|
||||
#include <QtProtobuf/qprotobufobject.h>
|
||||
#include <QtProtobuf/qprotobuflazymessagepointer.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
|
||||
|
||||
namespace qtgrpc::tests {
|
||||
class SimpleStringMessage;
|
||||
using SimpleStringMessageRepeated = QList<std::shared_ptr<SimpleStringMessage>>;
|
||||
class SimpleIntMessage;
|
||||
using SimpleIntMessageRepeated = QList<std::shared_ptr<SimpleIntMessage>>;
|
||||
class BlobMessage;
|
||||
using BlobMessageRepeated = QList<std::shared_ptr<BlobMessage>>;
|
||||
|
||||
class SimpleStringMessage : public QProtobufMessage
|
||||
{
|
||||
Q_GADGET
|
||||
Q_PROTOBUF_OBJECT
|
||||
Q_DECLARE_PROTOBUF_SERIALIZERS(SimpleStringMessage)
|
||||
Q_PROPERTY(QString testFieldString READ testFieldString WRITE setTestFieldString SCRIPTABLE true)
|
||||
|
||||
public:
|
||||
enum QtProtobufFieldEnum {
|
||||
TestFieldStringProtoFieldNumber = 6,
|
||||
};
|
||||
Q_ENUM(QtProtobufFieldEnum)
|
||||
|
||||
SimpleStringMessage();
|
||||
~SimpleStringMessage() override;
|
||||
SimpleStringMessage(const SimpleStringMessage &other);
|
||||
SimpleStringMessage &operator =(const SimpleStringMessage &other);
|
||||
SimpleStringMessage(SimpleStringMessage &&other) noexcept;
|
||||
SimpleStringMessage &operator =(SimpleStringMessage &&other) noexcept;
|
||||
bool operator ==(const SimpleStringMessage &other) const;
|
||||
bool operator !=(const SimpleStringMessage &other) const;
|
||||
|
||||
QString testFieldString() const {
|
||||
return m_testFieldString;
|
||||
}
|
||||
|
||||
void setTestFieldString(const QString &testFieldString);
|
||||
static void registerTypes();
|
||||
|
||||
private:
|
||||
QString m_testFieldString;
|
||||
};
|
||||
|
||||
|
||||
class SimpleIntMessage : public QProtobufMessage
|
||||
{
|
||||
Q_GADGET
|
||||
Q_PROTOBUF_OBJECT
|
||||
Q_DECLARE_PROTOBUF_SERIALIZERS(SimpleIntMessage)
|
||||
Q_PROPERTY(QtProtobuf::sint32 testField READ testField WRITE setTestField SCRIPTABLE true)
|
||||
|
||||
public:
|
||||
enum QtProtobufFieldEnum {
|
||||
TestFieldProtoFieldNumber = 1,
|
||||
};
|
||||
Q_ENUM(QtProtobufFieldEnum)
|
||||
|
||||
SimpleIntMessage();
|
||||
~SimpleIntMessage() override;
|
||||
SimpleIntMessage(const SimpleIntMessage &other);
|
||||
SimpleIntMessage &operator =(const SimpleIntMessage &other);
|
||||
SimpleIntMessage(SimpleIntMessage &&other) noexcept;
|
||||
SimpleIntMessage &operator =(SimpleIntMessage &&other) noexcept;
|
||||
bool operator ==(const SimpleIntMessage &other) const;
|
||||
bool operator !=(const SimpleIntMessage &other) const;
|
||||
|
||||
QtProtobuf::sint32 testField() const {
|
||||
return m_testField;
|
||||
}
|
||||
|
||||
void setTestField(const QtProtobuf::sint32 &testField) {
|
||||
if (m_testField != testField)
|
||||
m_testField = testField;
|
||||
}
|
||||
|
||||
static void registerTypes();
|
||||
|
||||
private:
|
||||
QtProtobuf::sint32 m_testField;
|
||||
};
|
||||
|
||||
|
||||
class BlobMessage : public QProtobufMessage
|
||||
{
|
||||
Q_GADGET
|
||||
Q_PROTOBUF_OBJECT
|
||||
Q_DECLARE_PROTOBUF_SERIALIZERS(BlobMessage)
|
||||
Q_PROPERTY(QByteArray testBytes READ testBytes WRITE setTestBytes SCRIPTABLE true)
|
||||
|
||||
public:
|
||||
enum QtProtobufFieldEnum {
|
||||
TestBytesProtoFieldNumber = 1,
|
||||
};
|
||||
Q_ENUM(QtProtobufFieldEnum)
|
||||
|
||||
BlobMessage();
|
||||
~BlobMessage() override;
|
||||
BlobMessage(const BlobMessage &other);
|
||||
BlobMessage &operator =(const BlobMessage &other);
|
||||
BlobMessage(BlobMessage &&other) noexcept;
|
||||
BlobMessage &operator =(BlobMessage &&other) noexcept;
|
||||
bool operator ==(const BlobMessage &other) const;
|
||||
bool operator !=(const BlobMessage &other) const;
|
||||
|
||||
QByteArray testBytes() const {
|
||||
return m_testBytes;
|
||||
}
|
||||
|
||||
void setTestBytes(const QByteArray &testBytes);
|
||||
static void registerTypes();
|
||||
|
||||
private:
|
||||
QByteArray m_testBytes;
|
||||
};
|
||||
|
||||
} // namespace qtgrpc::tests
|
||||
|
||||
Q_DECLARE_METATYPE(qtgrpc::tests::SimpleStringMessage)
|
||||
Q_DECLARE_METATYPE(qtgrpc::tests::SimpleIntMessage)
|
||||
Q_DECLARE_METATYPE(qtgrpc::tests::BlobMessage)
|
||||
#endif // Q_PROTOBUF_testservice_H
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/* This file is autogenerated. DO NOT CHANGE. All changes will be lost */
|
||||
|
||||
#include "qtgrpc/tests/testservice_client.grpc.qpb.h"
|
||||
|
||||
namespace qtgrpc::tests {
|
||||
namespace TestService {
|
||||
|
||||
Client::Client(QObject *parent) : QAbstractGrpcClient("qtgrpc.tests.TestService", parent)
|
||||
{
|
||||
}
|
||||
|
||||
QGrpcStatus Client::testMethod(const qtgrpc::tests::SimpleStringMessage &arg, qtgrpc::tests::SimpleStringMessage *ret)
|
||||
{
|
||||
return call<qtgrpc::tests::SimpleStringMessage>("testMethod", arg, ret);
|
||||
}
|
||||
|
||||
std::shared_ptr<QGrpcCallReply> Client::testMethod(const qtgrpc::tests::SimpleStringMessage &arg)
|
||||
{
|
||||
return call<qtgrpc::tests::SimpleStringMessage>("testMethod", arg);
|
||||
}
|
||||
|
||||
void Client::testMethod(const qtgrpc::tests::SimpleStringMessage &arg, const QObject *context, const std::function<void(std::shared_ptr<QGrpcCallReply>)> &callback)
|
||||
{
|
||||
std::shared_ptr<QGrpcCallReply> reply = call<qtgrpc::tests::SimpleStringMessage>("testMethod", arg);
|
||||
QObject::connect(reply.get(), &QGrpcCallReply::finished, context, [reply, callback]() {
|
||||
callback(reply);
|
||||
});
|
||||
}
|
||||
std::shared_ptr<QGrpcStream> Client::streamTestMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg)
|
||||
{
|
||||
return stream<qtgrpc::tests::SimpleStringMessage>("testMethodServerStream", arg);
|
||||
}
|
||||
std::shared_ptr<QGrpcStream> Client::streamTestMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg, const QWeakPointer<qtgrpc::tests::SimpleStringMessage> &ret)
|
||||
{
|
||||
return stream<qtgrpc::tests::SimpleStringMessage>("testMethodServerStream", arg, ret);
|
||||
}
|
||||
|
||||
QGrpcStatus Client::testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg, qtgrpc::tests::SimpleStringMessage *ret)
|
||||
{
|
||||
return call<qtgrpc::tests::SimpleStringMessage>("testMethodClientStream", arg, ret);
|
||||
}
|
||||
|
||||
std::shared_ptr<QGrpcCallReply> Client::testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg)
|
||||
{
|
||||
return call<qtgrpc::tests::SimpleStringMessage>("testMethodClientStream", arg);
|
||||
}
|
||||
|
||||
void Client::testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg, const QObject *context, const std::function<void(std::shared_ptr<QGrpcCallReply>)> &callback)
|
||||
{
|
||||
std::shared_ptr<QGrpcCallReply> reply = call<qtgrpc::tests::SimpleStringMessage>("testMethodClientStream", arg);
|
||||
QObject::connect(reply.get(), &QGrpcCallReply::finished, context, [reply, callback]() {
|
||||
callback(reply);
|
||||
});
|
||||
}
|
||||
std::shared_ptr<QGrpcStream> Client::streamTestMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg)
|
||||
{
|
||||
return stream<qtgrpc::tests::SimpleStringMessage>("testMethodBiStream", arg);
|
||||
}
|
||||
std::shared_ptr<QGrpcStream> Client::streamTestMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg, const QWeakPointer<qtgrpc::tests::SimpleStringMessage> &ret)
|
||||
{
|
||||
return stream<qtgrpc::tests::SimpleStringMessage>("testMethodBiStream", arg, ret);
|
||||
}
|
||||
} // namespace TestService
|
||||
} // namespace qtgrpc::tests
|
||||
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/* This file is autogenerated. DO NOT CHANGE. All changes will be lost */
|
||||
|
||||
#ifndef Q_PROTOBUF_testservice_client_H
|
||||
#define Q_PROTOBUF_testservice_client_H
|
||||
|
||||
#include <QtProtobuf/QProtobufMessage>
|
||||
#include <QtCore/QMetaType>
|
||||
#include <QtCore/QList>
|
||||
|
||||
#include <QtProtobuf/qprotobufobject.h>
|
||||
#include <QtProtobuf/qprotobuflazymessagepointer.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QAbstractGrpcClient>
|
||||
#include <QGrpcCallReply>
|
||||
#include <QGrpcStream>
|
||||
#include "qtgrpc/tests/testservice.qpb.h"
|
||||
|
||||
|
||||
namespace qtgrpc::tests {
|
||||
namespace TestService {
|
||||
|
||||
class Client : public QAbstractGrpcClient
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Client(QObject *parent = nullptr);
|
||||
QGrpcStatus testMethod(const qtgrpc::tests::SimpleStringMessage &arg, qtgrpc::tests::SimpleStringMessage *ret);
|
||||
std::shared_ptr<QGrpcCallReply> testMethod(const qtgrpc::tests::SimpleStringMessage &arg);
|
||||
Q_INVOKABLE void testMethod(const qtgrpc::tests::SimpleStringMessage &arg, const QObject *context, const std::function<void(std::shared_ptr<QGrpcCallReply>)> &callback);
|
||||
|
||||
std::shared_ptr<QGrpcStream> streamTestMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg);
|
||||
std::shared_ptr<QGrpcStream> streamTestMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg, const QWeakPointer<qtgrpc::tests::SimpleStringMessage> &ret);
|
||||
|
||||
QGrpcStatus testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg, qtgrpc::tests::SimpleStringMessage *ret);
|
||||
std::shared_ptr<QGrpcCallReply> testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg);
|
||||
Q_INVOKABLE void testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg, const QObject *context, const std::function<void(std::shared_ptr<QGrpcCallReply>)> &callback);
|
||||
|
||||
std::shared_ptr<QGrpcStream> streamTestMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg);
|
||||
std::shared_ptr<QGrpcStream> streamTestMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg, const QWeakPointer<qtgrpc::tests::SimpleStringMessage> &ret);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
} // namespace TestService
|
||||
} // namespace qtgrpc::tests
|
||||
|
||||
#endif // Q_PROTOBUF_testservice_client_H
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#include <QProtobufSerializer>
|
||||
#include <array>
|
||||
#include "qtgrpc/tests/testservice.qpb.h"
|
||||
|
||||
namespace qtgrpc::tests {
|
||||
static QtProtobuf::ProtoTypeRegistrar ProtoTypeRegistrarSimpleStringMessage(qRegisterProtobufType<SimpleStringMessage>);
|
||||
static QtProtobuf::ProtoTypeRegistrar ProtoTypeRegistrarSimpleIntMessage(qRegisterProtobufType<SimpleIntMessage>);
|
||||
static QtProtobuf::ProtoTypeRegistrar ProtoTypeRegistrarBlobMessage(qRegisterProtobufType<BlobMessage>);
|
||||
} // namespace qtgrpc::tests
|
||||
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/* This file is autogenerated. DO NOT CHANGE. All changes will be lost */
|
||||
|
||||
#ifndef Q_PROTOBUF_testservice_service_H
|
||||
#define Q_PROTOBUF_testservice_service_H
|
||||
|
||||
#include <QtProtobuf/QProtobufMessage>
|
||||
#include <QtCore/QMetaType>
|
||||
#include <QtCore/QList>
|
||||
|
||||
#include <QtProtobuf/qprotobufobject.h>
|
||||
#include <QtProtobuf/qprotobuflazymessagepointer.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QAbstractGrpcClient>
|
||||
#include <QGrpcCallReply>
|
||||
#include <QGrpcStream>
|
||||
#include <QAbstractGrpcService>
|
||||
#include "qtgrpc/tests/testservice.qpb.h"
|
||||
|
||||
|
||||
namespace qtgrpc::tests {
|
||||
namespace TestService {
|
||||
|
||||
class Service : public QAbstractGrpcService
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_INVOKABLE virtual qtgrpc::tests::SimpleStringMessage testMethod(const qtgrpc::tests::SimpleStringMessage &arg) = 0;
|
||||
Q_INVOKABLE virtual qtgrpc::tests::SimpleStringMessage testMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg) = 0;
|
||||
Q_INVOKABLE virtual qtgrpc::tests::SimpleStringMessage testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg) = 0;
|
||||
Q_INVOKABLE virtual qtgrpc::tests::SimpleStringMessage testMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg) = 0;
|
||||
};
|
||||
|
||||
} // namespace TestService
|
||||
} // namespace qtgrpc::tests
|
||||
|
||||
#endif // Q_PROTOBUF_testservice_service_H
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/* This file is autogenerated. DO NOT CHANGE. All changes will be lost */
|
||||
|
||||
#include "testservice_client.grpc.qpb.h"
|
||||
|
||||
namespace qtgrpc::tests {
|
||||
namespace TestService {
|
||||
|
||||
Client::Client(QObject *parent) : QAbstractGrpcClient("qtgrpc.tests.TestService", parent)
|
||||
{
|
||||
}
|
||||
|
||||
QGrpcStatus Client::testMethod(const qtgrpc::tests::SimpleStringMessage &arg, qtgrpc::tests::SimpleStringMessage *ret)
|
||||
{
|
||||
return call<qtgrpc::tests::SimpleStringMessage>("testMethod", arg, ret);
|
||||
}
|
||||
|
||||
std::shared_ptr<QGrpcCallReply> Client::testMethod(const qtgrpc::tests::SimpleStringMessage &arg)
|
||||
{
|
||||
return call<qtgrpc::tests::SimpleStringMessage>("testMethod", arg);
|
||||
}
|
||||
|
||||
void Client::testMethod(const qtgrpc::tests::SimpleStringMessage &arg, const QObject *context, const std::function<void(std::shared_ptr<QGrpcCallReply>)> &callback)
|
||||
{
|
||||
std::shared_ptr<QGrpcCallReply> reply = call<qtgrpc::tests::SimpleStringMessage>("testMethod", arg);
|
||||
QObject::connect(reply.get(), &QGrpcCallReply::finished, context, [reply, callback]() {
|
||||
callback(reply);
|
||||
});
|
||||
}
|
||||
std::shared_ptr<QGrpcStream> Client::streamTestMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg)
|
||||
{
|
||||
return stream<qtgrpc::tests::SimpleStringMessage>("testMethodServerStream", arg);
|
||||
}
|
||||
std::shared_ptr<QGrpcStream> Client::streamTestMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg, const QWeakPointer<qtgrpc::tests::SimpleStringMessage> &ret)
|
||||
{
|
||||
return stream<qtgrpc::tests::SimpleStringMessage>("testMethodServerStream", arg, ret);
|
||||
}
|
||||
|
||||
QGrpcStatus Client::testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg, qtgrpc::tests::SimpleStringMessage *ret)
|
||||
{
|
||||
return call<qtgrpc::tests::SimpleStringMessage>("testMethodClientStream", arg, ret);
|
||||
}
|
||||
|
||||
std::shared_ptr<QGrpcCallReply> Client::testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg)
|
||||
{
|
||||
return call<qtgrpc::tests::SimpleStringMessage>("testMethodClientStream", arg);
|
||||
}
|
||||
|
||||
void Client::testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg, const QObject *context, const std::function<void(std::shared_ptr<QGrpcCallReply>)> &callback)
|
||||
{
|
||||
std::shared_ptr<QGrpcCallReply> reply = call<qtgrpc::tests::SimpleStringMessage>("testMethodClientStream", arg);
|
||||
QObject::connect(reply.get(), &QGrpcCallReply::finished, context, [reply, callback]() {
|
||||
callback(reply);
|
||||
});
|
||||
}
|
||||
std::shared_ptr<QGrpcStream> Client::streamTestMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg)
|
||||
{
|
||||
return stream<qtgrpc::tests::SimpleStringMessage>("testMethodBiStream", arg);
|
||||
}
|
||||
std::shared_ptr<QGrpcStream> Client::streamTestMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg, const QWeakPointer<qtgrpc::tests::SimpleStringMessage> &ret)
|
||||
{
|
||||
return stream<qtgrpc::tests::SimpleStringMessage>("testMethodBiStream", arg, ret);
|
||||
}
|
||||
} // namespace TestService
|
||||
} // namespace qtgrpc::tests
|
||||
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/* This file is autogenerated. DO NOT CHANGE. All changes will be lost */
|
||||
|
||||
#ifndef Q_PROTOBUF_testservice_client_H
|
||||
#define Q_PROTOBUF_testservice_client_H
|
||||
|
||||
#include <QtProtobuf/QProtobufMessage>
|
||||
#include <QtCore/QMetaType>
|
||||
#include <QtCore/QList>
|
||||
|
||||
#include <QtProtobuf/qprotobufobject.h>
|
||||
#include <QtProtobuf/qprotobuflazymessagepointer.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QAbstractGrpcClient>
|
||||
#include <QGrpcCallReply>
|
||||
#include <QGrpcStream>
|
||||
#include "testservice.qpb.h"
|
||||
|
||||
|
||||
namespace qtgrpc::tests {
|
||||
namespace TestService {
|
||||
|
||||
class Client : public QAbstractGrpcClient
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Client(QObject *parent = nullptr);
|
||||
QGrpcStatus testMethod(const qtgrpc::tests::SimpleStringMessage &arg, qtgrpc::tests::SimpleStringMessage *ret);
|
||||
std::shared_ptr<QGrpcCallReply> testMethod(const qtgrpc::tests::SimpleStringMessage &arg);
|
||||
Q_INVOKABLE void testMethod(const qtgrpc::tests::SimpleStringMessage &arg, const QObject *context, const std::function<void(std::shared_ptr<QGrpcCallReply>)> &callback);
|
||||
|
||||
std::shared_ptr<QGrpcStream> streamTestMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg);
|
||||
std::shared_ptr<QGrpcStream> streamTestMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg, const QWeakPointer<qtgrpc::tests::SimpleStringMessage> &ret);
|
||||
|
||||
QGrpcStatus testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg, qtgrpc::tests::SimpleStringMessage *ret);
|
||||
std::shared_ptr<QGrpcCallReply> testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg);
|
||||
Q_INVOKABLE void testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg, const QObject *context, const std::function<void(std::shared_ptr<QGrpcCallReply>)> &callback);
|
||||
|
||||
std::shared_ptr<QGrpcStream> streamTestMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg);
|
||||
std::shared_ptr<QGrpcStream> streamTestMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg, const QWeakPointer<qtgrpc::tests::SimpleStringMessage> &ret);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
} // namespace TestService
|
||||
} // namespace qtgrpc::tests
|
||||
|
||||
#endif // Q_PROTOBUF_testservice_client_H
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/* This file is autogenerated. DO NOT CHANGE. All changes will be lost */
|
||||
|
||||
#ifndef Q_PROTOBUF_testservice_service_H
|
||||
#define Q_PROTOBUF_testservice_service_H
|
||||
|
||||
#include <QtProtobuf/QProtobufMessage>
|
||||
#include <QtCore/QMetaType>
|
||||
#include <QtCore/QList>
|
||||
|
||||
#include <QtProtobuf/qprotobufobject.h>
|
||||
#include <QtProtobuf/qprotobuflazymessagepointer.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QAbstractGrpcClient>
|
||||
#include <QGrpcCallReply>
|
||||
#include <QGrpcStream>
|
||||
#include <QAbstractGrpcService>
|
||||
#include "testservice.qpb.h"
|
||||
|
||||
|
||||
namespace qtgrpc::tests {
|
||||
namespace TestService {
|
||||
|
||||
class Service : public QAbstractGrpcService
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_INVOKABLE virtual qtgrpc::tests::SimpleStringMessage testMethod(const qtgrpc::tests::SimpleStringMessage &arg) = 0;
|
||||
Q_INVOKABLE virtual qtgrpc::tests::SimpleStringMessage testMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg) = 0;
|
||||
Q_INVOKABLE virtual qtgrpc::tests::SimpleStringMessage testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg) = 0;
|
||||
Q_INVOKABLE virtual qtgrpc::tests::SimpleStringMessage testMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg) = 0;
|
||||
};
|
||||
|
||||
} // namespace TestService
|
||||
} // namespace qtgrpc::tests
|
||||
|
||||
#endif // Q_PROTOBUF_testservice_service_H
|
||||
|
|
@ -0,0 +1,314 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include <QString>
|
||||
#include <QProcess>
|
||||
#include <QCryptographicHash>
|
||||
#include <qtprotobuftypes.h>
|
||||
|
||||
#define XSTR(x) DEFSTR(x)
|
||||
#define DEFSTR(x) #x
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
const QLatin1StringView serviceHeaderExtension("_service.grpc.qpb.h");
|
||||
const QLatin1StringView cppExtension("_client.grpc.qpb.cpp");
|
||||
const QLatin1StringView headerExtension("_client.grpc.qpb.h");
|
||||
const QLatin1StringView grpcGenQtprotobufKey(" --plugin=protoc-gen-qtgrpc=");
|
||||
const QLatin1StringView optKey(" --qtgrpc_opt=");
|
||||
const QLatin1StringView outputKey(" --qtgrpc_out=");
|
||||
const QLatin1StringView includeKey(" -I");
|
||||
#if defined(PROTOC_EXECUTABLE)
|
||||
const QLatin1StringView protocolBufferCompiler(XSTR(PROTOC_EXECUTABLE));
|
||||
#else
|
||||
#if defined(Q_OS_WIN)
|
||||
const QLatin1StringView protocolBufferCompiler("protoc.exe");
|
||||
#else
|
||||
const QLatin1StringView protocolBufferCompiler("protoc");
|
||||
#endif
|
||||
#endif
|
||||
#if defined(Q_OS_WIN)
|
||||
const QLatin1StringView qtgrpcgen("/qtgrpcgen.exe");
|
||||
#else
|
||||
const QLatin1StringView qtgrpcgen("/qtgrpcgen");
|
||||
#endif
|
||||
|
||||
QByteArray msgProcessStartFailed(const QProcess &p)
|
||||
{
|
||||
const QString result = QLatin1StringView("Could not start \"")
|
||||
+ QDir::toNativeSeparators(p.program()) + QLatin1StringView("\": ")
|
||||
+ p.errorString();
|
||||
return result.toLocal8Bit();
|
||||
}
|
||||
|
||||
QByteArray msgProcessTimeout(const QProcess &p)
|
||||
{
|
||||
return '"' + QDir::toNativeSeparators(p.program()).toLocal8Bit()
|
||||
+ "\" timed out.";
|
||||
}
|
||||
|
||||
QByteArray msgProcessCrashed(QProcess &p)
|
||||
{
|
||||
return '"' + QDir::toNativeSeparators(p.program()).toLocal8Bit()
|
||||
+ "\" crashed.\n" + p.readAllStandardError();
|
||||
}
|
||||
|
||||
QByteArray msgProcessFailed(QProcess &p)
|
||||
{
|
||||
return '"' + QDir::toNativeSeparators(p.program()).toLocal8Bit()
|
||||
+ "\" returned " + QByteArray::number(p.exitCode()) + ":\n"
|
||||
+ p.readAllStandardError();
|
||||
}
|
||||
|
||||
QByteArray hash(const QByteArray &fileData)
|
||||
{
|
||||
return QCryptographicHash::hash(fileData, QCryptographicHash::Sha1);
|
||||
}
|
||||
|
||||
QByteArrayList splitToLines(const QByteArray &data)
|
||||
{
|
||||
return data.split('\n');
|
||||
}
|
||||
|
||||
// Return size diff and first NOT equal line;
|
||||
QByteArray doCompare(const QByteArrayList &actual, const QByteArrayList &expected)
|
||||
{
|
||||
QByteArray ba;
|
||||
|
||||
if (actual.size() != expected.size()) {
|
||||
ba.append(QString("Length count different: actual: %1, expected: %2")
|
||||
.arg(actual.size()).arg(expected.size()).toUtf8());
|
||||
}
|
||||
|
||||
for (int i = 0, n = expected.size(); i != n; ++i) {
|
||||
QString expectedLine = expected.at(i);
|
||||
if (expectedLine != actual.at(i)) {
|
||||
ba.append("\n<<<<<< ACTUAL\n" + actual.at(i)
|
||||
+ "\n======\n" + expectedLine.toUtf8()
|
||||
+ "\n>>>>>> EXPECTED\n"
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ba;
|
||||
}
|
||||
|
||||
QByteArray msgCannotReadFile(const QFile &file)
|
||||
{
|
||||
const QString result = QLatin1StringView("Could not read file: ")
|
||||
+ QDir::toNativeSeparators(file.fileName())
|
||||
+ QLatin1StringView(": ") + file.errorString();
|
||||
return result.toLocal8Bit();
|
||||
}
|
||||
|
||||
void cleanFolder(const QString &folderName)
|
||||
{
|
||||
QDir dir(folderName);
|
||||
dir.removeRecursively();
|
||||
}
|
||||
|
||||
bool protocolCompilerAvailableToRun()
|
||||
{
|
||||
QProcess protoc;
|
||||
protoc.startCommand(protocolBufferCompiler + " --version");
|
||||
|
||||
if (!protoc.waitForStarted())
|
||||
return false;
|
||||
|
||||
if (!protoc.waitForFinished()) {
|
||||
protoc.kill();
|
||||
return false;
|
||||
}
|
||||
|
||||
return protoc.exitStatus() == QProcess::NormalExit;
|
||||
}
|
||||
|
||||
class tst_qtgrpcgen : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
|
||||
//! Test qt_add_grpc() cmake function
|
||||
void cmakeGeneratedFile_data();
|
||||
void cmakeGeneratedFile();
|
||||
|
||||
//! Test command-line call of qtgrpcgen
|
||||
void cmdLineGeneratedFile_data();
|
||||
void cmdLineGeneratedFile();
|
||||
|
||||
void cleanupTestCase();
|
||||
|
||||
private:
|
||||
QString m_grpcgen;
|
||||
QString m_cmakeGenerated;
|
||||
QString m_commandLineGenerated;
|
||||
QString m_expectedResult;
|
||||
QString m_protoFiles;
|
||||
};
|
||||
|
||||
void tst_qtgrpcgen::initTestCase()
|
||||
{
|
||||
m_grpcgen = QLibraryInfo::path(QLibraryInfo::LibraryExecutablesPath) + qtgrpcgen;
|
||||
|
||||
m_cmakeGenerated = QFINDTESTDATA("qt_grpc_generated");
|
||||
QVERIFY(!m_cmakeGenerated.isEmpty());
|
||||
|
||||
m_expectedResult = QFINDTESTDATA("data/expected_result");
|
||||
QVERIFY(!m_expectedResult.isEmpty());
|
||||
|
||||
m_protoFiles = QFINDTESTDATA("../shared/data/proto/");
|
||||
QVERIFY(!m_protoFiles.isEmpty());
|
||||
|
||||
QDir testOutputBaseDir(QCoreApplication::applicationDirPath());
|
||||
testOutputBaseDir.mkdir(QLatin1StringView("cmd_line_generation"));
|
||||
QLatin1StringView folders[] = {"comments"_L1, "extra-namespace"_L1,
|
||||
"fieldenum"_L1, "folder"_L1, "no-options"_L1};
|
||||
for (QLatin1StringView folder : folders)
|
||||
testOutputBaseDir.mkdir("cmd_line_generation/"_L1 + folder);
|
||||
|
||||
m_commandLineGenerated = testOutputBaseDir.absolutePath() +
|
||||
QLatin1StringView("/cmd_line_generation");
|
||||
QVERIFY(!m_commandLineGenerated.isEmpty());
|
||||
#ifdef Q_OS_MACOS
|
||||
if (!protocolCompilerAvailableToRun())
|
||||
QSKIP("Protocol buffer compiler is not provisioned for macOS ARM VMs: QTBUG-109130");
|
||||
#else
|
||||
QVERIFY(protocolCompilerAvailableToRun());
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_qtgrpcgen::cmakeGeneratedFile_data()
|
||||
{
|
||||
QTest::addColumn<QString>("fileName");
|
||||
QTest::addColumn<QString>("folder");
|
||||
QTest::addColumn<QString>("extension");
|
||||
|
||||
const QLatin1StringView extensions[]
|
||||
= {serviceHeaderExtension, cppExtension, headerExtension};
|
||||
|
||||
for (const auto extension : extensions) {
|
||||
QTest::addRow("testservice%s", extension.data())
|
||||
<< "testservice"
|
||||
<< "/folder/qtgrpc/tests/"
|
||||
<< QString(extension);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qtgrpcgen::cmakeGeneratedFile()
|
||||
{
|
||||
QFETCH(QString, fileName);
|
||||
QFETCH(QString, folder);
|
||||
QFETCH(QString, extension);
|
||||
|
||||
QFile expectedResultFile(m_expectedResult + folder + fileName + extension);
|
||||
QFile generatedFile(m_cmakeGenerated + folder + fileName + extension);
|
||||
|
||||
QVERIFY(expectedResultFile.exists());
|
||||
QVERIFY(generatedFile.exists());
|
||||
|
||||
QVERIFY2(expectedResultFile.open(QIODevice::ReadOnly | QIODevice::Text),
|
||||
msgCannotReadFile(expectedResultFile).constData());
|
||||
QVERIFY2(generatedFile.open(QIODevice::ReadOnly | QIODevice::Text),
|
||||
msgCannotReadFile(generatedFile).constData());
|
||||
|
||||
QByteArray expectedData = expectedResultFile.readAll();
|
||||
QByteArray generatedData = generatedFile.readAll();
|
||||
|
||||
expectedResultFile.close();
|
||||
generatedFile.close();
|
||||
|
||||
if (hash(expectedData).toHex() != hash(generatedData).toHex())
|
||||
{
|
||||
const QString diff = doCompare(splitToLines(generatedData),
|
||||
splitToLines(expectedData));
|
||||
QCOMPARE_GT(diff.size(), 0); // Hashes can only differ if content does.
|
||||
QFAIL(qPrintable(diff));
|
||||
}
|
||||
// Ensure we do see a failure, even in the unlikely case of a hash collision:
|
||||
QVERIFY(generatedData == expectedData);
|
||||
}
|
||||
|
||||
void tst_qtgrpcgen::cmdLineGeneratedFile_data()
|
||||
{
|
||||
QTest::addColumn<QString>("fileName");
|
||||
QTest::addColumn<QString>("folder");
|
||||
QTest::addColumn<QString>("extension");
|
||||
|
||||
const QLatin1StringView extensions[]
|
||||
= {serviceHeaderExtension, cppExtension, headerExtension};
|
||||
|
||||
for (const auto extension : extensions) {
|
||||
QTest::addRow("testservice%s", extension.data())
|
||||
<< "testservice"
|
||||
<< "/no-options/"
|
||||
<< QString(extension);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qtgrpcgen::cmdLineGeneratedFile()
|
||||
{
|
||||
QFETCH(QString, fileName);
|
||||
QFETCH(QString, folder);
|
||||
QFETCH(QString, extension);
|
||||
|
||||
QProcess process;
|
||||
process.setWorkingDirectory(m_commandLineGenerated);
|
||||
|
||||
/* Call command:
|
||||
protoc --plugin=protoc-gen-qtgrpc=<path/to/bin/>qtgrpcgen \
|
||||
--qtgrpc_opt=<option> \
|
||||
--qtgrpc_out=<output_dir> [-I/extra/proto/include/path] <protofile>.proto */
|
||||
process.startCommand(protocolBufferCompiler + QString(" ")
|
||||
+ grpcGenQtprotobufKey + m_grpcgen
|
||||
+ optKey + outputKey
|
||||
+ m_commandLineGenerated + folder
|
||||
+ includeKey + m_protoFiles
|
||||
+ " " + fileName + ".proto");
|
||||
|
||||
QVERIFY2(process.waitForStarted(), msgProcessStartFailed(process).constData());
|
||||
if (!process.waitForFinished()) {
|
||||
process.kill();
|
||||
QFAIL(msgProcessTimeout(process).constData());
|
||||
}
|
||||
QVERIFY2(process.exitStatus() == QProcess::NormalExit, msgProcessCrashed(process).constData());
|
||||
QVERIFY2(process.exitCode() == 0, msgProcessFailed(process).constData());
|
||||
|
||||
QFile expectedResultFile(m_expectedResult + folder + fileName + extension);
|
||||
QFile generatedFile(m_commandLineGenerated + folder + fileName + extension);
|
||||
|
||||
QVERIFY(generatedFile.exists());
|
||||
QVERIFY(expectedResultFile.exists());
|
||||
|
||||
QVERIFY2(expectedResultFile.open(QIODevice::ReadOnly | QIODevice::Text),
|
||||
msgCannotReadFile(expectedResultFile).constData());
|
||||
QVERIFY2(generatedFile.open(QIODevice::ReadOnly | QIODevice::Text),
|
||||
msgCannotReadFile(generatedFile).constData());
|
||||
|
||||
QByteArray expectedData = expectedResultFile.readAll();
|
||||
QByteArray generatedData = generatedFile.readAll();
|
||||
|
||||
expectedResultFile.close();
|
||||
generatedFile.close();
|
||||
|
||||
if (hash(expectedData).toHex() != hash(generatedData).toHex())
|
||||
{
|
||||
const QString diff = doCompare(splitToLines(generatedData),
|
||||
splitToLines(expectedData));
|
||||
QCOMPARE_GT(diff.size(), 0); // Hashes can only differ if content does.
|
||||
QFAIL(qPrintable(diff));
|
||||
}
|
||||
// Ensure we do see a failure, even in the unlikely case of a hash collision:
|
||||
QVERIFY(generatedData == expectedData);
|
||||
}
|
||||
|
||||
void tst_qtgrpcgen::cleanupTestCase()
|
||||
{
|
||||
// Leave this function at the bottom. It removes generated content.
|
||||
cleanFolder(m_commandLineGenerated);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qtgrpcgen)
|
||||
#include "tst_qtgrpcgen.moc"
|
||||
|
|
@ -148,6 +148,7 @@ qt_internal_add_test(tst_protobuf_non_packed_repeatedtypes
|
|||
LIBRARIES
|
||||
Qt::Test
|
||||
Qt::CorePrivate
|
||||
Qt::Protobuf
|
||||
)
|
||||
qt6_add_protobuf(tst_protobuf_non_packed_repeatedtypes
|
||||
PROTO_FILES
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Blacklist for testing
|
||||
# Blacklist for testing on ARM macos due to QTBUG-109130
|
||||
[initTestCase]
|
||||
macos arm ci
|
||||
[cmakeGeneratedFile_data]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package qtgrpc.tests;
|
||||
|
||||
message SimpleStringMessage {
|
||||
string testFieldString = 6;
|
||||
}
|
||||
|
||||
message SimpleIntMessage {
|
||||
sint32 testField= 1;
|
||||
}
|
||||
|
||||
message BlobMessage {
|
||||
bytes testBytes = 1;
|
||||
}
|
||||
|
||||
service TestService {
|
||||
rpc testMethod(SimpleStringMessage) returns (SimpleStringMessage) {}
|
||||
rpc testMethodServerStream(SimpleStringMessage) returns (stream SimpleStringMessage) {}
|
||||
rpc testMethodClientStream(stream SimpleStringMessage) returns (SimpleStringMessage) {}
|
||||
rpc testMethodBiStream(stream SimpleStringMessage) returns (stream SimpleStringMessage) {}
|
||||
}
|
||||
Loading…
Reference in New Issue