From f4d0f7c85eb5347b5296d44ae2ad3ba2e27e0050 Mon Sep 17 00:00:00 2001 From: Christian Alexander Wolf Date: Fri, 29 Jan 2021 20:33:27 +0100 Subject: [PATCH] feat: add support for deprecated fields to PHP compiler (#8223) * feat: add support for deprecated fields to PHP compiler * PR feedback 1 --- php/tests/GeneratedClassTest.php | 27 ++++++++++++ php/tests/GeneratedPhpdocTest.php | 7 ++++ php/tests/proto/test.proto | 3 ++ .../protobuf/compiler/php/php_generator.cc | 42 +++++++++++++------ 4 files changed, 67 insertions(+), 12 deletions(-) diff --git a/php/tests/GeneratedClassTest.php b/php/tests/GeneratedClassTest.php index f3f74d1d3c11..c0de0ba9b26b 100644 --- a/php/tests/GeneratedClassTest.php +++ b/php/tests/GeneratedClassTest.php @@ -71,6 +71,33 @@ public function testInt32Field() $this->assertSame(MIN_INT32, $m->getOptionalInt32()); } + ######################################################### + # Test deprecated int32 field. + ######################################################### + + public function testDeprecatedInt32Field() + { + $m = new TestMessage(); + + // temporarily change error handler to capture the deprecated errors + $deprecationCount = 0; + set_error_handler(function ($errno, $errstr) use (&$deprecationCount) { + if ($errstr === 'deprecated_optional_int32 is deprecated.') { + $deprecationCount++; + } + }, E_USER_DEPRECATED); + + // default test set + $m->setDeprecatedOptionalInt32(MAX_INT32); + $this->assertSame(MAX_INT32, $m->getDeprecatedOptionalInt32()); + $m->setDeprecatedOptionalInt32(MIN_INT32); + $this->assertSame(MIN_INT32, $m->getDeprecatedOptionalInt32()); + + restore_error_handler(); + + $this->assertSame(4, $deprecationCount); + } + ######################################################### # Test optional int32 field. ######################################################### diff --git a/php/tests/GeneratedPhpdocTest.php b/php/tests/GeneratedPhpdocTest.php index de672ac84e56..18963a9b39cf 100644 --- a/php/tests/GeneratedPhpdocTest.php +++ b/php/tests/GeneratedPhpdocTest.php @@ -340,6 +340,13 @@ public function providePhpDocForGettersAndSetters() ], '@param \NoNamespaceMessage $var' ], + [ + [ + 'setDeprecatedOptionalInt32', + 'getDeprecatedOptionalInt32', + ], + '@deprecated' + ], ]; } } diff --git a/php/tests/proto/test.proto b/php/tests/proto/test.proto index 8835729f0586..609b8cfe0cdc 100644 --- a/php/tests/proto/test.proto +++ b/php/tests/proto/test.proto @@ -147,6 +147,9 @@ message TestMessage { map map_string_any = 122; map map_string_list = 123; map map_string_struct = 124; + + // deprecated field + int32 deprecated_optional_int32 = 125 [deprecated=true]; } enum TestEnum { diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index 04d8f8c0701c..203b49f918f4 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -644,43 +644,50 @@ void GenerateFieldAccessor(const FieldDescriptor* field, const Options& options, // Generate getter. GenerateFieldDocComment(printer, field, options, kFieldGetter); + // deprecation + std::string deprecation_trigger = (field->options().deprecated()) ? "@trigger_error('" + + field->name() + " is deprecated.', E_USER_DEPRECATED);\n " : ""; + if (oneof != NULL) { printer->Print( "public function get^camel_name^()\n" "{\n" - " return $this->readOneof(^number^);\n" + " ^deprecation_trigger^return $this->readOneof(^number^);\n" "}\n\n" "public function has^camel_name^()\n" "{\n" - " return $this->hasOneof(^number^);\n" + " ^deprecation_trigger^return $this->hasOneof(^number^);\n" "}\n\n", "camel_name", UnderscoresToCamelCase(field->name(), true), - "number", IntToString(field->number())); + "number", IntToString(field->number()), + "deprecation_trigger", deprecation_trigger); } else if (field->has_presence()) { printer->Print( "public function get^camel_name^()\n" "{\n" - " return isset($this->^name^) ? $this->^name^ : ^default_value^;\n" + " ^deprecation_trigger^return isset($this->^name^) ? $this->^name^ : ^default_value^;\n" "}\n\n" "public function has^camel_name^()\n" "{\n" - " return isset($this->^name^);\n" + " ^deprecation_trigger^return isset($this->^name^);\n" "}\n\n" "public function clear^camel_name^()\n" "{\n" - " unset($this->^name^);\n" + " ^deprecation_trigger^unset($this->^name^);\n" "}\n\n", "camel_name", UnderscoresToCamelCase(field->name(), true), "name", field->name(), - "default_value", DefaultForField(field)); + "default_value", DefaultForField(field), + "deprecation_trigger", deprecation_trigger); } else { printer->Print( "public function get^camel_name^()\n" "{\n" - " return $this->^name^;\n" + " ^deprecation_trigger^return $this->^name^;\n" "}\n\n", - "camel_name", UnderscoresToCamelCase(field->name(), true), "name", - field->name()); + "camel_name", UnderscoresToCamelCase(field->name(), true), + "name", field->name(), + "deprecation_trigger", deprecation_trigger); } // For wrapper types, generate an additional getXXXUnwrapped getter @@ -692,10 +699,11 @@ void GenerateFieldAccessor(const FieldDescriptor* field, const Options& options, printer->Print( "public function get^camel_name^Unwrapped()\n" "{\n" - " return $this->readWrapperValue(\"^field_name^\");\n" + " ^deprecation_trigger^return $this->readWrapperValue(\"^field_name^\");\n" "}\n\n", "camel_name", UnderscoresToCamelCase(field->name(), true), - "field_name", field->name()); + "field_name", field->name(), + "deprecation_trigger", deprecation_trigger); } // Generate setter. @@ -707,6 +715,13 @@ void GenerateFieldAccessor(const FieldDescriptor* field, const Options& options, Indent(printer); + if (field->options().deprecated()) { + printer->Print( + "^deprecation_trigger^", + "deprecation_trigger", deprecation_trigger + ); + } + // Type check. if (field->is_map()) { const Descriptor* map_entry = field->message_type(); @@ -1741,6 +1756,9 @@ void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field, "php_type", PhpGetterTypeName(field, options), "maybe_null", can_return_null ? "|null" : ""); } + if (field->options().deprecated()) { + printer->Print(" * @deprecated\n"); + } printer->Print(" */\n"); }