diff --git a/src/tools/qtprotobufgen/qprotobufgenerator.cpp b/src/tools/qtprotobufgen/qprotobufgenerator.cpp index b136fe33..68b216f2 100644 --- a/src/tools/qtprotobufgen/qprotobufgenerator.cpp +++ b/src/tools/qtprotobufgen/qprotobufgenerator.cpp @@ -40,7 +40,6 @@ bool QProtobufGenerator::Generate(const FileDescriptor *file, { assert(file != nullptr); assert(generatorContext != nullptr); - return GenerateMessages(file, generatorContext); } @@ -266,6 +265,7 @@ void QProtobufGenerator::GenerateHeader(const FileDescriptor *file, } bool hasOneofFields = false; + bool hasOptionalFields = false; std::unordered_set qtTypesSet; common::iterateMessages( file, [&](const Descriptor *message) { @@ -286,12 +286,23 @@ void QProtobufGenerator::GenerateHeader(const FileDescriptor *file, + "/" + field->message_type()->name()); qtTypesSet.insert(field->message_type()->file()->package()); } + if (field->has_optional_keyword()) + hasOptionalFields = true; } }); if (hasOneofFields) externalIncludes.insert("QtProtobuf/qprotobufoneof.h"); + if (hasOptionalFields) { + std::cerr << "WARNING: '" << file->name() << "' contains 'optional' fields.\n" + "\nOptional fields are not supported in this qtprotobufgen version\n" + "The generator disregards the keyword, but generates the regular\n" + "fields instead.\n" + "\nPlease upgrade Qt to the most recent version to get full support\n" + "of the 'optional' fields.\n"; + } + for (const auto &qtTypeInclude: qtTypesSet) { std::string qtTypeLower = qtTypeInclude; std::transform(qtTypeLower.begin(), qtTypeLower.end(), diff --git a/src/tools/qtprotoccommon/generatorbase.cpp b/src/tools/qtprotoccommon/generatorbase.cpp index 5a49a0a1..00b453bb 100644 --- a/src/tools/qtprotoccommon/generatorbase.cpp +++ b/src/tools/qtprotoccommon/generatorbase.cpp @@ -29,6 +29,11 @@ bool GeneratorBase::GenerateAll(const std::vector &files return CodeGenerator::GenerateAll(files, parameter, generatorContext, error); } +uint64_t GeneratorBase::GetSupportedFeatures() const +{ + return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL; +} + std::string GeneratorBase::generateBaseName(const FileDescriptor *file, const std::string &name) { std::string outFileBasename; diff --git a/src/tools/qtprotoccommon/generatorbase.h b/src/tools/qtprotoccommon/generatorbase.h index 7a95504b..e1b52cf0 100644 --- a/src/tools/qtprotoccommon/generatorbase.h +++ b/src/tools/qtprotoccommon/generatorbase.h @@ -37,6 +37,8 @@ public: std::string *error) const override; bool HasGenerateAll() const override { return true; } + uint64_t GetSupportedFeatures() const override; + static void printDisclaimer(::google::protobuf::io::Printer *printer); void OpenFileNamespaces(const ::google::protobuf::FileDescriptor *file, google::protobuf::io::Printer *printer) const; diff --git a/tests/auto/protobuf/CMakeLists.txt b/tests/auto/protobuf/CMakeLists.txt index 3fbf2651..114da540 100644 --- a/tests/auto/protobuf/CMakeLists.txt +++ b/tests/auto/protobuf/CMakeLists.txt @@ -14,6 +14,7 @@ if(TARGET Qt6::qtprotobufgen) add_subdirectory(converters) add_subdirectory(duplicated_metatypes) add_subdirectory(recursive) + add_subdirectory(optional) if(TARGET Qt6::ProtobufWellKnownTypes) add_subdirectory(wellknown) endif() diff --git a/tests/auto/protobuf/optional/CMakeLists.txt b/tests/auto/protobuf/optional/CMakeLists.txt new file mode 100644 index 00000000..84007d9e --- /dev/null +++ b/tests/auto/protobuf/optional/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_protobuf_optional LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + +qt_internal_add_test(tst_protobuf_optional + SOURCES + tst_protobuf_optional.cpp + INCLUDE_DIRECTORIES + ../shared + LIBRARIES + Qt::Test + Qt::Protobuf +) +qt_autogen_tools_initial_setup(tst_protobuf_optional) + +qt6_add_protobuf(tst_protobuf_optional + PROTO_FILES + ../../shared/data/proto/optional.proto +) diff --git a/tests/auto/protobuf/optional/tst_protobuf_optional.cpp b/tests/auto/protobuf/optional/tst_protobuf_optional.cpp new file mode 100644 index 00000000..8fd604c5 --- /dev/null +++ b/tests/auto/protobuf/optional/tst_protobuf_optional.cpp @@ -0,0 +1,14 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include + +class QtProtobufOptionalTest : public QObject +{ + Q_OBJECT +}; + +QTEST_MAIN(QtProtobufOptionalTest) + +#include "tst_protobuf_optional.moc" diff --git a/tests/auto/shared/data/proto/optional.proto b/tests/auto/shared/data/proto/optional.proto new file mode 100644 index 00000000..2636b9c6 --- /dev/null +++ b/tests/auto/shared/data/proto/optional.proto @@ -0,0 +1,9 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only +syntax = "proto3"; + +package qtprotobufnamespace.optional.tests; + +message OptionalMessage { + optional sint32 testField = 2; +}