@@ -48,29 +48,29 @@ const std::string kDescriptorMetadataFile =
4848const std::string kDescriptorDirName = " Google/Protobuf/Internal" ;
4949const std::string kDescriptorPackageName = " Google\\ Protobuf\\ Internal" ;
5050const char * const kReservedNames [] = {
51- " abstract" , " and" , " array" , " as" , " break" ,
52- " callable" , " case" , " catch" , " class" , " clone" ,
53- " const" , " continue" , " declare" , " default" , " die" ,
54- " do" , " echo" , " else" , " elseif" , " empty" ,
55- " enddeclare" , " endfor" , " endforeach" , " endif" , " endswitch" ,
56- " endwhile" , " eval" , " exit" , " extends" , " final" ,
57- " finally" , " fn" , " for" , " foreach" , " function" ,
58- " global" , " goto" , " if" , " implements" , " include" ,
59- " include_once" , " instanceof" , " insteadof" , " interface" , " isset" ,
60- " list" , " match" , " namespace" , " new" , " or" ,
61- " parent" , " print" , " private" , " protected" , " public" ,
62- " require " , " require_once " , " return " , " self " , " static " ,
63- " switch " , " throw " , " trait " , " try " , " unset " ,
64- " use " , " var " , " while " , " xor " , " yield " ,
65- " int " , " float " , " bool " , " string " , " true " ,
66- " false " , " null" , " void" , " iterable" };
51+ " abstract" , " and" , " array" , " as" , " break" ,
52+ " callable" , " case" , " catch" , " class" , " clone" ,
53+ " const" , " continue" , " declare" , " default" , " die" ,
54+ " do" , " echo" , " else" , " elseif" , " empty" ,
55+ " enddeclare" , " endfor" , " endforeach" , " endif" , " endswitch" ,
56+ " endwhile" , " eval" , " exit" , " extends" , " final" ,
57+ " finally" , " fn" , " for" , " foreach" , " function" ,
58+ " global" , " goto" , " if" , " implements" , " include" ,
59+ " include_once" , " instanceof" , " insteadof" , " interface" , " isset" ,
60+ " list" , " match" , " namespace" , " new" , " or" ,
61+ " parent" , " print" , " private" , " protected" , " public" ,
62+ " readonly " , " require " , " require_once " , " return " , " self " ,
63+ " static " , " switch " , " throw " , " trait " , " try " ,
64+ " unset " , " use " , " var " , " while " , " xor " ,
65+ " yield " , " int " , " float " , " bool " , " string " ,
66+ " true " , " false " , " null" , " void" , " iterable" };
6767const char * const kValidConstantNames [] = {
6868 " int" , " float" , " bool" , " string" , " true" ,
6969 " false" , " null" , " void" , " iterable" , " parent" ,
70- " self"
70+ " self" , " readonly "
7171};
72- const int kReservedNamesSize = 79 ;
73- const int kValidConstantNamesSize = 11 ;
72+ const int kReservedNamesSize = 80 ;
73+ const int kValidConstantNamesSize = 12 ;
7474const int kFieldSetter = 1 ;
7575const int kFieldGetter = 2 ;
7676const int kFieldProperty = 3 ;
@@ -420,6 +420,16 @@ std::string LegacyGeneratedClassFileName(const DescriptorType* desc,
420420 return result + " .php" ;
421421}
422422
423+ template <typename DescriptorType>
424+ std::string LegacyReadOnlyGeneratedClassFileName (const DescriptorType* desc,
425+ const Options& options) {
426+ std::string php_namespace = RootPhpNamespace (desc, options);
427+ if (!php_namespace.empty ()) {
428+ return php_namespace + " /" + desc->name () + " .php" ;
429+ }
430+ return desc->name () + " .php" ;
431+ }
432+
423433std::string GeneratedServiceFileName (const ServiceDescriptor* service,
424434 const Options& options) {
425435 std::string result = FullClassName (service, options) + " Interface" ;
@@ -1302,6 +1312,32 @@ void LegacyGenerateClassFile(const FileDescriptor* file,
13021312 " fullname" , newname);
13031313}
13041314
1315+ template <typename DescriptorType>
1316+ void LegacyReadOnlyGenerateClassFile (const FileDescriptor* file,
1317+ const DescriptorType* desc, const Options& options,
1318+ GeneratorContext* generator_context) {
1319+ std::string filename = LegacyReadOnlyGeneratedClassFileName (desc, options);
1320+ std::unique_ptr<io::ZeroCopyOutputStream> output (
1321+ generator_context->Open (filename));
1322+ io::Printer printer (output.get (), ' ^' );
1323+
1324+ GenerateHead (file, &printer);
1325+
1326+ std::string php_namespace = RootPhpNamespace (desc, options);
1327+ if (!php_namespace.empty ()) {
1328+ printer.Print (
1329+ " namespace ^name^;\n\n " ,
1330+ " name" , php_namespace);
1331+ }
1332+ std::string newname = FullClassName (desc, options);
1333+ printer.Print (" class_exists(^new^::class);\n " ,
1334+ " new" , GeneratedClassNameImpl (desc));
1335+ printer.Print (" @trigger_error(__NAMESPACE__ . '\\ ^old^ is deprecated and will be removed in "
1336+ " the next major release. Use ^fullname^ instead', E_USER_DEPRECATED);\n\n " ,
1337+ " old" , desc->name (),
1338+ " fullname" , newname);
1339+ }
1340+
13051341void GenerateEnumFile (const FileDescriptor* file, const EnumDescriptor* en,
13061342 const Options& options,
13071343 GeneratorContext* generator_context) {
@@ -1405,6 +1441,19 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en,
14051441 " old" , LegacyFullClassName (en, options));
14061442 LegacyGenerateClassFile (file, en, options, generator_context);
14071443 }
1444+
1445+ // Write legacy file for backwards compatibility with "readonly" keywword
1446+ std::string lower = en->name ();
1447+ std::transform (lower.begin (), lower.end (), lower.begin (), ::tolower);
1448+ if (lower == " readonly" ) {
1449+ printer.Print (
1450+ " // Adding a class alias for backwards compatibility with the \" readonly\" keyword.\n " );
1451+ printer.Print (
1452+ " class_alias(^new^::class, __NAMESPACE__ . '\\ ^old^');\n\n " ,
1453+ " new" , fullname,
1454+ " old" , en->name ());
1455+ LegacyReadOnlyGenerateClassFile (file, en, options, generator_context);
1456+ }
14081457}
14091458
14101459void GenerateMessageFile (const FileDescriptor* file, const Descriptor* message,
@@ -1521,6 +1570,19 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
15211570 LegacyGenerateClassFile (file, message, options, generator_context);
15221571 }
15231572
1573+ // Write legacy file for backwards compatibility with "readonly" keywword
1574+ std::string lower = message->name ();
1575+ std::transform (lower.begin (), lower.end (), lower.begin (), ::tolower);
1576+ if (lower == " readonly" ) {
1577+ printer.Print (
1578+ " // Adding a class alias for backwards compatibility with the \" readonly\" keyword.\n " );
1579+ printer.Print (
1580+ " class_alias(^new^::class, __NAMESPACE__ . '\\ ^old^');\n\n " ,
1581+ " new" , fullname,
1582+ " old" , message->name ());
1583+ LegacyReadOnlyGenerateClassFile (file, message, options, generator_context);
1584+ }
1585+
15241586 // Nested messages and enums.
15251587 for (int i = 0 ; i < message->nested_type_count (); i++) {
15261588 GenerateMessageFile (file, message->nested_type (i), options,
0 commit comments