Generate enum for each Oneof field in the .proto message

Generate separate from the QtProtobufFieldEnum enum for each Oneof field.
Use that enum in the Oneof field number getter.
Fix formatting in protobuf generator code.

Fixes: QTBUG-109126
Change-Id: Ib889a499b9abdc39ea7416cea008d157881a15fc
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
This commit is contained in:
Konrad Kujawa 2023-03-24 10:30:23 +01:00
parent f674a912b1
commit ae2f22dce2
10 changed files with 118 additions and 39 deletions

View File

@ -335,16 +335,20 @@ void MessageDeclarationPrinter::printPrivateMethods()
Outdent();
}
void MessageDeclarationPrinter::printEnums()
{
Indent();
if (Options::instance().generateFieldEnum())
printFieldEnum();
if (m_descriptor->enum_type_count() > 0)
printQEnums();
if (m_descriptor->oneof_decl_count() > 0)
printOneofEnums();
Outdent();
}
void MessageDeclarationPrinter::printQEnums()
{
if (Options::instance().generateFieldEnum()) {
printFieldEnum();
}
if (m_descriptor->enum_type_count() <= 0)
return;
Indent();
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);
@ -367,7 +371,29 @@ void MessageDeclarationPrinter::printQEnums()
auto typeMap = common::produceEnumTypeMap(enumDescr, m_descriptor);
m_printer->Print(typeMap, CommonTemplates::UsingRepeatedEnumTemplate());
}
Outdent();
}
void MessageDeclarationPrinter::printOneofEnums()
{
common::iterateOneofFields(
m_descriptor, [this](const OneofDescriptor *oneofDescr, PropertyMap &typeMap) {
m_printer->Print(typeMap, CommonTemplates::EnumClassDefinitionTemplate());
Indent();
m_printer->Print({ { "enumvalue", "UninitializedField" },
{ "value", "QtProtobuf::InvalidFieldNumber" } },
CommonTemplates::EnumFieldTemplate());
for (int j = 0; j < oneofDescr->field_count(); ++j) {
const auto *valueDescr = oneofDescr->field(j);
m_printer->Print({ { "enumvalue",
utils::capitalizeAsciiName(valueDescr->name()) },
{ "value", std::to_string(valueDescr->number()) } },
CommonTemplates::EnumFieldTemplate());
}
Outdent();
m_printer->Print(CommonTemplates::SemicolonBlockEnclosureTemplate());
m_printer->Print(typeMap, CommonTemplates::QEnumTemplate());
m_printer->Print("\n");
});
}
void MessageDeclarationPrinter::printClassBody()
@ -375,7 +401,7 @@ void MessageDeclarationPrinter::printClassBody()
printProperties();
printPublicBlock();
printQEnums();
printEnums();
printNested();
printMaps();
@ -436,7 +462,6 @@ void MessageDeclarationPrinter::printDestructor()
void MessageDeclarationPrinter::printFieldEnum()
{
if (m_descriptor->field_count() > 0) {
Indent();
m_printer->Print(CommonTemplates::FieldEnumTemplate());
Indent();
common::iterateMessageFields(m_descriptor,
@ -448,7 +473,6 @@ void MessageDeclarationPrinter::printFieldEnum()
m_printer->Print(CommonTemplates::SemicolonBlockEnclosureTemplate());
m_printer->Print({ { "type", CommonTemplates::QtProtobufFieldEnum() } },
CommonTemplates::QEnumTemplate());
Outdent();
m_printer->Print("\n");
}
}

View File

@ -38,9 +38,11 @@ private:
void printMaps();
void printNested();
void printClassDeclarationBegin();
void printFieldEnum();
void printEnums();
void printFieldEnum();
void printQEnums();
void printOneofEnums();
//Recursive functionality
void printClassDeclarationPrivate();

View File

@ -267,6 +267,10 @@ const char *CommonTemplates::EnumDefinitionTemplate()
{
return "enum $type$ {\n";
}
const char *CommonTemplates::EnumClassDefinitionTemplate()
{
return "enum class $type$ {\n";
}
const char *CommonTemplates::EnumFieldTemplate()
{
return "$enumvalue$ = $value$,\n";
@ -494,12 +498,13 @@ const char *CommonTemplates::PrivateGetterOneofMessageDefinitionTemplate()
const char *CommonTemplates::GetterOneofFieldNumberDeclarationTemplate()
{
return "int $optional_property_name$Field() const;\n";
return "$type$ $optional_property_name$Field() const;\n";
}
const char *CommonTemplates::GetterOneofFieldNumberDefinitionTemplate()
{
return "int $classname$::$optional_property_name$Field() const\n{\n"
" return m_$optional_property_name$.fieldNumber();\n"
return "$classname$::$type$ $classname$::$optional_property_name$Field() const\n{\n"
" return "
"static_cast<$type$>(m_$optional_property_name$.fieldNumber());\n"
"}\n";
}

View File

@ -68,6 +68,7 @@ public:
static const char *PublicBlockTemplate();
static const char *PrivateBlockTemplate();
static const char *EnumDefinitionTemplate();
static const char *EnumClassDefinitionTemplate();
static const char *EnumFieldTemplate();
static const char *CopyConstructorDeclarationTemplate();
static const char *MoveConstructorDeclarationTemplate();

View File

@ -462,6 +462,7 @@ PropertyMap common::producePropertyMap(const OneofDescriptor *oneof, const Descr
propertyMap["optional_property_name_cap"] = utils::capitalizeAsciiName(oneof->name());
auto scopeTypeMap = produceMessageTypeMap(scope, nullptr);
propertyMap["classname"] = scope != nullptr ? scopeTypeMap["classname"] : "";
propertyMap["type"] = propertyMap["optional_property_name_cap"] + "Fields";
return propertyMap;
}

View File

@ -333,7 +333,7 @@ void QtProtobufTypesGenerationTest::OneofMessageEmptyTest()
OneofMessage test;
QVERIFY(!test.hasTestOneofFieldInt());
QVERIFY(!test.hasTestOneofComplexField());
QCOMPARE(test.testOneofField(), QtProtobuf::InvalidFieldNumber);
QCOMPARE(test.testOneofField(), OneofMessage::TestOneofFields::UninitializedField);
}
void QtProtobufTypesGenerationTest::OneofMessageTest()
@ -345,7 +345,7 @@ void QtProtobufTypesGenerationTest::OneofMessageTest()
QVERIFY(!test.hasTestOneofComplexField());
QVERIFY(!test.hasTestOneofSecondComplexField());
QCOMPARE(test.testOneofFieldInt(), 10);
QCOMPARE(test.testOneofField(), OneofMessage::TestOneofFieldIntProtoFieldNumber);
QCOMPARE(test.testOneofField(), OneofMessage::TestOneofFields::TestOneofFieldInt);
ComplexMessage complexField;
SimpleStringMessage stringField;
@ -357,7 +357,7 @@ void QtProtobufTypesGenerationTest::OneofMessageTest()
QVERIFY(test.hasTestOneofComplexField());
QVERIFY(!test.hasTestOneofSecondComplexField());
QCOMPARE(test.testOneofComplexField(), complexField);
QCOMPARE(test.testOneofField(), OneofMessage::TestOneofComplexFieldProtoFieldNumber);
QCOMPARE(test.testOneofField(), OneofMessage::TestOneofFields::TestOneofComplexField);
}
void QtProtobufTypesGenerationTest::OneofMessageCopyComplexValueTest()
@ -372,13 +372,13 @@ void QtProtobufTypesGenerationTest::OneofMessageCopyComplexValueTest()
QVERIFY(test.hasTestOneofComplexField());
QVERIFY(!test.hasTestOneofSecondComplexField());
QCOMPARE(test.testOneofComplexField(), complexField);
QCOMPARE(test.testOneofField(), OneofMessage::TestOneofComplexFieldProtoFieldNumber);
QCOMPARE(test.testOneofField(), OneofMessage::TestOneofFields::TestOneofComplexField);
test.setTestOneofSecondComplexField(test.testOneofComplexField());
QVERIFY(!test.hasTestOneofComplexField());
QVERIFY(test.hasTestOneofSecondComplexField());
QCOMPARE(test.testOneofSecondComplexField(), complexField);
QCOMPARE(test.testOneofField(), OneofMessage::TestOneofSecondComplexFieldProtoFieldNumber);
QCOMPARE(test.testOneofField(), OneofMessage::TestOneofFields::TestOneofSecondComplexField);
}
void QtProtobufTypesGenerationTest::AssignmentOperatorTest()

View File

@ -155,9 +155,9 @@ void OneofSimpleMessage::setTestOneofFieldSecondInt_p(QtProtobuf::int32 testOneo
m_testOneof.setValue(testOneofFieldSecondInt, 2);
}
int OneofSimpleMessage::testOneofField() const
OneofSimpleMessage::TestOneofFields OneofSimpleMessage::testOneofField() const
{
return m_testOneof.fieldNumber();
return static_cast<TestOneofFields>(m_testOneof.fieldNumber());
}
void OneofSimpleMessage::clearTestOneof()
{
@ -464,17 +464,17 @@ void OneofComplexMessage::setSecondSecondComplexField_p(ComplexMessage *secondSe
m_secondOneof.setValue(value, 6);
}
int OneofComplexMessage::testOneofField() const
OneofComplexMessage::TestOneofFields OneofComplexMessage::testOneofField() const
{
return m_testOneof.fieldNumber();
return static_cast<TestOneofFields>(m_testOneof.fieldNumber());
}
void OneofComplexMessage::clearTestOneof()
{
m_testOneof = QtProtobufPrivate::QProtobufOneof();
}
int OneofComplexMessage::secondOneofField() const
OneofComplexMessage::SecondOneofFields OneofComplexMessage::secondOneofField() const
{
return m_secondOneof.fieldNumber();
return static_cast<SecondOneofFields>(m_secondOneof.fieldNumber());
}
void OneofComplexMessage::clearSecondOneof()
{

View File

@ -41,6 +41,13 @@ public:
};
Q_ENUM(QtProtobufFieldEnum)
enum class TestOneofFields {
UninitializedField = QtProtobuf::InvalidFieldNumber,
TestOneofFieldInt = 1,
TestOneofFieldSecondInt = 2,
};
Q_ENUM(TestOneofFields)
OneofSimpleMessage();
~OneofSimpleMessage();
OneofSimpleMessage(const OneofSimpleMessage &other);
@ -55,7 +62,7 @@ public:
bool hasTestOneofFieldSecondInt() const;
QtProtobuf::int32 testOneofFieldSecondInt() const;
int testOneofField() const;
TestOneofFields testOneofField() const;
void setTestOneofFieldInt(const QtProtobuf::int32 &testOneofFieldInt);
void setTestOneofFieldSecondInt(const QtProtobuf::int32 &testOneofFieldSecondInt);
void clearTestOneof();
@ -100,6 +107,22 @@ public:
};
Q_ENUM(QtProtobufFieldEnum)
enum class TestOneofFields {
UninitializedField = QtProtobuf::InvalidFieldNumber,
TestOneofFieldInt = 42,
TestOneofComplexField = 3,
TestOneofSecondComplexField = 4,
};
Q_ENUM(TestOneofFields)
enum class SecondOneofFields {
UninitializedField = QtProtobuf::InvalidFieldNumber,
SecondFieldInt = 43,
SecondComplexField = 5,
SecondSecondComplexField = 6,
};
Q_ENUM(SecondOneofFields)
OneofComplexMessage();
~OneofComplexMessage();
OneofComplexMessage(const OneofComplexMessage &other);
@ -132,8 +155,8 @@ public:
bool hasSecondSecondComplexField() const;
ComplexMessage &secondSecondComplexField() const;
int testOneofField() const;
int secondOneofField() const;
TestOneofFields testOneofField() const;
SecondOneofFields secondOneofField() const;
void setTestFieldInt(const QtProtobuf::int32 &testFieldInt)
{
if (m_testFieldInt != testFieldInt)

View File

@ -155,9 +155,9 @@ void OneofSimpleMessage::setTestOneofFieldSecondInt_p(QtProtobuf::int32 testOneo
m_testOneof.setValue(testOneofFieldSecondInt, 2);
}
int OneofSimpleMessage::testOneofField() const
OneofSimpleMessage::TestOneofFields OneofSimpleMessage::testOneofField() const
{
return m_testOneof.fieldNumber();
return static_cast<TestOneofFields>(m_testOneof.fieldNumber());
}
void OneofSimpleMessage::clearTestOneof()
{
@ -464,17 +464,17 @@ void OneofComplexMessage::setSecondSecondComplexField_p(ComplexMessage *secondSe
m_secondOneof.setValue(value, 6);
}
int OneofComplexMessage::testOneofField() const
OneofComplexMessage::TestOneofFields OneofComplexMessage::testOneofField() const
{
return m_testOneof.fieldNumber();
return static_cast<TestOneofFields>(m_testOneof.fieldNumber());
}
void OneofComplexMessage::clearTestOneof()
{
m_testOneof = QtProtobufPrivate::QProtobufOneof();
}
int OneofComplexMessage::secondOneofField() const
OneofComplexMessage::SecondOneofFields OneofComplexMessage::secondOneofField() const
{
return m_secondOneof.fieldNumber();
return static_cast<SecondOneofFields>(m_secondOneof.fieldNumber());
}
void OneofComplexMessage::clearSecondOneof()
{

View File

@ -41,6 +41,13 @@ public:
};
Q_ENUM(QtProtobufFieldEnum)
enum class TestOneofFields {
UninitializedField = QtProtobuf::InvalidFieldNumber,
TestOneofFieldInt = 1,
TestOneofFieldSecondInt = 2,
};
Q_ENUM(TestOneofFields)
OneofSimpleMessage();
~OneofSimpleMessage();
OneofSimpleMessage(const OneofSimpleMessage &other);
@ -55,7 +62,7 @@ public:
bool hasTestOneofFieldSecondInt() const;
QtProtobuf::int32 testOneofFieldSecondInt() const;
int testOneofField() const;
TestOneofFields testOneofField() const;
void setTestOneofFieldInt(const QtProtobuf::int32 &testOneofFieldInt);
void setTestOneofFieldSecondInt(const QtProtobuf::int32 &testOneofFieldSecondInt);
void clearTestOneof();
@ -100,6 +107,22 @@ public:
};
Q_ENUM(QtProtobufFieldEnum)
enum class TestOneofFields {
UninitializedField = QtProtobuf::InvalidFieldNumber,
TestOneofFieldInt = 42,
TestOneofComplexField = 3,
TestOneofSecondComplexField = 4,
};
Q_ENUM(TestOneofFields)
enum class SecondOneofFields {
UninitializedField = QtProtobuf::InvalidFieldNumber,
SecondFieldInt = 43,
SecondComplexField = 5,
SecondSecondComplexField = 6,
};
Q_ENUM(SecondOneofFields)
OneofComplexMessage();
~OneofComplexMessage();
OneofComplexMessage(const OneofComplexMessage &other);
@ -132,8 +155,8 @@ public:
bool hasSecondSecondComplexField() const;
ComplexMessage &secondSecondComplexField() const;
int testOneofField() const;
int secondOneofField() const;
TestOneofFields testOneofField() const;
SecondOneofFields secondOneofField() const;
void setTestFieldInt(const QtProtobuf::int32 &testFieldInt)
{
if (m_testFieldInt != testFieldInt)