From 11fe1e2e4007343b10978f4faf3f67736fe98d29 Mon Sep 17 00:00:00 2001 From: Alexey Edelev Date: Wed, 16 Nov 2022 14:38:22 +0100 Subject: [PATCH] Add support for field flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the additional field to the property ordering structure to indicate the special attributes that the message fields may have, e.g. the 'packed' attribute. Task-number: QTBUG-103979 Change-Id: I62c974cc924011956feb7692d6cb4fcd072dc1e6 Reviewed-by: MÃ¥rten Nordheim --- src/protobuf/qtprotobuftypes.cpp | 8 +++++++- src/protobuf/qtprotobuftypes.h | 5 +++++ src/tools/qtprotobufgen/generatorcommon.cpp | 18 ++++++++++++++++++ src/tools/qtprotobufgen/generatorcommon.h | 2 ++ .../qtprotobufgen/messagedefinitionprinter.cpp | 9 ++++++++- src/tools/qtprotobufgen/templates.cpp | 6 ++++++ src/tools/qtprotobufgen/templates.h | 1 + 7 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/protobuf/qtprotobuftypes.cpp b/src/protobuf/qtprotobuftypes.cpp index d919af2b..3e4fb5c1 100644 --- a/src/protobuf/qtprotobuftypes.cpp +++ b/src/protobuf/qtprotobuftypes.cpp @@ -61,6 +61,12 @@ namespace QtProtobufPrivate { return -1; } + uint QProtobufPropertyOrdering::getFieldFlags(int index) const + { + Q_ASSERT(data); + return uint_dataForIndex(index, data->flagsOffset); + } + const uint *QProtobufPropertyOrdering::uint_data() const { Q_ASSERT(data); @@ -79,7 +85,7 @@ namespace QtProtobufPrivate { const char *QProtobufPropertyOrdering::char_data() const { Q_ASSERT(data); - const uint LastOffset = data->propertyIndexOffset; + const uint LastOffset = data->flagsOffset; const uint *u_data = &uint_dataForIndex(int(data->numFields - 1), LastOffset); ++u_data; quintptr uptr_data = quintptr(u_data); diff --git a/src/protobuf/qtprotobuftypes.h b/src/protobuf/qtprotobuftypes.h index b216dc62..603e7148 100644 --- a/src/protobuf/qtprotobuftypes.h +++ b/src/protobuf/qtprotobuftypes.h @@ -22,6 +22,8 @@ QT_BEGIN_NAMESPACE namespace QtProtobufPrivate { +enum FieldFlag : uint { NoFlags = 0x0 }; + struct QProtobufPropertyOrdering { const struct Data { @@ -29,11 +31,13 @@ struct QProtobufPropertyOrdering uint numFields; uint fieldNumberOffset; uint propertyIndexOffset; + uint flagsOffset; } *data; Q_PROTOBUF_EXPORT QUtf8StringView getJsonName(int index) const; Q_PROTOBUF_EXPORT int getFieldNumber(int index) const; Q_PROTOBUF_EXPORT int getPropertyIndex(int index) const; + Q_PROTOBUF_EXPORT uint getFieldFlags(int index) const; Q_PROTOBUF_EXPORT int indexOfFieldNumber(int fieldNumber) const; inline int fieldCount() const { return int(data->numFields); } private: @@ -58,6 +62,7 @@ struct QProtobufPropertyOrderingInfo return (overrideFieldNumber >= 0) ? overrideFieldNumber : ordering.getFieldNumber(index); } inline int getPropertyIndex() const { return ordering.getPropertyIndex(index); } + inline uint getFieldFlags() const { return ordering.getFieldFlags(index); } // Needed for maps, which uses field number 1 and 2 for key and value respectively QProtobufPropertyOrderingInfo infoForMapKey() const { return { ordering, index, 1 }; } diff --git a/src/tools/qtprotobufgen/generatorcommon.cpp b/src/tools/qtprotobufgen/generatorcommon.cpp index e6b762ec..4d23ff05 100644 --- a/src/tools/qtprotobufgen/generatorcommon.cpp +++ b/src/tools/qtprotobufgen/generatorcommon.cpp @@ -488,3 +488,21 @@ const Descriptor *common::findHighestMessage(const Descriptor *message) highestMessage = highestMessage->containing_type(); return highestMessage; } + +std::string common::collectFieldFlags([[maybe_unused]] const FieldDescriptor *field) +{ + std::string_view separator = " | "; + std::string_view active_separator; + std::string flags; + + auto writeFlag = [&](const char *flag) { + flags += active_separator; + flags += "QtProtobufPrivate::"; + flags += flag; + active_separator = separator; + }; + + writeFlag("NoFlags"); + + return flags; +} diff --git a/src/tools/qtprotobufgen/generatorcommon.h b/src/tools/qtprotobufgen/generatorcommon.h index d98e67a3..abe8f272 100644 --- a/src/tools/qtprotobufgen/generatorcommon.h +++ b/src/tools/qtprotobufgen/generatorcommon.h @@ -81,6 +81,8 @@ struct common { static bool isNested(const Descriptor *message); static const Descriptor *findHighestMessage(const Descriptor *message); + + static std::string collectFieldFlags(const google::protobuf::FieldDescriptor *field); }; } // namespace QtProtobuf::generator diff --git a/src/tools/qtprotobufgen/messagedefinitionprinter.cpp b/src/tools/qtprotobufgen/messagedefinitionprinter.cpp index 437cec9f..25bcf637 100644 --- a/src/tools/qtprotobufgen/messagedefinitionprinter.cpp +++ b/src/tools/qtprotobufgen/messagedefinitionprinter.cpp @@ -7,6 +7,7 @@ #include #include "options.h" #include "templates.h" +#include "generatorcommon.h" #include @@ -86,7 +87,7 @@ void MessageDefinitionPrinter::printRegisterBody() void MessageDefinitionPrinter::printFieldsOrdering() { const int fieldCount = m_descriptor->field_count(); - constexpr int MetaFieldsCount = 3; + constexpr int MetaFieldsCount = 4; constexpr int Version = 0; int uint_dataOffset = 1; // the json name offsets are always stored at offset 0 @@ -100,6 +101,8 @@ void MessageDefinitionPrinter::printFieldsOrdering() // +1 for EOS offset in JSON data { "property_index_offset", std::to_string(fieldCount * (uint_dataOffset++) + 1) }, // +1 for EOS offset in JSON data + { "field_flags_offset", std::to_string(fieldCount * (uint_dataOffset++) + 1) }, + // +1 for EOS offset in JSON data { "uint_size", std::to_string(fieldCount * MetaFieldsCount + 1) }, { "char_size", std::to_string(char_dataSize) }, }; @@ -125,6 +128,9 @@ void MessageDefinitionPrinter::printFieldsOrdering() m_printer->Print("// Property indices:\n"); printUintData(Templates::QtPropertyIndicesUintDataTemplate()); + m_printer->Print("// Field flags:\n"); + printUintData(Templates::FieldFlagsUintDataTemplate()); + Outdent(); m_printer->Print("},\n"); @@ -150,6 +156,7 @@ void MessageDefinitionPrinter::printUintData(const char *templateString) { "json_name_offset", std::to_string(jsonOffset) }, { "field_number", std::to_string(field->number()) }, { "property_index", std::to_string(++index) }, + { "field_flags", common::collectFieldFlags(field) }, { "json_name", field->json_name() }, }; m_printer->Print(variables, templateString); diff --git a/src/tools/qtprotobufgen/templates.cpp b/src/tools/qtprotobufgen/templates.cpp index f81734b7..0f82b284 100644 --- a/src/tools/qtprotobufgen/templates.cpp +++ b/src/tools/qtprotobufgen/templates.cpp @@ -552,6 +552,11 @@ const char *Templates::QtPropertyIndicesUintDataTemplate() return "$property_index$, /* = $json_name$ */\n"; } +const char *Templates::FieldFlagsUintDataTemplate() +{ + return "$field_flags$, /* = $json_name$ */\n"; +} + const char *Templates::PropertyOrderingDataOpeningTemplate() { return "static constexpr struct {\n" @@ -565,6 +570,7 @@ const char *Templates::PropertyOrderingDataOpeningTemplate() " $num_fields$, /* = num fields */\n" " $field_number_offset$, /* = field number offset */\n" " $property_index_offset$, /* = property index offset */\n" + " $field_flags_offset$, /* = field flags offset */\n" " },\n"; } diff --git a/src/tools/qtprotobufgen/templates.h b/src/tools/qtprotobufgen/templates.h index 94ec9b15..9d033299 100644 --- a/src/tools/qtprotobufgen/templates.h +++ b/src/tools/qtprotobufgen/templates.h @@ -117,6 +117,7 @@ public: static const char *JsonNameOffsetsUintDataTemplate(); static const char *FieldNumbersUintDataTemplate(); static const char *QtPropertyIndicesUintDataTemplate(); + static const char *FieldFlagsUintDataTemplate(); static const char *PropertyOrderingDataOpeningTemplate(); static const char *PropertyOrderingDataClosingTemplate(); static const char *PropertyOrderingDefinitionTemplate();