Change enum string name for reserved words (#9780)
* Change enum string name for reserved words
Update PHP descriptor protos
* conditionally generate value compat code
diff --git a/php/tests/GeneratedClassTest.php b/php/tests/GeneratedClassTest.php
index 3c4ef13..37c33df 100644
--- a/php/tests/GeneratedClassTest.php
+++ b/php/tests/GeneratedClassTest.php
@@ -291,6 +291,10 @@
// 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 1426112..135a92f 100644
--- a/src/google/protobuf/compiler/php/php_generator.cc
+++ b/src/google/protobuf/compiler/php/php_generator.cc
@@ -1373,11 +1373,18 @@
"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 @@
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 @@
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");