Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breaking Change: Remove deprecated legacy class aliases. #15709

Merged
merged 1 commit into from Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
60 changes: 0 additions & 60 deletions php/tests/GeneratedClassTest.php
Expand Up @@ -6,16 +6,12 @@
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\MapField;
use Google\Protobuf\Internal\GPBType;
use Bar\TestLegacyMessage;
use Bar\TestLegacyMessage_NestedEnum;
use Bar\TestLegacyMessage_NestedMessage;
use Foo\Test32Fields;
use Foo\TestEnum;
use Foo\TestIncludeNamespaceMessage;
use Foo\TestIncludePrefixMessage;
use Foo\TestMessage;
use Foo\TestMessage\Sub;
use Foo\TestMessage_Sub;
use Foo\TestMessage\NestedEnum;
use Foo\TestReverseFieldOrder;
use Foo\testLowerCaseMessage;
Expand Down Expand Up @@ -322,37 +318,6 @@ public function testNestedEnum()
$this->assertTrue(true);
}

public function testLegacyNestedEnum()
{
$m = new TestMessage();
$m->setOptionalNestedEnum(\Foo\TestMessage_NestedEnum::ZERO);
$this->assertTrue(true);
}

public function testLegacyTypehintWithNestedEnums()
{
$this->legacyEnum(new TestLegacyMessage\NestedEnum);
}

public function testLegacyReadOnlyMessage()
{
$this->assertTrue(class_exists('\Upper\READONLY'));
$this->assertTrue(class_exists('\Lower\readonly'));
$this->assertTrue(class_exists('\Php\Test\TestNamespace\PBEmpty\ReadOnly'));
}

public function testLegacyReadOnlyEnum()
{
$this->assertTrue(class_exists('\Upper_enum\READONLY'));
$this->assertTrue(class_exists('\Lower_enum\readonly'));
}

private function legacyEnum(TestLegacyMessage_NestedEnum $enum)
{
// If we made it here without a PHP Fatal error, the typehint worked
$this->assertTrue(true);
}

#########################################################
# Test float field.
#########################################################
Expand Down Expand Up @@ -516,31 +481,6 @@ public function testMessageField()
$this->assertFalse($m->hasOptionalMessage());
}

public function testLegacyMessageField()
{
$m = new TestMessage();

$sub_m = new TestMessage_Sub();
$sub_m->setA(1);
$m->setOptionalMessage($sub_m);
$this->assertSame(1, $m->getOptionalMessage()->getA());

$null = null;
$m->setOptionalMessage($null);
$this->assertNull($m->getOptionalMessage());
}

public function testLegacyTypehintWithNestedMessages()
{
$this->legacyMessage(new TestLegacyMessage\NestedMessage);
}

private function legacyMessage(TestLegacyMessage_NestedMessage $sub)
{
// If we made it here without a PHP Fatal error, the typehint worked
$this->assertTrue(true);
}

#########################################################
# Test repeated field.
#########################################################
Expand Down
11 changes: 0 additions & 11 deletions php/tests/proto/test_include.proto
Expand Up @@ -5,14 +5,3 @@ package bar;
message TestInclude {
int32 a = 1;
}

message TestLegacyMessage {
NestedMessage message = 1;
NestedEnum enum = 2;
message NestedMessage {
int32 a = 1;
}
enum NestedEnum {
ZERO = 0;
}
}
171 changes: 0 additions & 171 deletions src/google/protobuf/compiler/php/php_generator.cc
Expand Up @@ -103,17 +103,6 @@ std::string DescriptorFullName(const DescriptorType* desc, bool is_internal) {
return std::string(full_name);
}

template <typename DescriptorType>
std::string LegacyGeneratedClassName(const DescriptorType* desc) {
std::string classname = desc->name();
const Descriptor* containing = desc->containing_type();
while (containing != NULL) {
classname = containing->name() + '_' + classname;
containing = containing->containing_type();
}
return ClassNamePrefix(classname, desc) + classname;
}

std::string ConstantNamePrefix(absl::string_view classname) {
bool is_reserved = false;

Expand Down Expand Up @@ -170,17 +159,6 @@ std::string FullClassName(const DescriptorType* desc, bool is_descriptor) {
return FullClassName(desc, options);
}

template <typename DescriptorType>
std::string LegacyFullClassName(const DescriptorType* desc,
const Options& options) {
std::string classname = LegacyGeneratedClassName(desc);
std::string php_namespace = RootPhpNamespace(desc, options);
if (!php_namespace.empty()) {
return absl::StrCat(php_namespace, "\\", classname);
}
return classname;
}

std::string PhpNamePrefix(absl::string_view classname) {
if (IsReservedName(classname)) return "PB";
return "";
Expand Down Expand Up @@ -321,34 +299,6 @@ std::string GeneratedClassFileName(const DescriptorType* desc,
return absl::StrCat(result, ".php");
}

template <typename DescriptorType>
std::string LegacyGeneratedClassFileName(const DescriptorType* desc,
const Options& options) {
std::string result = LegacyFullClassName(desc, options);

for (int i = 0; i < result.size(); i++) {
if (result[i] == '\\') {
result[i] = '/';
}
}
return absl::StrCat(result, ".php");
}

template <typename DescriptorType>
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 absl::StrCat(php_namespace, "/", desc->name(), ".php");
}

return absl::StrCat(desc->name(), ".php");
}

std::string IntToString(int32_t value) {
std::ostringstream os;
os << value;
Expand Down Expand Up @@ -1168,83 +1118,6 @@ void GenerateMetadataFile(const FileDescriptor* file, const Options& options,
printer.Print("}\n\n");
}

template <typename DescriptorType>
void LegacyGenerateClassFile(const FileDescriptor* file,
const DescriptorType* desc, const Options& options,
GeneratorContext* generator_context) {
std::string filename = LegacyGeneratedClassFileName(desc, options);
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("if (false) {\n");
Indent(&printer);
printer.Print("/**\n");
printer.Print(" * This class is deprecated. Use ^new^ instead.\n", "new",
newname);
printer.Print(" * @deprecated\n");
printer.Print(" */\n");
printer.Print("class ^old^ {}\n", "old", LegacyGeneratedClassName(desc));
Outdent(&printer);
printer.Print("}\n");
printer.Print("class_exists(^new^::class);\n", "new",
GeneratedClassName(desc));
printer.Print(
"@trigger_error('^old^ is deprecated and will be removed in "
"the next major release. Use ^fullname^ instead', "
"E_USER_DEPRECATED);\n\n",
"old", LegacyFullClassName(desc, options), "fullname", newname);
}

template <typename DescriptorType>
void LegacyReadOnlyGenerateClassFile(const FileDescriptor* file,
const DescriptorType* desc,
const Options& options,
GeneratorContext* generator_context) {
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);

if (!php_namespace.empty()) {
printer.Print("namespace ^name^;\n\n", "name", php_namespace);
}

printer.Print(
"class_exists(^new^::class); // autoload the new class, which "
"will also create an alias to the deprecated class\n",
"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", classname);
}

bool GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en,
const Options& options,
GeneratorContext* generator_context, std::string* error) {
Expand Down Expand Up @@ -1369,28 +1242,6 @@ bool GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en,
Outdent(&printer);
printer.Print("}\n\n");

// write legacy alias for backwards compatibility with nested messages and
// enums
if (en->containing_type() != NULL) {
printer.Print(
"// Adding a class alias for backwards compatibility with the previous "
"class name.\n");
printer.Print("class_alias(^new^::class, \\^old^::class);\n\n", "new",
fullname, "old", LegacyFullClassName(en, options));
}

// Write legacy file for backwards compatibility with "readonly" keywword
std::string lower = en->name();
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
if (lower == "readonly") {
printer.Print(
"// Adding a class alias for backwards compatibility with the "
"\"readonly\" keyword.\n");
printer.Print("class_alias(^new^::class, __NAMESPACE__ . '\\^old^');\n\n",
"new", fullname, "old", en->name());
LegacyReadOnlyGenerateClassFile(file, en, options, generator_context);
}

return true;
}

Expand Down Expand Up @@ -1494,28 +1345,6 @@ bool GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
Outdent(&printer);
printer.Print("}\n\n");

// write legacy alias for backwards compatibility with nested messages and
// enums
if (message->containing_type() != NULL) {
printer.Print(
"// Adding a class alias for backwards compatibility with the previous "
"class name.\n");
printer.Print("class_alias(^new^::class, \\^old^::class);\n\n", "new",
fullname, "old", LegacyFullClassName(message, options));
}

// Write legacy file for backwards compatibility with "readonly" keywword
std::string lower = message->name();
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
if (lower == "readonly") {
printer.Print(
"// Adding a class alias for backwards compatibility with the "
"\"readonly\" keyword.\n");
printer.Print("class_alias(^new^::class, __NAMESPACE__ . '\\^old^');\n\n",
"new", fullname, "old", message->name());
LegacyReadOnlyGenerateClassFile(file, message, options, generator_context);
}

// Nested messages and enums.
for (int i = 0; i < message->nested_type_count(); i++) {
if (!GenerateMessageFile(file, message->nested_type(i), options,
Expand Down