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(); 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() 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) { for (int i = 0; i < m_descriptor->enum_type_count(); ++i) {
const auto *enumDescr = m_descriptor->enum_type(i); const auto *enumDescr = m_descriptor->enum_type(i);
auto typeMap = common::produceEnumTypeMap(enumDescr, m_descriptor); auto typeMap = common::produceEnumTypeMap(enumDescr, m_descriptor);
@ -367,7 +371,29 @@ void MessageDeclarationPrinter::printQEnums()
auto typeMap = common::produceEnumTypeMap(enumDescr, m_descriptor); auto typeMap = common::produceEnumTypeMap(enumDescr, m_descriptor);
m_printer->Print(typeMap, CommonTemplates::UsingRepeatedEnumTemplate()); 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() void MessageDeclarationPrinter::printClassBody()
@ -375,7 +401,7 @@ void MessageDeclarationPrinter::printClassBody()
printProperties(); printProperties();
printPublicBlock(); printPublicBlock();
printQEnums(); printEnums();
printNested(); printNested();
printMaps(); printMaps();
@ -436,7 +462,6 @@ void MessageDeclarationPrinter::printDestructor()
void MessageDeclarationPrinter::printFieldEnum() void MessageDeclarationPrinter::printFieldEnum()
{ {
if (m_descriptor->field_count() > 0) { if (m_descriptor->field_count() > 0) {
Indent();
m_printer->Print(CommonTemplates::FieldEnumTemplate()); m_printer->Print(CommonTemplates::FieldEnumTemplate());
Indent(); Indent();
common::iterateMessageFields(m_descriptor, common::iterateMessageFields(m_descriptor,
@ -448,7 +473,6 @@ void MessageDeclarationPrinter::printFieldEnum()
m_printer->Print(CommonTemplates::SemicolonBlockEnclosureTemplate()); m_printer->Print(CommonTemplates::SemicolonBlockEnclosureTemplate());
m_printer->Print({ { "type", CommonTemplates::QtProtobufFieldEnum() } }, m_printer->Print({ { "type", CommonTemplates::QtProtobufFieldEnum() } },
CommonTemplates::QEnumTemplate()); CommonTemplates::QEnumTemplate());
Outdent();
m_printer->Print("\n"); m_printer->Print("\n");
} }
} }

View File

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

View File

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

View File

@ -68,6 +68,7 @@ public:
static const char *PublicBlockTemplate(); static const char *PublicBlockTemplate();
static const char *PrivateBlockTemplate(); static const char *PrivateBlockTemplate();
static const char *EnumDefinitionTemplate(); static const char *EnumDefinitionTemplate();
static const char *EnumClassDefinitionTemplate();
static const char *EnumFieldTemplate(); static const char *EnumFieldTemplate();
static const char *CopyConstructorDeclarationTemplate(); static const char *CopyConstructorDeclarationTemplate();
static const char *MoveConstructorDeclarationTemplate(); 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()); propertyMap["optional_property_name_cap"] = utils::capitalizeAsciiName(oneof->name());
auto scopeTypeMap = produceMessageTypeMap(scope, nullptr); auto scopeTypeMap = produceMessageTypeMap(scope, nullptr);
propertyMap["classname"] = scope != nullptr ? scopeTypeMap["classname"] : ""; propertyMap["classname"] = scope != nullptr ? scopeTypeMap["classname"] : "";
propertyMap["type"] = propertyMap["optional_property_name_cap"] + "Fields";
return propertyMap; return propertyMap;
} }

View File

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

View File

@ -155,9 +155,9 @@ void OneofSimpleMessage::setTestOneofFieldSecondInt_p(QtProtobuf::int32 testOneo
m_testOneof.setValue(testOneofFieldSecondInt, 2); 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() void OneofSimpleMessage::clearTestOneof()
{ {
@ -464,17 +464,17 @@ void OneofComplexMessage::setSecondSecondComplexField_p(ComplexMessage *secondSe
m_secondOneof.setValue(value, 6); 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() void OneofComplexMessage::clearTestOneof()
{ {
m_testOneof = QtProtobufPrivate::QProtobufOneof(); 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() void OneofComplexMessage::clearSecondOneof()
{ {

View File

@ -41,6 +41,13 @@ public:
}; };
Q_ENUM(QtProtobufFieldEnum) Q_ENUM(QtProtobufFieldEnum)
enum class TestOneofFields {
UninitializedField = QtProtobuf::InvalidFieldNumber,
TestOneofFieldInt = 1,
TestOneofFieldSecondInt = 2,
};
Q_ENUM(TestOneofFields)
OneofSimpleMessage(); OneofSimpleMessage();
~OneofSimpleMessage(); ~OneofSimpleMessage();
OneofSimpleMessage(const OneofSimpleMessage &other); OneofSimpleMessage(const OneofSimpleMessage &other);
@ -55,7 +62,7 @@ public:
bool hasTestOneofFieldSecondInt() const; bool hasTestOneofFieldSecondInt() const;
QtProtobuf::int32 testOneofFieldSecondInt() const; QtProtobuf::int32 testOneofFieldSecondInt() const;
int testOneofField() const; TestOneofFields testOneofField() const;
void setTestOneofFieldInt(const QtProtobuf::int32 &testOneofFieldInt); void setTestOneofFieldInt(const QtProtobuf::int32 &testOneofFieldInt);
void setTestOneofFieldSecondInt(const QtProtobuf::int32 &testOneofFieldSecondInt); void setTestOneofFieldSecondInt(const QtProtobuf::int32 &testOneofFieldSecondInt);
void clearTestOneof(); void clearTestOneof();
@ -100,6 +107,22 @@ public:
}; };
Q_ENUM(QtProtobufFieldEnum) 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(); ~OneofComplexMessage();
OneofComplexMessage(const OneofComplexMessage &other); OneofComplexMessage(const OneofComplexMessage &other);
@ -132,8 +155,8 @@ public:
bool hasSecondSecondComplexField() const; bool hasSecondSecondComplexField() const;
ComplexMessage &secondSecondComplexField() const; ComplexMessage &secondSecondComplexField() const;
int testOneofField() const; TestOneofFields testOneofField() const;
int secondOneofField() const; SecondOneofFields secondOneofField() const;
void setTestFieldInt(const QtProtobuf::int32 &testFieldInt) void setTestFieldInt(const QtProtobuf::int32 &testFieldInt)
{ {
if (m_testFieldInt != testFieldInt) if (m_testFieldInt != testFieldInt)

View File

@ -155,9 +155,9 @@ void OneofSimpleMessage::setTestOneofFieldSecondInt_p(QtProtobuf::int32 testOneo
m_testOneof.setValue(testOneofFieldSecondInt, 2); 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() void OneofSimpleMessage::clearTestOneof()
{ {
@ -464,17 +464,17 @@ void OneofComplexMessage::setSecondSecondComplexField_p(ComplexMessage *secondSe
m_secondOneof.setValue(value, 6); 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() void OneofComplexMessage::clearTestOneof()
{ {
m_testOneof = QtProtobufPrivate::QProtobufOneof(); 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() void OneofComplexMessage::clearSecondOneof()
{ {

View File

@ -41,6 +41,13 @@ public:
}; };
Q_ENUM(QtProtobufFieldEnum) Q_ENUM(QtProtobufFieldEnum)
enum class TestOneofFields {
UninitializedField = QtProtobuf::InvalidFieldNumber,
TestOneofFieldInt = 1,
TestOneofFieldSecondInt = 2,
};
Q_ENUM(TestOneofFields)
OneofSimpleMessage(); OneofSimpleMessage();
~OneofSimpleMessage(); ~OneofSimpleMessage();
OneofSimpleMessage(const OneofSimpleMessage &other); OneofSimpleMessage(const OneofSimpleMessage &other);
@ -55,7 +62,7 @@ public:
bool hasTestOneofFieldSecondInt() const; bool hasTestOneofFieldSecondInt() const;
QtProtobuf::int32 testOneofFieldSecondInt() const; QtProtobuf::int32 testOneofFieldSecondInt() const;
int testOneofField() const; TestOneofFields testOneofField() const;
void setTestOneofFieldInt(const QtProtobuf::int32 &testOneofFieldInt); void setTestOneofFieldInt(const QtProtobuf::int32 &testOneofFieldInt);
void setTestOneofFieldSecondInt(const QtProtobuf::int32 &testOneofFieldSecondInt); void setTestOneofFieldSecondInt(const QtProtobuf::int32 &testOneofFieldSecondInt);
void clearTestOneof(); void clearTestOneof();
@ -100,6 +107,22 @@ public:
}; };
Q_ENUM(QtProtobufFieldEnum) 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(); ~OneofComplexMessage();
OneofComplexMessage(const OneofComplexMessage &other); OneofComplexMessage(const OneofComplexMessage &other);
@ -132,8 +155,8 @@ public:
bool hasSecondSecondComplexField() const; bool hasSecondSecondComplexField() const;
ComplexMessage &secondSecondComplexField() const; ComplexMessage &secondSecondComplexField() const;
int testOneofField() const; TestOneofFields testOneofField() const;
int secondOneofField() const; SecondOneofFields secondOneofField() const;
void setTestFieldInt(const QtProtobuf::int32 &testFieldInt) void setTestFieldInt(const QtProtobuf::int32 &testFieldInt)
{ {
if (m_testFieldInt != testFieldInt) if (m_testFieldInt != testFieldInt)