Merge pull request #10320 from bshaffer/fix-readonly-with-nested-messages
fix: PHP readonly legacy files for nested messages
diff --git a/php/tests/GeneratedClassTest.php b/php/tests/GeneratedClassTest.php
index 37c33df..b42649d 100644
--- a/php/tests/GeneratedClassTest.php
+++ b/php/tests/GeneratedClassTest.php
@@ -338,6 +338,7 @@
{
$this->assertTrue(class_exists('\Upper\READONLY'));
$this->assertTrue(class_exists('\Lower\readonly'));
+ $this->assertTrue(class_exists('\Php\Test\TestNamespace\PBEmpty\ReadOnly'));
}
public function testLegacyReadOnlyEnum()
diff --git a/php/tests/proto/test_php_namespace.proto b/php/tests/proto/test_php_namespace.proto
index 61085bf..eb4a523 100644
--- a/php/tests/proto/test_php_namespace.proto
+++ b/php/tests/proto/test_php_namespace.proto
@@ -27,5 +27,7 @@
enum NestedEnum {
ZERO = 0;
};
+ // Test previously unreserved name
+ message ReadOnly {}
}
}
diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc
index 6c824e3..b238703 100644
--- a/src/google/protobuf/compiler/php/php_generator.cc
+++ b/src/google/protobuf/compiler/php/php_generator.cc
@@ -421,12 +421,17 @@
}
template <typename DescriptorType>
-std::string LegacyReadOnlyGeneratedClassFileName(const DescriptorType* desc,
- const Options& options) {
- std::string php_namespace = RootPhpNamespace(desc, options);
+std::string LegacyReadOnlyGeneratedClassFileName(std::string php_namespace,
+ const DescriptorType* desc) {
if (!php_namespace.empty()) {
+ for (int i = 0; i < php_namespace.size(); i++) {
+ if (php_namespace[i] == '\\') {
+ php_namespace[i] = '/';
+ }
+ }
return php_namespace + "/" + desc->name() + ".php";
}
+
return desc->name() + ".php";
}
@@ -1316,27 +1321,39 @@
void LegacyReadOnlyGenerateClassFile(const FileDescriptor* file,
const DescriptorType* desc, const Options& options,
GeneratorContext* generator_context) {
- std::string filename = LegacyReadOnlyGeneratedClassFileName(desc, options);
+ std::string fullname = FullClassName(desc, options);
+ std::string php_namespace;
+ std::string classname;
+ int lastindex = fullname.find_last_of("\\");
+
+ if (lastindex != std::string::npos) {
+ php_namespace = fullname.substr(0, lastindex);
+ classname = fullname.substr(lastindex + 1);
+ } else {
+ php_namespace = "";
+ classname = fullname;
+ }
+
+ std::string filename = LegacyReadOnlyGeneratedClassFileName(php_namespace, desc);
std::unique_ptr<io::ZeroCopyOutputStream> output(
generator_context->Open(filename));
io::Printer printer(output.get(), '^');
GenerateHead(file, &printer);
- std::string php_namespace = RootPhpNamespace(desc, options);
if (!php_namespace.empty()) {
printer.Print(
"namespace ^name^;\n\n",
"name", php_namespace);
}
- std::string newname = FullClassName(desc, options);
+
printer.Print("class_exists(^new^::class); // autoload the new class, which "
"will also create an alias to the deprecated class\n",
- "new", GeneratedClassNameImpl(desc));
+ "new", classname);
printer.Print("@trigger_error(__NAMESPACE__ . '\\^old^ is deprecated and will be removed in "
"the next major release. Use ^fullname^ instead', E_USER_DEPRECATED);\n\n",
"old", desc->name(),
- "fullname", newname);
+ "fullname", classname);
}
void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en,