Add support for field flags

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 <marten.nordheim@qt.io>
This commit is contained in:
Alexey Edelev 2022-11-16 14:38:22 +01:00
parent 99bb364a7b
commit 11fe1e2e40
7 changed files with 47 additions and 2 deletions

View File

@ -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);

View File

@ -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 }; }

View File

@ -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;
}

View File

@ -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

View File

@ -7,6 +7,7 @@
#include <google/protobuf/descriptor.h>
#include "options.h"
#include "templates.h"
#include "generatorcommon.h"
#include <cassert>
@ -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);

View File

@ -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";
}

View File

@ -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();