From 4d56f2d83c69cda68ef87284bf9c9c884bfeccbf Mon Sep 17 00:00:00 2001 From: Noah Dietz Date: Tue, 26 Apr 2022 09:44:39 -0700 Subject: [PATCH] Change enum string name for reserved words (#9780) * Change enum string name for reserved words Update PHP descriptor protos * conditionally generate value compat code --- php/tests/GeneratedClassTest.php | 4 ++++ .../protobuf/compiler/php/php_generator.cc | 24 ++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/php/tests/GeneratedClassTest.php b/php/tests/GeneratedClassTest.php index 3c4ef139d..37c33dfab 100644 --- a/php/tests/GeneratedClassTest.php +++ b/php/tests/GeneratedClassTest.php @@ -291,6 +291,10 @@ class GeneratedClassTest extends TestBase // Test Enum methods $this->assertEquals('ONE', TestEnum::name(1)); $this->assertEquals(1, TestEnum::value('ONE')); + $this->assertEquals('ECHO', TestEnum::name(3)); + $this->assertEquals(3, TestEnum::value('ECHO')); + // Backwards compat value lookup by prefixed-name. + $this->assertEquals(3, TestEnum::value('PBECHO')); } public function testInvalidEnumValueThrowsException() diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index 14261124b..135a92f65 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -1373,11 +1373,18 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, "name", fullname); Indent(&printer); + bool hasReserved = false; for (int i = 0; i < en->value_count(); i++) { const EnumValueDescriptor* value = en->value(i); GenerateEnumValueDocComment(&printer, value); + + std::string prefix = ConstantNamePrefix(value->name()); + if (!prefix.empty()) { + hasReserved = true; + } + printer.Print("const ^name^ = ^number^;\n", - "name", ConstantNamePrefix(value->name()) + value->name(), + "name", prefix + value->name(), "number", IntToString(value->number())); } @@ -1385,8 +1392,9 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, Indent(&printer); for (int i = 0; i < en->value_count(); i++) { const EnumValueDescriptor* value = en->value(i); - printer.Print("self::^name^ => '^name^',\n", - "name", ConstantNamePrefix(value->name()) + value->name()); + printer.Print("self::^constant^ => '^name^',\n", + "constant", ConstantNamePrefix(value->name()) + value->name(), + "name", value->name()); } Outdent(&printer); printer.Print("];\n"); @@ -1416,12 +1424,22 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, printer.Print("$const = __CLASS__ . '::' . strtoupper($name);\n" "if (!defined($const)) {\n"); Indent(&printer); + if (hasReserved) { + printer.Print("$pbconst = __CLASS__. '::PB' . strtoupper($name);\n" + "if (!defined($pbconst)) {\n"); + Indent(&printer); + } printer.Print("throw new UnexpectedValueException(sprintf(\n"); Indent(&printer); Indent(&printer); printer.Print("'Enum %s has no value defined for name %s', __CLASS__, $name));\n"); Outdent(&printer); Outdent(&printer); + if (hasReserved) { + Outdent(&printer); + printer.Print("}\n" + "return constant($pbconst);\n"); + } Outdent(&printer); printer.Print("}\n" "return constant($const);\n");