Browse Source

Merge pull request #4675 from TeBoring/3.6.x

Cherry-pick php generated code changes into 3.6.x
Paul Yang 7 năm trước cách đây
mục cha
commit
4885b8058a
100 tập tin đã thay đổi với 2736 bổ sung831 xóa
  1. 1 0
      .gitignore
  2. 16 13
      Makefile.am
  3. 164 89
      php/ext/google/protobuf/def.c
  4. 113 6
      php/ext/google/protobuf/message.c
  5. 6 6
      php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php
  6. 81 27
      php/src/Google/Protobuf/Any.php
  7. 42 2
      php/src/Google/Protobuf/Api.php
  8. 12 2
      php/src/Google/Protobuf/BoolValue.php
  9. 12 2
      php/src/Google/Protobuf/BytesValue.php
  10. 12 2
      php/src/Google/Protobuf/DoubleValue.php
  11. 22 2
      php/src/Google/Protobuf/Duration.php
  12. 20 2
      php/src/Google/Protobuf/Enum.php
  13. 16 2
      php/src/Google/Protobuf/EnumValue.php
  14. 32 2
      php/src/Google/Protobuf/Field.php
  15. 42 0
      php/src/Google/Protobuf/Field/Cardinality.php
  16. 132 0
      php/src/Google/Protobuf/Field/Kind.php
  17. 16 2
      php/src/Google/Protobuf/FieldMask.php
  18. 6 29
      php/src/Google/Protobuf/Field_Cardinality.php
  19. 6 119
      php/src/Google/Protobuf/Field_Kind.php
  20. 12 2
      php/src/Google/Protobuf/FloatValue.php
  21. 10 2
      php/src/Google/Protobuf/GPBEmpty.php
  22. 12 2
      php/src/Google/Protobuf/Int32Value.php
  23. 12 2
      php/src/Google/Protobuf/Int64Value.php
  24. 26 6
      php/src/Google/Protobuf/Internal/DescriptorProto.php
  25. 18 4
      php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php
  26. 19 4
      php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php
  27. 22 4
      php/src/Google/Protobuf/Internal/EnumDescriptorProto.php
  28. 19 4
      php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php
  29. 20 2
      php/src/Google/Protobuf/Internal/EnumOptions.php
  30. 13 2
      php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php
  31. 17 2
      php/src/Google/Protobuf/Internal/EnumValueOptions.php
  32. 12 2
      php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php
  33. 40 2
      php/src/Google/Protobuf/Internal/FieldDescriptorProto.php
  34. 6 3
      php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php
  35. 6 3
      php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php
  36. 66 2
      php/src/Google/Protobuf/Internal/FieldOptions.php
  37. 6 3
      php/src/Google/Protobuf/Internal/FieldOptions/CType.php
  38. 6 3
      php/src/Google/Protobuf/Internal/FieldOptions/JSType.php
  39. 35 2
      php/src/Google/Protobuf/Internal/FileDescriptorProto.php
  40. 11 2
      php/src/Google/Protobuf/Internal/FileDescriptorSet.php
  41. 93 2
      php/src/Google/Protobuf/Internal/FileOptions.php
  42. 6 3
      php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php
  43. 13 5
      php/src/Google/Protobuf/Internal/GPBUtil.php
  44. 15 4
      php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php
  45. 27 4
      php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php
  46. 150 98
      php/src/Google/Protobuf/Internal/Message.php
  47. 56 2
      php/src/Google/Protobuf/Internal/MessageOptions.php
  48. 20 2
      php/src/Google/Protobuf/Internal/MethodDescriptorProto.php
  49. 18 2
      php/src/Google/Protobuf/Internal/MethodOptions.php
  50. 6 3
      php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php
  51. 12 2
      php/src/Google/Protobuf/Internal/OneofDescriptorProto.php
  52. 12 2
      php/src/Google/Protobuf/Internal/OneofOptions.php
  53. 13 2
      php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php
  54. 17 2
      php/src/Google/Protobuf/Internal/ServiceOptions.php
  55. 54 4
      php/src/Google/Protobuf/Internal/SourceCodeInfo.php
  56. 82 4
      php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php
  57. 21 4
      php/src/Google/Protobuf/Internal/UninterpretedOption.php
  58. 17 4
      php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php
  59. 12 2
      php/src/Google/Protobuf/ListValue.php
  60. 24 2
      php/src/Google/Protobuf/Method.php
  61. 15 2
      php/src/Google/Protobuf/Mixin.php
  62. 1 1
      php/src/Google/Protobuf/NullValue.php
  63. 20 2
      php/src/Google/Protobuf/Option.php
  64. 13 2
      php/src/Google/Protobuf/SourceContext.php
  65. 12 2
      php/src/Google/Protobuf/StringValue.php
  66. 12 2
      php/src/Google/Protobuf/Struct.php
  67. 1 1
      php/src/Google/Protobuf/Syntax.php
  68. 20 3
      php/src/Google/Protobuf/Timestamp.php
  69. 22 2
      php/src/Google/Protobuf/Type.php
  70. 12 2
      php/src/Google/Protobuf/UInt32Value.php
  71. 12 2
      php/src/Google/Protobuf/UInt64Value.php
  72. 22 2
      php/src/Google/Protobuf/Value.php
  73. 6 6
      php/tests/array_test.php
  74. 1 1
      php/tests/descriptors_test.php
  75. 3 3
      php/tests/encode_decode_test.php
  76. 2 2
      php/tests/gdb_test.sh
  77. 197 26
      php/tests/generated_class_test.php
  78. 11 3
      php/tests/generated_phpdoc_test.php
  79. 5 5
      php/tests/map_field_test.php
  80. 5 5
      php/tests/memory_leak_test.php
  81. 73 2
      php/tests/php_implementation_test.php
  82. 17 0
      php/tests/proto/empty/echo.proto
  83. 11 0
      php/tests/proto/test_empty_php_namespace.proto
  84. 11 0
      php/tests/proto/test_include.proto
  85. 10 4
      php/tests/proto/test_no_namespace.proto
  86. 23 0
      php/tests/proto/test_php_namespace.proto
  87. 8 0
      php/tests/proto/test_prefix.proto
  88. 1 1
      php/tests/test_base.php
  89. 9 9
      php/tests/test_util.php
  90. 43 43
      php/tests/undefined_test.php
  91. 6 6
      php/tests/well_known_test.php
  92. 5 0
      ruby/Rakefile
  93. 2 2
      ruby/lib/google/protobuf.rb
  94. 2 2
      ruby/lib/google/protobuf/message_exts.rb
  95. 24 0
      ruby/tests/encode_decode_test.rb
  96. 2 0
      ruby/tests/generated_code_test.rb
  97. 7 0
      ruby/tests/test_ruby_package.proto
  98. 267 157
      src/google/protobuf/compiler/php/php_generator.cc
  99. 0 10
      src/google/protobuf/compiler/php/php_generator.h
  100. 16 3
      src/google/protobuf/compiler/ruby/ruby_generator.cc

+ 1 - 0
.gitignore

@@ -174,6 +174,7 @@ js/testproto_libs2.js
 ruby/lib/
 ruby/lib/
 ruby/tests/generated_code_pb.rb
 ruby/tests/generated_code_pb.rb
 ruby/tests/test_import_pb.rb
 ruby/tests/test_import_pb.rb
+ruby/tests/test_ruby_package_pb.rb
 ruby/Gemfile.lock
 ruby/Gemfile.lock
 ruby/compatibility_tests/v3.0.0/protoc
 ruby/compatibility_tests/v3.0.0/protoc
 ruby/compatibility_tests/v3.0.0/tests/generated_code_pb.rb
 ruby/compatibility_tests/v3.0.0/tests/generated_code_pb.rb

+ 16 - 13
Makefile.am

@@ -619,7 +619,9 @@ php_EXTRA_DIST=                                                       \
   php/src/Google/Protobuf/Field.php                                   \
   php/src/Google/Protobuf/Field.php                                   \
   php/src/Google/Protobuf/FieldDescriptor.php                         \
   php/src/Google/Protobuf/FieldDescriptor.php                         \
   php/src/Google/Protobuf/FieldMask.php                               \
   php/src/Google/Protobuf/FieldMask.php                               \
+  php/src/Google/Protobuf/Field/Cardinality.php                       \
   php/src/Google/Protobuf/Field_Cardinality.php                       \
   php/src/Google/Protobuf/Field_Cardinality.php                       \
+  php/src/Google/Protobuf/Field/Kind.php                              \
   php/src/Google/Protobuf/Field_Kind.php                              \
   php/src/Google/Protobuf/Field_Kind.php                              \
   php/src/Google/Protobuf/FloatValue.php                              \
   php/src/Google/Protobuf/FloatValue.php                              \
   php/src/Google/Protobuf/GPBEmpty.php                                \
   php/src/Google/Protobuf/GPBEmpty.php                                \
@@ -630,30 +632,29 @@ php_EXTRA_DIST=                                                       \
   php/src/Google/Protobuf/Internal/Descriptor.php                     \
   php/src/Google/Protobuf/Internal/Descriptor.php                     \
   php/src/Google/Protobuf/Internal/DescriptorPool.php                 \
   php/src/Google/Protobuf/Internal/DescriptorPool.php                 \
   php/src/Google/Protobuf/Internal/DescriptorProto.php                \
   php/src/Google/Protobuf/Internal/DescriptorProto.php                \
-  php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php \
-  php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php  \
+  php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php \
+  php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php  \
   php/src/Google/Protobuf/Internal/EnumBuilderContext.php             \
   php/src/Google/Protobuf/Internal/EnumBuilderContext.php             \
   php/src/Google/Protobuf/Internal/EnumDescriptor.php                 \
   php/src/Google/Protobuf/Internal/EnumDescriptor.php                 \
   php/src/Google/Protobuf/Internal/EnumDescriptorProto.php            \
   php/src/Google/Protobuf/Internal/EnumDescriptorProto.php            \
-  php/src/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.php \
+  php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php \
   php/src/Google/Protobuf/Internal/EnumOptions.php                    \
   php/src/Google/Protobuf/Internal/EnumOptions.php                    \
   php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php       \
   php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php       \
   php/src/Google/Protobuf/Internal/EnumValueOptions.php               \
   php/src/Google/Protobuf/Internal/EnumValueOptions.php               \
   php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php          \
   php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php          \
-  php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php     \
   php/src/Google/Protobuf/Internal/FieldDescriptorProto.php           \
   php/src/Google/Protobuf/Internal/FieldDescriptorProto.php           \
   php/src/Google/Protobuf/Internal/FieldDescriptor.php                \
   php/src/Google/Protobuf/Internal/FieldDescriptor.php                \
   php/src/Google/Protobuf/Internal/FieldDescriptorProto.php           \
   php/src/Google/Protobuf/Internal/FieldDescriptorProto.php           \
-  php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php     \
-  php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php      \
+  php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php     \
+  php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php      \
   php/src/Google/Protobuf/Internal/FieldOptions.php                   \
   php/src/Google/Protobuf/Internal/FieldOptions.php                   \
-  php/src/Google/Protobuf/Internal/FieldOptions_CType.php             \
-  php/src/Google/Protobuf/Internal/FieldOptions_JSType.php            \
+  php/src/Google/Protobuf/Internal/FieldOptions/CType.php             \
+  php/src/Google/Protobuf/Internal/FieldOptions/JSType.php            \
   php/src/Google/Protobuf/Internal/FileDescriptor.php                 \
   php/src/Google/Protobuf/Internal/FileDescriptor.php                 \
   php/src/Google/Protobuf/Internal/FileDescriptorProto.php            \
   php/src/Google/Protobuf/Internal/FileDescriptorProto.php            \
   php/src/Google/Protobuf/Internal/FileDescriptorSet.php              \
   php/src/Google/Protobuf/Internal/FileDescriptorSet.php              \
   php/src/Google/Protobuf/Internal/FileOptions.php                    \
   php/src/Google/Protobuf/Internal/FileOptions.php                    \
-  php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php       \
+  php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php       \
   php/src/Google/Protobuf/Internal/GPBDecodeException.php             \
   php/src/Google/Protobuf/Internal/GPBDecodeException.php             \
   php/src/Google/Protobuf/Internal/GPBJsonWire.php                    \
   php/src/Google/Protobuf/Internal/GPBJsonWire.php                    \
   php/src/Google/Protobuf/Internal/GPBLabel.php                       \
   php/src/Google/Protobuf/Internal/GPBLabel.php                       \
@@ -662,7 +663,7 @@ php_EXTRA_DIST=                                                       \
   php/src/Google/Protobuf/Internal/GPBWire.php                        \
   php/src/Google/Protobuf/Internal/GPBWire.php                        \
   php/src/Google/Protobuf/Internal/GPBWireType.php                    \
   php/src/Google/Protobuf/Internal/GPBWireType.php                    \
   php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php              \
   php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php              \
-  php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php   \
+  php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php   \
   php/src/Google/Protobuf/Internal/GetPublicDescriptorTrait.php       \
   php/src/Google/Protobuf/Internal/GetPublicDescriptorTrait.php       \
   php/src/Google/Protobuf/Internal/HasPublicDescriptorTrait.php       \
   php/src/Google/Protobuf/Internal/HasPublicDescriptorTrait.php       \
   php/src/Google/Protobuf/Internal/MapEntry.php                       \
   php/src/Google/Protobuf/Internal/MapEntry.php                       \
@@ -673,7 +674,7 @@ php_EXTRA_DIST=                                                       \
   php/src/Google/Protobuf/Internal/MessageOptions.php                 \
   php/src/Google/Protobuf/Internal/MessageOptions.php                 \
   php/src/Google/Protobuf/Internal/MethodDescriptorProto.php          \
   php/src/Google/Protobuf/Internal/MethodDescriptorProto.php          \
   php/src/Google/Protobuf/Internal/MethodOptions.php                  \
   php/src/Google/Protobuf/Internal/MethodOptions.php                  \
-  php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php \
+  php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php \
   php/src/Google/Protobuf/Internal/OneofDescriptor.php                \
   php/src/Google/Protobuf/Internal/OneofDescriptor.php                \
   php/src/Google/Protobuf/Internal/OneofDescriptorProto.php           \
   php/src/Google/Protobuf/Internal/OneofDescriptorProto.php           \
   php/src/Google/Protobuf/Internal/OneofField.php                     \
   php/src/Google/Protobuf/Internal/OneofField.php                     \
@@ -684,9 +685,9 @@ php_EXTRA_DIST=                                                       \
   php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php         \
   php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php         \
   php/src/Google/Protobuf/Internal/ServiceOptions.php                 \
   php/src/Google/Protobuf/Internal/ServiceOptions.php                 \
   php/src/Google/Protobuf/Internal/SourceCodeInfo.php                 \
   php/src/Google/Protobuf/Internal/SourceCodeInfo.php                 \
-  php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php        \
+  php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php        \
   php/src/Google/Protobuf/Internal/UninterpretedOption.php            \
   php/src/Google/Protobuf/Internal/UninterpretedOption.php            \
-  php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php   \
+  php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php   \
   php/src/Google/Protobuf/ListValue.php                               \
   php/src/Google/Protobuf/ListValue.php                               \
   php/src/Google/Protobuf/Method.php                                  \
   php/src/Google/Protobuf/Method.php                                  \
   php/src/Google/Protobuf/Mixin.php                                   \
   php/src/Google/Protobuf/Mixin.php                                   \
@@ -716,6 +717,7 @@ php_EXTRA_DIST=                                                       \
   php/tests/map_field_test.php                                        \
   php/tests/map_field_test.php                                        \
   php/tests/memory_leak_test.php                                      \
   php/tests/memory_leak_test.php                                      \
   php/tests/php_implementation_test.php                               \
   php/tests/php_implementation_test.php                               \
+  php/tests/proto/empty/echo.proto                                    \
   php/tests/proto/test.proto                                          \
   php/tests/proto/test.proto                                          \
   php/tests/proto/test_descriptors.proto                              \
   php/tests/proto/test_descriptors.proto                              \
   php/tests/proto/test_empty_php_namespace.proto                      \
   php/tests/proto/test_empty_php_namespace.proto                      \
@@ -904,6 +906,7 @@ ruby_EXTRA_DIST=                                                             \
   ruby/tests/stress.rb                                                       \
   ruby/tests/stress.rb                                                       \
   ruby/tests/generated_code.proto                                            \
   ruby/tests/generated_code.proto                                            \
   ruby/tests/test_import.proto                                               \
   ruby/tests/test_import.proto                                               \
+  ruby/tests/test_ruby_package.proto                                         \
   ruby/tests/generated_code_test.rb                                          \
   ruby/tests/generated_code_test.rb                                          \
   ruby/tests/well_known_types_test.rb                                        \
   ruby/tests/well_known_types_test.rb                                        \
   ruby/travis-test.sh
   ruby/travis-test.sh

+ 164 - 89
php/ext/google/protobuf/def.c

@@ -718,105 +718,186 @@ PHP_METHOD(InternalDescriptorPool, getGeneratedPool) {
 #endif
 #endif
 }
 }
 
 
-static void classname_no_prefix(const char *fullname, const char *package_name,
-                                char *class_name) {
-  size_t i = 0, j;
-  bool first_char = true, is_reserved = false;
-  size_t pkg_name_len = package_name == NULL ? 0 : strlen(package_name);
-  size_t message_name_start = package_name == NULL ? 0 : pkg_name_len + 1;
-  size_t message_len = (strlen(fullname) - message_name_start);
+static size_t classname_len_max(const char *fullname,
+                                const char *package,
+                                const char *php_namespace,
+                                const char *prefix) {
+  size_t fullname_len = strlen(fullname);
+  size_t package_len = 0;
+  size_t prefix_len = 0;
+  size_t namespace_len = 0;
+  size_t length = fullname_len;
+  int i, segment, classname_start = 0;
+
+  if (package != NULL) {
+    package_len = strlen(package);
+  }
+  if (prefix != NULL) {
+    prefix_len = strlen(prefix);
+  }
+  if (php_namespace != NULL) {
+    namespace_len = strlen(php_namespace);
+  }
 
 
-  // Submessage is concatenated with its containing messages by '_'.
-  for (j = message_name_start; j < message_name_start + message_len; j++) {
-    if (fullname[j] == '.') {
-      class_name[i++] = '_';
-    } else {
-      class_name[i++] = fullname[j];
+  // Process package
+  if (package_len > 0) {
+    segment = 1;
+    for (i = 0; i < package_len; i++) {
+      if (package[i] == '.') {
+        segment++;
+      }
     }
     }
-  }
-}
+    // In case of reserved name in package.
+    length += 3 * segment;
 
 
-static const char *classname_prefix(const char *classname,
-                                    const char *prefix_given,
-                                    const char *package_name) {
-  size_t i;
-  bool is_reserved = false;
+    classname_start = package_len + 1;
+  }
 
 
-  if (prefix_given != NULL && strcmp(prefix_given, "") != 0) {
-    return prefix_given;
+  // Process class name
+  segment = 1;
+  for (i = classname_start; i < fullname_len; i++) {
+    if (fullname[i] == '.') {
+      segment++;
+    }
+  }
+  if (prefix_len == 0) {
+    length += 3 * segment;
+  } else {
+    length += prefix_len * segment;
   }
   }
 
 
-  char* lower = ALLOC_N(char, strlen(classname) + 1);
-  i = 0;
-  while(classname[i]) {
-    lower[i] = (char)tolower(classname[i]);
+  // The additional 2, one is for preceding '.' and the other is for trailing 0.
+  return length + namespace_len + 2;
+}
+
+static bool is_reserved(const char *segment, int length) {
+  bool result;
+  char* lower = ALLOC_N(char, length + 1);
+  memcpy(lower, segment, length);
+  int i = 0;
+  while(lower[i]) {
+    lower[i] = (char)tolower(lower[i]);
     i++;
     i++;
   }
   }
-  lower[i] = 0;
-
-  is_reserved = is_reserved_name(lower);
+  lower[length] = 0;
+  result = is_reserved_name(lower);
   FREE(lower);
   FREE(lower);
+  return result;
+}
 
 
-  if (is_reserved) {
-    if (package_name != NULL && strcmp("google.protobuf", package_name) == 0) {
-      return "GPB";
-    } else {
-      return "PB";
+static char* fill_prefix(const char *segment, int length,
+                         const char *prefix_given,
+                         const char *package_name, char *classname) {
+  size_t i;
+
+  if (prefix_given != NULL && strcmp(prefix_given, "") != 0) {
+    size_t prefix_len = strlen(prefix_given);
+    memcpy(classname, prefix_given, strlen(prefix_given));
+    classname += prefix_len;
+  } else {
+    if (is_reserved(segment, length)) {
+      if (package_name != NULL &&
+          strcmp("google.protobuf", package_name) == 0) {
+        memcpy(classname, "GPB", 3);
+        classname += 3;
+      } else {
+        memcpy(classname, "PB", 2);
+        classname += 2;
+      }
     }
     }
   }
   }
+  return classname;
+}
 
 
-  return "";
+static char* fill_segment(const char *segment, int length,
+                          char *classname, bool use_camel) {
+  memcpy(classname, segment, length);
+  if (use_camel && (segment[0] < 'A' || segment[0] > 'Z')) {
+    classname[0] += 'A' - 'a';
+  }
+  return classname + length;
 }
 }
 
 
-static void convert_to_class_name_inplace(const char *package,
-                                          const char *namespace_given,
-                                          const char *prefix, char *classname) {
-  size_t prefix_len = prefix == NULL ? 0 : strlen(prefix);
-  size_t classname_len = strlen(classname);
-  int i = 0, j;
-  bool first_char = true;
+static char* fill_namespace(const char *package, const char *namespace_given,
+                            char *classname) {
+  if (namespace_given != NULL) {
+    size_t namespace_len = strlen(namespace_given);
+    memcpy(classname, namespace_given, namespace_len);
+    classname += namespace_len;
+    *classname = '\\';
+    classname++;
+  } else if (package != NULL) {
+    int i = 0, j, offset = 0;
+    size_t package_len = strlen(package);
+    while (i < package_len) {
+      j = i;
+      while (j < package_len && package[j] != '.') {
+        j++;
+      }
+      classname = fill_prefix(package + i, j - i, "", package, classname);
+      classname = fill_segment(package + i, j - i, classname, true);
+      classname[0] = '\\';
+      classname++;
+      i = j + 1;
+    }
+  }
+  return classname;
+}
 
 
-  size_t package_len = package == NULL ? 0 : strlen(package);
-  size_t namespace_given_len =
-      namespace_given == NULL ? 0 : strlen(namespace_given);
-  bool use_namespace_given = namespace_given != NULL;
-  size_t namespace_len =
-      use_namespace_given ? namespace_given_len : package_len;
+static char* fill_classname(const char *fullname,
+                            const char *package,
+                            const char *namespace_given,
+                            const char *prefix, char *classname) {
+  int classname_start = 0;
+  if (package != NULL) {
+    size_t package_len = strlen(package);
+    classname_start = package_len == 0 ? 0 : package_len + 1;
+  }
+  size_t fullname_len = strlen(fullname);
+  classname = fill_prefix(fullname + classname_start,
+                          fullname_len - classname_start,
+                          prefix, package, classname);
+
+  int i = classname_start, j;
+  while (i < fullname_len) {
+    j = i;
+    while (j < fullname_len && fullname[j] != '.') {
+      j++;
+    }
+    classname = fill_segment(fullname + i, j - i, classname, false);
+    if (j != fullname_len) {
+      *classname = '_';
+      classname++;
+    }
+    i = j + 1;
+  }
+  return classname;
+}
 
 
-  int offset = namespace_len != 0 ? 2 : 0;
+static char* fill_qualified_classname(const char *fullname,
+                                      const char *package,
+                                      const char *namespace_given,
+                                      const char *prefix, char *classname) {
+  classname = fill_namespace(package, namespace_given, classname);
+  return fill_classname(fullname, package, namespace_given, prefix, classname);
+}
 
 
-  for (j = 0; j < classname_len; j++) {
-    classname[namespace_len + prefix_len + classname_len + offset - 1 - j] =
-        classname[classname_len - j - 1];
-  }
+static void classname_no_prefix(const char *fullname, const char *package_name,
+                                char *class_name) {
+  size_t i = 0, j;
+  bool first_char = true, is_reserved = false;
+  size_t pkg_name_len = package_name == NULL ? 0 : strlen(package_name);
+  size_t message_name_start = package_name == NULL ? 0 : pkg_name_len + 1;
+  size_t message_len = (strlen(fullname) - message_name_start);
 
 
-  if (namespace_len != 0) {
-    classname[i++] = '\\';
-    for (j = 0; j < namespace_len; j++) {
-      if (use_namespace_given) {
-        classname[i++] = namespace_given[j];
-        continue;
-      }
-      // php packages are divided by '\'.
-      if (package[j] == '.') {
-        classname[i++] = '\\';
-        first_char = true;
-      } else if (first_char) {
-        // PHP package uses camel case.
-        if (package[j] < 'A' || package[j] > 'Z') {
-          classname[i++] = package[j] + 'A' - 'a';
-        } else {
-          classname[i++] = package[j];
-        }
-        first_char = false;
-      } else {
-        classname[i++] = package[j];
-      }
+  // Submessage is concatenated with its containing messages by '_'.
+  for (j = message_name_start; j < message_name_start + message_len; j++) {
+    if (fullname[j] == '.') {
+      class_name[i++] = '_';
+    } else {
+      class_name[i++] = fullname[j];
     }
     }
-    classname[i++] = '\\';
   }
   }
-
-  memcpy(classname + i, prefix, prefix_len);
 }
 }
 
 
 void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len,
 void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len,
@@ -858,20 +939,14 @@ void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len,
      * bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if    \
      * bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if    \
      * given message is google.protobuf.Empty.*/                               \
      * given message is google.protobuf.Empty.*/                               \
     const char *fullname = upb_##def_type_lower##_fullname(def_type_lower);    \
     const char *fullname = upb_##def_type_lower##_fullname(def_type_lower);    \
+    const char *package = upb_filedef_package(files[0]);                       \
     const char *php_namespace = upb_filedef_phpnamespace(files[0]);            \
     const char *php_namespace = upb_filedef_phpnamespace(files[0]);            \
     const char *prefix_given = upb_filedef_phpprefix(files[0]);                \
     const char *prefix_given = upb_filedef_phpprefix(files[0]);                \
-    size_t classname_len = strlen(fullname) + 5;                               \
-    if (prefix_given != NULL) {                                                \
-      classname_len += strlen(prefix_given);                                   \
-    }                                                                          \
-    if (php_namespace != NULL) {                                               \
-      classname_len += strlen(php_namespace);                                  \
-    }                                                                          \
+    size_t classname_len = classname_len_max(fullname, package,                \
+                                             php_namespace, prefix_given);     \
     char *classname = ecalloc(sizeof(char), classname_len);                    \
     char *classname = ecalloc(sizeof(char), classname_len);                    \
-    const char *package = upb_filedef_package(files[0]);                       \
-    classname_no_prefix(fullname, package, classname);                         \
-    const char *prefix = classname_prefix(classname, prefix_given, package);   \
-    convert_to_class_name_inplace(package, php_namespace, prefix, classname);  \
+    fill_qualified_classname(fullname, package, php_namespace,                 \
+                             prefix_given, classname);                         \
     PHP_PROTO_CE_DECLARE pce;                                                  \
     PHP_PROTO_CE_DECLARE pce;                                                  \
     if (php_proto_zend_lookup_class(classname, strlen(classname), &pce) ==     \
     if (php_proto_zend_lookup_class(classname, strlen(classname), &pce) ==     \
         FAILURE) {                                                             \
         FAILURE) {                                                             \

+ 113 - 6
php/ext/google/protobuf/message.c

@@ -282,15 +282,118 @@ void build_class_from_descriptor(
 // PHP Methods
 // PHP Methods
 // -----------------------------------------------------------------------------
 // -----------------------------------------------------------------------------
 
 
+void Message_construct(zval* msg, zval* array_wrapper) {
+  zend_class_entry* ce = Z_OBJCE_P(msg);
+  MessageHeader* intern = NULL;
+  if (EXPECTED(class_added(ce))) {
+    intern = UNBOX(MessageHeader, msg);
+    custom_data_init(ce, intern PHP_PROTO_TSRMLS_CC);
+  }
+
+  if (array_wrapper == NULL) {
+    return;
+  }
+
+  HashTable* array = Z_ARRVAL_P(array_wrapper);
+  HashPosition pointer;
+  zval key;
+  void* value;
+  const upb_fielddef* field;
+
+  for (zend_hash_internal_pointer_reset_ex(array, &pointer);
+       php_proto_zend_hash_get_current_data_ex(array, (void**)&value,
+                                               &pointer) == SUCCESS;
+       zend_hash_move_forward_ex(array, &pointer)) {
+    zend_hash_get_current_key_zval_ex(array, &key, &pointer);
+    field = upb_msgdef_ntofz(intern->descriptor->msgdef, Z_STRVAL_P(&key));
+    if (field == NULL) {
+      zend_error(E_USER_ERROR, "Unknown field: %s", Z_STRVAL_P(&key));
+    }
+    if (upb_fielddef_ismap(field)) {
+      PHP_PROTO_FAKE_SCOPE_BEGIN(Z_OBJCE_P(msg));
+      zval* submap = message_get_property_internal(msg, &key TSRMLS_CC);
+      PHP_PROTO_FAKE_SCOPE_END;
+      HashTable* subtable = HASH_OF(
+          CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value));
+      HashPosition subpointer;
+      zval subkey;
+      void* memory;
+      for (zend_hash_internal_pointer_reset_ex(subtable, &subpointer);
+           php_proto_zend_hash_get_current_data_ex(subtable, (void**)&memory,
+                                                   &subpointer) == SUCCESS;
+           zend_hash_move_forward_ex(subtable, &subpointer)) {
+        zend_hash_get_current_key_zval_ex(subtable, &subkey, &subpointer);
+        map_field_handlers->write_dimension(
+            submap, &subkey,
+            CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory) TSRMLS_CC);
+        zval_dtor(&subkey);
+      }
+    } else if (upb_fielddef_isseq(field)) {
+      PHP_PROTO_FAKE_SCOPE_BEGIN(Z_OBJCE_P(msg));
+      zval* subarray = message_get_property_internal(msg, &key TSRMLS_CC);
+      PHP_PROTO_FAKE_SCOPE_END;
+      HashTable* subtable = HASH_OF(
+          CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value));
+      HashPosition subpointer;
+      void* memory;
+      for (zend_hash_internal_pointer_reset_ex(subtable, &subpointer);
+           php_proto_zend_hash_get_current_data_ex(subtable, (void**)&memory,
+                                                   &subpointer) == SUCCESS;
+           zend_hash_move_forward_ex(subtable, &subpointer)) {
+        repeated_field_handlers->write_dimension(
+            subarray, NULL,
+            CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory) TSRMLS_CC);
+      }
+    } else if (upb_fielddef_issubmsg(field)) {
+      const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(field);
+      PHP_PROTO_HASHTABLE_VALUE desc_php = get_def_obj(submsgdef);
+      Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, desc_php);
+      zend_property_info* property_info;
+      PHP_PROTO_FAKE_SCOPE_BEGIN(Z_OBJCE_P(msg));
+#if PHP_MAJOR_VERSION < 7
+      property_info =
+          zend_get_property_info(Z_OBJCE_P(msg), &key, true TSRMLS_CC);
+#else
+      property_info =
+          zend_get_property_info(Z_OBJCE_P(msg), Z_STR_P(&key), true);
+#endif
+      PHP_PROTO_FAKE_SCOPE_END;
+      CACHED_VALUE* cached = OBJ_PROP(Z_OBJ_P(msg), property_info->offset);
+#if PHP_MAJOR_VERSION < 7
+      SEPARATE_ZVAL_IF_NOT_REF(cached);
+#endif
+      zval* submsg = CACHED_PTR_TO_ZVAL_PTR(cached);
+      ZVAL_OBJ(submsg, desc->klass->create_object(desc->klass TSRMLS_CC));
+      Message_construct(submsg, NULL);
+      MessageHeader* from = UNBOX(MessageHeader,
+                                  CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value));
+      MessageHeader* to = UNBOX(MessageHeader, submsg);
+      if(from->descriptor != to->descriptor) {
+        zend_error(E_USER_ERROR, "Cannot merge messages with different class.");
+        return;
+      }
+
+      layout_merge(from->descriptor->layout, from, to TSRMLS_CC);
+    } else {
+      message_set_property_internal(msg, &key,
+          CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value) TSRMLS_CC);
+    }
+    zval_dtor(&key);
+  }
+}
+
 // At the first time the message is created, the class entry hasn't been
 // At the first time the message is created, the class entry hasn't been
 // modified. As a result, the first created instance will be a normal zend
 // modified. As a result, the first created instance will be a normal zend
 // object. Here, we manually modify it to our message in such a case.
 // object. Here, we manually modify it to our message in such a case.
 PHP_METHOD(Message, __construct) {
 PHP_METHOD(Message, __construct) {
-  zend_class_entry* ce = Z_OBJCE_P(getThis());
-  if (EXPECTED(class_added(ce))) {
-    MessageHeader* intern = UNBOX(MessageHeader, getThis());
-    custom_data_init(ce, intern PHP_PROTO_TSRMLS_CC);
+  // Init message with array
+  zval* array_wrapper = NULL;
+  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+                            "|a!", &array_wrapper) == FAILURE) {
+    return;
   }
   }
+
+  Message_construct(getThis(), array_wrapper);
 }
 }
 
 
 PHP_METHOD(Message, clear) {
 PHP_METHOD(Message, clear) {
@@ -755,7 +858,7 @@ static zend_function_entry field_cardinality_methods[] = {
 zend_class_entry* field_cardinality_type;
 zend_class_entry* field_cardinality_type;
 
 
 // Init class entry.
 // Init class entry.
-PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field_Cardinality",
+PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field\\Cardinality",
                                 Field_Cardinality, field_cardinality)
                                 Field_Cardinality, field_cardinality)
   zend_declare_class_constant_long(field_cardinality_type,
   zend_declare_class_constant_long(field_cardinality_type,
                                    "CARDINALITY_UNKNOWN", 19, 0 TSRMLS_CC);
                                    "CARDINALITY_UNKNOWN", 19, 0 TSRMLS_CC);
@@ -765,6 +868,8 @@ PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field_Cardinality",
                                    "CARDINALITY_REQUIRED", 20, 2 TSRMLS_CC);
                                    "CARDINALITY_REQUIRED", 20, 2 TSRMLS_CC);
   zend_declare_class_constant_long(field_cardinality_type,
   zend_declare_class_constant_long(field_cardinality_type,
                                    "CARDINALITY_REPEATED", 20, 3 TSRMLS_CC);
                                    "CARDINALITY_REPEATED", 20, 3 TSRMLS_CC);
+  const char *alias = "Google\\Protobuf\\Field_Cardinality";
+  zend_register_class_alias_ex(alias, strlen(alias), field_cardinality_type TSRMLS_CC);
 PHP_PROTO_INIT_ENUMCLASS_END
 PHP_PROTO_INIT_ENUMCLASS_END
 
 
 // -----------------------------------------------------------------------------
 // -----------------------------------------------------------------------------
@@ -778,7 +883,7 @@ static zend_function_entry field_kind_methods[] = {
 zend_class_entry* field_kind_type;
 zend_class_entry* field_kind_type;
 
 
 // Init class entry.
 // Init class entry.
-PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field_Kind",
+PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field\\Kind",
                                 Field_Kind, field_kind)
                                 Field_Kind, field_kind)
   zend_declare_class_constant_long(field_kind_type,
   zend_declare_class_constant_long(field_kind_type,
                                    "TYPE_UNKNOWN", 12, 0 TSRMLS_CC);
                                    "TYPE_UNKNOWN", 12, 0 TSRMLS_CC);
@@ -818,6 +923,8 @@ PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field_Kind",
                                    "TYPE_SINT32", 11, 17 TSRMLS_CC);
                                    "TYPE_SINT32", 11, 17 TSRMLS_CC);
   zend_declare_class_constant_long(field_kind_type,
   zend_declare_class_constant_long(field_kind_type,
                                    "TYPE_SINT64", 11, 18 TSRMLS_CC);
                                    "TYPE_SINT64", 11, 18 TSRMLS_CC);
+  const char *alias = "Google\\Protobuf\\Field_Kind";
+  zend_register_class_alias_ex(alias, strlen(alias), field_kind_type TSRMLS_CC);
 PHP_PROTO_INIT_ENUMCLASS_END
 PHP_PROTO_INIT_ENUMCLASS_END
 
 
 // -----------------------------------------------------------------------------
 // -----------------------------------------------------------------------------

+ 6 - 6
php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php

@@ -46,13 +46,13 @@ class Descriptor
             ->repeated('reserved_name', \Google\Protobuf\Internal\GPBType::STRING, 10)
             ->repeated('reserved_name', \Google\Protobuf\Internal\GPBType::STRING, 10)
             ->finalizeToPool();
             ->finalizeToPool();
 
 
-        $pool->addMessage('google.protobuf.internal.DescriptorProto.ExtensionRange', \Google\Protobuf\Internal\DescriptorProto_ExtensionRange::class)
+        $pool->addMessage('google.protobuf.internal.DescriptorProto.ExtensionRange', \Google\Protobuf\Internal\DescriptorProto\ExtensionRange::class)
             ->optional('start', \Google\Protobuf\Internal\GPBType::INT32, 1)
             ->optional('start', \Google\Protobuf\Internal\GPBType::INT32, 1)
             ->optional('end', \Google\Protobuf\Internal\GPBType::INT32, 2)
             ->optional('end', \Google\Protobuf\Internal\GPBType::INT32, 2)
             ->optional('options', \Google\Protobuf\Internal\GPBType::MESSAGE, 3, 'google.protobuf.internal.ExtensionRangeOptions')
             ->optional('options', \Google\Protobuf\Internal\GPBType::MESSAGE, 3, 'google.protobuf.internal.ExtensionRangeOptions')
             ->finalizeToPool();
             ->finalizeToPool();
 
 
-        $pool->addMessage('google.protobuf.internal.DescriptorProto.ReservedRange', \Google\Protobuf\Internal\DescriptorProto_ReservedRange::class)
+        $pool->addMessage('google.protobuf.internal.DescriptorProto.ReservedRange', \Google\Protobuf\Internal\DescriptorProto\ReservedRange::class)
             ->optional('start', \Google\Protobuf\Internal\GPBType::INT32, 1)
             ->optional('start', \Google\Protobuf\Internal\GPBType::INT32, 1)
             ->optional('end', \Google\Protobuf\Internal\GPBType::INT32, 2)
             ->optional('end', \Google\Protobuf\Internal\GPBType::INT32, 2)
             ->finalizeToPool();
             ->finalizeToPool();
@@ -114,7 +114,7 @@ class Descriptor
             ->repeated('reserved_name', \Google\Protobuf\Internal\GPBType::STRING, 5)
             ->repeated('reserved_name', \Google\Protobuf\Internal\GPBType::STRING, 5)
             ->finalizeToPool();
             ->finalizeToPool();
 
 
-        $pool->addMessage('google.protobuf.internal.EnumDescriptorProto.EnumReservedRange', \Google\Protobuf\Internal\EnumDescriptorProto_EnumReservedRange::class)
+        $pool->addMessage('google.protobuf.internal.EnumDescriptorProto.EnumReservedRange', \Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange::class)
             ->optional('start', \Google\Protobuf\Internal\GPBType::INT32, 1)
             ->optional('start', \Google\Protobuf\Internal\GPBType::INT32, 1)
             ->optional('end', \Google\Protobuf\Internal\GPBType::INT32, 2)
             ->optional('end', \Google\Protobuf\Internal\GPBType::INT32, 2)
             ->finalizeToPool();
             ->finalizeToPool();
@@ -242,7 +242,7 @@ class Descriptor
             ->optional('aggregate_value', \Google\Protobuf\Internal\GPBType::STRING, 8)
             ->optional('aggregate_value', \Google\Protobuf\Internal\GPBType::STRING, 8)
             ->finalizeToPool();
             ->finalizeToPool();
 
 
-        $pool->addMessage('google.protobuf.internal.UninterpretedOption.NamePart', \Google\Protobuf\Internal\UninterpretedOption_NamePart::class)
+        $pool->addMessage('google.protobuf.internal.UninterpretedOption.NamePart', \Google\Protobuf\Internal\UninterpretedOption\NamePart::class)
             ->required('name_part', \Google\Protobuf\Internal\GPBType::STRING, 1)
             ->required('name_part', \Google\Protobuf\Internal\GPBType::STRING, 1)
             ->required('is_extension', \Google\Protobuf\Internal\GPBType::BOOL, 2)
             ->required('is_extension', \Google\Protobuf\Internal\GPBType::BOOL, 2)
             ->finalizeToPool();
             ->finalizeToPool();
@@ -251,7 +251,7 @@ class Descriptor
             ->repeated('location', \Google\Protobuf\Internal\GPBType::MESSAGE, 1, 'google.protobuf.internal.SourceCodeInfo.Location')
             ->repeated('location', \Google\Protobuf\Internal\GPBType::MESSAGE, 1, 'google.protobuf.internal.SourceCodeInfo.Location')
             ->finalizeToPool();
             ->finalizeToPool();
 
 
-        $pool->addMessage('google.protobuf.internal.SourceCodeInfo.Location', \Google\Protobuf\Internal\SourceCodeInfo_Location::class)
+        $pool->addMessage('google.protobuf.internal.SourceCodeInfo.Location', \Google\Protobuf\Internal\SourceCodeInfo\Location::class)
             ->repeated('path', \Google\Protobuf\Internal\GPBType::INT32, 1)
             ->repeated('path', \Google\Protobuf\Internal\GPBType::INT32, 1)
             ->repeated('span', \Google\Protobuf\Internal\GPBType::INT32, 2)
             ->repeated('span', \Google\Protobuf\Internal\GPBType::INT32, 2)
             ->optional('leading_comments', \Google\Protobuf\Internal\GPBType::STRING, 3)
             ->optional('leading_comments', \Google\Protobuf\Internal\GPBType::STRING, 3)
@@ -263,7 +263,7 @@ class Descriptor
             ->repeated('annotation', \Google\Protobuf\Internal\GPBType::MESSAGE, 1, 'google.protobuf.internal.GeneratedCodeInfo.Annotation')
             ->repeated('annotation', \Google\Protobuf\Internal\GPBType::MESSAGE, 1, 'google.protobuf.internal.GeneratedCodeInfo.Annotation')
             ->finalizeToPool();
             ->finalizeToPool();
 
 
-        $pool->addMessage('google.protobuf.internal.GeneratedCodeInfo.Annotation', \Google\Protobuf\Internal\GeneratedCodeInfo_Annotation::class)
+        $pool->addMessage('google.protobuf.internal.GeneratedCodeInfo.Annotation', \Google\Protobuf\Internal\GeneratedCodeInfo\Annotation::class)
             ->repeated('path', \Google\Protobuf\Internal\GPBType::INT32, 1)
             ->repeated('path', \Google\Protobuf\Internal\GPBType::INT32, 1)
             ->optional('source_file', \Google\Protobuf\Internal\GPBType::STRING, 2)
             ->optional('source_file', \Google\Protobuf\Internal\GPBType::STRING, 2)
             ->optional('begin', \Google\Protobuf\Internal\GPBType::INT32, 3)
             ->optional('begin', \Google\Protobuf\Internal\GPBType::INT32, 3)

+ 81 - 27
php/src/Google/Protobuf/Any.php

@@ -5,9 +5,9 @@
 namespace Google\Protobuf;
 namespace Google\Protobuf;
 
 
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBType;
-use Google\Protobuf\Internal\GPBUtil;
 use Google\Protobuf\Internal\Message;
 use Google\Protobuf\Internal\Message;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
 
 
 /**
 /**
  * `Any` contains an arbitrary serialized protocol buffer message along with a
  * `Any` contains an arbitrary serialized protocol buffer message along with a
@@ -37,6 +37,14 @@ use Google\Protobuf\Internal\RepeatedField;
  *     if any.Is(Foo.DESCRIPTOR):
  *     if any.Is(Foo.DESCRIPTOR):
  *       any.Unpack(foo)
  *       any.Unpack(foo)
  *       ...
  *       ...
+ *  Example 4: Pack and unpack a message in Go
+ *      foo := &pb.Foo{...}
+ *      any, err := ptypes.MarshalAny(foo)
+ *      ...
+ *      foo := &pb.Foo{}
+ *      if err := ptypes.UnmarshalAny(any, foo); err != nil {
+ *        ...
+ *      }
  * The pack methods provided by protobuf library will by default use
  * The pack methods provided by protobuf library will by default use
  * 'type.googleapis.com/full.type.name' as the type URL and the unpack
  * 'type.googleapis.com/full.type.name' as the type URL and the unpack
  * methods only use the fully qualified type name after the last '/'
  * methods only use the fully qualified type name after the last '/'
@@ -71,15 +79,16 @@ use Google\Protobuf\Internal\RepeatedField;
 class Any extends \Google\Protobuf\Internal\Message
 class Any extends \Google\Protobuf\Internal\Message
 {
 {
     /**
     /**
-     * A URL/resource name whose content describes the type of the
-     * serialized protocol buffer message.
-     * For URLs which use the scheme `http`, `https`, or no scheme, the
-     * following restrictions and interpretations apply:
+     * A URL/resource name that uniquely identifies the type of the serialized
+     * protocol buffer message. The last segment of the URL's path must represent
+     * the fully qualified name of the type (as in
+     * `path/google.protobuf.Duration`). The name should be in a canonical form
+     * (e.g., leading "." is not accepted).
+     * In practice, teams usually precompile into the binary all types that they
+     * expect it to use in the context of Any. However, for URLs which use the
+     * scheme `http`, `https`, or no scheme, one can optionally set up a type
+     * server that maps type URLs to message definitions as follows:
      * * If no scheme is provided, `https` is assumed.
      * * If no scheme is provided, `https` is assumed.
-     * * The last segment of the URL's path must represent the fully
-     *   qualified name of the type (as in `path/google.protobuf.Duration`).
-     *   The name should be in a canonical form (e.g., leading "." is
-     *   not accepted).
      * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
      * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
      *   value in binary format, or produce an error.
      *   value in binary format, or produce an error.
      * * Applications are allowed to cache lookup results based on the
      * * Applications are allowed to cache lookup results based on the
@@ -87,6 +96,9 @@ class Any extends \Google\Protobuf\Internal\Message
      *   lookup. Therefore, binary compatibility needs to be preserved
      *   lookup. Therefore, binary compatibility needs to be preserved
      *   on changes to types. (Use versioned type names to manage
      *   on changes to types. (Use versioned type names to manage
      *   breaking changes.)
      *   breaking changes.)
+     * Note: this functionality is not currently available in the official
+     * protobuf release, and it is not used for type URLs beginning with
+     * type.googleapis.com.
      * Schemes other than `http`, `https` (or the empty scheme) might be
      * Schemes other than `http`, `https` (or the empty scheme) might be
      * used with implementation specific semantics.
      * used with implementation specific semantics.
      *
      *
@@ -102,21 +114,55 @@ class Any extends \Google\Protobuf\Internal\Message
 
 
     const TYPE_URL_PREFIX = 'type.googleapis.com/';
     const TYPE_URL_PREFIX = 'type.googleapis.com/';
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $type_url
+     *           A URL/resource name that uniquely identifies the type of the serialized
+     *           protocol buffer message. The last segment of the URL's path must represent
+     *           the fully qualified name of the type (as in
+     *           `path/google.protobuf.Duration`). The name should be in a canonical form
+     *           (e.g., leading "." is not accepted).
+     *           In practice, teams usually precompile into the binary all types that they
+     *           expect it to use in the context of Any. However, for URLs which use the
+     *           scheme `http`, `https`, or no scheme, one can optionally set up a type
+     *           server that maps type URLs to message definitions as follows:
+     *           * If no scheme is provided, `https` is assumed.
+     *           * An HTTP GET on the URL must yield a [google.protobuf.Type][]
+     *             value in binary format, or produce an error.
+     *           * Applications are allowed to cache lookup results based on the
+     *             URL, or have them precompiled into a binary to avoid any
+     *             lookup. Therefore, binary compatibility needs to be preserved
+     *             on changes to types. (Use versioned type names to manage
+     *             breaking changes.)
+     *           Note: this functionality is not currently available in the official
+     *           protobuf release, and it is not used for type URLs beginning with
+     *           type.googleapis.com.
+     *           Schemes other than `http`, `https` (or the empty scheme) might be
+     *           used with implementation specific semantics.
+     *     @type string $value
+     *           Must be a valid serialized protocol buffer of the above specified type.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Any::initOnce();
         \GPBMetadata\Google\Protobuf\Any::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**
-     * A URL/resource name whose content describes the type of the
-     * serialized protocol buffer message.
-     * For URLs which use the scheme `http`, `https`, or no scheme, the
-     * following restrictions and interpretations apply:
+     * A URL/resource name that uniquely identifies the type of the serialized
+     * protocol buffer message. The last segment of the URL's path must represent
+     * the fully qualified name of the type (as in
+     * `path/google.protobuf.Duration`). The name should be in a canonical form
+     * (e.g., leading "." is not accepted).
+     * In practice, teams usually precompile into the binary all types that they
+     * expect it to use in the context of Any. However, for URLs which use the
+     * scheme `http`, `https`, or no scheme, one can optionally set up a type
+     * server that maps type URLs to message definitions as follows:
      * * If no scheme is provided, `https` is assumed.
      * * If no scheme is provided, `https` is assumed.
-     * * The last segment of the URL's path must represent the fully
-     *   qualified name of the type (as in `path/google.protobuf.Duration`).
-     *   The name should be in a canonical form (e.g., leading "." is
-     *   not accepted).
      * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
      * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
      *   value in binary format, or produce an error.
      *   value in binary format, or produce an error.
      * * Applications are allowed to cache lookup results based on the
      * * Applications are allowed to cache lookup results based on the
@@ -124,6 +170,9 @@ class Any extends \Google\Protobuf\Internal\Message
      *   lookup. Therefore, binary compatibility needs to be preserved
      *   lookup. Therefore, binary compatibility needs to be preserved
      *   on changes to types. (Use versioned type names to manage
      *   on changes to types. (Use versioned type names to manage
      *   breaking changes.)
      *   breaking changes.)
+     * Note: this functionality is not currently available in the official
+     * protobuf release, and it is not used for type URLs beginning with
+     * type.googleapis.com.
      * Schemes other than `http`, `https` (or the empty scheme) might be
      * Schemes other than `http`, `https` (or the empty scheme) might be
      * used with implementation specific semantics.
      * used with implementation specific semantics.
      *
      *
@@ -136,15 +185,16 @@ class Any extends \Google\Protobuf\Internal\Message
     }
     }
 
 
     /**
     /**
-     * A URL/resource name whose content describes the type of the
-     * serialized protocol buffer message.
-     * For URLs which use the scheme `http`, `https`, or no scheme, the
-     * following restrictions and interpretations apply:
+     * A URL/resource name that uniquely identifies the type of the serialized
+     * protocol buffer message. The last segment of the URL's path must represent
+     * the fully qualified name of the type (as in
+     * `path/google.protobuf.Duration`). The name should be in a canonical form
+     * (e.g., leading "." is not accepted).
+     * In practice, teams usually precompile into the binary all types that they
+     * expect it to use in the context of Any. However, for URLs which use the
+     * scheme `http`, `https`, or no scheme, one can optionally set up a type
+     * server that maps type URLs to message definitions as follows:
      * * If no scheme is provided, `https` is assumed.
      * * If no scheme is provided, `https` is assumed.
-     * * The last segment of the URL's path must represent the fully
-     *   qualified name of the type (as in `path/google.protobuf.Duration`).
-     *   The name should be in a canonical form (e.g., leading "." is
-     *   not accepted).
      * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
      * * An HTTP GET on the URL must yield a [google.protobuf.Type][]
      *   value in binary format, or produce an error.
      *   value in binary format, or produce an error.
      * * Applications are allowed to cache lookup results based on the
      * * Applications are allowed to cache lookup results based on the
@@ -152,6 +202,9 @@ class Any extends \Google\Protobuf\Internal\Message
      *   lookup. Therefore, binary compatibility needs to be preserved
      *   lookup. Therefore, binary compatibility needs to be preserved
      *   on changes to types. (Use versioned type names to manage
      *   on changes to types. (Use versioned type names to manage
      *   breaking changes.)
      *   breaking changes.)
+     * Note: this functionality is not currently available in the official
+     * protobuf release, and it is not used for type URLs beginning with
+     * type.googleapis.com.
      * Schemes other than `http`, `https` (or the empty scheme) might be
      * Schemes other than `http`, `https` (or the empty scheme) might be
      * used with implementation specific semantics.
      * used with implementation specific semantics.
      *
      *
@@ -269,3 +322,4 @@ class Any extends \Google\Protobuf\Internal\Message
         return $this->type_url === $type_url;
         return $this->type_url === $type_url;
     }
     }
 }
 }
+

+ 42 - 2
php/src/Google/Protobuf/Api.php

@@ -83,9 +83,49 @@ class Api extends \Google\Protobuf\Internal\Message
      */
      */
     private $syntax = 0;
     private $syntax = 0;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name
+     *           The fully qualified name of this interface, including package name
+     *           followed by the interface's simple name.
+     *     @type \Google\Protobuf\Method[]|\Google\Protobuf\Internal\RepeatedField $methods
+     *           The methods of this interface, in unspecified order.
+     *     @type \Google\Protobuf\Option[]|\Google\Protobuf\Internal\RepeatedField $options
+     *           Any metadata attached to the interface.
+     *     @type string $version
+     *           A version string for this interface. If specified, must have the form
+     *           `major-version.minor-version`, as in `1.10`. If the minor version is
+     *           omitted, it defaults to zero. If the entire version field is empty, the
+     *           major version is derived from the package name, as outlined below. If the
+     *           field is not empty, the version in the package name will be verified to be
+     *           consistent with what is provided here.
+     *           The versioning schema uses [semantic
+     *           versioning](http://semver.org) where the major version number
+     *           indicates a breaking change and the minor version an additive,
+     *           non-breaking change. Both version numbers are signals to users
+     *           what to expect from different versions, and should be carefully
+     *           chosen based on the product plan.
+     *           The major version is also reflected in the package name of the
+     *           interface, which must end in `v<major-version>`, as in
+     *           `google.feature.v1`. For major versions 0 and 1, the suffix can
+     *           be omitted. Zero major versions must only be used for
+     *           experimental, non-GA interfaces.
+     *     @type \Google\Protobuf\SourceContext $source_context
+     *           Source context for the protocol buffer service represented by this
+     *           message.
+     *     @type \Google\Protobuf\Mixin[]|\Google\Protobuf\Internal\RepeatedField $mixins
+     *           Included interfaces. See [Mixin][].
+     *     @type int $syntax
+     *           The source syntax of the service.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Api::initOnce();
         \GPBMetadata\Google\Protobuf\Api::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 12 - 2
php/src/Google/Protobuf/BoolValue.php

@@ -23,9 +23,19 @@ class BoolValue extends \Google\Protobuf\Internal\Message
      */
      */
     private $value = false;
     private $value = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type bool $value
+     *           The bool value.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 12 - 2
php/src/Google/Protobuf/BytesValue.php

@@ -23,9 +23,19 @@ class BytesValue extends \Google\Protobuf\Internal\Message
      */
      */
     private $value = '';
     private $value = '';
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $value
+     *           The bytes value.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 12 - 2
php/src/Google/Protobuf/DoubleValue.php

@@ -23,9 +23,19 @@ class DoubleValue extends \Google\Protobuf\Internal\Message
      */
      */
     private $value = 0.0;
     private $value = 0.0;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type float $value
+     *           The double value.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 22 - 2
php/src/Google/Protobuf/Duration.php

@@ -79,9 +79,28 @@ class Duration extends \Google\Protobuf\Internal\Message
      */
      */
     private $nanos = 0;
     private $nanos = 0;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int|string $seconds
+     *           Signed seconds of the span of time. Must be from -315,576,000,000
+     *           to +315,576,000,000 inclusive. Note: these bounds are computed from:
+     *           60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
+     *     @type int $nanos
+     *           Signed fractions of a second at nanosecond resolution of the span
+     *           of time. Durations less than one second are represented with a 0
+     *           `seconds` field and a positive or negative `nanos` field. For durations
+     *           of one second or more, a non-zero value for the `nanos` field must be
+     *           of the same sign as the `seconds` field. Must be from -999,999,999
+     *           to +999,999,999 inclusive.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Duration::initOnce();
         \GPBMetadata\Google\Protobuf\Duration::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**
@@ -149,5 +168,6 @@ class Duration extends \Google\Protobuf\Internal\Message
 
 
         return $this;
         return $this;
     }
     }
+
 }
 }
 
 

+ 20 - 2
php/src/Google/Protobuf/Enum.php

@@ -46,9 +46,27 @@ class Enum extends \Google\Protobuf\Internal\Message
      */
      */
     private $syntax = 0;
     private $syntax = 0;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name
+     *           Enum type name.
+     *     @type \Google\Protobuf\EnumValue[]|\Google\Protobuf\Internal\RepeatedField $enumvalue
+     *           Enum value definitions.
+     *     @type \Google\Protobuf\Option[]|\Google\Protobuf\Internal\RepeatedField $options
+     *           Protocol buffer options.
+     *     @type \Google\Protobuf\SourceContext $source_context
+     *           The source context.
+     *     @type int $syntax
+     *           The source syntax.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Type::initOnce();
         \GPBMetadata\Google\Protobuf\Type::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 16 - 2
php/src/Google/Protobuf/EnumValue.php

@@ -34,9 +34,23 @@ class EnumValue extends \Google\Protobuf\Internal\Message
      */
      */
     private $options;
     private $options;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name
+     *           Enum value name.
+     *     @type int $number
+     *           Enum value number.
+     *     @type \Google\Protobuf\Option[]|\Google\Protobuf\Internal\RepeatedField $options
+     *           Protocol buffer options.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Type::initOnce();
         \GPBMetadata\Google\Protobuf\Type::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 32 - 2
php/src/Google/Protobuf/Field.php

@@ -78,9 +78,39 @@ class Field extends \Google\Protobuf\Internal\Message
      */
      */
     private $default_value = '';
     private $default_value = '';
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int $kind
+     *           The field type.
+     *     @type int $cardinality
+     *           The field cardinality.
+     *     @type int $number
+     *           The field number.
+     *     @type string $name
+     *           The field name.
+     *     @type string $type_url
+     *           The field type URL, without the scheme, for message or enumeration
+     *           types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
+     *     @type int $oneof_index
+     *           The index of the field type in `Type.oneofs`, for message or enumeration
+     *           types. The first type has index 1; zero means the type is not in the list.
+     *     @type bool $packed
+     *           Whether to use alternative packed wire representation.
+     *     @type \Google\Protobuf\Option[]|\Google\Protobuf\Internal\RepeatedField $options
+     *           The protocol buffer options.
+     *     @type string $json_name
+     *           The field JSON name.
+     *     @type string $default_value
+     *           The string value of the default value of this field. Proto2 syntax only.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Type::initOnce();
         \GPBMetadata\Google\Protobuf\Type::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 42 - 0
php/src/Google/Protobuf/Field/Cardinality.php

@@ -0,0 +1,42 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/type.proto
+
+namespace Google\Protobuf\Field;
+
+/**
+ * Whether a field is optional, required, or repeated.
+ *
+ * Protobuf type <code>google.protobuf.Field.Cardinality</code>
+ */
+class Cardinality
+{
+    /**
+     * For fields with unknown cardinality.
+     *
+     * Generated from protobuf enum <code>CARDINALITY_UNKNOWN = 0;</code>
+     */
+    const CARDINALITY_UNKNOWN = 0;
+    /**
+     * For optional fields.
+     *
+     * Generated from protobuf enum <code>CARDINALITY_OPTIONAL = 1;</code>
+     */
+    const CARDINALITY_OPTIONAL = 1;
+    /**
+     * For required fields. Proto2 syntax only.
+     *
+     * Generated from protobuf enum <code>CARDINALITY_REQUIRED = 2;</code>
+     */
+    const CARDINALITY_REQUIRED = 2;
+    /**
+     * For repeated fields.
+     *
+     * Generated from protobuf enum <code>CARDINALITY_REPEATED = 3;</code>
+     */
+    const CARDINALITY_REPEATED = 3;
+}
+
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(Cardinality::class, \Google\Protobuf\Field_Cardinality::class);
+

+ 132 - 0
php/src/Google/Protobuf/Field/Kind.php

@@ -0,0 +1,132 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/type.proto
+
+namespace Google\Protobuf\Field;
+
+/**
+ * Basic field types.
+ *
+ * Protobuf type <code>google.protobuf.Field.Kind</code>
+ */
+class Kind
+{
+    /**
+     * Field type unknown.
+     *
+     * Generated from protobuf enum <code>TYPE_UNKNOWN = 0;</code>
+     */
+    const TYPE_UNKNOWN = 0;
+    /**
+     * Field type double.
+     *
+     * Generated from protobuf enum <code>TYPE_DOUBLE = 1;</code>
+     */
+    const TYPE_DOUBLE = 1;
+    /**
+     * Field type float.
+     *
+     * Generated from protobuf enum <code>TYPE_FLOAT = 2;</code>
+     */
+    const TYPE_FLOAT = 2;
+    /**
+     * Field type int64.
+     *
+     * Generated from protobuf enum <code>TYPE_INT64 = 3;</code>
+     */
+    const TYPE_INT64 = 3;
+    /**
+     * Field type uint64.
+     *
+     * Generated from protobuf enum <code>TYPE_UINT64 = 4;</code>
+     */
+    const TYPE_UINT64 = 4;
+    /**
+     * Field type int32.
+     *
+     * Generated from protobuf enum <code>TYPE_INT32 = 5;</code>
+     */
+    const TYPE_INT32 = 5;
+    /**
+     * Field type fixed64.
+     *
+     * Generated from protobuf enum <code>TYPE_FIXED64 = 6;</code>
+     */
+    const TYPE_FIXED64 = 6;
+    /**
+     * Field type fixed32.
+     *
+     * Generated from protobuf enum <code>TYPE_FIXED32 = 7;</code>
+     */
+    const TYPE_FIXED32 = 7;
+    /**
+     * Field type bool.
+     *
+     * Generated from protobuf enum <code>TYPE_BOOL = 8;</code>
+     */
+    const TYPE_BOOL = 8;
+    /**
+     * Field type string.
+     *
+     * Generated from protobuf enum <code>TYPE_STRING = 9;</code>
+     */
+    const TYPE_STRING = 9;
+    /**
+     * Field type group. Proto2 syntax only, and deprecated.
+     *
+     * Generated from protobuf enum <code>TYPE_GROUP = 10;</code>
+     */
+    const TYPE_GROUP = 10;
+    /**
+     * Field type message.
+     *
+     * Generated from protobuf enum <code>TYPE_MESSAGE = 11;</code>
+     */
+    const TYPE_MESSAGE = 11;
+    /**
+     * Field type bytes.
+     *
+     * Generated from protobuf enum <code>TYPE_BYTES = 12;</code>
+     */
+    const TYPE_BYTES = 12;
+    /**
+     * Field type uint32.
+     *
+     * Generated from protobuf enum <code>TYPE_UINT32 = 13;</code>
+     */
+    const TYPE_UINT32 = 13;
+    /**
+     * Field type enum.
+     *
+     * Generated from protobuf enum <code>TYPE_ENUM = 14;</code>
+     */
+    const TYPE_ENUM = 14;
+    /**
+     * Field type sfixed32.
+     *
+     * Generated from protobuf enum <code>TYPE_SFIXED32 = 15;</code>
+     */
+    const TYPE_SFIXED32 = 15;
+    /**
+     * Field type sfixed64.
+     *
+     * Generated from protobuf enum <code>TYPE_SFIXED64 = 16;</code>
+     */
+    const TYPE_SFIXED64 = 16;
+    /**
+     * Field type sint32.
+     *
+     * Generated from protobuf enum <code>TYPE_SINT32 = 17;</code>
+     */
+    const TYPE_SINT32 = 17;
+    /**
+     * Field type sint64.
+     *
+     * Generated from protobuf enum <code>TYPE_SINT64 = 18;</code>
+     */
+    const TYPE_SINT64 = 18;
+}
+
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(Kind::class, \Google\Protobuf\Field_Kind::class);
+

+ 16 - 2
php/src/Google/Protobuf/FieldMask.php

@@ -162,6 +162,10 @@ use Google\Protobuf\Internal\GPBUtil;
  *     }
  *     }
  * Note that oneof type names ("test_oneof" in this case) cannot be used in
  * Note that oneof type names ("test_oneof" in this case) cannot be used in
  * paths.
  * paths.
+ * ## Field Mask Verification
+ * The implementation of any API method which has a FieldMask type field in the
+ * request should verify the included field paths, and return an
+ * `INVALID_ARGUMENT` error if any path is duplicated or unmappable.
  *
  *
  * Generated from protobuf message <code>google.protobuf.FieldMask</code>
  * Generated from protobuf message <code>google.protobuf.FieldMask</code>
  */
  */
@@ -174,9 +178,19 @@ class FieldMask extends \Google\Protobuf\Internal\Message
      */
      */
     private $paths;
     private $paths;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string[]|\Google\Protobuf\Internal\RepeatedField $paths
+     *           The set of field mask paths.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\FieldMask::initOnce();
         \GPBMetadata\Google\Protobuf\FieldMask::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 6 - 29
php/src/Google/Protobuf/Field_Cardinality.php

@@ -4,36 +4,13 @@
 
 
 namespace Google\Protobuf;
 namespace Google\Protobuf;
 
 
-/**
- * Whether a field is optional, required, or repeated.
- *
- * Protobuf enum <code>Google\Protobuf\Field\Cardinality</code>
- */
-class Field_Cardinality
-{
+if (false) {
     /**
     /**
-     * For fields with unknown cardinality.
-     *
-     * Generated from protobuf enum <code>CARDINALITY_UNKNOWN = 0;</code>
+     * This class is deprecated. Use Google\Protobuf\Field\Cardinality instead.
+     * @deprecated
      */
      */
-    const CARDINALITY_UNKNOWN = 0;
-    /**
-     * For optional fields.
-     *
-     * Generated from protobuf enum <code>CARDINALITY_OPTIONAL = 1;</code>
-     */
-    const CARDINALITY_OPTIONAL = 1;
-    /**
-     * For required fields. Proto2 syntax only.
-     *
-     * Generated from protobuf enum <code>CARDINALITY_REQUIRED = 2;</code>
-     */
-    const CARDINALITY_REQUIRED = 2;
-    /**
-     * For repeated fields.
-     *
-     * Generated from protobuf enum <code>CARDINALITY_REPEATED = 3;</code>
-     */
-    const CARDINALITY_REPEATED = 3;
+    class Field_Cardinality {}
 }
 }
+class_exists(Field\Cardinality::class);
+@trigger_error('Google\Protobuf\Field_Cardinality is deprecated and will be removed in the next major release. Use Google\Protobuf\Field\Cardinality instead', E_USER_DEPRECATED);
 
 

+ 6 - 119
php/src/Google/Protobuf/Field_Kind.php

@@ -4,126 +4,13 @@
 
 
 namespace Google\Protobuf;
 namespace Google\Protobuf;
 
 
-/**
- * Basic field types.
- *
- * Protobuf enum <code>Google\Protobuf\Field\Kind</code>
- */
-class Field_Kind
-{
+if (false) {
     /**
     /**
-     * Field type unknown.
-     *
-     * Generated from protobuf enum <code>TYPE_UNKNOWN = 0;</code>
+     * This class is deprecated. Use Google\Protobuf\Field\Kind instead.
+     * @deprecated
      */
      */
-    const TYPE_UNKNOWN = 0;
-    /**
-     * Field type double.
-     *
-     * Generated from protobuf enum <code>TYPE_DOUBLE = 1;</code>
-     */
-    const TYPE_DOUBLE = 1;
-    /**
-     * Field type float.
-     *
-     * Generated from protobuf enum <code>TYPE_FLOAT = 2;</code>
-     */
-    const TYPE_FLOAT = 2;
-    /**
-     * Field type int64.
-     *
-     * Generated from protobuf enum <code>TYPE_INT64 = 3;</code>
-     */
-    const TYPE_INT64 = 3;
-    /**
-     * Field type uint64.
-     *
-     * Generated from protobuf enum <code>TYPE_UINT64 = 4;</code>
-     */
-    const TYPE_UINT64 = 4;
-    /**
-     * Field type int32.
-     *
-     * Generated from protobuf enum <code>TYPE_INT32 = 5;</code>
-     */
-    const TYPE_INT32 = 5;
-    /**
-     * Field type fixed64.
-     *
-     * Generated from protobuf enum <code>TYPE_FIXED64 = 6;</code>
-     */
-    const TYPE_FIXED64 = 6;
-    /**
-     * Field type fixed32.
-     *
-     * Generated from protobuf enum <code>TYPE_FIXED32 = 7;</code>
-     */
-    const TYPE_FIXED32 = 7;
-    /**
-     * Field type bool.
-     *
-     * Generated from protobuf enum <code>TYPE_BOOL = 8;</code>
-     */
-    const TYPE_BOOL = 8;
-    /**
-     * Field type string.
-     *
-     * Generated from protobuf enum <code>TYPE_STRING = 9;</code>
-     */
-    const TYPE_STRING = 9;
-    /**
-     * Field type group. Proto2 syntax only, and deprecated.
-     *
-     * Generated from protobuf enum <code>TYPE_GROUP = 10;</code>
-     */
-    const TYPE_GROUP = 10;
-    /**
-     * Field type message.
-     *
-     * Generated from protobuf enum <code>TYPE_MESSAGE = 11;</code>
-     */
-    const TYPE_MESSAGE = 11;
-    /**
-     * Field type bytes.
-     *
-     * Generated from protobuf enum <code>TYPE_BYTES = 12;</code>
-     */
-    const TYPE_BYTES = 12;
-    /**
-     * Field type uint32.
-     *
-     * Generated from protobuf enum <code>TYPE_UINT32 = 13;</code>
-     */
-    const TYPE_UINT32 = 13;
-    /**
-     * Field type enum.
-     *
-     * Generated from protobuf enum <code>TYPE_ENUM = 14;</code>
-     */
-    const TYPE_ENUM = 14;
-    /**
-     * Field type sfixed32.
-     *
-     * Generated from protobuf enum <code>TYPE_SFIXED32 = 15;</code>
-     */
-    const TYPE_SFIXED32 = 15;
-    /**
-     * Field type sfixed64.
-     *
-     * Generated from protobuf enum <code>TYPE_SFIXED64 = 16;</code>
-     */
-    const TYPE_SFIXED64 = 16;
-    /**
-     * Field type sint32.
-     *
-     * Generated from protobuf enum <code>TYPE_SINT32 = 17;</code>
-     */
-    const TYPE_SINT32 = 17;
-    /**
-     * Field type sint64.
-     *
-     * Generated from protobuf enum <code>TYPE_SINT64 = 18;</code>
-     */
-    const TYPE_SINT64 = 18;
+    class Field_Kind {}
 }
 }
+class_exists(Field\Kind::class);
+@trigger_error('Google\Protobuf\Field_Kind is deprecated and will be removed in the next major release. Use Google\Protobuf\Field\Kind instead', E_USER_DEPRECATED);
 
 

+ 12 - 2
php/src/Google/Protobuf/FloatValue.php

@@ -23,9 +23,19 @@ class FloatValue extends \Google\Protobuf\Internal\Message
      */
      */
     private $value = 0.0;
     private $value = 0.0;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type float $value
+     *           The float value.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 10 - 2
php/src/Google/Protobuf/GPBEmpty.php

@@ -22,9 +22,17 @@ use Google\Protobuf\Internal\GPBUtil;
 class GPBEmpty extends \Google\Protobuf\Internal\Message
 class GPBEmpty extends \Google\Protobuf\Internal\Message
 {
 {
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\GPBEmpty::initOnce();
         \GPBMetadata\Google\Protobuf\GPBEmpty::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
 }
 }

+ 12 - 2
php/src/Google/Protobuf/Int32Value.php

@@ -23,9 +23,19 @@ class Int32Value extends \Google\Protobuf\Internal\Message
      */
      */
     private $value = 0;
     private $value = 0;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int $value
+     *           The int32 value.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 12 - 2
php/src/Google/Protobuf/Int64Value.php

@@ -23,9 +23,19 @@ class Int64Value extends \Google\Protobuf\Internal\Message
      */
      */
     private $value = 0;
     private $value = 0;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int|string $value
+     *           The int64 value.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 26 - 6
php/src/Google/Protobuf/Internal/DescriptorProto.php

@@ -71,9 +71,29 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message
     private $reserved_name;
     private $reserved_name;
     private $has_reserved_name = false;
     private $has_reserved_name = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name
+     *     @type \Google\Protobuf\Internal\FieldDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $field
+     *     @type \Google\Protobuf\Internal\FieldDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $extension
+     *     @type \Google\Protobuf\Internal\DescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $nested_type
+     *     @type \Google\Protobuf\Internal\EnumDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $enum_type
+     *     @type \Google\Protobuf\Internal\DescriptorProto\ExtensionRange[]|\Google\Protobuf\Internal\RepeatedField $extension_range
+     *     @type \Google\Protobuf\Internal\OneofDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $oneof_decl
+     *     @type \Google\Protobuf\Internal\MessageOptions $options
+     *     @type \Google\Protobuf\Internal\DescriptorProto\ReservedRange[]|\Google\Protobuf\Internal\RepeatedField $reserved_range
+     *     @type string[]|\Google\Protobuf\Internal\RepeatedField $reserved_name
+     *           Reserved field names, which may not be used by fields in the same message.
+     *           A given name may only be reserved once.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**
@@ -227,12 +247,12 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message
 
 
     /**
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;</code>
      * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;</code>
-     * @param \Google\Protobuf\Internal\DescriptorProto_ExtensionRange[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @param \Google\Protobuf\Internal\DescriptorProto\ExtensionRange[]|\Google\Protobuf\Internal\RepeatedField $var
      * @return $this
      * @return $this
      */
      */
     public function setExtensionRange($var)
     public function setExtensionRange($var)
     {
     {
-        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto_ExtensionRange::class);
+        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto\ExtensionRange::class);
         $this->extension_range = $arr;
         $this->extension_range = $arr;
         $this->has_extension_range = true;
         $this->has_extension_range = true;
 
 
@@ -311,12 +331,12 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message
 
 
     /**
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;</code>
      * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;</code>
-     * @param \Google\Protobuf\Internal\DescriptorProto_ReservedRange[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @param \Google\Protobuf\Internal\DescriptorProto\ReservedRange[]|\Google\Protobuf\Internal\RepeatedField $var
      * @return $this
      * @return $this
      */
      */
     public function setReservedRange($var)
     public function setReservedRange($var)
     {
     {
-        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto_ReservedRange::class);
+        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto\ReservedRange::class);
         $this->reserved_range = $arr;
         $this->reserved_range = $arr;
         $this->has_reserved_range = true;
         $this->has_reserved_range = true;
 
 

+ 18 - 4
php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php → php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php

@@ -2,7 +2,7 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: google/protobuf/descriptor.proto
 # source: google/protobuf/descriptor.proto
 
 
-namespace Google\Protobuf\Internal;
+namespace Google\Protobuf\Internal\DescriptorProto;
 
 
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\GPBWire;
@@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil;
 /**
 /**
  * Generated from protobuf message <code>google.protobuf.DescriptorProto.ExtensionRange</code>
  * Generated from protobuf message <code>google.protobuf.DescriptorProto.ExtensionRange</code>
  */
  */
-class DescriptorProto_ExtensionRange extends \Google\Protobuf\Internal\Message
+class ExtensionRange extends \Google\Protobuf\Internal\Message
 {
 {
     /**
     /**
      * Generated from protobuf field <code>optional int32 start = 1;</code>
      * Generated from protobuf field <code>optional int32 start = 1;</code>
@@ -31,9 +31,20 @@ class DescriptorProto_ExtensionRange extends \Google\Protobuf\Internal\Message
     private $options = null;
     private $options = null;
     private $has_options = false;
     private $has_options = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int $start
+     *     @type int $end
+     *     @type \Google\Protobuf\Internal\ExtensionRangeOptions $options
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**
@@ -122,3 +133,6 @@ class DescriptorProto_ExtensionRange extends \Google\Protobuf\Internal\Message
 
 
 }
 }
 
 
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(ExtensionRange::class, \Google\Protobuf\Internal\DescriptorProto_ExtensionRange::class);
+

+ 19 - 4
php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php → php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php

@@ -2,7 +2,7 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: google/protobuf/descriptor.proto
 # source: google/protobuf/descriptor.proto
 
 
-namespace Google\Protobuf\Internal;
+namespace Google\Protobuf\Internal\DescriptorProto;
 
 
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\GPBWire;
@@ -17,7 +17,7 @@ use Google\Protobuf\Internal\GPBUtil;
  *
  *
  * Generated from protobuf message <code>google.protobuf.DescriptorProto.ReservedRange</code>
  * Generated from protobuf message <code>google.protobuf.DescriptorProto.ReservedRange</code>
  */
  */
-class DescriptorProto_ReservedRange extends \Google\Protobuf\Internal\Message
+class ReservedRange extends \Google\Protobuf\Internal\Message
 {
 {
     /**
     /**
      * Inclusive.
      * Inclusive.
@@ -34,9 +34,21 @@ class DescriptorProto_ReservedRange extends \Google\Protobuf\Internal\Message
     private $end = 0;
     private $end = 0;
     private $has_end = false;
     private $has_end = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int $start
+     *           Inclusive.
+     *     @type int $end
+     *           Exclusive.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**
@@ -105,3 +117,6 @@ class DescriptorProto_ReservedRange extends \Google\Protobuf\Internal\Message
 
 
 }
 }
 
 
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(ReservedRange::class, \Google\Protobuf\Internal\DescriptorProto_ReservedRange::class);
+

+ 22 - 4
php/src/Google/Protobuf/Internal/EnumDescriptorProto.php

@@ -50,9 +50,27 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message
     private $reserved_name;
     private $reserved_name;
     private $has_reserved_name = false;
     private $has_reserved_name = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name
+     *     @type \Google\Protobuf\Internal\EnumValueDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $value
+     *     @type \Google\Protobuf\Internal\EnumOptions $options
+     *     @type \Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange[]|\Google\Protobuf\Internal\RepeatedField $reserved_range
+     *           Range of reserved numeric values. Reserved numeric values may not be used
+     *           by enum values in the same enum declaration. Reserved ranges may not
+     *           overlap.
+     *     @type string[]|\Google\Protobuf\Internal\RepeatedField $reserved_name
+     *           Reserved enum value names, which may not be reused. A given name may only
+     *           be reserved once.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**
@@ -158,12 +176,12 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message
      * overlap.
      * overlap.
      *
      *
      * Generated from protobuf field <code>repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;</code>
      * Generated from protobuf field <code>repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;</code>
-     * @param \Google\Protobuf\Internal\EnumDescriptorProto_EnumReservedRange[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @param \Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange[]|\Google\Protobuf\Internal\RepeatedField $var
      * @return $this
      * @return $this
      */
      */
     public function setReservedRange($var)
     public function setReservedRange($var)
     {
     {
-        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto_EnumReservedRange::class);
+        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange::class);
         $this->reserved_range = $arr;
         $this->reserved_range = $arr;
         $this->has_reserved_range = true;
         $this->has_reserved_range = true;
 
 

+ 19 - 4
php/src/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.php → php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php

@@ -2,7 +2,7 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: google/protobuf/descriptor.proto
 # source: google/protobuf/descriptor.proto
 
 
-namespace Google\Protobuf\Internal;
+namespace Google\Protobuf\Internal\EnumDescriptorProto;
 
 
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\GPBWire;
@@ -19,7 +19,7 @@ use Google\Protobuf\Internal\GPBUtil;
  *
  *
  * Generated from protobuf message <code>google.protobuf.EnumDescriptorProto.EnumReservedRange</code>
  * Generated from protobuf message <code>google.protobuf.EnumDescriptorProto.EnumReservedRange</code>
  */
  */
-class EnumDescriptorProto_EnumReservedRange extends \Google\Protobuf\Internal\Message
+class EnumReservedRange extends \Google\Protobuf\Internal\Message
 {
 {
     /**
     /**
      * Inclusive.
      * Inclusive.
@@ -36,9 +36,21 @@ class EnumDescriptorProto_EnumReservedRange extends \Google\Protobuf\Internal\Me
     private $end = 0;
     private $end = 0;
     private $has_end = false;
     private $has_end = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int $start
+     *           Inclusive.
+     *     @type int $end
+     *           Inclusive.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**
@@ -107,3 +119,6 @@ class EnumDescriptorProto_EnumReservedRange extends \Google\Protobuf\Internal\Me
 
 
 }
 }
 
 
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(EnumReservedRange::class, \Google\Protobuf\Internal\EnumDescriptorProto_EnumReservedRange::class);
+

+ 20 - 2
php/src/Google/Protobuf/Internal/EnumOptions.php

@@ -41,9 +41,27 @@ class EnumOptions extends \Google\Protobuf\Internal\Message
     private $uninterpreted_option;
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
     private $has_uninterpreted_option = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type bool $allow_alias
+     *           Set this option to true to allow mapping different tag names to the same
+     *           value.
+     *     @type bool $deprecated
+     *           Is this enum deprecated?
+     *           Depending on the target platform, this can emit Deprecated annotations
+     *           for the enum, or it will be completely ignored; in the very least, this
+     *           is a formalization for deprecating enums.
+     *     @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option
+     *           The parser stores options it doesn't recognize here. See above.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 13 - 2
php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php

@@ -33,9 +33,20 @@ class EnumValueDescriptorProto extends \Google\Protobuf\Internal\Message
     private $options = null;
     private $options = null;
     private $has_options = false;
     private $has_options = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name
+     *     @type int $number
+     *     @type \Google\Protobuf\Internal\EnumValueOptions $options
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 17 - 2
php/src/Google/Protobuf/Internal/EnumValueOptions.php

@@ -33,9 +33,24 @@ class EnumValueOptions extends \Google\Protobuf\Internal\Message
     private $uninterpreted_option;
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
     private $has_uninterpreted_option = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type bool $deprecated
+     *           Is this enum value deprecated?
+     *           Depending on the target platform, this can emit Deprecated annotations
+     *           for the enum value, or it will be completely ignored; in the very least,
+     *           this is a formalization for deprecating enum values.
+     *     @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option
+     *           The parser stores options it doesn't recognize here. See above.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 12 - 2
php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php

@@ -23,9 +23,19 @@ class ExtensionRangeOptions extends \Google\Protobuf\Internal\Message
     private $uninterpreted_option;
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
     private $has_uninterpreted_option = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option
+     *           The parser stores options it doesn't recognize here. See above.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 40 - 2
php/src/Google/Protobuf/Internal/FieldDescriptorProto.php

@@ -94,9 +94,47 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message
     private $options = null;
     private $options = null;
     private $has_options = false;
     private $has_options = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name
+     *     @type int $number
+     *     @type int $label
+     *     @type int $type
+     *           If type_name is set, this need not be set.  If both this and type_name
+     *           are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
+     *     @type string $type_name
+     *           For message and enum types, this is the name of the type.  If the name
+     *           starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping
+     *           rules are used to find the type (i.e. first the nested types within this
+     *           message are searched, then within the parent, on up to the root
+     *           namespace).
+     *     @type string $extendee
+     *           For extensions, this is the name of the type being extended.  It is
+     *           resolved in the same manner as type_name.
+     *     @type string $default_value
+     *           For numeric types, contains the original text representation of the value.
+     *           For booleans, "true" or "false".
+     *           For strings, contains the default text contents (not escaped in any way).
+     *           For bytes, contains the C escaped value.  All bytes >= 128 are escaped.
+     *           TODO(kenton):  Base-64 encode?
+     *     @type int $oneof_index
+     *           If set, gives the index of a oneof in the containing type's oneof_decl
+     *           list.  This field is a member of that oneof.
+     *     @type string $json_name
+     *           JSON name of this field. The value is set by protocol compiler. If the
+     *           user has set a "json_name" option on this field, that option's value
+     *           will be used. Otherwise, it's deduced from the field's name by converting
+     *           it to camelCase.
+     *     @type \Google\Protobuf\Internal\FieldOptions $options
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 6 - 3
php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php → php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php

@@ -2,12 +2,12 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: google/protobuf/descriptor.proto
 # source: google/protobuf/descriptor.proto
 
 
-namespace Google\Protobuf\Internal;
+namespace Google\Protobuf\Internal\FieldDescriptorProto;
 
 
 /**
 /**
- * Protobuf enum <code>Google\Protobuf\Internal</code>
+ * Protobuf type <code>google.protobuf.FieldDescriptorProto.Label</code>
  */
  */
-class FieldDescriptorProto_Label
+class Label
 {
 {
     /**
     /**
      * 0 is reserved for errors
      * 0 is reserved for errors
@@ -25,3 +25,6 @@ class FieldDescriptorProto_Label
     const LABEL_REPEATED = 3;
     const LABEL_REPEATED = 3;
 }
 }
 
 
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(Label::class, \Google\Protobuf\Internal\FieldDescriptorProto_Label::class);
+

+ 6 - 3
php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php → php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php

@@ -2,12 +2,12 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: google/protobuf/descriptor.proto
 # source: google/protobuf/descriptor.proto
 
 
-namespace Google\Protobuf\Internal;
+namespace Google\Protobuf\Internal\FieldDescriptorProto;
 
 
 /**
 /**
- * Protobuf enum <code>Google\Protobuf\Internal</code>
+ * Protobuf type <code>google.protobuf.FieldDescriptorProto.Type</code>
  */
  */
-class FieldDescriptorProto_Type
+class Type
 {
 {
     /**
     /**
      * 0 is reserved for errors.
      * 0 is reserved for errors.
@@ -105,3 +105,6 @@ class FieldDescriptorProto_Type
     const TYPE_SINT64 = 18;
     const TYPE_SINT64 = 18;
 }
 }
 
 
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(Type::class, \Google\Protobuf\Internal\FieldDescriptorProto_Type::class);
+

+ 66 - 2
php/src/Google/Protobuf/Internal/FieldOptions.php

@@ -107,9 +107,73 @@ class FieldOptions extends \Google\Protobuf\Internal\Message
     private $uninterpreted_option;
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
     private $has_uninterpreted_option = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int $ctype
+     *           The ctype option instructs the C++ code generator to use a different
+     *           representation of the field than it normally would.  See the specific
+     *           options below.  This option is not yet implemented in the open source
+     *           release -- sorry, we'll try to include it in a future version!
+     *     @type bool $packed
+     *           The packed option can be enabled for repeated primitive fields to enable
+     *           a more efficient representation on the wire. Rather than repeatedly
+     *           writing the tag and type for each element, the entire array is encoded as
+     *           a single length-delimited blob. In proto3, only explicit setting it to
+     *           false will avoid using packed encoding.
+     *     @type int $jstype
+     *           The jstype option determines the JavaScript type used for values of the
+     *           field.  The option is permitted only for 64 bit integral and fixed types
+     *           (int64, uint64, sint64, fixed64, sfixed64).  A field with jstype JS_STRING
+     *           is represented as JavaScript string, which avoids loss of precision that
+     *           can happen when a large value is converted to a floating point JavaScript.
+     *           Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
+     *           use the JavaScript "number" type.  The behavior of the default option
+     *           JS_NORMAL is implementation dependent.
+     *           This option is an enum to permit additional types to be added, e.g.
+     *           goog.math.Integer.
+     *     @type bool $lazy
+     *           Should this field be parsed lazily?  Lazy applies only to message-type
+     *           fields.  It means that when the outer message is initially parsed, the
+     *           inner message's contents will not be parsed but instead stored in encoded
+     *           form.  The inner message will actually be parsed when it is first accessed.
+     *           This is only a hint.  Implementations are free to choose whether to use
+     *           eager or lazy parsing regardless of the value of this option.  However,
+     *           setting this option true suggests that the protocol author believes that
+     *           using lazy parsing on this field is worth the additional bookkeeping
+     *           overhead typically needed to implement it.
+     *           This option does not affect the public interface of any generated code;
+     *           all method signatures remain the same.  Furthermore, thread-safety of the
+     *           interface is not affected by this option; const methods remain safe to
+     *           call from multiple threads concurrently, while non-const methods continue
+     *           to require exclusive access.
+     *           Note that implementations may choose not to check required fields within
+     *           a lazy sub-message.  That is, calling IsInitialized() on the outer message
+     *           may return true even if the inner message has missing required fields.
+     *           This is necessary because otherwise the inner message would have to be
+     *           parsed in order to perform the check, defeating the purpose of lazy
+     *           parsing.  An implementation which chooses not to check required fields
+     *           must be consistent about it.  That is, for any particular sub-message, the
+     *           implementation must either *always* check its required fields, or *never*
+     *           check its required fields, regardless of whether or not the message has
+     *           been parsed.
+     *     @type bool $deprecated
+     *           Is this field deprecated?
+     *           Depending on the target platform, this can emit Deprecated annotations
+     *           for accessors, or it will be completely ignored; in the very least, this
+     *           is a formalization for deprecating fields.
+     *     @type bool $weak
+     *           For Google-internal migration only. Do not use.
+     *     @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option
+     *           The parser stores options it doesn't recognize here. See above.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 6 - 3
php/src/Google/Protobuf/Internal/FieldOptions_CType.php → php/src/Google/Protobuf/Internal/FieldOptions/CType.php

@@ -2,12 +2,12 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: google/protobuf/descriptor.proto
 # source: google/protobuf/descriptor.proto
 
 
-namespace Google\Protobuf\Internal;
+namespace Google\Protobuf\Internal\FieldOptions;
 
 
 /**
 /**
- * Protobuf enum <code>Google\Protobuf\Internal</code>
+ * Protobuf type <code>google.protobuf.FieldOptions.CType</code>
  */
  */
-class FieldOptions_CType
+class CType
 {
 {
     /**
     /**
      * Default mode.
      * Default mode.
@@ -25,3 +25,6 @@ class FieldOptions_CType
     const STRING_PIECE = 2;
     const STRING_PIECE = 2;
 }
 }
 
 
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(CType::class, \Google\Protobuf\Internal\FieldOptions_CType::class);
+

+ 6 - 3
php/src/Google/Protobuf/Internal/FieldOptions_JSType.php → php/src/Google/Protobuf/Internal/FieldOptions/JSType.php

@@ -2,12 +2,12 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: google/protobuf/descriptor.proto
 # source: google/protobuf/descriptor.proto
 
 
-namespace Google\Protobuf\Internal;
+namespace Google\Protobuf\Internal\FieldOptions;
 
 
 /**
 /**
- * Protobuf enum <code>Google\Protobuf\Internal</code>
+ * Protobuf type <code>google.protobuf.FieldOptions.JSType</code>
  */
  */
-class FieldOptions_JSType
+class JSType
 {
 {
     /**
     /**
      * Use the default type.
      * Use the default type.
@@ -29,3 +29,6 @@ class FieldOptions_JSType
     const JS_NUMBER = 2;
     const JS_NUMBER = 2;
 }
 }
 
 
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(JSType::class, \Google\Protobuf\Internal\FieldOptions_JSType::class);
+

+ 35 - 2
php/src/Google/Protobuf/Internal/FileDescriptorProto.php

@@ -99,9 +99,42 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message
     private $syntax = '';
     private $syntax = '';
     private $has_syntax = false;
     private $has_syntax = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name
+     *           file name, relative to root of source tree
+     *     @type string $package
+     *           e.g. "foo", "foo.bar", etc.
+     *     @type string[]|\Google\Protobuf\Internal\RepeatedField $dependency
+     *           Names of files imported by this file.
+     *     @type int[]|\Google\Protobuf\Internal\RepeatedField $public_dependency
+     *           Indexes of the public imported files in the dependency list above.
+     *     @type int[]|\Google\Protobuf\Internal\RepeatedField $weak_dependency
+     *           Indexes of the weak imported files in the dependency list.
+     *           For Google-internal migration only. Do not use.
+     *     @type \Google\Protobuf\Internal\DescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $message_type
+     *           All top-level definitions in this file.
+     *     @type \Google\Protobuf\Internal\EnumDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $enum_type
+     *     @type \Google\Protobuf\Internal\ServiceDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $service
+     *     @type \Google\Protobuf\Internal\FieldDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $extension
+     *     @type \Google\Protobuf\Internal\FileOptions $options
+     *     @type \Google\Protobuf\Internal\SourceCodeInfo $source_code_info
+     *           This field contains optional information about the original source code.
+     *           You may safely remove this entire field without harming runtime
+     *           functionality of the descriptors -- the information is needed only by
+     *           development tools.
+     *     @type string $syntax
+     *           The syntax of the proto file.
+     *           The supported values are "proto2" and "proto3".
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 11 - 2
php/src/Google/Protobuf/Internal/FileDescriptorSet.php

@@ -24,9 +24,18 @@ class FileDescriptorSet extends \Google\Protobuf\Internal\Message
     private $file;
     private $file;
     private $has_file = false;
     private $has_file = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type \Google\Protobuf\Internal\FileDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $file
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 93 - 2
php/src/Google/Protobuf/Internal/FileOptions.php

@@ -200,9 +200,100 @@ class FileOptions extends \Google\Protobuf\Internal\Message
     private $uninterpreted_option;
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
     private $has_uninterpreted_option = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $java_package
+     *           Sets the Java package where classes generated from this .proto will be
+     *           placed.  By default, the proto package is used, but this is often
+     *           inappropriate because proto packages do not normally start with backwards
+     *           domain names.
+     *     @type string $java_outer_classname
+     *           If set, all the classes from the .proto file are wrapped in a single
+     *           outer class with the given name.  This applies to both Proto1
+     *           (equivalent to the old "--one_java_file" option) and Proto2 (where
+     *           a .proto always translates to a single class, but you may want to
+     *           explicitly choose the class name).
+     *     @type bool $java_multiple_files
+     *           If set true, then the Java code generator will generate a separate .java
+     *           file for each top-level message, enum, and service defined in the .proto
+     *           file.  Thus, these types will *not* be nested inside the outer class
+     *           named by java_outer_classname.  However, the outer class will still be
+     *           generated to contain the file's getDescriptor() method as well as any
+     *           top-level extensions defined in the file.
+     *     @type bool $java_generate_equals_and_hash
+     *           This option does nothing.
+     *     @type bool $java_string_check_utf8
+     *           If set true, then the Java2 code generator will generate code that
+     *           throws an exception whenever an attempt is made to assign a non-UTF-8
+     *           byte sequence to a string field.
+     *           Message reflection will do the same.
+     *           However, an extension field still accepts non-UTF-8 byte sequences.
+     *           This option has no effect on when used with the lite runtime.
+     *     @type int $optimize_for
+     *     @type string $go_package
+     *           Sets the Go package where structs generated from this .proto will be
+     *           placed. If omitted, the Go package will be derived from the following:
+     *             - The basename of the package import path, if provided.
+     *             - Otherwise, the package statement in the .proto file, if present.
+     *             - Otherwise, the basename of the .proto file, without extension.
+     *     @type bool $cc_generic_services
+     *           Should generic services be generated in each language?  "Generic" services
+     *           are not specific to any particular RPC system.  They are generated by the
+     *           main code generators in each language (without additional plugins).
+     *           Generic services were the only kind of service generation supported by
+     *           early versions of google.protobuf.
+     *           Generic services are now considered deprecated in favor of using plugins
+     *           that generate code specific to your particular RPC system.  Therefore,
+     *           these default to false.  Old code which depends on generic services should
+     *           explicitly set them to true.
+     *     @type bool $java_generic_services
+     *     @type bool $py_generic_services
+     *     @type bool $php_generic_services
+     *     @type bool $deprecated
+     *           Is this file deprecated?
+     *           Depending on the target platform, this can emit Deprecated annotations
+     *           for everything in the file, or it will be completely ignored; in the very
+     *           least, this is a formalization for deprecating files.
+     *     @type bool $cc_enable_arenas
+     *           Enables the use of arenas for the proto messages in this file. This applies
+     *           only to generated classes for C++.
+     *     @type string $objc_class_prefix
+     *           Sets the objective c class prefix which is prepended to all objective c
+     *           generated classes from this .proto. There is no default.
+     *     @type string $csharp_namespace
+     *           Namespace for generated classes; defaults to the package.
+     *     @type string $swift_prefix
+     *           By default Swift generators will take the proto package and CamelCase it
+     *           replacing '.' with underscore and use that to prefix the types/symbols
+     *           defined. When this options is provided, they will use this value instead
+     *           to prefix the types/symbols defined.
+     *     @type string $php_class_prefix
+     *           Sets the php class prefix which is prepended to all php generated classes
+     *           from this .proto. Default is empty.
+     *     @type string $php_namespace
+     *           Use this option to change the namespace of php generated classes. Default
+     *           is empty. When this option is empty, the package name will be used for
+     *           determining the namespace.
+     *     @type string $php_metadata_namespace
+     *           Use this option to change the namespace of php generated metadata classes.
+     *           Default is empty. When this option is empty, the proto file name will be used
+     *           for determining the namespace.
+     *     @type string $ruby_package
+     *           Use this option to change the package of ruby generated classes. Default
+     *           is empty. When this option is not set, the package name will be used for
+     *           determining the ruby package.
+     *     @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option
+     *           The parser stores options it doesn't recognize here.
+     *           See the documentation for the "Options" section above.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 6 - 3
php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php → php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php

@@ -2,14 +2,14 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: google/protobuf/descriptor.proto
 # source: google/protobuf/descriptor.proto
 
 
-namespace Google\Protobuf\Internal;
+namespace Google\Protobuf\Internal\FileOptions;
 
 
 /**
 /**
  * Generated classes can be optimized for speed or code size.
  * Generated classes can be optimized for speed or code size.
  *
  *
- * Protobuf enum <code>Google\Protobuf\Internal</code>
+ * Protobuf type <code>google.protobuf.FileOptions.OptimizeMode</code>
  */
  */
-class FileOptions_OptimizeMode
+class OptimizeMode
 {
 {
     /**
     /**
      * Generate complete code for parsing, serialization,
      * Generate complete code for parsing, serialization,
@@ -31,3 +31,6 @@ class FileOptions_OptimizeMode
     const LITE_RUNTIME = 3;
     const LITE_RUNTIME = 3;
 }
 }
 
 
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(OptimizeMode::class, \Google\Protobuf\Internal\FileOptions_OptimizeMode::class);
+

+ 13 - 5
php/src/Google/Protobuf/Internal/GPBUtil.php

@@ -191,7 +191,7 @@ class GPBUtil
         $var = boolval($var);
         $var = boolval($var);
     }
     }
 
 
-    public static function checkMessage(&$var, $klass)
+    public static function checkMessage(&$var, $klass, $newClass = null)
     {
     {
         if (!$var instanceof $klass && !is_null($var)) {
         if (!$var instanceof $klass && !is_null($var)) {
             throw new \Exception("Expect $klass.");
             throw new \Exception("Expect $klass.");
@@ -303,8 +303,11 @@ class GPBUtil
         $name,
         $name,
         $file_proto)
         $file_proto)
     {
     {
-        $classname = implode('_', explode('.', $name));
-        return static::getClassNamePrefix($classname, $file_proto) . $classname;
+        $parts = explode('.', $name);
+        foreach ($parts as $i => $part) {
+            $parts[$i] = static::getClassNamePrefix($parts[$i], $file_proto) . $parts[$i];
+        }
+        return implode('\\', $parts);
     }
     }
 
 
     public static function getFullClassName(
     public static function getFullClassName(
@@ -347,9 +350,14 @@ class GPBUtil
         if ($package === "") {
         if ($package === "") {
             $classname = $class_name_without_package;
             $classname = $class_name_without_package;
         } else {
         } else {
+            $parts = array_map('ucwords', explode('.', $package));
+            foreach ($parts as $i => $part) {
+                $parts[$i] = self::getClassNamePrefix($part, $file_proto).$part;
+            }
             $classname =
             $classname =
-                implode('\\', array_map('ucwords', explode('.', $package))).
-                "\\".$class_name_without_package;
+                implode('\\', $parts) .
+                "\\".self::getClassNamePrefix($class_name_without_package,$file_proto).
+                $class_name_without_package;
         }
         }
     }
     }
 
 

+ 15 - 4
php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php

@@ -28,9 +28,20 @@ class GeneratedCodeInfo extends \Google\Protobuf\Internal\Message
     private $annotation;
     private $annotation;
     private $has_annotation = false;
     private $has_annotation = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type \Google\Protobuf\Internal\GeneratedCodeInfo\Annotation[]|\Google\Protobuf\Internal\RepeatedField $annotation
+     *           An Annotation connects some span of text in generated code to an element
+     *           of its generating .proto file.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**
@@ -50,12 +61,12 @@ class GeneratedCodeInfo extends \Google\Protobuf\Internal\Message
      * of its generating .proto file.
      * of its generating .proto file.
      *
      *
      * Generated from protobuf field <code>repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;</code>
      * Generated from protobuf field <code>repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;</code>
-     * @param \Google\Protobuf\Internal\GeneratedCodeInfo_Annotation[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @param \Google\Protobuf\Internal\GeneratedCodeInfo\Annotation[]|\Google\Protobuf\Internal\RepeatedField $var
      * @return $this
      * @return $this
      */
      */
     public function setAnnotation($var)
     public function setAnnotation($var)
     {
     {
-        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\GeneratedCodeInfo_Annotation::class);
+        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\GeneratedCodeInfo\Annotation::class);
         $this->annotation = $arr;
         $this->annotation = $arr;
         $this->has_annotation = true;
         $this->has_annotation = true;
 
 

+ 27 - 4
php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php → php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php

@@ -2,7 +2,7 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: google/protobuf/descriptor.proto
 # source: google/protobuf/descriptor.proto
 
 
-namespace Google\Protobuf\Internal;
+namespace Google\Protobuf\Internal\GeneratedCodeInfo;
 
 
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\GPBWire;
@@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil;
 /**
 /**
  * Generated from protobuf message <code>google.protobuf.GeneratedCodeInfo.Annotation</code>
  * Generated from protobuf message <code>google.protobuf.GeneratedCodeInfo.Annotation</code>
  */
  */
-class GeneratedCodeInfo_Annotation extends \Google\Protobuf\Internal\Message
+class Annotation extends \Google\Protobuf\Internal\Message
 {
 {
     /**
     /**
      * Identifies the element in the original source .proto file. This field
      * Identifies the element in the original source .proto file. This field
@@ -48,9 +48,29 @@ class GeneratedCodeInfo_Annotation extends \Google\Protobuf\Internal\Message
     private $end = 0;
     private $end = 0;
     private $has_end = false;
     private $has_end = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int[]|\Google\Protobuf\Internal\RepeatedField $path
+     *           Identifies the element in the original source .proto file. This field
+     *           is formatted the same as SourceCodeInfo.Location.path.
+     *     @type string $source_file
+     *           Identifies the filesystem path to the original source .proto.
+     *     @type int $begin
+     *           Identifies the starting offset in bytes in the generated code
+     *           that relates to the identified object.
+     *     @type int $end
+     *           Identifies the ending offset in bytes in the generated code that
+     *           relates to the identified offset. The end offset should be one past
+     *           the last relevant byte (so the length of the text = end - begin).
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**
@@ -191,3 +211,6 @@ class GeneratedCodeInfo_Annotation extends \Google\Protobuf\Internal\Message
 
 
 }
 }
 
 
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(Annotation::class, \Google\Protobuf\Internal\GeneratedCodeInfo_Annotation::class);
+

+ 150 - 98
php/src/Google/Protobuf/Internal/Message.php

@@ -66,19 +66,30 @@ class Message
     /**
     /**
      * @ignore
      * @ignore
      */
      */
-    public function __construct($desc = NULL)
+    public function __construct($data = NULL)
     {
     {
         // MapEntry message is shared by all types of map fields, whose
         // MapEntry message is shared by all types of map fields, whose
         // descriptors are different from each other. Thus, we cannot find a
         // descriptors are different from each other. Thus, we cannot find a
         // specific descriptor from the descriptor pool.
         // specific descriptor from the descriptor pool.
-        if (get_class($this) === 'Google\Protobuf\Internal\MapEntry') {
-            $this->desc = $desc;
-            foreach ($desc->getField() as $field) {
-                $setter = $field->getSetter();
-                $this->$setter($this->defaultValue($field));
+        if ($this instanceof MapEntry) {
+            $this->initWithDescriptor($data);
+        } else {
+            $this->initWithGeneratedPool();
+            if (is_array($data)) {
+                $this->mergeFromArray($data);
+            } else if (!empty($data)) {
+                throw new \InvalidArgumentException(
+                    'Message constructor must be an array or null.'
+                );
             }
             }
-            return;
         }
         }
+    }
+
+    /**
+     * @ignore
+     */
+    private function initWithGeneratedPool()
+    {
         $pool = DescriptorPool::getGeneratedPool();
         $pool = DescriptorPool::getGeneratedPool();
         $this->desc = $pool->getDescriptorByClassName(get_class($this));
         $this->desc = $pool->getDescriptorByClassName(get_class($this));
         if (is_null($this->desc)) {
         if (is_null($this->desc)) {
@@ -151,6 +162,19 @@ class Message
         }
         }
     }
     }
 
 
+    /**
+     * @ignore
+     */
+    private function initWithDescriptor(Descriptor $desc)
+    {
+        $this->desc = $desc;
+        foreach ($desc->getField() as $field) {
+            $setter = $field->getSetter();
+            $defaultValue = $this->defaultValue($field);
+            $this->$setter($defaultValue);
+        }
+    }
+
     protected function readOneof($number)
     protected function readOneof($number)
     {
     {
         $field = $this->desc->getFieldByNumber($number);
         $field = $this->desc->getFieldByNumber($number);
@@ -628,58 +652,58 @@ class Message
      */
      */
     public function mergeFrom($msg)
     public function mergeFrom($msg)
     {
     {
-      if (get_class($this) !== get_class($msg)) {
-          user_error("Cannot merge messages with different class.");
-          return;
-      }
-
-      foreach ($this->desc->getField() as $field) {
-          $setter = $field->getSetter();
-          $getter = $field->getGetter();
-          if ($field->isMap()) {
-              if (count($msg->$getter()) != 0) {
-                  $value_field = $field->getMessageType()->getFieldByNumber(2);
-                  foreach ($msg->$getter() as $key => $value) {
-                      if ($value_field->getType() == GPBType::MESSAGE) {
-                          $klass = $value_field->getMessageType()->getClass();
-                          $copy = new $klass;
-                          $copy->mergeFrom($value);
-
-                          $this->kvUpdateHelper($field, $key, $copy);
-                      } else {
-                          $this->kvUpdateHelper($field, $key, $value);
-                      }
-                  }
-              }
-          } else if ($field->getLabel() === GPBLabel::REPEATED) {
-              if (count($msg->$getter()) != 0) {
-                  foreach ($msg->$getter() as $tmp) {
-                      if ($field->getType() == GPBType::MESSAGE) {
-                          $klass = $field->getMessageType()->getClass();
-                          $copy = new $klass;
-                          $copy->mergeFrom($tmp);
-                          $this->appendHelper($field, $copy);
-                      } else {
-                          $this->appendHelper($field, $tmp);
-                      }
-                  }
-              }
-          } else if ($field->getLabel() === GPBLabel::OPTIONAL) {
-              if($msg->$getter() !== $this->defaultValue($field)) {
-                  $tmp = $msg->$getter();
-                  if ($field->getType() == GPBType::MESSAGE) {
-                      if (is_null($this->$getter())) {
-                          $klass = $field->getMessageType()->getClass();
-                          $new_msg = new $klass;
-                          $this->$setter($new_msg);
-                      }
-                      $this->$getter()->mergeFrom($tmp);
-                  } else {
-                      $this->$setter($tmp);
-                  }
-              }
-          }
-      }
+        if (get_class($this) !== get_class($msg)) {
+            user_error("Cannot merge messages with different class.");
+            return;
+        }
+
+        foreach ($this->desc->getField() as $field) {
+            $setter = $field->getSetter();
+            $getter = $field->getGetter();
+            if ($field->isMap()) {
+                if (count($msg->$getter()) != 0) {
+                    $value_field = $field->getMessageType()->getFieldByNumber(2);
+                    foreach ($msg->$getter() as $key => $value) {
+                        if ($value_field->getType() == GPBType::MESSAGE) {
+                            $klass = $value_field->getMessageType()->getClass();
+                            $copy = new $klass;
+                            $copy->mergeFrom($value);
+
+                            $this->kvUpdateHelper($field, $key, $copy);
+                        } else {
+                            $this->kvUpdateHelper($field, $key, $value);
+                        }
+                    }
+                }
+            } else if ($field->getLabel() === GPBLabel::REPEATED) {
+                if (count($msg->$getter()) != 0) {
+                    foreach ($msg->$getter() as $tmp) {
+                        if ($field->getType() == GPBType::MESSAGE) {
+                            $klass = $field->getMessageType()->getClass();
+                            $copy = new $klass;
+                            $copy->mergeFrom($tmp);
+                            $this->appendHelper($field, $copy);
+                        } else {
+                            $this->appendHelper($field, $tmp);
+                        }
+                    }
+                }
+            } else if ($field->getLabel() === GPBLabel::OPTIONAL) {
+                if($msg->$getter() !== $this->defaultValue($field)) {
+                    $tmp = $msg->$getter();
+                    if ($field->getType() == GPBType::MESSAGE) {
+                        if (is_null($this->$getter())) {
+                            $klass = $field->getMessageType()->getClass();
+                            $new_msg = new $klass;
+                            $this->$setter($new_msg);
+                        }
+                        $this->$getter()->mergeFrom($tmp);
+                    } else {
+                        $this->$setter($tmp);
+                    }
+                }
+            }
+        }
     }
     }
 
 
     /**
     /**
@@ -763,7 +787,8 @@ class Message
                     try {
                     try {
                         $timestamp = GPBUtil::parseTimestamp($value);
                         $timestamp = GPBUtil::parseTimestamp($value);
                     } catch (\Exception $e) {
                     } catch (\Exception $e) {
-                        throw new GPBDecodeException("Invalid RFC 3339 timestamp: ".$e->getMessage());
+                        throw new GPBDecodeException(
+                            "Invalid RFC 3339 timestamp: ".$e->getMessage());
                     }
                     }
 
 
                     $submsg->setSeconds($timestamp->getSeconds());
                     $submsg->setSeconds($timestamp->getSeconds());
@@ -775,7 +800,8 @@ class Message
                     try {
                     try {
                         return GPBUtil::parseFieldMask($value);
                         return GPBUtil::parseFieldMask($value);
                     } catch (\Exception $e) {
                     } catch (\Exception $e) {
-                        throw new GPBDecodeException("Invalid FieldMask: ".$e->getMessage());
+                        throw new GPBDecodeException(
+                            "Invalid FieldMask: ".$e->getMessage());
                     }
                     }
                 } else {
                 } else {
                     if (is_null($value) &&
                     if (is_null($value) &&
@@ -792,21 +818,23 @@ class Message
             case GPBType::ENUM:
             case GPBType::ENUM:
                 if (is_null($value)) {
                 if (is_null($value)) {
                     return $this->defaultValue($field);
                     return $this->defaultValue($field);
-                } else if (is_integer($value)) {
+                }
+                if (is_integer($value)) {
                     return $value;
                     return $value;
-                } else {
-                    $enum_value =
-                        $field->getEnumType()->getValueByName($value);
                 }
                 }
+                $enum_value = $field->getEnumType()->getValueByName($value);
                 if (!is_null($enum_value)) {
                 if (!is_null($enum_value)) {
                     return $enum_value->getNumber();
                     return $enum_value->getNumber();
                 }
                 }
+                throw new GPBDecodeException(
+                        "Enum field only accepts integer or enum value name");
             case GPBType::STRING:
             case GPBType::STRING:
                 if (is_null($value)) {
                 if (is_null($value)) {
                     return $this->defaultValue($field);
                     return $this->defaultValue($field);
                 }
                 }
                 if (!is_string($value)) {
                 if (!is_string($value)) {
-                    throw new GPBDecodeException("Expect string");
+                    throw new GPBDecodeException(
+                        "String field only accepts string value");
                 }
                 }
                 return $value;
                 return $value;
             case GPBType::BYTES:
             case GPBType::BYTES:
@@ -814,12 +842,12 @@ class Message
                     return $this->defaultValue($field);
                     return $this->defaultValue($field);
                 }
                 }
                 if (!is_string($value)) {
                 if (!is_string($value)) {
-                    throw new GPBDecodeException("Expect string");
+                    throw new GPBDecodeException(
+                        "Byte field only accepts string value");
                 }
                 }
                 $proto_value = base64_decode($value, true);
                 $proto_value = base64_decode($value, true);
                 if ($proto_value === false) {
                 if ($proto_value === false) {
-                    throw new GPBDecodeException(
-                        "Invalid base64 characters");
+                    throw new GPBDecodeException("Invalid base64 characters");
                 }
                 }
                 return $proto_value;
                 return $proto_value;
             case GPBType::BOOL:
             case GPBType::BOOL:
@@ -834,27 +862,14 @@ class Message
                         return false;
                         return false;
                     }
                     }
                     throw new GPBDecodeException(
                     throw new GPBDecodeException(
-                        "Bool field only accept bool value");
+                        "Bool field only accepts bool value");
                 }
                 }
                 if (!is_bool($value)) {
                 if (!is_bool($value)) {
                     throw new GPBDecodeException(
                     throw new GPBDecodeException(
-                        "Bool field only accept bool value");
+                        "Bool field only accepts bool value");
                 }
                 }
                 return $value;
                 return $value;
             case GPBType::FLOAT:
             case GPBType::FLOAT:
-                if (is_null($value)) {
-                    return $this->defaultValue($field);
-                }
-                if ($value === "Infinity") {
-                    return INF;
-                }
-                if ($value === "-Infinity") {
-                    return -INF;
-                }
-                if ($value === "NaN") {
-                    return NAN;
-                }
-                return $value;
             case GPBType::DOUBLE:
             case GPBType::DOUBLE:
                 if (is_null($value)) {
                 if (is_null($value)) {
                     return $this->defaultValue($field);
                     return $this->defaultValue($field);
@@ -943,6 +958,39 @@ class Message
         }
         }
     }
     }
 
 
+    /**
+     * Populates the message from a user-supplied PHP array. Array keys
+     * correspond to Message properties and nested message properties.
+     *
+     * Example:
+     * ```
+     * $message->mergeFromArray([
+     *     'name' => 'This is a message name',
+     *     'interval' => [
+     *          'startTime' => time() - 60,
+     *          'endTime' => time(),
+     *     ]
+     * ]);
+     * ```
+     *
+     * @param array $array An array containing message properties and values.
+     * @return null.
+     * @throws Exception Invalid data.
+     */
+    protected function mergeFromArray(array $array)
+    {
+        // Just call the setters for the field names
+        foreach ($array as $key => $value) {
+            $field = $this->desc->getFieldByName($key);
+            if (is_null($field)) {
+                throw new \UnexpectedValueException(
+                    'Invalid message property: ' . $key);
+            }
+            $setter = $field->getSetter();
+            $this->$setter($value);
+        }
+    }
+
     protected function mergeFromJsonArray($array)
     protected function mergeFromJsonArray($array)
     {
     {
         if (is_a($this, "Google\Protobuf\Any")) {
         if (is_a($this, "Google\Protobuf\Any")) {
@@ -1035,6 +1083,11 @@ class Message
             }
             }
             return;
             return;
         }
         }
+        $this->mergeFromArrayJsonImpl($array);
+    }
+
+    private function mergeFromArrayJsonImpl($array)
+    {
         foreach ($array as $key => $value) {
         foreach ($array as $key => $value) {
             $field = $this->desc->getFieldByJsonName($key);
             $field = $this->desc->getFieldByJsonName($key);
             if (is_null($field)) {
             if (is_null($field)) {
@@ -1043,7 +1096,6 @@ class Message
                     continue;
                     continue;
                 }
                 }
             }
             }
-            $setter = $field->getSetter();
             if ($field->isMap()) {
             if ($field->isMap()) {
                 if (is_null($value)) {
                 if (is_null($value)) {
                     continue;
                     continue;
@@ -1055,15 +1107,13 @@ class Message
                         throw new \Exception(
                         throw new \Exception(
                             "Map value field element cannot be null.");
                             "Map value field element cannot be null.");
                     }
                     }
-                    $proto_key =
-                        $this->convertJsonValueToProtoValue(
-                            $tmp_key,
-                            $key_field,
-                            true);
-                    $proto_value =
-                        $this->convertJsonValueToProtoValue(
-                            $tmp_value,
-                            $value_field);
+                    $proto_key = $this->convertJsonValueToProtoValue(
+                        $tmp_key,
+                        $key_field,
+                        true);
+                    $proto_value = $this->convertJsonValueToProtoValue(
+                        $tmp_value,
+                        $value_field);
                     self::kvUpdateHelper($field, $proto_key, $proto_value);
                     self::kvUpdateHelper($field, $proto_key, $proto_value);
                 }
                 }
             } else if ($field->isRepeated()) {
             } else if ($field->isRepeated()) {
@@ -1075,14 +1125,16 @@ class Message
                         throw new \Exception(
                         throw new \Exception(
                             "Repeated field elements cannot be null.");
                             "Repeated field elements cannot be null.");
                     }
                     }
-                    $proto_value =
-                        $this->convertJsonValueToProtoValue($tmp, $field);
+                    $proto_value = $this->convertJsonValueToProtoValue(
+                        $tmp,
+                        $field);
                     self::appendHelper($field, $proto_value);
                     self::appendHelper($field, $proto_value);
                 }
                 }
             } else {
             } else {
                 $setter = $field->getSetter();
                 $setter = $field->getSetter();
-                $proto_value =
-                    $this->convertJsonValueToProtoValue($value, $field);
+                $proto_value = $this->convertJsonValueToProtoValue(
+                    $value,
+                    $field);
                 if ($field->getType() === GPBType::MESSAGE) {
                 if ($field->getType() === GPBType::MESSAGE) {
                     if (is_null($proto_value)) {
                     if (is_null($proto_value)) {
                         continue;
                         continue;

+ 56 - 2
php/src/Google/Protobuf/Internal/MessageOptions.php

@@ -87,9 +87,63 @@ class MessageOptions extends \Google\Protobuf\Internal\Message
     private $uninterpreted_option;
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
     private $has_uninterpreted_option = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type bool $message_set_wire_format
+     *           Set true to use the old proto1 MessageSet wire format for extensions.
+     *           This is provided for backwards-compatibility with the MessageSet wire
+     *           format.  You should not use this for any other reason:  It's less
+     *           efficient, has fewer features, and is more complicated.
+     *           The message must be defined exactly as follows:
+     *             message Foo {
+     *               option message_set_wire_format = true;
+     *               extensions 4 to max;
+     *             }
+     *           Note that the message cannot have any defined fields; MessageSets only
+     *           have extensions.
+     *           All extensions of your type must be singular messages; e.g. they cannot
+     *           be int32s, enums, or repeated messages.
+     *           Because this is an option, the above two restrictions are not enforced by
+     *           the protocol compiler.
+     *     @type bool $no_standard_descriptor_accessor
+     *           Disables the generation of the standard "descriptor()" accessor, which can
+     *           conflict with a field of the same name.  This is meant to make migration
+     *           from proto1 easier; new code should avoid fields named "descriptor".
+     *     @type bool $deprecated
+     *           Is this message deprecated?
+     *           Depending on the target platform, this can emit Deprecated annotations
+     *           for the message, or it will be completely ignored; in the very least,
+     *           this is a formalization for deprecating messages.
+     *     @type bool $map_entry
+     *           Whether the message is an automatically generated map entry type for the
+     *           maps field.
+     *           For maps fields:
+     *               map<KeyType, ValueType> map_field = 1;
+     *           The parsed descriptor looks like:
+     *               message MapFieldEntry {
+     *                   option map_entry = true;
+     *                   optional KeyType key = 1;
+     *                   optional ValueType value = 2;
+     *               }
+     *               repeated MapFieldEntry map_field = 1;
+     *           Implementations may choose not to generate the map_entry=true message, but
+     *           use a native map in the target language to hold the keys and values.
+     *           The reflection APIs in such implementions still need to work as
+     *           if the field is a repeated message field.
+     *           NOTE: Do not set the option in .proto files. Always use the maps syntax
+     *           instead. The option should only be implicitly set by the proto compiler
+     *           parser.
+     *     @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option
+     *           The parser stores options it doesn't recognize here. See above.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 20 - 2
php/src/Google/Protobuf/Internal/MethodDescriptorProto.php

@@ -55,9 +55,27 @@ class MethodDescriptorProto extends \Google\Protobuf\Internal\Message
     private $server_streaming = false;
     private $server_streaming = false;
     private $has_server_streaming = false;
     private $has_server_streaming = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name
+     *     @type string $input_type
+     *           Input and output type names.  These are resolved in the same way as
+     *           FieldDescriptorProto.type_name, but must refer to a message type.
+     *     @type string $output_type
+     *     @type \Google\Protobuf\Internal\MethodOptions $options
+     *     @type bool $client_streaming
+     *           Identifies if client streams multiple client messages
+     *     @type bool $server_streaming
+     *           Identifies if server streams multiple server messages
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 18 - 2
php/src/Google/Protobuf/Internal/MethodOptions.php

@@ -38,9 +38,25 @@ class MethodOptions extends \Google\Protobuf\Internal\Message
     private $uninterpreted_option;
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
     private $has_uninterpreted_option = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type bool $deprecated
+     *           Is this method deprecated?
+     *           Depending on the target platform, this can emit Deprecated annotations
+     *           for the method, or it will be completely ignored; in the very least,
+     *           this is a formalization for deprecating methods.
+     *     @type int $idempotency_level
+     *     @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option
+     *           The parser stores options it doesn't recognize here. See above.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 6 - 3
php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php → php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php

@@ -2,16 +2,16 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: google/protobuf/descriptor.proto
 # source: google/protobuf/descriptor.proto
 
 
-namespace Google\Protobuf\Internal;
+namespace Google\Protobuf\Internal\MethodOptions;
 
 
 /**
 /**
  * Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
  * Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
  * or neither? HTTP based RPC implementation may choose GET verb for safe
  * or neither? HTTP based RPC implementation may choose GET verb for safe
  * methods, and PUT verb for idempotent methods instead of the default POST.
  * methods, and PUT verb for idempotent methods instead of the default POST.
  *
  *
- * Protobuf enum <code>Google\Protobuf\Internal</code>
+ * Protobuf type <code>google.protobuf.MethodOptions.IdempotencyLevel</code>
  */
  */
-class MethodOptions_IdempotencyLevel
+class IdempotencyLevel
 {
 {
     /**
     /**
      * Generated from protobuf enum <code>IDEMPOTENCY_UNKNOWN = 0;</code>
      * Generated from protobuf enum <code>IDEMPOTENCY_UNKNOWN = 0;</code>
@@ -31,3 +31,6 @@ class MethodOptions_IdempotencyLevel
     const IDEMPOTENT = 2;
     const IDEMPOTENT = 2;
 }
 }
 
 
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(IdempotencyLevel::class, \Google\Protobuf\Internal\MethodOptions_IdempotencyLevel::class);
+

+ 12 - 2
php/src/Google/Protobuf/Internal/OneofDescriptorProto.php

@@ -28,9 +28,19 @@ class OneofDescriptorProto extends \Google\Protobuf\Internal\Message
     private $options = null;
     private $options = null;
     private $has_options = false;
     private $has_options = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name
+     *     @type \Google\Protobuf\Internal\OneofOptions $options
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 12 - 2
php/src/Google/Protobuf/Internal/OneofOptions.php

@@ -23,9 +23,19 @@ class OneofOptions extends \Google\Protobuf\Internal\Message
     private $uninterpreted_option;
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
     private $has_uninterpreted_option = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option
+     *           The parser stores options it doesn't recognize here. See above.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 13 - 2
php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php

@@ -33,9 +33,20 @@ class ServiceDescriptorProto extends \Google\Protobuf\Internal\Message
     private $options = null;
     private $options = null;
     private $has_options = false;
     private $has_options = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name
+     *     @type \Google\Protobuf\Internal\MethodDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $method
+     *     @type \Google\Protobuf\Internal\ServiceOptions $options
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 17 - 2
php/src/Google/Protobuf/Internal/ServiceOptions.php

@@ -33,9 +33,24 @@ class ServiceOptions extends \Google\Protobuf\Internal\Message
     private $uninterpreted_option;
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
     private $has_uninterpreted_option = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type bool $deprecated
+     *           Is this service deprecated?
+     *           Depending on the target platform, this can emit Deprecated annotations
+     *           for the service, or it will be completely ignored; in the very least,
+     *           this is a formalization for deprecating services.
+     *     @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option
+     *           The parser stores options it doesn't recognize here. See above.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 54 - 4
php/src/Google/Protobuf/Internal/SourceCodeInfo.php

@@ -66,9 +66,59 @@ class SourceCodeInfo extends \Google\Protobuf\Internal\Message
     private $location;
     private $location;
     private $has_location = false;
     private $has_location = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type \Google\Protobuf\Internal\SourceCodeInfo\Location[]|\Google\Protobuf\Internal\RepeatedField $location
+     *           A Location identifies a piece of source code in a .proto file which
+     *           corresponds to a particular definition.  This information is intended
+     *           to be useful to IDEs, code indexers, documentation generators, and similar
+     *           tools.
+     *           For example, say we have a file like:
+     *             message Foo {
+     *               optional string foo = 1;
+     *             }
+     *           Let's look at just the field definition:
+     *             optional string foo = 1;
+     *             ^       ^^     ^^  ^  ^^^
+     *             a       bc     de  f  ghi
+     *           We have the following locations:
+     *             span   path               represents
+     *             [a,i)  [ 4, 0, 2, 0 ]     The whole field definition.
+     *             [a,b)  [ 4, 0, 2, 0, 4 ]  The label (optional).
+     *             [c,d)  [ 4, 0, 2, 0, 5 ]  The type (string).
+     *             [e,f)  [ 4, 0, 2, 0, 1 ]  The name (foo).
+     *             [g,h)  [ 4, 0, 2, 0, 3 ]  The number (1).
+     *           Notes:
+     *           - A location may refer to a repeated field itself (i.e. not to any
+     *             particular index within it).  This is used whenever a set of elements are
+     *             logically enclosed in a single code segment.  For example, an entire
+     *             extend block (possibly containing multiple extension definitions) will
+     *             have an outer location whose path refers to the "extensions" repeated
+     *             field without an index.
+     *           - Multiple locations may have the same path.  This happens when a single
+     *             logical declaration is spread out across multiple places.  The most
+     *             obvious example is the "extend" block again -- there may be multiple
+     *             extend blocks in the same scope, each of which will have the same path.
+     *           - A location's span is not always a subset of its parent's span.  For
+     *             example, the "extendee" of an extension declaration appears at the
+     *             beginning of the "extend" block and is shared by all extensions within
+     *             the block.
+     *           - Just because a location's span is a subset of some other location's span
+     *             does not mean that it is a descendent.  For example, a "group" defines
+     *             both a type and a field in a single declaration.  Thus, the locations
+     *             corresponding to the type and field and their components will overlap.
+     *           - Code which tries to interpret locations should probably be designed to
+     *             ignore those that it doesn't understand, as more types of locations could
+     *             be recorded in the future.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**
@@ -166,12 +216,12 @@ class SourceCodeInfo extends \Google\Protobuf\Internal\Message
      *   be recorded in the future.
      *   be recorded in the future.
      *
      *
      * Generated from protobuf field <code>repeated .google.protobuf.SourceCodeInfo.Location location = 1;</code>
      * Generated from protobuf field <code>repeated .google.protobuf.SourceCodeInfo.Location location = 1;</code>
-     * @param \Google\Protobuf\Internal\SourceCodeInfo_Location[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @param \Google\Protobuf\Internal\SourceCodeInfo\Location[]|\Google\Protobuf\Internal\RepeatedField $var
      * @return $this
      * @return $this
      */
      */
     public function setLocation($var)
     public function setLocation($var)
     {
     {
-        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\SourceCodeInfo_Location::class);
+        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\SourceCodeInfo\Location::class);
         $this->location = $arr;
         $this->location = $arr;
         $this->has_location = true;
         $this->has_location = true;
 
 

+ 82 - 4
php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php → php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php

@@ -2,7 +2,7 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: google/protobuf/descriptor.proto
 # source: google/protobuf/descriptor.proto
 
 
-namespace Google\Protobuf\Internal;
+namespace Google\Protobuf\Internal\SourceCodeInfo;
 
 
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\GPBWire;
@@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil;
 /**
 /**
  * Generated from protobuf message <code>google.protobuf.SourceCodeInfo.Location</code>
  * Generated from protobuf message <code>google.protobuf.SourceCodeInfo.Location</code>
  */
  */
-class SourceCodeInfo_Location extends \Google\Protobuf\Internal\Message
+class Location extends \Google\Protobuf\Internal\Message
 {
 {
     /**
     /**
      * Identifies which part of the FileDescriptorProto was defined at this
      * Identifies which part of the FileDescriptorProto was defined at this
@@ -106,9 +106,84 @@ class SourceCodeInfo_Location extends \Google\Protobuf\Internal\Message
     private $leading_detached_comments;
     private $leading_detached_comments;
     private $has_leading_detached_comments = false;
     private $has_leading_detached_comments = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int[]|\Google\Protobuf\Internal\RepeatedField $path
+     *           Identifies which part of the FileDescriptorProto was defined at this
+     *           location.
+     *           Each element is a field number or an index.  They form a path from
+     *           the root FileDescriptorProto to the place where the definition.  For
+     *           example, this path:
+     *             [ 4, 3, 2, 7, 1 ]
+     *           refers to:
+     *             file.message_type(3)  // 4, 3
+     *                 .field(7)         // 2, 7
+     *                 .name()           // 1
+     *           This is because FileDescriptorProto.message_type has field number 4:
+     *             repeated DescriptorProto message_type = 4;
+     *           and DescriptorProto.field has field number 2:
+     *             repeated FieldDescriptorProto field = 2;
+     *           and FieldDescriptorProto.name has field number 1:
+     *             optional string name = 1;
+     *           Thus, the above path gives the location of a field name.  If we removed
+     *           the last element:
+     *             [ 4, 3, 2, 7 ]
+     *           this path refers to the whole field declaration (from the beginning
+     *           of the label to the terminating semicolon).
+     *     @type int[]|\Google\Protobuf\Internal\RepeatedField $span
+     *           Always has exactly three or four elements: start line, start column,
+     *           end line (optional, otherwise assumed same as start line), end column.
+     *           These are packed into a single field for efficiency.  Note that line
+     *           and column numbers are zero-based -- typically you will want to add
+     *           1 to each before displaying to a user.
+     *     @type string $leading_comments
+     *           If this SourceCodeInfo represents a complete declaration, these are any
+     *           comments appearing before and after the declaration which appear to be
+     *           attached to the declaration.
+     *           A series of line comments appearing on consecutive lines, with no other
+     *           tokens appearing on those lines, will be treated as a single comment.
+     *           leading_detached_comments will keep paragraphs of comments that appear
+     *           before (but not connected to) the current element. Each paragraph,
+     *           separated by empty lines, will be one comment element in the repeated
+     *           field.
+     *           Only the comment content is provided; comment markers (e.g. //) are
+     *           stripped out.  For block comments, leading whitespace and an asterisk
+     *           will be stripped from the beginning of each line other than the first.
+     *           Newlines are included in the output.
+     *           Examples:
+     *             optional int32 foo = 1;  // Comment attached to foo.
+     *             // Comment attached to bar.
+     *             optional int32 bar = 2;
+     *             optional string baz = 3;
+     *             // Comment attached to baz.
+     *             // Another line attached to baz.
+     *             // Comment attached to qux.
+     *             //
+     *             // Another line attached to qux.
+     *             optional double qux = 4;
+     *             // Detached comment for corge. This is not leading or trailing comments
+     *             // to qux or corge because there are blank lines separating it from
+     *             // both.
+     *             // Detached comment for corge paragraph 2.
+     *             optional string corge = 5;
+     *             /&#42; Block comment attached
+     *              * to corge.  Leading asterisks
+     *              * will be removed. *&#47;
+     *             /&#42; Block comment attached to
+     *              * grault. *&#47;
+     *             optional int32 grault = 6;
+     *             // ignored detached comments.
+     *     @type string $trailing_comments
+     *     @type string[]|\Google\Protobuf\Internal\RepeatedField $leading_detached_comments
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**
@@ -383,3 +458,6 @@ class SourceCodeInfo_Location extends \Google\Protobuf\Internal\Message
 
 
 }
 }
 
 
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(Location::class, \Google\Protobuf\Internal\SourceCodeInfo_Location::class);
+

+ 21 - 4
php/src/Google/Protobuf/Internal/UninterpretedOption.php

@@ -61,9 +61,26 @@ class UninterpretedOption extends \Google\Protobuf\Internal\Message
     private $aggregate_value = '';
     private $aggregate_value = '';
     private $has_aggregate_value = false;
     private $has_aggregate_value = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type \Google\Protobuf\Internal\UninterpretedOption\NamePart[]|\Google\Protobuf\Internal\RepeatedField $name
+     *     @type string $identifier_value
+     *           The value of the uninterpreted option, in whatever type the tokenizer
+     *           identified it as during parsing. Exactly one of these should be set.
+     *     @type int|string $positive_int_value
+     *     @type int|string $negative_int_value
+     *     @type float $double_value
+     *     @type string $string_value
+     *     @type string $aggregate_value
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**
@@ -77,12 +94,12 @@ class UninterpretedOption extends \Google\Protobuf\Internal\Message
 
 
     /**
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption.NamePart name = 2;</code>
      * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption.NamePart name = 2;</code>
-     * @param \Google\Protobuf\Internal\UninterpretedOption_NamePart[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @param \Google\Protobuf\Internal\UninterpretedOption\NamePart[]|\Google\Protobuf\Internal\RepeatedField $var
      * @return $this
      * @return $this
      */
      */
     public function setName($var)
     public function setName($var)
     {
     {
-        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption_NamePart::class);
+        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption\NamePart::class);
         $this->name = $arr;
         $this->name = $arr;
         $this->has_name = true;
         $this->has_name = true;
 
 

+ 17 - 4
php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php → php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php

@@ -2,7 +2,7 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: google/protobuf/descriptor.proto
 # source: google/protobuf/descriptor.proto
 
 
-namespace Google\Protobuf\Internal;
+namespace Google\Protobuf\Internal\UninterpretedOption;
 
 
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\GPBWire;
@@ -19,7 +19,7 @@ use Google\Protobuf\Internal\GPBUtil;
  *
  *
  * Generated from protobuf message <code>google.protobuf.UninterpretedOption.NamePart</code>
  * Generated from protobuf message <code>google.protobuf.UninterpretedOption.NamePart</code>
  */
  */
-class UninterpretedOption_NamePart extends \Google\Protobuf\Internal\Message
+class NamePart extends \Google\Protobuf\Internal\Message
 {
 {
     /**
     /**
      * Generated from protobuf field <code>required string name_part = 1;</code>
      * Generated from protobuf field <code>required string name_part = 1;</code>
@@ -32,9 +32,19 @@ class UninterpretedOption_NamePart extends \Google\Protobuf\Internal\Message
     private $is_extension = false;
     private $is_extension = false;
     private $has_is_extension = false;
     private $has_is_extension = false;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name_part
+     *     @type bool $is_extension
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
         \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**
@@ -95,3 +105,6 @@ class UninterpretedOption_NamePart extends \Google\Protobuf\Internal\Message
 
 
 }
 }
 
 
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(NamePart::class, \Google\Protobuf\Internal\UninterpretedOption_NamePart::class);
+

+ 12 - 2
php/src/Google/Protobuf/ListValue.php

@@ -23,9 +23,19 @@ class ListValue extends \Google\Protobuf\Internal\Message
      */
      */
     private $values;
     private $values;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type \Google\Protobuf\Value[]|\Google\Protobuf\Internal\RepeatedField $values
+     *           Repeated field of dynamically typed values.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Struct::initOnce();
         \GPBMetadata\Google\Protobuf\Struct::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 24 - 2
php/src/Google/Protobuf/Method.php

@@ -58,9 +58,31 @@ class Method extends \Google\Protobuf\Internal\Message
      */
      */
     private $syntax = 0;
     private $syntax = 0;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name
+     *           The simple name of this method.
+     *     @type string $request_type_url
+     *           A URL of the input message type.
+     *     @type bool $request_streaming
+     *           If true, the request is streamed.
+     *     @type string $response_type_url
+     *           The URL of the output message type.
+     *     @type bool $response_streaming
+     *           If true, the response is streamed.
+     *     @type \Google\Protobuf\Option[]|\Google\Protobuf\Internal\RepeatedField $options
+     *           Any metadata attached to the method.
+     *     @type int $syntax
+     *           The source syntax of this method.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Api::initOnce();
         \GPBMetadata\Google\Protobuf\Api::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 15 - 2
php/src/Google/Protobuf/Mixin.php

@@ -90,9 +90,22 @@ class Mixin extends \Google\Protobuf\Internal\Message
      */
      */
     private $root = '';
     private $root = '';
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name
+     *           The fully qualified name of the interface which is included.
+     *     @type string $root
+     *           If non-empty specifies a path under which inherited HTTP paths
+     *           are rooted.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Api::initOnce();
         \GPBMetadata\Google\Protobuf\Api::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 1 - 1
php/src/Google/Protobuf/NullValue.php

@@ -9,7 +9,7 @@ namespace Google\Protobuf;
  * `Value` type union.
  * `Value` type union.
  *  The JSON representation for `NullValue` is JSON `null`.
  *  The JSON representation for `NullValue` is JSON `null`.
  *
  *
- * Protobuf enum <code>Google\Protobuf\NullValue</code>
+ * Protobuf type <code>google.protobuf.NullValue</code>
  */
  */
 class NullValue
 class NullValue
 {
 {

+ 20 - 2
php/src/Google/Protobuf/Option.php

@@ -35,9 +35,27 @@ class Option extends \Google\Protobuf\Internal\Message
      */
      */
     private $value = null;
     private $value = null;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name
+     *           The option's name. For protobuf built-in options (options defined in
+     *           descriptor.proto), this is the short name. For example, `"map_entry"`.
+     *           For custom options, it should be the fully-qualified name. For example,
+     *           `"google.api.http"`.
+     *     @type \Google\Protobuf\Any $value
+     *           The option's value packed in an Any message. If the value is a primitive,
+     *           the corresponding wrapper type defined in google/protobuf/wrappers.proto
+     *           should be used. If the value is an enum, it should be stored as an int32
+     *           value using the google.protobuf.Int32Value type.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Type::initOnce();
         \GPBMetadata\Google\Protobuf\Type::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 13 - 2
php/src/Google/Protobuf/SourceContext.php

@@ -24,9 +24,20 @@ class SourceContext extends \Google\Protobuf\Internal\Message
      */
      */
     private $file_name = '';
     private $file_name = '';
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $file_name
+     *           The path-qualified name of the .proto file that contained the associated
+     *           protobuf element.  For example: `"google/protobuf/source_context.proto"`.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\SourceContext::initOnce();
         \GPBMetadata\Google\Protobuf\SourceContext::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 12 - 2
php/src/Google/Protobuf/StringValue.php

@@ -23,9 +23,19 @@ class StringValue extends \Google\Protobuf\Internal\Message
      */
      */
     private $value = '';
     private $value = '';
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $value
+     *           The string value.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 12 - 2
php/src/Google/Protobuf/Struct.php

@@ -28,9 +28,19 @@ class Struct extends \Google\Protobuf\Internal\Message
      */
      */
     private $fields;
     private $fields;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type array|\Google\Protobuf\Internal\MapField $fields
+     *           Unordered map of dynamically typed values.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Struct::initOnce();
         \GPBMetadata\Google\Protobuf\Struct::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 1 - 1
php/src/Google/Protobuf/Syntax.php

@@ -7,7 +7,7 @@ namespace Google\Protobuf;
 /**
 /**
  * The syntax in which a protocol buffer element is defined.
  * The syntax in which a protocol buffer element is defined.
  *
  *
- * Protobuf enum <code>Google\Protobuf\Syntax</code>
+ * Protobuf type <code>google.protobuf.Syntax</code>
  */
  */
 class Syntax
 class Syntax
 {
 {

+ 20 - 3
php/src/Google/Protobuf/Timestamp.php

@@ -89,9 +89,26 @@ class Timestamp extends \Google\Protobuf\Internal\Message
      */
      */
     private $nanos = 0;
     private $nanos = 0;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int|string $seconds
+     *           Represents seconds of UTC time since Unix epoch
+     *           1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
+     *           9999-12-31T23:59:59Z inclusive.
+     *     @type int $nanos
+     *           Non-negative fractions of a second at nanosecond resolution. Negative
+     *           second values with fractions must still have non-negative nanos values
+     *           that count forward in time. Must be from 0 to 999,999,999
+     *           inclusive.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Timestamp::initOnce();
         \GPBMetadata\Google\Protobuf\Timestamp::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**
@@ -156,7 +173,7 @@ class Timestamp extends \Google\Protobuf\Internal\Message
         return $this;
         return $this;
     }
     }
 
 
-    /**
+    /*
      * Converts PHP DateTime to Timestamp.
      * Converts PHP DateTime to Timestamp.
      *
      *
      * @param \DateTime $datetime
      * @param \DateTime $datetime

+ 22 - 2
php/src/Google/Protobuf/Type.php

@@ -52,9 +52,29 @@ class Type extends \Google\Protobuf\Internal\Message
      */
      */
     private $syntax = 0;
     private $syntax = 0;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name
+     *           The fully qualified message name.
+     *     @type \Google\Protobuf\Field[]|\Google\Protobuf\Internal\RepeatedField $fields
+     *           The list of fields.
+     *     @type string[]|\Google\Protobuf\Internal\RepeatedField $oneofs
+     *           The list of types appearing in `oneof` definitions in this type.
+     *     @type \Google\Protobuf\Option[]|\Google\Protobuf\Internal\RepeatedField $options
+     *           The protocol buffer options.
+     *     @type \Google\Protobuf\SourceContext $source_context
+     *           The source context.
+     *     @type int $syntax
+     *           The source syntax.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Type::initOnce();
         \GPBMetadata\Google\Protobuf\Type::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 12 - 2
php/src/Google/Protobuf/UInt32Value.php

@@ -23,9 +23,19 @@ class UInt32Value extends \Google\Protobuf\Internal\Message
      */
      */
     private $value = 0;
     private $value = 0;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int $value
+     *           The uint32 value.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 12 - 2
php/src/Google/Protobuf/UInt64Value.php

@@ -23,9 +23,19 @@ class UInt64Value extends \Google\Protobuf\Internal\Message
      */
      */
     private $value = 0;
     private $value = 0;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int|string $value
+     *           The uint64 value.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
         \GPBMetadata\Google\Protobuf\Wrappers::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 22 - 2
php/src/Google/Protobuf/Value.php

@@ -21,9 +21,29 @@ class Value extends \Google\Protobuf\Internal\Message
 {
 {
     protected $kind;
     protected $kind;
 
 
-    public function __construct() {
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int $null_value
+     *           Represents a null value.
+     *     @type float $number_value
+     *           Represents a double value.
+     *     @type string $string_value
+     *           Represents a string value.
+     *     @type bool $bool_value
+     *           Represents a boolean value.
+     *     @type \Google\Protobuf\Struct $struct_value
+     *           Represents a structured value.
+     *     @type \Google\Protobuf\ListValue $list_value
+     *           Represents a repeated `Value`.
+     * }
+     */
+    public function __construct($data = NULL) {
         \GPBMetadata\Google\Protobuf\Struct::initOnce();
         \GPBMetadata\Google\Protobuf\Struct::initOnce();
-        parent::__construct();
+        parent::__construct($data);
     }
     }
 
 
     /**
     /**

+ 6 - 6
php/tests/array_test.php

@@ -5,7 +5,7 @@ require_once('test_util.php');
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBType;
 use Foo\TestMessage;
 use Foo\TestMessage;
-use Foo\TestMessage_Sub;
+use Foo\TestMessage\Sub;
 
 
 class RepeatedFieldTest extends PHPUnit_Framework_TestCase
 class RepeatedFieldTest extends PHPUnit_Framework_TestCase
 {
 {
@@ -456,10 +456,10 @@ class RepeatedFieldTest extends PHPUnit_Framework_TestCase
 
 
     public function testMessage()
     public function testMessage()
     {
     {
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
+        $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
 
 
         // Test append.
         // Test append.
-        $sub_m = new TestMessage_Sub();
+        $sub_m = new Sub();
         $sub_m->setA(1);
         $sub_m->setA(1);
         $arr[] = $sub_m;
         $arr[] = $sub_m;
         $this->assertSame(1, $arr[0]->getA());
         $this->assertSame(1, $arr[0]->getA());
@@ -467,15 +467,15 @@ class RepeatedFieldTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(1, count($arr));
         $this->assertEquals(1, count($arr));
 
 
         // Test set.
         // Test set.
-        $sub_m = new TestMessage_Sub();
+        $sub_m = new Sub();
         $sub_m->setA(2);
         $sub_m->setA(2);
         $arr[0] = $sub_m;
         $arr[0] = $sub_m;
         $this->assertSame(2, $arr[0]->getA());
         $this->assertSame(2, $arr[0]->getA());
 
 
         // Test foreach.
         // Test foreach.
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
+        $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
         for ($i = 0; $i < 3; $i++) {
         for ($i = 0; $i < 3; $i++) {
-          $arr[] = new TestMessage_Sub();
+          $arr[] = new Sub();
           $arr[$i]->setA($i);
           $arr[$i]->setA($i);
         }
         }
         $i = 0;
         $i = 0;

+ 1 - 1
php/tests/descriptors_test.php

@@ -10,7 +10,7 @@ use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\MapField;
 use Google\Protobuf\Internal\MapField;
 use Descriptors\TestDescriptorsEnum;
 use Descriptors\TestDescriptorsEnum;
 use Descriptors\TestDescriptorsMessage;
 use Descriptors\TestDescriptorsMessage;
-use Descriptors\TestDescriptorsMessage_Sub;
+use Descriptors\TestDescriptorsMessage\Sub;
 
 
 class DescriptorsTest extends TestBase
 class DescriptorsTest extends TestBase
 {
 {

+ 3 - 3
php/tests/encode_decode_test.php

@@ -7,7 +7,7 @@ use Google\Protobuf\RepeatedField;
 use Google\Protobuf\GPBType;
 use Google\Protobuf\GPBType;
 use Foo\TestEnum;
 use Foo\TestEnum;
 use Foo\TestMessage;
 use Foo\TestMessage;
-use Foo\TestMessage_Sub;
+use Foo\TestMessage\Sub;
 use Foo\TestPackedMessage;
 use Foo\TestPackedMessage;
 use Foo\TestRandomFieldOrder;
 use Foo\TestRandomFieldOrder;
 use Foo\TestUnpackedMessage;
 use Foo\TestUnpackedMessage;
@@ -82,7 +82,7 @@ class EncodeDecodeTest extends TestBase
         $n->mergeFromString($data);
         $n->mergeFromString($data);
         $this->assertSame('abc', $n->getOneofString());
         $this->assertSame('abc', $n->getOneofString());
 
 
-        $sub_m = new TestMessage_Sub();
+        $sub_m = new Sub();
         $sub_m->setA(1);
         $sub_m->setA(1);
         $m->setOneofMessage($sub_m);
         $m->setOneofMessage($sub_m);
         $data = $m->serializeToString();
         $data = $m->serializeToString();
@@ -105,7 +105,7 @@ class EncodeDecodeTest extends TestBase
         $this->assertSame("oneof_string", $n->getMyOneof());
         $this->assertSame("oneof_string", $n->getMyOneof());
         $this->assertSame("", $n->getOneofString());
         $this->assertSame("", $n->getOneofString());
 
 
-        $sub_m = new TestMessage_Sub();
+        $sub_m = new Sub();
         $m->setOneofMessage($sub_m);
         $m->setOneofMessage($sub_m);
         $data = $m->serializeToString();
         $data = $m->serializeToString();
         $n = new TestMessage();
         $n = new TestMessage();

+ 2 - 2
php/tests/gdb_test.sh

@@ -11,8 +11,8 @@ php -i | grep "Configuration"
 # gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which
 # gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which
 # phpunit` --bootstrap autoload.php tmp_test.php
 # phpunit` --bootstrap autoload.php tmp_test.php
 #
 #
-# gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php encode_decode_test.php
+gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php generated_class_test.php
 #
 #
-gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php
+# gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php
 #
 #
 # USE_ZEND_ALLOC=0 valgrind --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php
 # USE_ZEND_ALLOC=0 valgrind --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php

+ 197 - 26
php/tests/generated_class_test.php

@@ -8,14 +8,20 @@ require_once('test_util.php');
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\MapField;
 use Google\Protobuf\Internal\MapField;
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBType;
+use Bar\TestLegacyMessage;
+use Bar\TestLegacyMessage_NestedEnum;
+use Bar\TestLegacyMessage_NestedMessage;
 use Foo\TestEnum;
 use Foo\TestEnum;
 use Foo\TestIncludeNamespaceMessage;
 use Foo\TestIncludeNamespaceMessage;
 use Foo\TestIncludePrefixMessage;
 use Foo\TestIncludePrefixMessage;
 use Foo\TestMessage;
 use Foo\TestMessage;
+use Foo\TestMessage\Sub;
 use Foo\TestMessage_Sub;
 use Foo\TestMessage_Sub;
+use Foo\TestMessage\NestedEnum;
 use Foo\TestReverseFieldOrder;
 use Foo\TestReverseFieldOrder;
 use Foo\testLowerCaseMessage;
 use Foo\testLowerCaseMessage;
 use Foo\testLowerCaseEnum;
 use Foo\testLowerCaseEnum;
+use PBEmpty\PBEcho\TestEmptyPackage;
 use Php\Test\TestNamespace;
 use Php\Test\TestNamespace;
 
 
 class GeneratedClassTest extends TestBase
 class GeneratedClassTest extends TestBase
@@ -229,11 +235,28 @@ class GeneratedClassTest extends TestBase
     }
     }
 
 
     public function testNestedEnum()
     public function testNestedEnum()
+    {
+        $m = new TestMessage();
+        $m->setOptionalNestedEnum(NestedEnum::ZERO);
+    }
+
+    public function testLegacyNestedEnum()
     {
     {
         $m = new TestMessage();
         $m = new TestMessage();
         $m->setOptionalNestedEnum(\Foo\TestMessage_NestedEnum::ZERO);
         $m->setOptionalNestedEnum(\Foo\TestMessage_NestedEnum::ZERO);
     }
     }
 
 
+    public function testLegacyTypehintWithNestedEnums()
+    {
+        $this->legacyEnum(new TestLegacyMessage\NestedEnum);
+    }
+
+    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.
     # Test float field.
     #########################################################
     #########################################################
@@ -370,6 +393,20 @@ class GeneratedClassTest extends TestBase
     {
     {
         $m = new TestMessage();
         $m = new TestMessage();
 
 
+        $sub_m = new 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 testLegacyMessageField()
+    {
+        $m = new TestMessage();
+
         $sub_m = new TestMessage_Sub();
         $sub_m = new TestMessage_Sub();
         $sub_m->setA(1);
         $sub_m->setA(1);
         $m->setOptionalMessage($sub_m);
         $m->setOptionalMessage($sub_m);
@@ -380,6 +417,17 @@ class GeneratedClassTest extends TestBase
         $this->assertNull($m->getOptionalMessage());
         $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.
     # Test repeated field.
     #########################################################
     #########################################################
@@ -474,7 +522,7 @@ class GeneratedClassTest extends TestBase
         $this->assertSame(NULL, $m->getOneofMessage());
         $this->assertSame(NULL, $m->getOneofMessage());
         $this->assertSame("oneof_string", $m->getMyOneof());
         $this->assertSame("oneof_string", $m->getMyOneof());
 
 
-        $sub_m = new TestMessage_Sub();
+        $sub_m = new Sub();
         $sub_m->setA(1);
         $sub_m->setA(1);
         $m->setOneofMessage($sub_m);
         $m->setOneofMessage($sub_m);
         $this->assertSame(0, $m->getOneofInt32());
         $this->assertSame(0, $m->getOneofInt32());
@@ -513,7 +561,7 @@ class GeneratedClassTest extends TestBase
 
 
         // Singular
         // Singular
         $n->setOptionalInt32(100);
         $n->setOptionalInt32(100);
-        $sub1 = new TestMessage_Sub();
+        $sub1 = new Sub();
         $sub1->setA(101);
         $sub1->setA(101);
 
 
         $b = $sub1->getB();
         $b = $sub1->getB();
@@ -531,7 +579,7 @@ class GeneratedClassTest extends TestBase
         $repeatedString[] = 'abc';
         $repeatedString[] = 'abc';
         $n->setRepeatedString($repeatedString);
         $n->setRepeatedString($repeatedString);
 
 
-        $sub2 = new TestMessage_Sub();
+        $sub2 = new Sub();
         $sub2->setA(201);
         $sub2->setA(201);
         $repeatedMessage = $n->getRepeatedMessage();
         $repeatedMessage = $n->getRepeatedMessage();
         $repeatedMessage[] = $sub2;
         $repeatedMessage[] = $sub2;
@@ -548,9 +596,9 @@ class GeneratedClassTest extends TestBase
         $n->setMapStringString($mapStringString);
         $n->setMapStringString($mapStringString);
 
 
         $mapInt32Message = $n->getMapInt32Message();
         $mapInt32Message = $n->getMapInt32Message();
-        $mapInt32Message[1] = new TestMessage_Sub();
+        $mapInt32Message[1] = new Sub();
         $mapInt32Message[1]->setA(302);
         $mapInt32Message[1]->setA(302);
-        $mapInt32Message[2] = new TestMessage_Sub();
+        $mapInt32Message[2] = new Sub();
         $mapInt32Message[2]->setA(303);
         $mapInt32Message[2]->setA(303);
         $n->setMapInt32Message($mapInt32Message);
         $n->setMapInt32Message($mapInt32Message);
 
 
@@ -607,7 +655,7 @@ class GeneratedClassTest extends TestBase
         $m->mergeFrom($n);
         $m->mergeFrom($n);
         $this->assertSame(1, $m->getOneofInt32());
         $this->assertSame(1, $m->getOneofInt32());
 
 
-        $sub = new TestMessage_Sub();
+        $sub = new Sub();
         $n->setOneofMessage($sub);
         $n->setOneofMessage($sub);
         $n->getOneofMessage()->setA(400);
         $n->getOneofMessage()->setA(400);
         $m->mergeFrom($n);
         $m->mergeFrom($n);
@@ -630,14 +678,15 @@ class GeneratedClassTest extends TestBase
     public function testMessageWithoutNamespace()
     public function testMessageWithoutNamespace()
     {
     {
         $m = new TestMessage();
         $m = new TestMessage();
-        $sub = new NoNameSpaceMessage();
-        $m->setOptionalNoNamespaceMessage($sub);
+        $n = new NoNameSpaceMessage();
+        $m->setOptionalNoNamespaceMessage($n);
         $repeatedNoNamespaceMessage = $m->getRepeatedNoNamespaceMessage();
         $repeatedNoNamespaceMessage = $m->getRepeatedNoNamespaceMessage();
         $repeatedNoNamespaceMessage[] = new NoNameSpaceMessage();
         $repeatedNoNamespaceMessage[] = new NoNameSpaceMessage();
         $m->setRepeatedNoNamespaceMessage($repeatedNoNamespaceMessage);
         $m->setRepeatedNoNamespaceMessage($repeatedNoNamespaceMessage);
 
 
-        $n = new NoNamespaceMessage();
-        $n->setB(NoNamespaceMessage_NestedEnum::ZERO);
+        // test nested messages
+        $sub = new NoNamespaceMessage\NestedMessage();
+        $n->setNestedMessage($sub);
     }
     }
 
 
     public function testEnumWithoutNamespace()
     public function testEnumWithoutNamespace()
@@ -650,35 +699,91 @@ class GeneratedClassTest extends TestBase
     }
     }
 
 
     #########################################################
     #########################################################
-    # Test message with given prefix.
+    # Test message with given namespace.
     #########################################################
     #########################################################
 
 
-    public function testPrefixMessage()
+    public function testNestedMessagesAndEnums()
     {
     {
+        $m = new TestMessage();
+        $n = new TestMessage\Sub();
+        $m->setOptionalMessage($n);
+        $m->setOptionalNestedEnum(TestMessage\NestedEnum::ZERO);
+        $this->assertSame($n, $m->getOptionalMessage());
+        $this->assertSame(TestMessage\NestedEnum::ZERO, $m->getOptionalNestedEnum());
+    }
+
+    public function testMessagesAndEnumsWithPrefix()
+    {
+        // Test message prefix
         $m = new TestIncludePrefixMessage();
         $m = new TestIncludePrefixMessage();
         $n = new PrefixTestPrefix();
         $n = new PrefixTestPrefix();
         $n->setA(1);
         $n->setA(1);
         $m->setPrefixMessage($n);
         $m->setPrefixMessage($n);
         $this->assertSame(1, $m->getPrefixMessage()->getA());
         $this->assertSame(1, $m->getPrefixMessage()->getA());
+
+        // Test nested message prefix
+        $o = new PrefixTestPrefix();
+        $p = new PrefixTestPrefix\PrefixNestedMessage();
+        $o->setNestedMessage($p);
+        $o->setNestedEnum(PrefixTestPrefix\PrefixNestedEnum::ZERO);
+        $this->assertSame($p, $o->getNestedMessage());
+        $this->assertSame(PrefixTestPrefix\PrefixNestedEnum::ZERO, $o->getNestedEnum());
     }
     }
 
 
-    #########################################################
-    # Test message with given namespace.
-    #########################################################
+    public function testMessagesAndEnumsWithPhpNamespace()
+    {
+        $m = new TestNamespace();
+        $n = new TestNamespace\NestedMessage();
+        $m->setNestedMessage($n);
+        $m->setNestedEnum(TestNamespace\NestedEnum::ZERO);
+        $this->assertSame($n, $m->getNestedMessage());
+        $this->assertSame(TestNamespace\NestedEnum::ZERO, $m->getNestedEnum());
+    }
 
 
-    public function testNamespaceMessage()
+    public function testMesssagesAndEnumsWithEmptyPhpNamespace()
     {
     {
-        $m = new TestIncludeNamespaceMessage();
+        $m = new TestEmptyNamespace();
+        $n = new TestEmptyNamespace\NestedMessage();
+        $m->setNestedMessage($n);
+        $m->setNestedEnum(TestEmptyNamespace\NestedEnum::ZERO);
+        $this->assertSame($n, $m->getNestedMessage());
+        $this->assertSame(TestEmptyNamespace\NestedEnum::ZERO, $m->getNestedEnum());
+    }
 
 
-        $n = new TestNamespace();
-        $n->setA(1);
-        $m->setNamespaceMessage($n);
-        $this->assertSame(1, $m->getNamespaceMessage()->getA());
+    public function testMessagesAndEnumsWithNoNamespace()
+    {
+        $m = new NoNamespaceMessage();
+        $n = new NoNamespaceMessage\NestedMessage();
+        $m->setNestedMessage($n);
+        $m->setNestedEnum(NoNamespaceMessage\NestedEnum::ZERO);
+        $this->assertSame($n, $m->getNestedMessage());
+        $this->assertSame(NoNamespaceMessage\NestedEnum::ZERO, $m->getNestedEnum());
+    }
 
 
-        $n = new TestEmptyNamespace();
-        $n->setA(1);
-        $m->setEmptyNamespaceMessage($n);
-        $this->assertSame(1, $m->getEmptyNamespaceMessage()->getA());
+    public function testReservedWordsInPackageName()
+    {
+        $m = new TestEmptyPackage();
+        $n = new TestEmptyPackage\NestedMessage();
+        $m->setNestedMessage($n);
+        $m->setNestedEnum(TestEmptyPackage\NestedEnum::ZERO);
+        $this->assertSame($n, $m->getNestedMessage());
+        $this->assertSame(TestEmptyPackage\NestedEnum::ZERO, $m->getNestedEnum());
+    }
+
+    public function testReservedWordsInNamespace()
+    {
+        $m = new TestNamespace();
+        $n = new TestNamespace\PBEmpty();
+        $o = new TestNamespace\PBEmpty\NestedMessage();
+        $n->setNestedMessage($o);
+        $n->setNestedEnum(TestNamespace\PBEmpty\NestedEnum::ZERO);
+        $m->setReservedName($n);
+        $this->assertSame($n, $m->getReservedName());
+        $this->assertSame($o, $n->getNestedMessage());
+        $this->assertSame(
+            TestNamespace\PBEmpty\NestedEnum::ZERO,
+            $n->getNestedEnum()
+        );
     }
     }
 
 
     #########################################################
     #########################################################
@@ -687,7 +792,7 @@ class GeneratedClassTest extends TestBase
 
 
     public function testPrefixForReservedWords()
     public function testPrefixForReservedWords()
     {
     {
-        $m = new \Foo\TestMessage_Empty();
+        $m = new \Foo\TestMessage\PBEmpty();
         $m = new \Foo\PBEmpty();
         $m = new \Foo\PBEmpty();
         $m = new \PrefixEmpty();
         $m = new \PrefixEmpty();
         $m = new \Foo\PBARRAY();
         $m = new \Foo\PBARRAY();
@@ -1171,4 +1276,70 @@ class GeneratedClassTest extends TestBase
         $m = new testLowerCaseMessage();
         $m = new testLowerCaseMessage();
         $n = testLowerCaseEnum::VALUE;
         $n = testLowerCaseEnum::VALUE;
     }
     }
+
+    #########################################################
+    # Test Array Constructor.
+    #########################################################
+
+    public function testArrayConstructor()
+    {
+        $m = new TestMessage([
+            'optional_int32' => -42,
+            'optional_int64' => -43,
+            'optional_uint32' => 42,
+            'optional_uint64' => 43,
+            'optional_sint32' => -44,
+            'optional_sint64' => -45,
+            'optional_fixed32' => 46,
+            'optional_fixed64' => 47,
+            'optional_sfixed32' => -46,
+            'optional_sfixed64' => -47,
+            'optional_float' => 1.5,
+            'optional_double' => 1.6,
+            'optional_bool' => true,
+            'optional_string' => 'a',
+            'optional_bytes' => 'b',
+            'optional_enum' => TestEnum::ONE,
+            'optional_message' => new Sub([
+                'a' => 33
+            ]),
+            'repeated_int32' => [-42, -52],
+            'repeated_int64' => [-43, -53],
+            'repeated_uint32' => [42, 52],
+            'repeated_uint64' => [43, 53],
+            'repeated_sint32' => [-44, -54],
+            'repeated_sint64' => [-45, -55],
+            'repeated_fixed32' => [46, 56],
+            'repeated_fixed64' => [47, 57],
+            'repeated_sfixed32' => [-46, -56],
+            'repeated_sfixed64' => [-47, -57],
+            'repeated_float' => [1.5, 2.5],
+            'repeated_double' => [1.6, 2.6],
+            'repeated_bool' => [true, false],
+            'repeated_string' => ['a', 'c'],
+            'repeated_bytes' => ['b', 'd'],
+            'repeated_enum' => [TestEnum::ZERO, TestEnum::ONE],
+            'repeated_message' => [new Sub(['a' => 34]),
+                                   new Sub(['a' => 35])],
+            'map_int32_int32' => [-62 => -62],
+            'map_int64_int64' => [-63 => -63],
+            'map_uint32_uint32' => [62 => 62],
+            'map_uint64_uint64' => [63 => 63],
+            'map_sint32_sint32' => [-64 => -64],
+            'map_sint64_sint64' => [-65 => -65],
+            'map_fixed32_fixed32' => [66 => 66],
+            'map_fixed64_fixed64' => [67 => 67],
+            'map_sfixed32_sfixed32' => [-68 => -68],
+            'map_sfixed64_sfixed64' => [-69 => -69],
+            'map_int32_float' => [1 => 3.5],
+            'map_int32_double' => [1 => 3.6],
+            'map_bool_bool' => [true => true],
+            'map_string_string' => ['e' => 'e'],
+            'map_int32_bytes' => [1 => 'f'],
+            'map_int32_enum' => [1 => TestEnum::ONE],
+            'map_int32_message' => [1 => new Sub(['a' => 36])],
+        ]);
+
+        TestUtil::assertTestMessage($m);
+    }
 }
 }

+ 11 - 3
php/tests/generated_phpdoc_test.php

@@ -16,6 +16,14 @@ class GeneratedPhpdocTest extends TestBase
         $this->assertContains('foo.TestMessage', $doc);
         $this->assertContains('foo.TestMessage', $doc);
     }
     }
 
 
+    public function testPhpDocForConstructor()
+    {
+        $class = new ReflectionClass('Foo\TestMessage');
+        $doc = $class->getMethod('__construct')->getDocComment();
+        $this->assertContains('@param array $data', $doc);
+        $this->assertContains('@type int $optional_int32', $doc);
+    }
+
     /**
     /**
      * @dataProvider providePhpDocForGettersAndSetters
      * @dataProvider providePhpDocForGettersAndSetters
      */
      */
@@ -193,7 +201,7 @@ class GeneratedPhpdocTest extends TestBase
                 [
                 [
                     'setRepeatedMessage',
                     'setRepeatedMessage',
                 ],
                 ],
-                '@param \Foo\TestMessage_Sub[]|\Google\Protobuf\Internal\RepeatedField $var'
+                '@param \Foo\TestMessage\Sub[]|\Google\Protobuf\Internal\RepeatedField $var'
             ],
             ],
             [
             [
                 [
                 [
@@ -286,14 +294,14 @@ class GeneratedPhpdocTest extends TestBase
                     'getOptionalMessage',
                     'getOptionalMessage',
                     'getOneofMessage'
                     'getOneofMessage'
                 ],
                 ],
-                '@return \Foo\TestMessage_Sub'
+                '@return \Foo\TestMessage\Sub'
             ],
             ],
             [
             [
                 [
                 [
                     'setOptionalMessage',
                     'setOptionalMessage',
                     'setOneofMessage'
                     'setOneofMessage'
                 ],
                 ],
-                '@param \Foo\TestMessage_Sub $var'
+                '@param \Foo\TestMessage\Sub $var'
             ],
             ],
             [
             [
                 [
                 [

+ 5 - 5
php/tests/map_field_test.php

@@ -5,7 +5,7 @@ require_once('test_util.php');
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\MapField;
 use Google\Protobuf\Internal\MapField;
 use Foo\TestMessage;
 use Foo\TestMessage;
-use Foo\TestMessage_Sub;
+use Foo\TestMessage\Sub;
 
 
 class MapFieldTest extends PHPUnit_Framework_TestCase {
 class MapFieldTest extends PHPUnit_Framework_TestCase {
 
 
@@ -408,10 +408,10 @@ class MapFieldTest extends PHPUnit_Framework_TestCase {
 
 
     public function testMessage() {
     public function testMessage() {
         $arr = new MapField(GPBType::INT32,
         $arr = new MapField(GPBType::INT32,
-            GPBType::MESSAGE, TestMessage_Sub::class);
+            GPBType::MESSAGE, Sub::class);
 
 
         // Test append.
         // Test append.
-        $sub_m = new TestMessage_Sub();
+        $sub_m = new Sub();
         $sub_m->setA(1);
         $sub_m->setA(1);
         $arr[0] = $sub_m;
         $arr[0] = $sub_m;
         $this->assertSame(1, $arr[0]->getA());
         $this->assertSame(1, $arr[0]->getA());
@@ -420,9 +420,9 @@ class MapFieldTest extends PHPUnit_Framework_TestCase {
 
 
         // Test foreach.
         // Test foreach.
         $arr = new MapField(GPBType::INT32,
         $arr = new MapField(GPBType::INT32,
-            GPBType::MESSAGE, TestMessage_Sub::class);
+            GPBType::MESSAGE, Sub::class);
         for ($i = 0; $i < 3; $i++) {
         for ($i = 0; $i < 3; $i++) {
-          $arr[$i] = new TestMessage_Sub();;
+          $arr[$i] = new Sub();;
           $arr[$i]->setA($i);
           $arr[$i]->setA($i);
         }
         }
         $i = 0;
         $i = 0;

+ 5 - 5
php/tests/memory_leak_test.php

@@ -15,9 +15,9 @@ require_once('generated/Foo/TestEnum.php');
 require_once('generated/Foo/TestIncludeNamespaceMessage.php');
 require_once('generated/Foo/TestIncludeNamespaceMessage.php');
 require_once('generated/Foo/TestIncludePrefixMessage.php');
 require_once('generated/Foo/TestIncludePrefixMessage.php');
 require_once('generated/Foo/TestMessage.php');
 require_once('generated/Foo/TestMessage.php');
-require_once('generated/Foo/TestMessage_Empty.php');
-require_once('generated/Foo/TestMessage_NestedEnum.php');
-require_once('generated/Foo/TestMessage_Sub.php');
+require_once('generated/Foo/TestMessage/PBEmpty.php');
+require_once('generated/Foo/TestMessage/NestedEnum.php');
+require_once('generated/Foo/TestMessage/Sub.php');
 require_once('generated/Foo/TestPackedMessage.php');
 require_once('generated/Foo/TestPackedMessage.php');
 require_once('generated/Foo/TestPhpDoc.php');
 require_once('generated/Foo/TestPhpDoc.php');
 require_once('generated/Foo/TestRandomFieldOrder.php');
 require_once('generated/Foo/TestRandomFieldOrder.php');
@@ -37,7 +37,7 @@ require_once('test_util.php');
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBType;
 use Foo\TestMessage;
 use Foo\TestMessage;
-use Foo\TestMessage_Sub;
+use Foo\TestMessage\Sub;
 
 
 $from = new TestMessage();
 $from = new TestMessage();
 TestUtil::setTestMessage($from);
 TestUtil::setTestMessage($from);
@@ -97,7 +97,7 @@ $n = new TestMessage();
 $n->mergeFromString($data);
 $n->mergeFromString($data);
 assert('abc' === $n->getOneofString());
 assert('abc' === $n->getOneofString());
 
 
-$sub_m = new TestMessage_Sub();
+$sub_m = new Sub();
 $sub_m->setA(1);
 $sub_m->setA(1);
 $m->setOneofMessage($sub_m);
 $m->setOneofMessage($sub_m);
 assert(0 === $m->getOneofInt32());
 assert(0 === $m->getOneofInt32());

+ 73 - 2
php/tests/php_implementation_test.php

@@ -3,8 +3,9 @@
 require_once('test_base.php');
 require_once('test_base.php');
 require_once('test_util.php');
 require_once('test_util.php');
 
 
+use Foo\TestEnum;
 use Foo\TestMessage;
 use Foo\TestMessage;
-use Foo\TestMessage_Sub;
+use Foo\TestMessage\Sub;
 use Foo\TestPackedMessage;
 use Foo\TestPackedMessage;
 use Google\Protobuf\Internal\CodedInputStream;
 use Google\Protobuf\Internal\CodedInputStream;
 use Google\Protobuf\Internal\FileDescriptorSet;
 use Google\Protobuf\Internal\FileDescriptorSet;
@@ -15,7 +16,6 @@ use Google\Protobuf\Internal\CodedOutputStream;
 
 
 class ImplementationTest extends TestBase
 class ImplementationTest extends TestBase
 {
 {
-
     public function testReadInt32()
     public function testReadInt32()
     {
     {
         $value = null;
         $value = null;
@@ -513,4 +513,75 @@ class ImplementationTest extends TestBase
         TestUtil::setTestPackedMessage($m);
         TestUtil::setTestPackedMessage($m);
         $this->assertSame(166, $m->byteSize());
         $this->assertSame(166, $m->byteSize());
     }
     }
+
+    /**
+     * @expectedException UnexpectedValueException
+     * @expectedExceptionMessage Invalid message property: optionalInt32
+     */
+    public function testArrayConstructorJsonCaseThrowsException()
+    {
+        $m = new TestMessage([
+            'optionalInt32' => -42,
+        ]);
+    }
+
+    /**
+     * @expectedException Exception
+     * @expectedExceptionMessage Expect Foo\TestMessage_Sub.
+     */
+    public function testArraysForMessagesThrowsException()
+    {
+        $m = new TestMessage([
+            'optional_message' => [
+                'a' => 33
+            ]
+        ]);
+    }
+
+    public function testArrayConstructorWithNullValues()
+    {
+        $requestData = [
+            'optional_bool' => null,
+            'optional_string' => null,
+            'optional_bytes' => null,
+            'optional_message' => null,
+        ];
+
+        $m = new TestMessage($requestData);
+
+        $this->assertSame(false, $m->getOptionalBool());
+        $this->assertSame('', $m->getOptionalString());
+        $this->assertSame('', $m->getOptionalBytes());
+        $this->assertSame(null, $m->getOptionalMessage());
+    }
+
+    /**
+     * @dataProvider provideArrayConstructorWithNullValuesThrowsException
+     * @expectedException Exception
+     */
+    public function testArrayConstructorWithNullValuesThrowsException($requestData)
+    {
+        $m = new TestMessage($requestData);
+    }
+
+    public function provideArrayConstructorWithNullValuesThrowsException()
+    {
+        return [
+            [['optional_int32' => null]],
+            [['optional_int64' => null]],
+            [['optional_uint32' => null]],
+            [['optional_uint64' => null]],
+            [['optional_sint32' => null]],
+            [['optional_sint64' => null]],
+            [['optional_fixed32' => null]],
+            [['optional_fixed64' => null]],
+            [['optional_sfixed32' => null]],
+            [['optional_sfixed64' => null]],
+            [['optional_float' => null]],
+            [['optional_double' => null]],
+            [['optional_enum' => null]],
+            [['repeated_int32' => null]],
+            [['map_int32_int32' => null]],
+        ];
+    }
 }
 }

+ 17 - 0
php/tests/proto/empty/echo.proto

@@ -0,0 +1,17 @@
+syntax = "proto3";
+
+package empty.echo;
+
+message TestEmptyPackage {
+  int32 a = 1;
+
+  // Test nested messages, enums, and reserved names
+  NestedMessage nested_message = 2;
+  NestedEnum nested_enum = 3;
+  message NestedMessage {
+    int32 a = 1;
+  }
+  enum NestedEnum {
+      ZERO = 0;
+  };
+}

+ 11 - 0
php/tests/proto/test_empty_php_namespace.proto

@@ -2,7 +2,18 @@ syntax = "proto3";
 
 
 package foo;
 package foo;
 option php_namespace = "";
 option php_namespace = "";
+option php_metadata_namespace = "";
 
 
 message TestEmptyNamespace {
 message TestEmptyNamespace {
   int32 a = 1;
   int32 a = 1;
+
+  // Test nested messages, enums, and reserved names
+  NestedMessage nested_message = 2;
+  NestedEnum nested_enum = 3;
+  message NestedMessage {
+    int32 a = 1;
+  }
+  enum NestedEnum {
+      ZERO = 0;
+  };
 }
 }

+ 11 - 0
php/tests/proto/test_include.proto

@@ -5,3 +5,14 @@ package bar;
 message TestInclude {
 message TestInclude {
   int32 a = 1;
   int32 a = 1;
 }
 }
+
+message TestLegacyMessage {
+  NestedMessage message = 1;
+  NestedEnum enum = 2;
+  message NestedMessage {
+    int32 a = 1;
+  }
+  enum NestedEnum {
+    ZERO = 0;
+  }
+}

+ 10 - 4
php/tests/proto/test_no_namespace.proto

@@ -1,13 +1,19 @@
 syntax = "proto3";
 syntax = "proto3";
 
 
+option php_metadata_namespace = "\\";
+
 message NoNamespaceMessage {
 message NoNamespaceMessage {
   int32 a = 1;
   int32 a = 1;
 
 
-  enum NestedEnum {
-    ZERO = 0;
+  // Test nested messages, enums, and reserved names
+  NestedMessage nested_message = 2;
+  NestedEnum nested_enum = 3;
+  message NestedMessage {
+    int32 a = 1;
   }
   }
-  NestedEnum b = 2;
-  repeated NestedEnum c = 3;
+  enum NestedEnum {
+      ZERO = 0;
+  };
 }
 }
 
 
 enum NoNamespaceEnum {
 enum NoNamespaceEnum {

+ 23 - 0
php/tests/proto/test_php_namespace.proto

@@ -2,7 +2,30 @@ syntax = "proto3";
 
 
 package foo;
 package foo;
 option php_namespace = "Php\\Test";
 option php_namespace = "Php\\Test";
+option php_metadata_namespace = "Metadata\\Php\\Test";
 
 
 message TestNamespace {
 message TestNamespace {
   int32 a = 1;
   int32 a = 1;
+
+  // Test nested messages, enums, and reserved names
+  NestedMessage nested_message = 2;
+  NestedEnum nested_enum = 3;
+  Empty reserved_name = 4;
+  message NestedMessage {
+    int32 a = 1;
+  }
+  enum NestedEnum {
+      ZERO = 0;
+  };
+  // Test reserved name
+  message Empty {
+    NestedMessage nested_message = 1;
+    NestedEnum nested_enum = 2;
+    message NestedMessage {
+      int32 a = 1;
+    }
+    enum NestedEnum {
+      ZERO = 0;
+    };
+  }
 }
 }

+ 8 - 0
php/tests/proto/test_prefix.proto

@@ -4,6 +4,14 @@ option php_class_prefix = "Prefix";
 
 
 message TestPrefix {
 message TestPrefix {
   int32 a = 1;
   int32 a = 1;
+  NestedMessage nested_message = 2;
+  NestedEnum nested_enum = 3;
+  message NestedMessage {
+    int32 a = 1;
+  }
+  enum NestedEnum {
+      ZERO = 0;
+  };
 }
 }
 
 
 // Test prefix for reserved words.
 // Test prefix for reserved words.

+ 1 - 1
php/tests/test_base.php

@@ -2,7 +2,7 @@
 
 
 use Foo\TestMessage;
 use Foo\TestMessage;
 use Foo\TestEnum;
 use Foo\TestEnum;
-use Foo\TestMessage_Sub;
+use Foo\TestMessage\Sub;
 
 
 class TestBase extends PHPUnit_Framework_TestCase
 class TestBase extends PHPUnit_Framework_TestCase
 {
 {

+ 9 - 9
php/tests/test_util.php

@@ -2,7 +2,7 @@
 
 
 use Foo\TestEnum;
 use Foo\TestEnum;
 use Foo\TestMessage;
 use Foo\TestMessage;
-use Foo\TestMessage_Sub;
+use Foo\TestMessage\Sub;
 use Foo\TestPackedMessage;
 use Foo\TestPackedMessage;
 use Foo\TestUnpackedMessage;
 use Foo\TestUnpackedMessage;
 
 
@@ -67,7 +67,7 @@ class TestUtil
         $m->setOptionalString('a');
         $m->setOptionalString('a');
         $m->setOptionalBytes('b');
         $m->setOptionalBytes('b');
         $m->setOptionalEnum(TestEnum::ONE);
         $m->setOptionalEnum(TestEnum::ONE);
-        $sub = new TestMessage_Sub();
+        $sub = new Sub();
         $m->setOptionalMessage($sub);
         $m->setOptionalMessage($sub);
         $m->getOptionalMessage()->SetA(33);
         $m->getOptionalMessage()->SetA(33);
 
 
@@ -87,7 +87,7 @@ class TestUtil
         self::appendHelper($m, 'RepeatedString',   'a');
         self::appendHelper($m, 'RepeatedString',   'a');
         self::appendHelper($m, 'RepeatedBytes',    'b');
         self::appendHelper($m, 'RepeatedBytes',    'b');
         self::appendHelper($m, 'RepeatedEnum',     TestEnum::ZERO);
         self::appendHelper($m, 'RepeatedEnum',     TestEnum::ZERO);
-        self::appendHelper($m, 'RepeatedMessage',  new TestMessage_Sub());
+        self::appendHelper($m, 'RepeatedMessage',  new Sub());
         $m->getRepeatedMessage()[0]->setA(34);
         $m->getRepeatedMessage()[0]->setA(34);
 
 
         self::appendHelper($m, 'RepeatedInt32',    -52);
         self::appendHelper($m, 'RepeatedInt32',    -52);
@@ -106,7 +106,7 @@ class TestUtil
         self::appendHelper($m, 'RepeatedString',   'c');
         self::appendHelper($m, 'RepeatedString',   'c');
         self::appendHelper($m, 'RepeatedBytes',    'd');
         self::appendHelper($m, 'RepeatedBytes',    'd');
         self::appendHelper($m, 'RepeatedEnum',     TestEnum::ONE);
         self::appendHelper($m, 'RepeatedEnum',     TestEnum::ONE);
-        self::appendHelper($m, 'RepeatedMessage',  new TestMessage_Sub());
+        self::appendHelper($m, 'RepeatedMessage',  new Sub());
         $m->getRepeatedMessage()[1]->SetA(35);
         $m->getRepeatedMessage()[1]->SetA(35);
 
 
         self::kvUpdateHelper($m, 'MapInt32Int32', -62, -62);
         self::kvUpdateHelper($m, 'MapInt32Int32', -62, -62);
@@ -125,13 +125,13 @@ class TestUtil
         self::kvUpdateHelper($m, 'MapStringString', 'e', 'e');
         self::kvUpdateHelper($m, 'MapStringString', 'e', 'e');
         self::kvUpdateHelper($m, 'MapInt32Bytes', 1, 'f');
         self::kvUpdateHelper($m, 'MapInt32Bytes', 1, 'f');
         self::kvUpdateHelper($m, 'MapInt32Enum', 1, TestEnum::ONE);
         self::kvUpdateHelper($m, 'MapInt32Enum', 1, TestEnum::ONE);
-        self::kvUpdateHelper($m, 'MapInt32Message', 1, new TestMessage_Sub());
+        self::kvUpdateHelper($m, 'MapInt32Message', 1, new Sub());
         $m->getMapInt32Message()[1]->SetA(36);
         $m->getMapInt32Message()[1]->SetA(36);
     }
     }
 
 
     public static function setTestMessage2(TestMessage $m)
     public static function setTestMessage2(TestMessage $m)
     {
     {
-        $sub = new TestMessage_Sub();
+        $sub = new Sub();
 
 
         $m->setOptionalInt32(-142);
         $m->setOptionalInt32(-142);
         $m->setOptionalInt64(-143);
         $m->setOptionalInt64(-143);
@@ -168,7 +168,7 @@ class TestUtil
         self::appendHelper($m, 'RepeatedString',   'aa');
         self::appendHelper($m, 'RepeatedString',   'aa');
         self::appendHelper($m, 'RepeatedBytes',    'bb');
         self::appendHelper($m, 'RepeatedBytes',    'bb');
         self::appendHelper($m, 'RepeatedEnum',     TestEnum::TWO);
         self::appendHelper($m, 'RepeatedEnum',     TestEnum::TWO);
-        self::appendHelper($m, 'RepeatedMessage',  new TestMessage_Sub());
+        self::appendHelper($m, 'RepeatedMessage',  new Sub());
         $m->getRepeatedMessage()[0]->setA(134);
         $m->getRepeatedMessage()[0]->setA(134);
 
 
         self::kvUpdateHelper($m, 'MapInt32Int32', -62, -162);
         self::kvUpdateHelper($m, 'MapInt32Int32', -62, -162);
@@ -187,7 +187,7 @@ class TestUtil
         self::kvUpdateHelper($m, 'MapStringString', 'e', 'ee');
         self::kvUpdateHelper($m, 'MapStringString', 'e', 'ee');
         self::kvUpdateHelper($m, 'MapInt32Bytes', 1, 'ff');
         self::kvUpdateHelper($m, 'MapInt32Bytes', 1, 'ff');
         self::kvUpdateHelper($m, 'MapInt32Enum', 1, TestEnum::TWO);
         self::kvUpdateHelper($m, 'MapInt32Enum', 1, TestEnum::TWO);
-        self::kvUpdateHelper($m, 'MapInt32Message', 1, new TestMessage_Sub());
+        self::kvUpdateHelper($m, 'MapInt32Message', 1, new Sub());
         $m->getMapInt32Message()[1]->SetA(136);
         $m->getMapInt32Message()[1]->SetA(136);
 
 
         self::kvUpdateHelper($m, 'MapInt32Int32', -162, -162);
         self::kvUpdateHelper($m, 'MapInt32Int32', -162, -162);
@@ -206,7 +206,7 @@ class TestUtil
         self::kvUpdateHelper($m, 'MapStringString', 'ee', 'ee');
         self::kvUpdateHelper($m, 'MapStringString', 'ee', 'ee');
         self::kvUpdateHelper($m, 'MapInt32Bytes', 2, 'ff');
         self::kvUpdateHelper($m, 'MapInt32Bytes', 2, 'ff');
         self::kvUpdateHelper($m, 'MapInt32Enum', 2, TestEnum::TWO);
         self::kvUpdateHelper($m, 'MapInt32Enum', 2, TestEnum::TWO);
-        self::kvUpdateHelper($m, 'MapInt32Message', 2, new TestMessage_Sub());
+        self::kvUpdateHelper($m, 'MapInt32Message', 2, new Sub());
         $m->getMapInt32Message()[2]->SetA(136);
         $m->getMapInt32Message()[2]->SetA(136);
     }
     }
 
 

+ 43 - 43
php/tests/undefined_test.php

@@ -5,7 +5,7 @@ require_once('test_util.php');
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBType;
 use Foo\TestMessage;
 use Foo\TestMessage;
-use Foo\TestMessage_Sub;
+use Foo\TestMessage\Sub;
 
 
 class UndefinedTest extends PHPUnit_Framework_TestCase
 class UndefinedTest extends PHPUnit_Framework_TestCase
 {
 {
@@ -35,7 +35,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testInt32AppendMessageFail()
     public function testInt32AppendMessageFail()
     {
     {
         $arr = new RepeatedField(GPBType::INT32);
         $arr = new RepeatedField(GPBType::INT32);
-        $arr[] = new TestMessage_Sub();
+        $arr[] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -45,7 +45,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     {
     {
         $arr = new RepeatedField(GPBType::INT32);
         $arr = new RepeatedField(GPBType::INT32);
         $arr[] = 0;
         $arr[] = 0;
-        $arr[0] = new TestMessage_Sub();
+        $arr[0] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -73,7 +73,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testUint32AppendMessageFail()
     public function testUint32AppendMessageFail()
     {
     {
         $arr = new RepeatedField(GPBType::UINT32);
         $arr = new RepeatedField(GPBType::UINT32);
-        $arr[] = new TestMessage_Sub();
+        $arr[] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -83,7 +83,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     {
     {
         $arr = new RepeatedField(GPBType::UINT32);
         $arr = new RepeatedField(GPBType::UINT32);
         $arr[] = 0;
         $arr[] = 0;
-        $arr[0] = new TestMessage_Sub();
+        $arr[0] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -111,7 +111,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testInt64AppendMessageFail()
     public function testInt64AppendMessageFail()
     {
     {
         $arr = new RepeatedField(GPBType::INT64);
         $arr = new RepeatedField(GPBType::INT64);
-        $arr[] = new TestMessage_Sub();
+        $arr[] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -121,7 +121,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     {
     {
         $arr = new RepeatedField(GPBType::INT64);
         $arr = new RepeatedField(GPBType::INT64);
         $arr[] = 0;
         $arr[] = 0;
-        $arr[0] = new TestMessage_Sub();
+        $arr[0] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -149,7 +149,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testUint64AppendMessageFail()
     public function testUint64AppendMessageFail()
     {
     {
         $arr = new RepeatedField(GPBType::UINT64);
         $arr = new RepeatedField(GPBType::UINT64);
-        $arr[] = new TestMessage_Sub();
+        $arr[] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -159,7 +159,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     {
     {
         $arr = new RepeatedField(GPBType::UINT64);
         $arr = new RepeatedField(GPBType::UINT64);
         $arr[] = 0;
         $arr[] = 0;
-        $arr[0] = new TestMessage_Sub();
+        $arr[0] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -187,7 +187,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testFloatAppendMessageFail()
     public function testFloatAppendMessageFail()
     {
     {
         $arr = new RepeatedField(GPBType::FLOAT);
         $arr = new RepeatedField(GPBType::FLOAT);
-        $arr[] = new TestMessage_Sub();
+        $arr[] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -197,7 +197,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     {
     {
         $arr = new RepeatedField(GPBType::FLOAT);
         $arr = new RepeatedField(GPBType::FLOAT);
         $arr[] = 0.0;
         $arr[] = 0.0;
-        $arr[0] = new TestMessage_Sub();
+        $arr[0] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -225,7 +225,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testDoubleAppendMessageFail()
     public function testDoubleAppendMessageFail()
     {
     {
         $arr = new RepeatedField(GPBType::DOUBLE);
         $arr = new RepeatedField(GPBType::DOUBLE);
-        $arr[] = new TestMessage_Sub();
+        $arr[] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -235,7 +235,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     {
     {
         $arr = new RepeatedField(GPBType::DOUBLE);
         $arr = new RepeatedField(GPBType::DOUBLE);
         $arr[] = 0.0;
         $arr[] = 0.0;
-        $arr[0] = new TestMessage_Sub();
+        $arr[0] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -244,7 +244,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testBoolAppendMessageFail()
     public function testBoolAppendMessageFail()
     {
     {
         $arr = new RepeatedField(GPBType::BOOL);
         $arr = new RepeatedField(GPBType::BOOL);
-        $arr[] = new TestMessage_Sub();
+        $arr[] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -254,7 +254,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     {
     {
         $arr = new RepeatedField(GPBType::BOOL);
         $arr = new RepeatedField(GPBType::BOOL);
         $arr[] = true;
         $arr[] = true;
-        $arr[0] = new TestMessage_Sub();
+        $arr[0] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -263,7 +263,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testStringAppendMessageFail()
     public function testStringAppendMessageFail()
     {
     {
         $arr = new RepeatedField(GPBType::STRING);
         $arr = new RepeatedField(GPBType::STRING);
-        $arr[] = new TestMessage_Sub();
+        $arr[] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -273,7 +273,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     {
     {
         $arr = new RepeatedField(GPBType::STRING);
         $arr = new RepeatedField(GPBType::STRING);
         $arr[] = 'abc';
         $arr[] = 'abc';
-        $arr[0] = new TestMessage_Sub();
+        $arr[0] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -302,7 +302,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
      */
      */
     public function testMessageAppendIntFail()
     public function testMessageAppendIntFail()
     {
     {
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
+        $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
         $arr[] = 1;
         $arr[] = 1;
     }
     }
 
 
@@ -311,8 +311,8 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
      */
      */
     public function testMessageSetIntFail()
     public function testMessageSetIntFail()
     {
     {
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
-        $arr[] = new TestMessage_Sub;
+        $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
+        $arr[] = new Sub;
         $arr[0] = 'abc';
         $arr[0] = 'abc';
     }
     }
 
 
@@ -321,7 +321,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
      */
      */
     public function testMessageAppendStringFail()
     public function testMessageAppendStringFail()
     {
     {
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
+        $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
         $arr[] = 'abc';
         $arr[] = 'abc';
     }
     }
 
 
@@ -330,8 +330,8 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
      */
      */
     public function testMessageSetStringFail()
     public function testMessageSetStringFail()
     {
     {
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
-        $arr[] = new TestMessage_Sub;
+        $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
+        $arr[] = new Sub;
         $arr[0] = 'abc';
         $arr[0] = 'abc';
     }
     }
 
 
@@ -340,7 +340,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
      */
      */
     public function testMessageAppendOtherMessageFail()
     public function testMessageAppendOtherMessageFail()
     {
     {
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
+        $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
         $arr[] = new TestMessage;
         $arr[] = new TestMessage;
     }
     }
 
 
@@ -349,7 +349,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
      */
      */
     public function testMessageAppendNullFail()
     public function testMessageAppendNullFail()
     {
     {
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
+        $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
         $null = null;
         $null = null;
         $arr[] = $null;
         $arr[] = $null;
     }
     }
@@ -359,8 +359,8 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
      */
      */
     public function testMessageSetNullFail()
     public function testMessageSetNullFail()
     {
     {
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
-        $arr[] = new TestMessage_Sub();
+        $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
+        $arr[] = new Sub();
         $null = null;
         $null = null;
         $arr[0] = $null;
         $arr[0] = $null;
     }
     }
@@ -397,7 +397,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     {
     {
         $arr = new RepeatedField(GPBType::INT32);
         $arr = new RepeatedField(GPBType::INT32);
         $arr[] = 0;
         $arr[] = 0;
-        $arr[new TestMessage_Sub()] = 0;
+        $arr[new Sub()] = 0;
     }
     }
 
 
     /**
     /**
@@ -656,7 +656,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testMessageMergeFromInvalidTypeFail()
     public function testMessageMergeFromInvalidTypeFail()
     {
     {
         $m = new TestMessage();
         $m = new TestMessage();
-        $n = new TestMessage_Sub();
+        $n = new Sub();
         $m->mergeFrom($n);
         $m->mergeFrom($n);
     }
     }
 
 
@@ -684,7 +684,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testInt32SetMessageKeyFail()
     public function testInt32SetMessageKeyFail()
     {
     {
         $arr = new MapField(GPBType::INT32, GPBType::INT32);
         $arr = new MapField(GPBType::INT32, GPBType::INT32);
-        $arr[new TestMessage_Sub()] = 0;
+        $arr[new Sub()] = 0;
     }
     }
 
 
     /**
     /**
@@ -693,7 +693,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testInt32SetMessageValueFail()
     public function testInt32SetMessageValueFail()
     {
     {
         $arr = new MapField(GPBType::INT32, GPBType::INT32);
         $arr = new MapField(GPBType::INT32, GPBType::INT32);
-        $arr[0] = new TestMessage_Sub();
+        $arr[0] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -720,7 +720,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testUint32SetMessageKeyFail()
     public function testUint32SetMessageKeyFail()
     {
     {
         $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
         $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
-        $arr[new TestMessage_Sub()] = 0;
+        $arr[new Sub()] = 0;
     }
     }
 
 
     /**
     /**
@@ -729,7 +729,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testUint32SetMessageValueFail()
     public function testUint32SetMessageValueFail()
     {
     {
         $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
         $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
-        $arr[0] = new TestMessage_Sub();
+        $arr[0] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -756,7 +756,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testInt64SetMessageKeyFail()
     public function testInt64SetMessageKeyFail()
     {
     {
         $arr = new MapField(GPBType::INT64, GPBType::INT64);
         $arr = new MapField(GPBType::INT64, GPBType::INT64);
-        $arr[new TestMessage_Sub()] = 0;
+        $arr[new Sub()] = 0;
     }
     }
 
 
     /**
     /**
@@ -765,7 +765,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testInt64SetMessageValueFail()
     public function testInt64SetMessageValueFail()
     {
     {
         $arr = new MapField(GPBType::INT64, GPBType::INT64);
         $arr = new MapField(GPBType::INT64, GPBType::INT64);
-        $arr[0] = new TestMessage_Sub();
+        $arr[0] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -792,7 +792,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testUint64SetMessageKeyFail()
     public function testUint64SetMessageKeyFail()
     {
     {
         $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
         $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
-        $arr[new TestMessage_Sub()] = 0;
+        $arr[new Sub()] = 0;
     }
     }
 
 
     /**
     /**
@@ -801,7 +801,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testUint64SetMessageValueFail()
     public function testUint64SetMessageValueFail()
     {
     {
         $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
         $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
-        $arr[0] = new TestMessage_Sub();
+        $arr[0] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -819,7 +819,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testDoubleSetMessageValueFail()
     public function testDoubleSetMessageValueFail()
     {
     {
         $arr = new MapField(GPBType::INT64, GPBType::DOUBLE);
         $arr = new MapField(GPBType::INT64, GPBType::DOUBLE);
-        $arr[0] = new TestMessage_Sub();
+        $arr[0] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -828,7 +828,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testBoolSetMessageKeyFail()
     public function testBoolSetMessageKeyFail()
     {
     {
         $arr = new MapField(GPBType::BOOL, GPBType::BOOL);
         $arr = new MapField(GPBType::BOOL, GPBType::BOOL);
-        $arr[new TestMessage_Sub()] = true;
+        $arr[new Sub()] = true;
     }
     }
 
 
     /**
     /**
@@ -837,7 +837,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testBoolSetMessageValueFail()
     public function testBoolSetMessageValueFail()
     {
     {
         $arr = new MapField(GPBType::BOOL, GPBType::BOOL);
         $arr = new MapField(GPBType::BOOL, GPBType::BOOL);
-        $arr[true] = new TestMessage_Sub();
+        $arr[true] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -864,7 +864,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testStringSetMessageKeyFail()
     public function testStringSetMessageKeyFail()
     {
     {
         $arr = new MapField(GPBType::STRING, GPBType::STRING);
         $arr = new MapField(GPBType::STRING, GPBType::STRING);
-        $arr[new TestMessage_Sub()] = 'abc';
+        $arr[new Sub()] = 'abc';
     }
     }
 
 
     /**
     /**
@@ -873,7 +873,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     public function testStringSetMessageValueFail()
     public function testStringSetMessageValueFail()
     {
     {
         $arr = new MapField(GPBType::STRING, GPBType::STRING);
         $arr = new MapField(GPBType::STRING, GPBType::STRING);
-        $arr['abc'] = new TestMessage_Sub();
+        $arr['abc'] = new Sub();
     }
     }
 
 
     /**
     /**
@@ -903,7 +903,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase
     {
     {
        $arr =
        $arr =
            new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class);
            new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class);
-       $arr[0] = new TestMessage_Sub();
+       $arr[0] = new Sub();
     }
     }
 
 
     /**
     /**

+ 6 - 6
php/tests/well_known_test.php

@@ -14,8 +14,8 @@ use Google\Protobuf\Enum;
 use Google\Protobuf\EnumValue;
 use Google\Protobuf\EnumValue;
 use Google\Protobuf\Field;
 use Google\Protobuf\Field;
 use Google\Protobuf\FieldMask;
 use Google\Protobuf\FieldMask;
-use Google\Protobuf\Field_Cardinality;
-use Google\Protobuf\Field_Kind;
+use Google\Protobuf\Field\Cardinality;
+use Google\Protobuf\Field\Kind;
 use Google\Protobuf\FloatValue;
 use Google\Protobuf\FloatValue;
 use Google\Protobuf\GPBEmpty;
 use Google\Protobuf\GPBEmpty;
 use Google\Protobuf\Int32Value;
 use Google\Protobuf\Int32Value;
@@ -206,11 +206,11 @@ class WellKnownTest extends TestBase {
     {
     {
         $m = new Field();
         $m = new Field();
 
 
-        $m->setKind(Field_Kind::TYPE_DOUBLE);
-        $this->assertSame(Field_Kind::TYPE_DOUBLE, $m->getKind());
+        $m->setKind(Kind::TYPE_DOUBLE);
+        $this->assertSame(Kind::TYPE_DOUBLE, $m->getKind());
 
 
-        $m->setCardinality(Field_Cardinality::CARDINALITY_OPTIONAL);
-        $this->assertSame(Field_Cardinality::CARDINALITY_OPTIONAL, $m->getCardinality());
+        $m->setCardinality(Cardinality::CARDINALITY_OPTIONAL);
+        $this->assertSame(Cardinality::CARDINALITY_OPTIONAL, $m->getCardinality());
 
 
         $m->setNumber(1);
         $m->setNumber(1);
         $this->assertSame(1, $m->getNumber());
         $this->assertSame(1, $m->getNumber());

+ 5 - 0
ruby/Rakefile

@@ -87,6 +87,7 @@ end
 # Proto for tests.
 # Proto for tests.
 genproto_output << "tests/generated_code.rb"
 genproto_output << "tests/generated_code.rb"
 genproto_output << "tests/test_import.rb"
 genproto_output << "tests/test_import.rb"
+genproto_output << "tests/test_ruby_package.rb"
 file "tests/generated_code.rb" => "tests/generated_code.proto" do |file_task|
 file "tests/generated_code.rb" => "tests/generated_code.proto" do |file_task|
   sh "../src/protoc --ruby_out=. tests/generated_code.proto"
   sh "../src/protoc --ruby_out=. tests/generated_code.proto"
 end
 end
@@ -95,6 +96,10 @@ file "tests/test_import.rb" => "tests/test_import.proto" do |file_task|
   sh "../src/protoc --ruby_out=. tests/test_import.proto"
   sh "../src/protoc --ruby_out=. tests/test_import.proto"
 end
 end
 
 
+file "tests/test_ruby_package.rb" => "tests/test_ruby_package.proto" do |file_task|
+  sh "../src/protoc --ruby_out=. tests/test_ruby_package.proto"
+end
+
 task :genproto => genproto_output
 task :genproto => genproto_output
 
 
 task :clean do
 task :clean do

+ 2 - 2
ruby/lib/google/protobuf.rb

@@ -60,8 +60,8 @@ module Google
       msg.to_proto
       msg.to_proto
     end
     end
 
 
-    def self.encode_json(msg)
-      msg.to_json
+    def self.encode_json(msg, options = {})
+      msg.to_json(options)
     end
     end
 
 
     def self.decode(klass, proto)
     def self.decode(klass, proto)

+ 2 - 2
ruby/lib/google/protobuf/message_exts.rb

@@ -40,8 +40,8 @@ module Google
       module ClassMethods
       module ClassMethods
       end
       end
 
 
-      def to_json
-        self.class.encode_json(self)
+      def to_json(options = {})
+        self.class.encode_json(self, options)
       end
       end
 
 
       def to_proto
       def to_proto

+ 24 - 0
ruby/tests/encode_decode_test.rb

@@ -60,4 +60,28 @@ class EncodeDecodeTest < Test::Unit::TestCase
     to = A::B::C::TestMessage.encode(m.oneof_msg)
     to = A::B::C::TestMessage.encode(m.oneof_msg)
     assert_equal '', to
     assert_equal '', to
   end
   end
+
+  def test_encode_json
+    msg = A::B::C::TestMessage.new({ optional_int32: 22 })
+    json = msg.to_json
+
+    to = A::B::C::TestMessage.decode_json(json)
+    assert_equal to.optional_int32, 22
+
+    msg = A::B::C::TestMessage.new({ optional_int32: 22 })
+    json = msg.to_json({ preserve_proto_fieldnames: true })
+
+    assert_match 'optional_int32', json
+
+    to = A::B::C::TestMessage.decode_json(json)
+    assert_equal 22, to.optional_int32
+
+    msg = A::B::C::TestMessage.new({ optional_int32: 22 })
+    json = A::B::C::TestMessage.encode_json(
+      msg,
+      { preserve_proto_fieldnames: true, emit_defaults: true }
+    )
+
+    assert_match 'optional_int32', json
+  end
 end
 end

+ 2 - 0
ruby/tests/generated_code_test.rb

@@ -5,6 +5,7 @@ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
 
 
 require 'generated_code_pb'
 require 'generated_code_pb'
 require 'test_import_pb'
 require 'test_import_pb'
+require 'test_ruby_package_pb'
 require 'test/unit'
 require 'test/unit'
 
 
 class GeneratedCodeTest < Test::Unit::TestCase
 class GeneratedCodeTest < Test::Unit::TestCase
@@ -15,5 +16,6 @@ class GeneratedCodeTest < Test::Unit::TestCase
     # aspect of the extension (basic.rb is for that).
     # aspect of the extension (basic.rb is for that).
     m = A::B::C::TestMessage.new()
     m = A::B::C::TestMessage.new()
     m2 = FooBar::TestImportedMessage.new()
     m2 = FooBar::TestImportedMessage.new()
+    m3 = A::B::TestRubyPackageMessage.new()
   end
   end
 end
 end

+ 7 - 0
ruby/tests/test_ruby_package.proto

@@ -0,0 +1,7 @@
+syntax = "proto3";
+
+package foo_bar;
+
+option ruby_package = "A.B";
+
+message TestRubyPackageMessage {}

+ 267 - 157
src/google/protobuf/compiler/php/php_generator.cc

@@ -83,7 +83,7 @@ std::string PhpName(const std::string& full_name, bool is_descriptor);
 std::string DefaultForField(FieldDescriptor* field);
 std::string DefaultForField(FieldDescriptor* field);
 std::string IntToString(int32 value);
 std::string IntToString(int32 value);
 std::string FilenameToClassname(const string& filename);
 std::string FilenameToClassname(const string& filename);
-std::string GeneratedMetadataFileName(const std::string& proto_file,
+std::string GeneratedMetadataFileName(const FileDescriptor* file,
                                       bool is_descriptor);
                                       bool is_descriptor);
 std::string LabelForField(FieldDescriptor* field);
 std::string LabelForField(FieldDescriptor* field);
 std::string TypeName(FieldDescriptor* field);
 std::string TypeName(FieldDescriptor* field);
@@ -94,6 +94,9 @@ void Indent(io::Printer* printer);
 void Outdent(io::Printer* printer);
 void Outdent(io::Printer* printer);
 void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message,
 void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message,
                                int is_descriptor);
                                int is_descriptor);
+void GenerateMessageConstructorDocComment(io::Printer* printer,
+                                          const Descriptor* message,
+                                          int is_descriptor);
 void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field,
 void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field,
                              int is_descriptor, int function_type);
                              int is_descriptor, int function_type);
 void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_,
 void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_,
@@ -105,31 +108,40 @@ void GenerateServiceDocComment(io::Printer* printer,
 void GenerateServiceMethodDocComment(io::Printer* printer,
 void GenerateServiceMethodDocComment(io::Printer* printer,
                               const MethodDescriptor* method);
                               const MethodDescriptor* method);
 
 
-std::string RenameEmpty(const std::string& name) {
-  if (name == "Empty") {
-    return "GPBEmpty";
-  } else {
-    return name;
+
+std::string ReservedNamePrefix(const string& classname,
+                                const FileDescriptor* file) {
+  bool is_reserved = false;
+
+  string lower = classname;
+  transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
+
+  for (int i = 0; i < kReservedNamesSize; i++) {
+    if (lower == kReservedNames[i]) {
+      is_reserved = true;
+      break;
+    }
   }
   }
-}
 
 
-std::string MessageFullName(const Descriptor* message, bool is_descriptor) {
-  if (is_descriptor) {
-    return StringReplace(message->full_name(),
-                         "google.protobuf",
-                         "google.protobuf.internal", false);
-  } else {
-    return message->full_name();
+  if (is_reserved) {
+    if (file->package() == "google.protobuf") {
+      return "GPB";
+    } else {
+      return "PB";
+    }
   }
   }
+
+  return "";
 }
 }
 
 
-std::string EnumFullName(const EnumDescriptor* envm, bool is_descriptor) {
+template <typename DescriptorType>
+std::string DescriptorFullName(const DescriptorType* desc, bool is_descriptor) {
   if (is_descriptor) {
   if (is_descriptor) {
-    return StringReplace(envm->full_name(),
+    return StringReplace(desc->full_name(),
                          "google.protobuf",
                          "google.protobuf",
                          "google.protobuf.internal", false);
                          "google.protobuf.internal", false);
   } else {
   } else {
-    return envm->full_name();
+    return desc->full_name();
   }
   }
 }
 }
 
 
@@ -141,22 +153,43 @@ std::string ClassNamePrefix(const string& classname,
     return prefix;
     return prefix;
   }
   }
 
 
-  bool is_reserved = false;
+  return ReservedNamePrefix(classname, desc->file());
+}
+
+template <typename DescriptorType>
+std::string GeneratedClassName(const DescriptorType* desc) {
+  std::string classname = ClassNamePrefix(desc->name(), desc) + desc->name();
+  const Descriptor* containing = desc->containing_type();
+  while (containing != NULL) {
+    classname = ClassNamePrefix(containing->name(), desc) + containing->name()
+       + '\\' + classname;
+    containing = containing->containing_type();
+  }
+  return classname;
+}
 
 
+std::string GeneratedClassName(const ServiceDescriptor* desc) {
+  std::string classname = desc->name();
+  return ClassNamePrefix(classname, desc) + classname;
+}
+
+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 ClassNamePrefix(const string& classname) {
   string lower = classname;
   string lower = classname;
   transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
   transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
 
 
   for (int i = 0; i < kReservedNamesSize; i++) {
   for (int i = 0; i < kReservedNamesSize; i++) {
     if (lower == kReservedNames[i]) {
     if (lower == kReservedNames[i]) {
-      is_reserved = true;
-      break;
-    }
-  }
-
-  if (is_reserved) {
-    if (desc->file()->package() == "google.protobuf") {
-      return "GPB";
-    } else {
       return "PB";
       return "PB";
     }
     }
   }
   }
@@ -192,34 +225,39 @@ std::string ConstantNamePrefix(const string& classname) {
 }
 }
 
 
 template <typename DescriptorType>
 template <typename DescriptorType>
-std::string NamespacedName(const string& classname,
-                            const DescriptorType* desc, bool is_descriptor) {
+std::string RootPhpNamespace(const DescriptorType* desc, bool is_descriptor) {
   if (desc->file()->options().has_php_namespace()) {
   if (desc->file()->options().has_php_namespace()) {
     const string& php_namespace = desc->file()->options().php_namespace();
     const string& php_namespace = desc->file()->options().php_namespace();
     if (php_namespace != "") {
     if (php_namespace != "") {
-      return php_namespace + '\\' + classname;
-    } else {
-      return classname;
+      return php_namespace;
     }
     }
+    return "";
   }
   }
 
 
-  if (desc->file()->package() == "") {
-    return classname;
-  } else {
-    return PhpName(desc->file()->package(), is_descriptor) + '\\' +
-           classname;
+  if (desc->file()->package() != "") {
+    return PhpName(desc->file()->package(), is_descriptor);
   }
   }
+  return "";
 }
 }
 
 
 template <typename DescriptorType>
 template <typename DescriptorType>
 std::string FullClassName(const DescriptorType* desc, bool is_descriptor) {
 std::string FullClassName(const DescriptorType* desc, bool is_descriptor) {
   string classname = GeneratedClassName(desc);
   string classname = GeneratedClassName(desc);
-  return NamespacedName(classname, desc, is_descriptor);
+  string php_namespace = RootPhpNamespace(desc, is_descriptor);
+  if (php_namespace != "") {
+    return php_namespace + "\\" + classname;
+  }
+  return classname;
 }
 }
 
 
-std::string FullClassName(const ServiceDescriptor* desc, bool is_descriptor) {
-  string classname = GeneratedClassName(desc);
-  return NamespacedName(classname, desc, is_descriptor);
+template <typename DescriptorType>
+std::string LegacyFullClassName(const DescriptorType* desc, bool is_descriptor) {
+  string classname = LegacyGeneratedClassName(desc);
+  string php_namespace = RootPhpNamespace(desc, is_descriptor);
+  if (php_namespace != "") {
+    return php_namespace + "\\" + classname;
+  }
+  return classname;
 }
 }
 
 
 std::string PhpName(const std::string& full_name, bool is_descriptor) {
 std::string PhpName(const std::string& full_name, bool is_descriptor) {
@@ -227,20 +265,23 @@ std::string PhpName(const std::string& full_name, bool is_descriptor) {
     return kDescriptorPackageName;
     return kDescriptorPackageName;
   }
   }
 
 
+  std::string segment;
   std::string result;
   std::string result;
   bool cap_next_letter = true;
   bool cap_next_letter = true;
   for (int i = 0; i < full_name.size(); i++) {
   for (int i = 0; i < full_name.size(); i++) {
     if ('a' <= full_name[i] && full_name[i] <= 'z' && cap_next_letter) {
     if ('a' <= full_name[i] && full_name[i] <= 'z' && cap_next_letter) {
-      result += full_name[i] + ('A' - 'a');
+      segment += full_name[i] + ('A' - 'a');
       cap_next_letter = false;
       cap_next_letter = false;
     } else if (full_name[i] == '.') {
     } else if (full_name[i] == '.') {
-      result += '\\';
+      result += ClassNamePrefix(segment) + segment + '\\';
+      segment = "";
       cap_next_letter = true;
       cap_next_letter = true;
     } else {
     } else {
-      result += full_name[i];
+      segment += full_name[i];
       cap_next_letter = false;
       cap_next_letter = false;
     }
     }
   }
   }
+  result += ClassNamePrefix(segment) + segment;
   return result;
   return result;
 }
 }
 
 
@@ -268,11 +309,13 @@ std::string DefaultForField(const FieldDescriptor* field) {
   }
   }
 }
 }
 
 
-std::string GeneratedMetadataFileName(const std::string& proto_file,
+std::string GeneratedMetadataFileName(const FileDescriptor* file,
                                       bool is_descriptor) {
                                       bool is_descriptor) {
+  const string& proto_file = file->name();
   int start_index = 0;
   int start_index = 0;
   int first_index = proto_file.find_first_of("/", start_index);
   int first_index = proto_file.find_first_of("/", start_index);
-  std::string result = "GPBMetadata/";
+  std::string result = "";
+  std::string segment = "";
 
 
   if (proto_file == kEmptyFile) {
   if (proto_file == kEmptyFile) {
     return kEmptyMetadataFile;
     return kEmptyMetadataFile;
@@ -290,24 +333,44 @@ std::string GeneratedMetadataFileName(const std::string& proto_file,
     file_no_suffix = proto_file.substr(0, lastindex);
     file_no_suffix = proto_file.substr(0, lastindex);
   }
   }
 
 
-  while (first_index != string::npos) {
-    result += UnderscoresToCamelCase(
-        file_no_suffix.substr(start_index, first_index - start_index), true);
-    result += "/";
-    start_index = first_index + 1;
-    first_index = file_no_suffix.find_first_of("/", start_index);
+  if (file->options().has_php_metadata_namespace()) {
+    const string& php_metadata_namespace =
+        file->options().php_metadata_namespace();
+    if (php_metadata_namespace != "" && php_metadata_namespace != "\\") {
+      result += php_metadata_namespace;
+      std::replace(result.begin(), result.end(), '\\', '/');
+      if (result.at(result.size() - 1) != '/') {
+        result += "/";
+      }
+    }
+  } else {
+    result += "GPBMetadata/";
+    while (first_index != string::npos) {
+      segment = UnderscoresToCamelCase(
+          file_no_suffix.substr(start_index, first_index - start_index), true);
+      result += ReservedNamePrefix(segment, file) + segment + "/";
+      start_index = first_index + 1;
+      first_index = file_no_suffix.find_first_of("/", start_index);
+    }
   }
   }
 
 
   // Append file name.
   // Append file name.
-  result += RenameEmpty(UnderscoresToCamelCase(
-      file_no_suffix.substr(start_index, first_index - start_index), true));
+  int file_name_start = file_no_suffix.find_last_of("/");
+  if (file_name_start == string::npos) {
+    file_name_start = 0;
+  } else {
+    file_name_start += 1;
+  }
+  segment = UnderscoresToCamelCase(
+      file_no_suffix.substr(file_name_start, first_index - file_name_start), true);
 
 
-  return result += ".php";
+  return result + ReservedNamePrefix(segment, file) + segment + ".php";
 }
 }
 
 
-std::string GeneratedMessageFileName(const Descriptor* message,
+template <typename DescriptorType>
+std::string GeneratedClassFileName(const DescriptorType* desc,
                                      bool is_descriptor) {
                                      bool is_descriptor) {
-  std::string result = FullClassName(message, is_descriptor);
+  std::string result = FullClassName(desc, is_descriptor);
   for (int i = 0; i < result.size(); i++) {
   for (int i = 0; i < result.size(); i++) {
     if (result[i] == '\\') {
     if (result[i] == '\\') {
       result[i] = '/';
       result[i] = '/';
@@ -316,9 +379,11 @@ std::string GeneratedMessageFileName(const Descriptor* message,
   return result + ".php";
   return result + ".php";
 }
 }
 
 
-std::string GeneratedEnumFileName(const EnumDescriptor* en,
-                                  bool is_descriptor) {
-  std::string result = FullClassName(en, is_descriptor);
+template <typename DescriptorType>
+std::string LegacyGeneratedClassFileName(const DescriptorType* desc,
+                                     bool is_descriptor) {
+  std::string result = LegacyFullClassName(desc, is_descriptor);
+
   for (int i = 0; i < result.size(); i++) {
   for (int i = 0; i < result.size(); i++) {
     if (result[i] == '\\') {
     if (result[i] == '\\') {
       result[i] = '/';
       result[i] = '/';
@@ -461,10 +526,10 @@ std::string PhpGetterTypeName(const FieldDescriptor* field, bool is_descriptor)
 std::string EnumOrMessageSuffix(
 std::string EnumOrMessageSuffix(
     const FieldDescriptor* field, bool is_descriptor) {
     const FieldDescriptor* field, bool is_descriptor) {
   if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
   if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
-    return ", '" + MessageFullName(field->message_type(), is_descriptor) + "'";
+    return ", '" + DescriptorFullName(field->message_type(), is_descriptor) + "'";
   }
   }
   if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
   if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
-    return ", '" + EnumFullName(field->enum_type(), is_descriptor) + "'";
+    return ", '" + DescriptorFullName(field->enum_type(), is_descriptor) + "'";
   }
   }
   return "";
   return "";
 }
 }
@@ -651,11 +716,11 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor,
   } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
   } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
     printer->Print(
     printer->Print(
         "GPBUtil::checkMessage($var, \\^class_name^::class);\n",
         "GPBUtil::checkMessage($var, \\^class_name^::class);\n",
-        "class_name", FullClassName(field->message_type(), is_descriptor));
+        "class_name", LegacyFullClassName(field->message_type(), is_descriptor));
   } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
   } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
     printer->Print(
     printer->Print(
         "GPBUtil::checkEnum($var, \\^class_name^::class);\n",
         "GPBUtil::checkEnum($var, \\^class_name^::class);\n",
-        "class_name", FullClassName(field->enum_type(), is_descriptor));
+        "class_name", LegacyFullClassName(field->enum_type(), is_descriptor));
   } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
   } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
     printer->Print(
     printer->Print(
         "GPBUtil::checkString($var, ^utf8^);\n",
         "GPBUtil::checkString($var, ^utf8^);\n",
@@ -711,7 +776,7 @@ void GenerateEnumToPool(const EnumDescriptor* en, io::Printer* printer) {
   printer->Print(
   printer->Print(
       "$pool->addEnum('^name^', "
       "$pool->addEnum('^name^', "
       "\\Google\\Protobuf\\Internal\\^class_name^::class)\n",
       "\\Google\\Protobuf\\Internal\\^class_name^::class)\n",
-      "name", EnumFullName(en, true),
+      "name", DescriptorFullName(en, true),
       "class_name", en->name());
       "class_name", en->name());
   Indent(printer);
   Indent(printer);
 
 
@@ -743,13 +808,13 @@ void GenerateMessageToPool(const string& name_prefix, const Descriptor* message,
   if (message->options().map_entry()) {
   if (message->options().map_entry()) {
     return;
     return;
   }
   }
-  string class_name = name_prefix.empty()?
-      message->name() : name_prefix + "_" + message->name();
+  string class_name = (name_prefix.empty() ? "" : name_prefix + "\\") +
+    ReservedNamePrefix(message->name(), message->file()) + message->name();
 
 
   printer->Print(
   printer->Print(
       "$pool->addMessage('^message^', "
       "$pool->addMessage('^message^', "
       "\\Google\\Protobuf\\Internal\\^class_name^::class)\n",
       "\\Google\\Protobuf\\Internal\\^class_name^::class)\n",
-      "message", MessageFullName(message, true),
+      "message", DescriptorFullName(message, true),
       "class_name", class_name);
       "class_name", class_name);
 
 
   Indent(printer);
   Indent(printer);
@@ -851,7 +916,7 @@ void GenerateAddFileToPool(const FileDescriptor* file, bool is_descriptor,
         continue;
         continue;
       }
       }
       std::string dependency_filename =
       std::string dependency_filename =
-          GeneratedMetadataFileName(name, is_descriptor);
+          GeneratedMetadataFileName(file->dependency(i), is_descriptor);
       printer->Print(
       printer->Print(
           "\\^name^::initOnce();\n",
           "\\^name^::initOnce();\n",
           "name", FilenameToClassname(dependency_filename));
           "name", FilenameToClassname(dependency_filename));
@@ -945,7 +1010,7 @@ std::string FilenameToClassname(const string& filename) {
 void GenerateMetadataFile(const FileDescriptor* file,
 void GenerateMetadataFile(const FileDescriptor* file,
                           bool is_descriptor,
                           bool is_descriptor,
                           GeneratorContext* generator_context) {
                           GeneratorContext* generator_context) {
-  std::string filename = GeneratedMetadataFileName(file->name(), is_descriptor);
+  std::string filename = GeneratedMetadataFileName(file, is_descriptor);
   std::unique_ptr<io::ZeroCopyOutputStream> output(
   std::unique_ptr<io::ZeroCopyOutputStream> output(
       generator_context->Open(filename));
       generator_context->Open(filename));
   io::Printer printer(output.get(), '^');
   io::Printer printer(output.get(), '^');
@@ -955,11 +1020,11 @@ void GenerateMetadataFile(const FileDescriptor* file,
   std::string fullname = FilenameToClassname(filename);
   std::string fullname = FilenameToClassname(filename);
   int lastindex = fullname.find_last_of("\\");
   int lastindex = fullname.find_last_of("\\");
 
 
-  printer.Print(
-      "namespace ^name^;\n\n",
-      "name", fullname.substr(0, lastindex));
-
   if (lastindex != string::npos) {
   if (lastindex != string::npos) {
+    printer.Print(
+        "namespace ^name^;\n\n",
+        "name", fullname.substr(0, lastindex));
+
     printer.Print(
     printer.Print(
         "class ^name^\n"
         "class ^name^\n"
         "{\n",
         "{\n",
@@ -978,9 +1043,47 @@ void GenerateMetadataFile(const FileDescriptor* file,
   printer.Print("}\n\n");
   printer.Print("}\n\n");
 }
 }
 
 
+template <typename DescriptorType>
+void LegacyGenerateClassFile(const FileDescriptor* file, const DescriptorType* desc,
+                         bool is_descriptor,
+                         GeneratorContext* generator_context) {
+
+  std::string filename = LegacyGeneratedClassFileName(desc, is_descriptor);
+  std::unique_ptr<io::ZeroCopyOutputStream> output(
+      generator_context->Open(filename));
+  io::Printer printer(output.get(), '^');
+
+  GenerateHead(file, &printer);
+
+  std::string php_namespace = RootPhpNamespace(desc, is_descriptor);
+  if (php_namespace != "") {
+    printer.Print(
+        "namespace ^name^;\n\n",
+        "name", php_namespace);
+  }
+  std::string newname = FullClassName(desc, is_descriptor);
+  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, is_descriptor),
+      "fullname", newname);
+}
+
 void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en,
 void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en,
                       bool is_descriptor, GeneratorContext* generator_context) {
                       bool is_descriptor, GeneratorContext* generator_context) {
-  std::string filename = GeneratedEnumFileName(en, is_descriptor);
+  std::string filename = GeneratedClassFileName(en, is_descriptor);
   std::unique_ptr<io::ZeroCopyOutputStream> output(
   std::unique_ptr<io::ZeroCopyOutputStream> output(
       generator_context->Open(filename));
       generator_context->Open(filename));
   io::Printer printer(output.get(), '^');
   io::Printer printer(output.get(), '^');
@@ -990,32 +1093,22 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en,
   std::string fullname = FilenameToClassname(filename);
   std::string fullname = FilenameToClassname(filename);
   int lastindex = fullname.find_last_of("\\");
   int lastindex = fullname.find_last_of("\\");
 
 
-  if (file->options().has_php_namespace()) {
-    const string& php_namespace = file->options().php_namespace();
-    if (!php_namespace.empty()) {
-      printer.Print(
-          "namespace ^name^;\n\n",
-          "name", php_namespace);
-    }
-  } else if (!file->package().empty()) {
+  if (lastindex != string::npos) {
     printer.Print(
     printer.Print(
         "namespace ^name^;\n\n",
         "namespace ^name^;\n\n",
         "name", fullname.substr(0, lastindex));
         "name", fullname.substr(0, lastindex));
   }
   }
 
 
-  GenerateEnumDocComment(&printer, en, is_descriptor);
-
   if (lastindex != string::npos) {
   if (lastindex != string::npos) {
-    printer.Print(
-        "class ^name^\n"
-        "{\n",
-        "name", fullname.substr(lastindex + 1));
-  } else {
-    printer.Print(
-        "class ^name^\n"
-        "{\n",
-        "name", fullname);
+    fullname = fullname.substr(lastindex + 1);
   }
   }
+
+  GenerateEnumDocComment(&printer, en, is_descriptor);
+
+  printer.Print(
+      "class ^name^\n"
+      "{\n",
+      "name", fullname);
   Indent(&printer);
   Indent(&printer);
 
 
   for (int i = 0; i < en->value_count(); i++) {
   for (int i = 0; i < en->value_count(); i++) {
@@ -1028,6 +1121,17 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en,
 
 
   Outdent(&printer);
   Outdent(&printer);
   printer.Print("}\n\n");
   printer.Print("}\n\n");
+
+  // write legacy file for backwards compatiblity 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, is_descriptor));
+    LegacyGenerateClassFile(file, en, is_descriptor, generator_context);
+  }
 }
 }
 
 
 void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
 void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
@@ -1039,7 +1143,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
     return;
     return;
   }
   }
 
 
-  std::string filename = GeneratedMessageFileName(message, is_descriptor);
+  std::string filename = GeneratedClassFileName(message, is_descriptor);
   std::unique_ptr<io::ZeroCopyOutputStream> output(
   std::unique_ptr<io::ZeroCopyOutputStream> output(
       generator_context->Open(filename));
       generator_context->Open(filename));
   io::Printer printer(output.get(), '^');
   io::Printer printer(output.get(), '^');
@@ -1049,14 +1153,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
   std::string fullname = FilenameToClassname(filename);
   std::string fullname = FilenameToClassname(filename);
   int lastindex = fullname.find_last_of("\\");
   int lastindex = fullname.find_last_of("\\");
 
 
-  if (file->options().has_php_namespace()) {
-    const string& php_namespace = file->options().php_namespace();
-    if (!php_namespace.empty()) {
-      printer.Print(
-          "namespace ^name^;\n\n",
-          "name", php_namespace);
-    }
-  } else if (!file->package().empty()) {
+  if (lastindex != string::npos) {
     printer.Print(
     printer.Print(
         "namespace ^name^;\n\n",
         "namespace ^name^;\n\n",
         "name", fullname.substr(0, lastindex));
         "name", fullname.substr(0, lastindex));
@@ -1066,16 +1163,13 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
 
 
   GenerateMessageDocComment(&printer, message, is_descriptor);
   GenerateMessageDocComment(&printer, message, is_descriptor);
   if (lastindex != string::npos) {
   if (lastindex != string::npos) {
-    printer.Print(
-        "class ^name^ extends \\Google\\Protobuf\\Internal\\Message\n"
-        "{\n",
-        "name", fullname.substr(lastindex + 1));
-  } else {
-    printer.Print(
-        "class ^name^ extends \\Google\\Protobuf\\Internal\\Message\n"
-        "{\n",
-        "name", fullname);
+    fullname = fullname.substr(lastindex + 1);
   }
   }
+
+  printer.Print(
+      "class ^name^ extends \\Google\\Protobuf\\Internal\\Message\n"
+      "{\n",
+      "name", fullname);
   Indent(&printer);
   Indent(&printer);
 
 
   // Field and oneof definitions.
   // Field and oneof definitions.
@@ -1089,16 +1183,17 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
   }
   }
   printer.Print("\n");
   printer.Print("\n");
 
 
+  GenerateMessageConstructorDocComment(&printer, message, is_descriptor);
   printer.Print(
   printer.Print(
-      "public function __construct() {\n");
+      "public function __construct($data = NULL) {\n");
   Indent(&printer);
   Indent(&printer);
 
 
   std::string metadata_filename =
   std::string metadata_filename =
-      GeneratedMetadataFileName(file->name(), is_descriptor);
+      GeneratedMetadataFileName(file, is_descriptor);
   std::string metadata_fullname = FilenameToClassname(metadata_filename);
   std::string metadata_fullname = FilenameToClassname(metadata_filename);
   printer.Print(
   printer.Print(
       "\\^fullname^::initOnce();\n"
       "\\^fullname^::initOnce();\n"
-      "parent::__construct();\n",
+      "parent::__construct($data);\n",
       "fullname", metadata_fullname);
       "fullname", metadata_fullname);
 
 
   Outdent(&printer);
   Outdent(&printer);
@@ -1126,6 +1221,17 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
   Outdent(&printer);
   Outdent(&printer);
   printer.Print("}\n\n");
   printer.Print("}\n\n");
 
 
+  // write legacy file for backwards compatiblity 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, is_descriptor));
+    LegacyGenerateClassFile(file, message, is_descriptor, generator_context);
+  }
+
   // Nested messages and enums.
   // Nested messages and enums.
   for (int i = 0; i < message->nested_type_count(); i++) {
   for (int i = 0; i < message->nested_type_count(); i++) {
     GenerateMessageFile(file, message->nested_type(i), is_descriptor,
     GenerateMessageFile(file, message->nested_type(i), is_descriptor,
@@ -1150,14 +1256,9 @@ void GenerateServiceFile(const FileDescriptor* file,
   std::string fullname = FilenameToClassname(filename);
   std::string fullname = FilenameToClassname(filename);
   int lastindex = fullname.find_last_of("\\");
   int lastindex = fullname.find_last_of("\\");
 
 
-  if (file->options().has_php_namespace()) {
-    const string& php_namespace = file->options().php_namespace();
-    if (!php_namespace.empty()) {
-      printer.Print(
-          "namespace ^name^;\n\n",
-          "name", php_namespace);
-    }
-  } else if (!file->package().empty()) {
+  if (!file->options().php_namespace().empty() ||
+      (!file->options().has_php_namespace() && !file->package().empty()) ||
+      lastindex != string::npos) {
     printer.Print(
     printer.Print(
         "namespace ^name^;\n\n",
         "namespace ^name^;\n\n",
         "name", fullname.substr(0, lastindex));
         "name", fullname.substr(0, lastindex));
@@ -1251,7 +1352,8 @@ static string EscapePhpdoc(const string& input) {
 }
 }
 
 
 static void GenerateDocCommentBodyForLocation(
 static void GenerateDocCommentBodyForLocation(
-    io::Printer* printer, const SourceLocation& location) {
+    io::Printer* printer, const SourceLocation& location, bool trailingNewline,
+    int indentCount) {
   string comments = location.leading_comments.empty() ?
   string comments = location.leading_comments.empty() ?
       location.trailing_comments : location.leading_comments;
       location.trailing_comments : location.leading_comments;
   if (!comments.empty()) {
   if (!comments.empty()) {
@@ -1272,14 +1374,16 @@ static void GenerateDocCommentBodyForLocation(
       // Most lines should start with a space.  Watch out for lines that start
       // Most lines should start with a space.  Watch out for lines that start
       // with a /, since putting that right after the leading asterisk will
       // with a /, since putting that right after the leading asterisk will
       // close the comment.
       // close the comment.
-      if (!lines[i].empty() && lines[i][0] == '/') {
+      if (indentCount == 0 && !lines[i].empty() && lines[i][0] == '/') {
         printer->Print(" * ^line^\n", "line", lines[i]);
         printer->Print(" * ^line^\n", "line", lines[i]);
       } else {
       } else {
-        printer->Print(" *^line^\n", "line", lines[i]);
+        std::string indent = std::string(indentCount, ' ');
+        printer->Print(" *^ind^^line^\n", "ind", indent, "line", lines[i]);
       }
       }
     }
     }
-    printer->Print(
-        " *\n");
+    if (trailingNewline) {
+      printer->Print(" *\n");
+    }
   }
   }
 }
 }
 
 
@@ -1288,7 +1392,7 @@ static void GenerateDocCommentBody(
     io::Printer* printer, const DescriptorType* descriptor) {
     io::Printer* printer, const DescriptorType* descriptor) {
   SourceLocation location;
   SourceLocation location;
   if (descriptor->GetSourceLocation(&location)) {
   if (descriptor->GetSourceLocation(&location)) {
-    GenerateDocCommentBodyForLocation(printer, location);
+    GenerateDocCommentBodyForLocation(printer, location, true, 0);
   }
   }
 }
 }
 
 
@@ -1310,10 +1414,41 @@ void GenerateMessageDocComment(io::Printer* printer,
   printer->Print(
   printer->Print(
     " * Generated from protobuf message <code>^messagename^</code>\n"
     " * Generated from protobuf message <code>^messagename^</code>\n"
     " */\n",
     " */\n",
-    "fullname", EscapePhpdoc(PhpName(message->full_name(), is_descriptor)),
+    "fullname", EscapePhpdoc(FullClassName(message, is_descriptor)),
     "messagename", EscapePhpdoc(message->full_name()));
     "messagename", EscapePhpdoc(message->full_name()));
 }
 }
 
 
+void GenerateMessageConstructorDocComment(io::Printer* printer,
+                                          const Descriptor* message,
+                                          int is_descriptor) {
+  // In theory we should have slightly different comments for setters, getters,
+  // etc., but in practice everyone already knows the difference between these
+  // so it's redundant information.
+
+  // We start the comment with the main body based on the comments from the
+  // .proto file (if present). We then end with the field declaration, e.g.:
+  //   optional string foo = 5;
+  // If the field is a group, the debug string might end with {.
+  printer->Print("/**\n");
+  printer->Print(" * Constructor.\n");
+  printer->Print(" *\n");
+  printer->Print(" * @param array $data {\n");
+  printer->Print(" *     Optional. Data for populating the Message object.\n");
+  printer->Print(" *\n");
+  for (int i = 0; i < message->field_count(); i++) {
+    const FieldDescriptor* field = message->field(i);
+    printer->Print(" *     @type ^php_type^ $^var^\n",
+      "php_type", PhpSetterTypeName(field, is_descriptor),
+      "var", field->name());
+    SourceLocation location;
+    if (field->GetSourceLocation(&location)) {
+      GenerateDocCommentBodyForLocation(printer, location, false, 10);
+    }
+  }
+  printer->Print(" * }\n");
+  printer->Print(" */\n");
+}
+
 void GenerateServiceDocComment(io::Printer* printer,
 void GenerateServiceDocComment(io::Printer* printer,
                                const ServiceDescriptor* service) {
                                const ServiceDescriptor* service) {
   printer->Print("/**\n");
   printer->Print("/**\n");
@@ -1355,9 +1490,9 @@ void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_,
   printer->Print("/**\n");
   printer->Print("/**\n");
   GenerateDocCommentBody(printer, enum_);
   GenerateDocCommentBody(printer, enum_);
   printer->Print(
   printer->Print(
-    " * Protobuf enum <code>^fullname^</code>\n"
+    " * Protobuf type <code>^fullname^</code>\n"
     " */\n",
     " */\n",
-    "fullname", EscapePhpdoc(PhpName(enum_->full_name(), is_descriptor)));
+    "fullname", EscapePhpdoc(enum_->full_name()));
 }
 }
 
 
 void GenerateEnumValueDocComment(io::Printer* printer,
 void GenerateEnumValueDocComment(io::Printer* printer,
@@ -1410,31 +1545,6 @@ bool Generator::Generate(const FileDescriptor* file, const string& parameter,
   return true;
   return true;
 }
 }
 
 
-std::string GeneratedClassName(const Descriptor* 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 GeneratedClassName(const EnumDescriptor* 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 GeneratedClassName(const ServiceDescriptor* desc) {
-  std::string classname = desc->name();
-  return ClassNamePrefix(classname, desc) + classname;
-}
-
 }  // namespace php
 }  // namespace php
 }  // namespace compiler
 }  // namespace compiler
 }  // namespace protobuf
 }  // namespace protobuf

+ 0 - 10
src/google/protobuf/compiler/php/php_generator.h

@@ -51,16 +51,6 @@ class LIBPROTOC_EXPORT Generator
 
 
 };
 };
 
 
-// To skip reserved keywords in php, some generated classname are prefixed.
-// Other code generators may need following API to figure out the actual
-// classname.
-LIBPROTOC_EXPORT std::string GeneratedClassName(
-    const google::protobuf::Descriptor* desc);
-LIBPROTOC_EXPORT std::string GeneratedClassName(
-    const google::protobuf::EnumDescriptor* desc);
-LIBPROTOC_EXPORT std::string GeneratedClassName(
-    const google::protobuf::ServiceDescriptor* desc);
-
 }  // namespace php
 }  // namespace php
 }  // namespace compiler
 }  // namespace compiler
 }  // namespace protobuf
 }  // namespace protobuf

+ 16 - 3
src/google/protobuf/compiler/ruby/ruby_generator.cc

@@ -337,9 +337,20 @@ void GenerateEnumAssignment(
 }
 }
 
 
 int GeneratePackageModules(
 int GeneratePackageModules(
-    std::string package_name,
+    const FileDescriptor* file,
     google::protobuf::io::Printer* printer) {
     google::protobuf::io::Printer* printer) {
   int levels = 0;
   int levels = 0;
+  bool need_change_to_module;
+  std::string package_name;
+
+  if (file->options().has_ruby_package()) {
+    package_name = file->options().ruby_package();
+    need_change_to_module = false;
+  } else {
+    package_name = file->package();
+    need_change_to_module = true;
+  }
+
   while (!package_name.empty()) {
   while (!package_name.empty()) {
     size_t dot_index = package_name.find(".");
     size_t dot_index = package_name.find(".");
     string component;
     string component;
@@ -350,7 +361,9 @@ int GeneratePackageModules(
       component = package_name.substr(0, dot_index);
       component = package_name.substr(0, dot_index);
       package_name = package_name.substr(dot_index + 1);
       package_name = package_name.substr(dot_index + 1);
     }
     }
-    component = PackageToModule(component);
+    if (need_change_to_module) {
+      component = PackageToModule(component);
+    }
     printer->Print(
     printer->Print(
       "module $name$\n",
       "module $name$\n",
       "name", component);
       "name", component);
@@ -462,7 +475,7 @@ bool GenerateFile(const FileDescriptor* file, io::Printer* printer,
   printer->Print(
   printer->Print(
     "end\n\n");
     "end\n\n");
 
 
-  int levels = GeneratePackageModules(file->package(), printer);
+  int levels = GeneratePackageModules(file, printer);
   for (int i = 0; i < file->message_type_count(); i++) {
   for (int i = 0; i < file->message_type_count(); i++) {
     GenerateMessageAssignment("", file->message_type(i), printer);
     GenerateMessageAssignment("", file->message_type(i), printer);
   }
   }

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác