Bläddra i källkod

Rename Empty to GPBEmpty in php generated file. (#2379)

In php, class name cannot be "Empty". Modified code generator to (#2375) generate GPBEmpty instead (for google.protobuf.Empty only). Also change
runtime code to work with the new generated code accordingly.
Paul Yang 8 år sedan
förälder
incheckning
2286e5f4d0

+ 9 - 2
php/ext/google/protobuf/def.c

@@ -257,6 +257,11 @@ static void convert_to_class_name_inplace(char *class_name,
   bool first_char = false;
   size_t pkg_name_len = package_name == NULL ? 0 : strlen(package_name);
 
+  // In php, class name cannot be Empty.
+  if (strcmp("google.protobuf.Empty", fullname) == 0) {
+    fullname = "google.protobuf.GPBEmpty";
+  }
+
   if (pkg_name_len == 0) {
     strcpy(class_name, fullname);
   } else {
@@ -330,9 +335,11 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) {
         upb_msgdef_mapentry(upb_downcast_msgdef(def))) {                       \
       break;                                                                   \
     }                                                                          \
-    /* Prepend '.' to package name to make it absolute. */                     \
+    /* Prepend '.' to package name to make it absolute. In the 5 additional    \
+     * bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if    \
+     * given message is google.protobuf.Empty.*/                               \
     const char *fullname = upb_##def_type_lower##_fullname(def_type_lower);    \
-    char *klass_name = ecalloc(sizeof(char), 2 + strlen(fullname));            \
+    char *klass_name = ecalloc(sizeof(char), 5 + strlen(fullname));            \
     convert_to_class_name_inplace(klass_name, fullname,                        \
                                   upb_filedef_package(files[0]));              \
     zend_class_entry **pce;                                                    \

+ 2 - 2
php/ext/google/protobuf/message.c

@@ -177,8 +177,8 @@ static zend_object_value message_create(zend_class_entry* ce TSRMLS_DC) {
 
   zend_object_std_init(&msg->std, ce TSRMLS_CC);
   object_properties_init(&msg->std, ce);
-  layout_init(desc->layout, message_data(msg), msg->std.properties_table
-	      TSRMLS_CC);
+  layout_init(desc->layout, message_data(msg),
+              msg->std.properties_table TSRMLS_CC);
 
   return_value.handle = zend_objects_store_put(
       msg, (zend_objects_store_dtor_t)zend_objects_destroy_object, message_free,

+ 14 - 1
php/src/Google/Protobuf/descriptor.php

@@ -215,6 +215,18 @@ class Descriptor
         return $desc;
     }
 }
+
+function addPrefixIfSpecial(
+    $name,
+    $package)
+{
+    if ($name === "Empty" && $package === "google.protobuf") {
+        return "GPBEmpty";
+    } else {
+        return $name;
+    }
+}
+
 function getFullClassName(
     $proto,
     $containing,
@@ -224,7 +236,8 @@ function getFullClassName(
     &$fullname)
 {
     // Full name needs to start with '.'.
-    $message_name_without_package = $proto->getName();
+    $message_name_without_package =
+        addPrefixIfSpecial($proto->getName(), $package);
     if ($containing !== "") {
         $message_name_without_package =
             $containing . "." . $message_name_without_package;

+ 28 - 0
php/tests/google/protobuf/empty.pb.php

@@ -0,0 +1,28 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/empty.proto
+
+namespace Google\Protobuf;
+
+use Google\Protobuf\Internal\DescriptorPool;
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+class GPBEmpty extends \Google\Protobuf\Internal\Message
+{
+
+}
+
+$pool = DescriptorPool::getGeneratedPool();
+
+$pool->internalAddGeneratedFile(hex2bin(
+    "0ab7010a1b676f6f676c652f70726f746f6275662f656d7074792e70726f" .
+    "746f120f676f6f676c652e70726f746f62756622070a05456d7074794276" .
+    "0a13636f6d2e676f6f676c652e70726f746f627566420a456d7074795072" .
+    "6f746f50015a276769746875622e636f6d2f676f6c616e672f70726f746f" .
+    "6275662f7074797065732f656d707479f80101a20203475042aa021e476f" .
+    "6f676c652e50726f746f6275662e57656c6c4b6e6f776e54797065736206" .
+    "70726f746f33"
+));
+

+ 1 - 1
php/tests/test.sh

@@ -10,7 +10,7 @@ set -e
 phpize && ./configure --enable-debug CFLAGS='-g -O0' && make
 popd
 
-tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php )
+tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php )
 
 for t in "${tests[@]}"
 do

+ 13 - 0
php/tests/well_known_test.php

@@ -0,0 +1,13 @@
+<?php
+
+require_once("google/protobuf/empty.pb.php");
+
+use Google\Protobuf\GPBEmpty;
+
+class WellKnownTest extends PHPUnit_Framework_TestCase {
+
+    public function testNone() {
+      $msg = new GPBEmpty();
+    }
+
+}

+ 1 - 0
phpunit.xml

@@ -8,6 +8,7 @@
       <file>php/tests/encode_decode_test.php</file>
       <file>php/tests/generated_class_test.php</file>
       <file>php/tests/map_field_test.php</file>
+      <file>php/tests/well_known_test.php</file>
     </testsuite>
   </testsuites>
 </phpunit>

+ 16 - 2
src/google/protobuf/compiler/php/php_generator.cc

@@ -70,6 +70,16 @@ void GenerateEnum(const google::protobuf::EnumDescriptor* en,
 void Indent(google::protobuf::io::Printer* printer);
 void Outdent(google::protobuf::io::Printer* printer);
 
+std::string MessagePrefix(const google::protobuf::Descriptor* message) {
+  // Empty cannot be php class name.
+  if (message->name() == "Empty" &&
+      message->file()->package() == "google.protobuf") {
+    return "GPB";
+  } else {
+    return "";
+  }
+}
+
 std::string MessageName(const google::protobuf::Descriptor* message,
                         bool is_descriptor) {
   string message_name = message->name();
@@ -78,6 +88,8 @@ std::string MessageName(const google::protobuf::Descriptor* message,
     message_name = descriptor->name() + '_' + message_name;
     descriptor = descriptor->containing_type();
   }
+  message_name = MessagePrefix(message) + message_name;
+
   return PhpName(message->file()->package(), is_descriptor) + '\\' +
          message_name;
 }
@@ -483,8 +495,10 @@ void GenerateMessage(const string& name_prefix,
     return;
   }
 
-  string message_name = name_prefix.empty()?
-      message->name() : name_prefix + "_" + message->name();
+  string message_name =
+      name_prefix.empty()
+          ? message->name()
+          : name_prefix + "_" + MessagePrefix(message) + message->name();
 
   printer->Print(
       "class @name@ extends \\Google\\Protobuf\\Internal\\Message\n"