فهرست منبع

Sync from Piper @353127564

PROTOBUF_SYNC_PIPER
Deanna Garcia 4 سال پیش
والد
کامیت
a00125024e
100فایلهای تغییر یافته به همراه1765 افزوده شده و 1454 حذف شده
  1. 1 1
      .github/workflows/codespell.yml
  2. 3 0
      .gitignore
  3. 26 0
      CHANGES.txt
  4. 14 5
      Makefile.am
  5. 1 1
      Protobuf-C++.podspec
  6. 0 2
      README.md
  7. 0 1
      cmake/conformance.cmake
  8. 6 1
      cmake/install.cmake
  9. 1 1
      cmake/protobuf-lite.pc.cmake
  10. 1 1
      cmake/protobuf.pc.cmake
  11. 1 1
      configure.ac
  12. 3 3
      conformance/Makefile.am
  13. 31 22
      conformance/conformance_ruby.rb
  14. 55 111
      conformance/failure_list_ruby.txt
  15. 0 1
      csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
  16. 0 1
      csharp/src/Google.Protobuf.Benchmarks/Google.Protobuf.Benchmarks.csproj
  17. 0 1
      csharp/src/Google.Protobuf.Test.TestProtos/Google.Protobuf.Test.TestProtos.csproj
  18. 0 1
      csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
  19. 0 1
      csharp/src/Google.Protobuf/Google.Protobuf.csproj
  20. 8 0
      docs/options.md
  21. 21 24
      java/core/src/main/java/com/google/protobuf/Descriptors.java
  22. 2 0
      java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
  23. 32 7
      java/core/src/main/java/com/google/protobuf/RawMessageInfo.java
  24. 210 158
      java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
  25. 12 10
      java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java
  26. 6 6
      java/core/src/test/java/com/google/protobuf/Proto3MessageLiteInfoFactory.java
  27. 14 14
      java/core/src/test/java/com/google/protobuf/TextFormatTest.java
  28. 2 2
      java/pom.xml
  29. 1 0
      java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
  30. 3 0
      js/binary/decoder_test.js
  31. 1 1
      js/binary/utils.js
  32. 1 1
      js/package.json
  33. 15 63
      kokoro/linux/dockerfile/test/php/Dockerfile
  34. 1 1
      kokoro/linux/dockerfile/test/php80/Dockerfile
  35. 50 78
      kokoro/linux/dockerfile/test/php_32bit/Dockerfile
  36. 2 1
      kokoro/linux/dockerfile/test/ruby/Dockerfile
  37. 1 1
      kokoro/linux/php80/build.sh
  38. 18 0
      kokoro/linux/ruby30/build.sh
  39. 11 0
      kokoro/linux/ruby30/continuous.cfg
  40. 11 0
      kokoro/linux/ruby30/presubmit.cfg
  41. 5 1
      kokoro/macos/prepare_build_macos_rc
  42. 13 0
      kokoro/macos/ruby30/build.sh
  43. 5 0
      kokoro/macos/ruby30/continuous.cfg
  44. 5 0
      kokoro/macos/ruby30/presubmit.cfg
  45. 10 7
      kokoro/release/ruby/macos/ruby/ruby_build_environment.sh
  46. 318 296
      m4/ax_pthread.m4
  47. 1 1
      objectivec/GPBMessage.m
  48. 2 2
      php/composer.json
  49. 4 3
      php/ext/google/protobuf/array.c
  50. 33 28
      php/ext/google/protobuf/def.c
  51. 4 3
      php/ext/google/protobuf/map.c
  52. 13 8
      php/ext/google/protobuf/message.c
  53. 1 0
      php/ext/google/protobuf/protobuf.c
  54. 7 0
      php/ext/google/protobuf/protobuf.h
  55. 205 197
      php/ext/google/protobuf/wkt.inc
  56. 1 1
      php/src/Google/Protobuf/Api.php
  57. 1 1
      php/src/Google/Protobuf/Enum.php
  58. 1 1
      php/src/Google/Protobuf/Internal/DescriptorProto.php
  59. 1 1
      php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php
  60. 1 1
      php/src/Google/Protobuf/Internal/EnumDescriptorProto.php
  61. 1 1
      php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php
  62. 1 1
      php/src/Google/Protobuf/Internal/FieldDescriptorProto.php
  63. 2 2
      php/src/Google/Protobuf/Internal/FileDescriptorProto.php
  64. 1 1
      php/src/Google/Protobuf/Internal/GPBUtil.php
  65. 1 1
      php/src/Google/Protobuf/Internal/MapField.php
  66. 1 1
      php/src/Google/Protobuf/Internal/MethodDescriptorProto.php
  67. 1 1
      php/src/Google/Protobuf/Internal/OneofDescriptorProto.php
  68. 1 1
      php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php
  69. 1 1
      php/src/Google/Protobuf/Option.php
  70. 1 1
      php/src/Google/Protobuf/Type.php
  71. 2 2
      php/src/Google/Protobuf/Value.php
  72. 20 17
      php/tests/ArrayTest.php
  73. 4 6
      php/tests/DescriptorsTest.php
  74. 47 70
      php/tests/EncodeDecodeTest.php
  75. 28 19
      php/tests/GeneratedClassTest.php
  76. 4 4
      php/tests/GeneratedPhpdocTest.php
  77. 35 18
      php/tests/GeneratedServiceTest.php
  78. 12 9
      php/tests/MapFieldTest.php
  79. 17 10
      php/tests/PhpImplementationTest.php
  80. 6 9
      php/tests/WellKnownTest.php
  81. 5 1
      php/tests/WrapperTypeSettersTest.php
  82. 5 3
      php/tests/test.sh
  83. 24 0
      php/tests/test_base.php
  84. 1 1
      python/google/protobuf/__init__.py
  85. 32 9
      python/google/protobuf/descriptor.py
  86. 1 3
      python/google/protobuf/internal/factory_test1.proto
  87. 17 0
      python/google/protobuf/internal/message_factory_test.py
  88. 27 0
      python/google/protobuf/internal/unknown_fields_test.py
  89. 44 19
      python/google/protobuf/message_factory.py
  90. 26 0
      python/google/protobuf/proto_api.h
  91. 114 103
      python/google/protobuf/pyext/message.cc
  92. 46 45
      python/google/protobuf/pyext/message.h
  93. 10 2
      python/google/protobuf/pyext/message_module.cc
  94. 4 0
      python/google/protobuf/pyext/repeated_composite_container.cc
  95. 4 0
      python/google/protobuf/pyext/repeated_scalar_container.cc
  96. 1 0
      python/google/protobuf/pyext/unknown_fields.cc
  97. 1 14
      python/google/protobuf/service_reflection.py
  98. 4 1
      python/google/protobuf/text_format.py
  99. 14 2
      ruby/Rakefile
  100. 3 3
      ruby/compatibility_tests/v3.0.0/tests/basic.rb

+ 1 - 1
.github/workflows/codespell.yml

@@ -13,4 +13,4 @@ jobs:
         with:
           check_filenames: true
           skip: ./.git,./conformance/third_party,*.snk,*.pb,*.pb.cc,*.pb.h,./src/google/protobuf/testdata,./objectivec/Tests,./python/compatibility_tests/v2.5.0/tests/google/protobuf/internal
-          ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,files',fo,fundementals,hel,importd,inout,leapyear,nd,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od"
+          ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,files',fo,fundementals,hel,importd,inout,leapyear,nd,nin,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od"

+ 3 - 0
.gitignore

@@ -137,6 +137,7 @@ conformance/*.class
 
 # php test output
 composer.lock
+php/.phpunit.result.cache
 php/tests/.phpunit.result.cache
 php/tests/generated/
 php/tests/old_protoc
@@ -162,6 +163,7 @@ php/ext/google/protobuf/configure.ac
 php/ext/google/protobuf/configure.in
 php/ext/google/protobuf/mkinstalldirs
 php/ext/google/protobuf/run-tests.php
+php/ext/google/protobuf/third_party/
 vendor/
 
 # JavaScript artifacts
@@ -190,6 +192,7 @@ ruby/tests/generated_code_pb.rb
 ruby/tests/test_import_pb.rb
 ruby/tests/test_ruby_package_pb.rb
 ruby/tests/generated_code_proto2_pb.rb
+ruby/tests/multi_level_nesting_test_pb.rb
 ruby/tests/test_import_proto2_pb.rb
 ruby/tests/test_ruby_package_proto2_pb.rb
 ruby/Gemfile.lock

+ 26 - 0
CHANGES.txt

@@ -1,3 +1,29 @@
+Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
+
+  C++
+  * MessageDifferencer: fixed bug when using custom ignore with multiple
+    unknown fields
+  * Use init_seg in MSVC to push initialization to an earlier phase.
+  * Runtime no longer triggers -Wsign-compare warnings.
+  * Fixed -Wtautological-constant-out-of-range-compare warning.
+  * DynamicCastToGenerated works for nullptr input for even if RTTI is disabled
+  * Arena is refactored and optimized.
+  * Clarified/specified that the exact value of Arena::SpaceAllocated() is an
+    implementation detail users must not rely on. It should not be used in
+    unit tests.
+  * Change the signature of Any::PackFrom() to return false on error.
+
+  Java
+  * Avoid possible UnsupportedOperationException when using CodedInputSteam
+    with a direct ByteBuffer.
+  * Make Durations.comparator() and Timestamps.comparator() Serializable.
+  * Add more detailed error information for dynamic message field type
+    validation failure
+
+  Python
+  * Provided an override for the reverse() method that will reverse the internal
+    collection directly instead of using the other methods of the BaseContainer.
+
 2020-11-11 version 3.14.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
 
   Protocol Compiler

+ 14 - 5
Makefile.am

@@ -89,6 +89,7 @@ csharp_EXTRA_DIST=                                                           \
   csharp/src/Google.Protobuf.Benchmarks/BenchmarkDatasetConfig.cs            \
   csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs           \
   csharp/src/Google.Protobuf.Benchmarks/Benchmarks.cs                        \
+  csharp/src/Google.Protobuf.Benchmarks/ByteStringBenchmark.cs               \
   csharp/src/Google.Protobuf.Benchmarks/Google.Protobuf.Benchmarks.csproj    \
   csharp/src/Google.Protobuf.Benchmarks/GoogleMessageBenchmark.cs            \
   csharp/src/Google.Protobuf.Benchmarks/ParseMessagesBenchmark.cs            \
@@ -171,6 +172,7 @@ csharp_EXTRA_DIST=                                                           \
   csharp/src/Google.Protobuf.sln                                             \
   csharp/src/Google.Protobuf/ByteArray.cs                                    \
   csharp/src/Google.Protobuf/ByteString.cs                                   \
+  csharp/src/Google.Protobuf/ByteStringAsync.cs                              \
   csharp/src/Google.Protobuf/CodedInputStream.cs                             \
   csharp/src/Google.Protobuf/CodedOutputStream.ComputeSize.cs                \
   csharp/src/Google.Protobuf/CodedOutputStream.cs                            \
@@ -268,7 +270,8 @@ csharp_EXTRA_DIST=                                                           \
   csharp/src/Google.Protobuf/WriteContext.cs                                 \
   csharp/src/Google.Protobuf/WriteBufferHelper.cs                            \
   csharp/src/Google.Protobuf/UnknownField.cs                                 \
-  csharp/src/Google.Protobuf/UnknownFieldSet.cs
+  csharp/src/Google.Protobuf/UnknownFieldSet.cs                              \
+  csharp/src/Google.Protobuf/UnsafeByteOperations.cs
 
 java_EXTRA_DIST=                                                                   \
   java/README.md                                                                   \
@@ -772,13 +775,11 @@ php_EXTRA_DIST=                                                       \
   php/ext/google/protobuf/arena.h                                     \
   php/ext/google/protobuf/array.c                                     \
   php/ext/google/protobuf/array.h                                     \
-  php/ext/google/protobuf/bundled_php.h                               \
   php/ext/google/protobuf/config.m4                                   \
   php/ext/google/protobuf/convert.c                                   \
   php/ext/google/protobuf/convert.h                                   \
   php/ext/google/protobuf/def.c                                       \
   php/ext/google/protobuf/def.h                                       \
-  php/ext/google/protobuf/make-preload.php                            \
   php/ext/google/protobuf/map.c                                       \
   php/ext/google/protobuf/map.h                                       \
   php/ext/google/protobuf/message.c                                   \
@@ -790,8 +791,10 @@ php_EXTRA_DIST=                                                       \
   php/ext/google/protobuf/php-upb.h                                   \
   php/ext/google/protobuf/protobuf.c                                  \
   php/ext/google/protobuf/protobuf.h                                  \
+  php/ext/google/protobuf/wkt.inc                                     \
   php/generate_descriptor_protos.sh                                   \
   php/phpunit.xml                                                     \
+  php/prepare_c_extension.sh                                          \
   php/release.sh                                                      \
   php/src/GPBMetadata/Google/Protobuf/Any.php                         \
   php/src/GPBMetadata/Google/Protobuf/Api.php                         \
@@ -827,6 +830,7 @@ php_EXTRA_DIST=                                                       \
   php/src/Google/Protobuf/GPBEmpty.php                                \
   php/src/Google/Protobuf/Int32Value.php                              \
   php/src/Google/Protobuf/Int64Value.php                              \
+  php/src/Google/Protobuf/Internal/AnyBase.php                        \
   php/src/Google/Protobuf/Internal/CodedInputStream.php               \
   php/src/Google/Protobuf/Internal/CodedOutputStream.php              \
   php/src/Google/Protobuf/Internal/Descriptor.php                     \
@@ -886,6 +890,7 @@ php_EXTRA_DIST=                                                       \
   php/src/Google/Protobuf/Internal/ServiceOptions.php                 \
   php/src/Google/Protobuf/Internal/SourceCodeInfo.php                 \
   php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php        \
+  php/src/Google/Protobuf/Internal/TimestampBase.php                  \
   php/src/Google/Protobuf/Internal/UninterpretedOption.php            \
   php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php   \
   php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php \
@@ -1110,13 +1115,15 @@ ruby_EXTRA_DIST=                                                             \
   ruby/src/main/java/com/google/protobuf/jruby/RubyBuilder.java              \
   ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptor.java           \
   ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptorPool.java       \
+  ruby/src/main/java/com/google/protobuf/jruby/RubyEnum.java                 \
   ruby/src/main/java/com/google/protobuf/jruby/RubyEnumBuilderContext.java   \
   ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java       \
-  ruby/src/main/java/com/google/protobuf/jruby/RubyEnum.java                 \
   ruby/src/main/java/com/google/protobuf/jruby/RubyFieldDescriptor.java      \
+  ruby/src/main/java/com/google/protobuf/jruby/RubyFileBuilderContext.java   \
+  ruby/src/main/java/com/google/protobuf/jruby/RubyFileDescriptor.java       \
   ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java                  \
-  ruby/src/main/java/com/google/protobuf/jruby/RubyMessageBuilderContext.java \
   ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java              \
+  ruby/src/main/java/com/google/protobuf/jruby/RubyMessageBuilderContext.java \
   ruby/src/main/java/com/google/protobuf/jruby/RubyOneofBuilderContext.java  \
   ruby/src/main/java/com/google/protobuf/jruby/RubyOneofDescriptor.java      \
   ruby/src/main/java/com/google/protobuf/jruby/RubyProtobuf.java             \
@@ -1390,6 +1397,8 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST)   \
   python/release/wheel/README.md         \
   third_party/six.BUILD                  \
   third_party/zlib.BUILD                 \
+  third_party/wyhash/LICENSE             \
+  third_party/wyhash/wyhash.h            \
   util/python/BUILD
 
 

+ 1 - 1
Protobuf-C++.podspec

@@ -1,6 +1,6 @@
 Pod::Spec.new do |s|
   s.name     = 'Protobuf-C++'
-  s.version  = '3.13.0'
+  s.version  = '3.14.0'
   s.summary  = 'Protocol Buffers v3 runtime library for C++.'
   s.homepage = 'https://github.com/google/protobuf'
   s.license  = '3-Clause BSD License'

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 2
README.md


+ 0 - 1
cmake/conformance.cmake

@@ -21,7 +21,6 @@ add_custom_command(
 add_executable(conformance_test_runner
   ${protobuf_source_dir}/conformance/conformance.pb.cc
   ${protobuf_source_dir}/conformance/conformance_test.cc
-  ${protobuf_source_dir}/conformance/binary_json_conformance_main.cc
   ${protobuf_source_dir}/conformance/binary_json_conformance_suite.cc
   ${protobuf_source_dir}/conformance/binary_json_conformance_suite.h
   ${protobuf_source_dir}/conformance/conformance_test_runner.cc

+ 6 - 1
cmake/install.cmake

@@ -102,12 +102,16 @@ endforeach()
 
 # Install configuration
 set(_cmakedir_desc "Directory relative to CMAKE_INSTALL to install the cmake configuration files")
+set(_exampledir_desc "Directory relative to CMAKE_INSTALL_DATA to install examples")
 if(NOT MSVC)
   set(CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/protobuf" CACHE STRING "${_cmakedir_desc}")
+  set(CMAKE_INSTALL_EXAMPLEDIR "${CMAKE_INSTALL_DATADIR}/protobuf/examples" CACHE STRING "${_exampledir_desc}")
 else()
   set(CMAKE_INSTALL_CMAKEDIR "cmake" CACHE STRING "${_cmakedir_desc}")
+  set(CMAKE_INSTALL_EXAMPLEDIR "examples" CACHE STRING "${_exampledir_desc}")
 endif()
 mark_as_advanced(CMAKE_INSTALL_CMAKEDIR)
+mark_as_advanced(CMAKE_INSTALL_EXAMPLEDIR)
 
 configure_file(protobuf-config.cmake.in
   ${CMAKE_INSTALL_CMAKEDIR}/protobuf-config.cmake @ONLY)
@@ -145,6 +149,7 @@ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}/
 
 option(protobuf_INSTALL_EXAMPLES "Install the examples folder" OFF)
 if(protobuf_INSTALL_EXAMPLES)
-  install(DIRECTORY ../examples/ DESTINATION examples
+  install(DIRECTORY ../examples/
+    DESTINATION "${CMAKE_INSTALL_EXAMPLEDIR}"
     COMPONENT protobuf-examples)
 endif()

+ 1 - 1
cmake/protobuf-lite.pc.cmake

@@ -7,5 +7,5 @@ Name: Protocol Buffers
 Description: Google's Data Interchange Format
 Version: @protobuf_VERSION@
 Libs: -L${libdir} -lprotobuf-lite @CMAKE_THREAD_LIBS_INIT@
-Cflags: -I${includedir} @CMAKE_THREAD_LIBS_INIT@
+Cflags: -I${includedir}
 Conflicts: protobuf

+ 1 - 1
cmake/protobuf.pc.cmake

@@ -7,5 +7,5 @@ Name: Protocol Buffers
 Description: Google's Data Interchange Format
 Version: @protobuf_VERSION@
 Libs: -L${libdir} -lprotobuf @CMAKE_THREAD_LIBS_INIT@
-Cflags: -I${includedir} @CMAKE_THREAD_LIBS_INIT@
+Cflags: -I${includedir}
 Conflicts: protobuf-lite

+ 1 - 1
configure.ac

@@ -17,7 +17,7 @@ AC_PREREQ(2.59)
 # In the SVN trunk, the version should always be the next anticipated release
 # version with the "-pre" suffix.  (We used to use "-SNAPSHOT" but this pushed
 # the size of one file name in the dist tarfile over the 99-char limit.)
-AC_INIT([Protocol Buffers],[3.13.0],[protobuf@googlegroups.com],[protobuf])
+AC_INIT([Protocol Buffers],[3.14.0],[protobuf@googlegroups.com],[protobuf])
 
 AM_MAINTAINER_MODE([enable])
 

+ 3 - 3
conformance/Makefile.am

@@ -347,15 +347,15 @@ test_csharp: protoc_middleman conformance-test-runner conformance-csharp
 test_ruby: protoc_middleman conformance-test-runner $(other_language_protoc_outputs)
 	RUBYLIB=../ruby/lib:. ./conformance-test-runner --enforce_recommended --failure_list failure_list_ruby.txt --text_format_failure_list text_format_failure_list_ruby.txt ./conformance_ruby.rb
 
+test_jruby: protoc_middleman conformance-test-runner $(other_language_protoc_outputs)
+	RUBYLIB=../ruby/lib:. ./conformance-test-runner --enforce_recommended --failure_list failure_list_jruby.txt --text_format_failure_list text_format_failure_list_jruby.txt ./conformance_ruby.rb
+
 test_php: protoc_middleman conformance-test-runner conformance-php $(other_language_protoc_outputs)
 	./conformance-test-runner --enforce_recommended --failure_list failure_list_php.txt --text_format_failure_list text_format_failure_list_php.txt ./conformance-php
 
 test_php_c: protoc_middleman conformance-test-runner conformance-php-c $(other_language_protoc_outputs)
 	./conformance-test-runner --enforce_recommended --failure_list failure_list_php_c.txt --text_format_failure_list text_format_failure_list_php.txt ./conformance-php-c
 
-test_php_c_32: protoc_middleman conformance-test-runner conformance-php-c $(other_language_protoc_outputs)
-	./conformance-test-runner --enforce_recommended --failure_list failure_list_php_c_32.txt --text_format_failure_list text_format_failure_list_php.txt ./conformance-php-c
-
 # These depend on library paths being properly set up.  The easiest way to
 # run them is to just use "tox" from the python dir.
 test_python: protoc_middleman conformance-test-runner

+ 31 - 22
conformance/conformance_ruby.rb

@@ -32,6 +32,7 @@
 
 require 'conformance_pb'
 require 'google/protobuf/test_messages_proto3_pb'
+require 'google/protobuf/test_messages_proto2_pb'
 
 $test_count = 0
 $verbose = false
@@ -39,39 +40,39 @@ $verbose = false
 def do_test(request)
   test_message = ProtobufTestMessages::Proto3::TestAllTypesProto3.new
   response = Conformance::ConformanceResponse.new
+  descriptor = Google::Protobuf::DescriptorPool.generated_pool.lookup(request.message_type)
+
+  unless descriptor
+    response.skipped = "Unknown message type: " + request.message_type
+  end
 
   begin
     case request.payload
     when :protobuf_payload
-      if request.message_type.eql?('protobuf_test_messages.proto3.TestAllTypesProto3')
-        begin
-          test_message = ProtobufTestMessages::Proto3::TestAllTypesProto3.decode(
-              request.protobuf_payload)
-        rescue Google::Protobuf::ParseError => err
-          response.parse_error = err.message.encode('utf-8')
-          return response
-        end
-      elsif request.message_type.eql?('protobuf_test_messages.proto2.TestAllTypesProto2')
-        response.skipped = "Ruby doesn't support proto2"
+      begin
+        test_message = descriptor.msgclass.decode(request.protobuf_payload)
+      rescue Google::Protobuf::ParseError => err
+        response.parse_error = err.message.encode('utf-8')
         return response
-      else
-        fail "Protobuf request doesn't have specific payload type"
       end
 
     when :json_payload
       begin
-        test_message = ProtobufTestMessages::Proto3::TestAllTypesProto3.decode_json(
-            request.json_payload)
+        options = {}
+        if request.test_category == :JSON_IGNORE_UNKNOWN_PARSING_TEST
+          options[:ignore_unknown_fields] = true
+        end
+        test_message = descriptor.msgclass.decode_json(request.json_payload, options)
       rescue Google::Protobuf::ParseError => err
         response.parse_error = err.message.encode('utf-8')
         return response
       end
-	
-	when :text_payload
-	  begin
-		response.skipped = "Ruby doesn't support proto2"
-        return response   
-	  end
+
+    when :text_payload
+      begin
+        response.skipped = "Ruby doesn't support text format"
+        return response
+      end
 
     when nil
       fail "Request didn't have payload"
@@ -82,10 +83,18 @@ def do_test(request)
       fail 'Unspecified output format'
 
     when :PROTOBUF
-      response.protobuf_payload = test_message.to_proto
+      begin
+        response.protobuf_payload = test_message.to_proto
+      rescue Google::Protobuf::ParseError => err
+        response.serialize_error = err.message.encode('utf-8')
+      end
 
     when :JSON
-      response.json_payload = test_message.to_json
+      begin
+        response.json_payload = test_message.to_json
+      rescue Google::Protobuf::ParseError => err
+        response.serialize_error = err.message.encode('utf-8')
+      end
 
     when nil
       fail "Request didn't have requested output format"

+ 55 - 111
conformance/failure_list_ruby.txt

@@ -1,114 +1,58 @@
-Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
-Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
-Recommended.FieldMaskTooManyUnderscore.JsonOutput
 Recommended.Proto2.JsonInput.FieldNameExtension.Validator
-Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput
-Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput
-Recommended.Proto3.JsonInput.DurationHas3FractionalDigits.Validator
-Recommended.Proto3.JsonInput.DurationHas6FractionalDigits.Validator
-Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
-Recommended.Proto3.JsonInput.MapFieldValueIsNull
-Recommended.Proto3.JsonInput.NullValueInNormalMessage.Validator
-Recommended.Proto3.JsonInput.NullValueInOtherOneofNewFormat.Validator
-Recommended.Proto3.JsonInput.NullValueInOtherOneofOldFormat.Validator
-Recommended.Proto3.JsonInput.RepeatedFieldMessageElementIsNull
-Recommended.Proto3.JsonInput.RepeatedFieldPrimitiveElementIsNull
-Recommended.Proto3.JsonInput.StringEndsWithEscapeChar
-Recommended.Proto3.JsonInput.StringFieldSurrogateInWrongOrder
-Recommended.Proto3.JsonInput.StringFieldUnpairedHighSurrogate
-Recommended.Proto3.JsonInput.StringFieldUnpairedLowSurrogate
-Recommended.Proto3.JsonInput.TimestampHas3FractionalDigits.Validator
-Recommended.Proto3.JsonInput.TimestampHas6FractionalDigits.Validator
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.Merge.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.UnpackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput
 Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[3].ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[4].ProtobufOutput
-Required.DurationProtoInputTooLarge.JsonOutput
-Required.DurationProtoInputTooSmall.JsonOutput
-Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator
-Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
-Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
-Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
-Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
-Required.Proto3.JsonInput.DoubleFieldNan.JsonOutput
-Required.Proto3.JsonInput.DurationMinValue.JsonOutput
-Required.Proto3.JsonInput.DurationRepeatedValue.JsonOutput
-Required.Proto3.JsonInput.FloatFieldInfinity.JsonOutput
-Required.Proto3.JsonInput.FloatFieldNan.JsonOutput
-Required.Proto3.JsonInput.FloatFieldNegativeInfinity.JsonOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonFalse.ProtobufOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonNull.ProtobufOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonNumber.ProtobufOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonObject.ProtobufOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonString.ProtobufOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonTrue.ProtobufOutput
-Required.Proto3.JsonInput.OneofFieldDuplicate
-Required.Proto3.JsonInput.RejectTopLevelNull
-Required.Proto3.JsonInput.StringFieldSurrogatePair.JsonOutput
-Required.Proto3.JsonInput.StringFieldSurrogatePair.ProtobufOutput
-Required.Proto3.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
-Required.Proto3.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
-Required.Proto3.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
-Required.Proto3.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.MissingDefault.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.JsonOutput
-Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[2].JsonOutput
-Required.TimestampProtoInputTooLarge.JsonOutput
-Required.TimestampProtoInputTooSmall.JsonOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput
+Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.UnpackedOutput.ProtobufOutput

+ 0 - 1
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj

@@ -5,7 +5,6 @@
     <TargetFrameworks>net451;netcoreapp2.1</TargetFrameworks>
     <AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
     <SignAssembly>true</SignAssembly>
-    <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
     <IsPackable>False</IsPackable>
   </PropertyGroup>
 

+ 0 - 1
csharp/src/Google.Protobuf.Benchmarks/Google.Protobuf.Benchmarks.csproj

@@ -5,7 +5,6 @@
     <TargetFramework>netcoreapp3.1</TargetFramework>
     <AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
     <SignAssembly>true</SignAssembly>
-    <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
     <IsPackable>False</IsPackable>
     <DebugType>pdbonly</DebugType>
     <DebugSymbols>true</DebugSymbols>

+ 0 - 1
csharp/src/Google.Protobuf.Test.TestProtos/Google.Protobuf.Test.TestProtos.csproj

@@ -10,7 +10,6 @@
     <LangVersion>3.0</LangVersion>
     <AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
     <SignAssembly>true</SignAssembly>
-    <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
     <IsPackable>False</IsPackable>
   </PropertyGroup>
 

+ 0 - 1
csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj

@@ -4,7 +4,6 @@
     <TargetFrameworks>net451;netcoreapp2.1</TargetFrameworks>
     <AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
     <SignAssembly>true</SignAssembly>
-    <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
     <IsPackable>False</IsPackable>
     <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
   </PropertyGroup>

+ 0 - 1
csharp/src/Google.Protobuf/Google.Protobuf.csproj

@@ -12,7 +12,6 @@
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
     <SignAssembly>true</SignAssembly>
-    <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
     <PackageTags>Protocol;Buffers;Binary;Serialization;Format;Google;proto;proto3</PackageTags>
     <PackageReleaseNotes>C# proto3 support</PackageReleaseNotes>
     <PackageProjectUrl>https://github.com/protocolbuffers/protobuf</PackageProjectUrl>

+ 8 - 0
docs/options.md

@@ -252,3 +252,11 @@ with info about your project (name and website) so we can add an entry for you.
 1. Confluent Schema Registry
    * Website: https://github.com/confluentinc/schema-registry
    * Extensions: 1088
+   
+1. ScalaPB Validate
+   * Website: https://scalapb.github.io/docs/validation
+   * Extension: 1089
+   
+1. Astounding (Currently Private)
+   * Website: https://github.com/PbPipes/Astounding 
+   * Extension: 1090

+ 21 - 24
java/core/src/main/java/com/google/protobuf/Descriptors.java

@@ -190,7 +190,7 @@ public final class Descriptors {
         name = packageName + '.' + name;
       }
       final GenericDescriptor result = pool.findSymbol(name);
-      if (result != null && result instanceof Descriptor && result.getFile() == this) {
+      if (result instanceof Descriptor && result.getFile() == this) {
         return (Descriptor) result;
       } else {
         return null;
@@ -214,7 +214,7 @@ public final class Descriptors {
         name = packageName + '.' + name;
       }
       final GenericDescriptor result = pool.findSymbol(name);
-      if (result != null && result instanceof EnumDescriptor && result.getFile() == this) {
+      if (result instanceof EnumDescriptor && result.getFile() == this) {
         return (EnumDescriptor) result;
       } else {
         return null;
@@ -238,7 +238,7 @@ public final class Descriptors {
         name = packageName + '.' + name;
       }
       final GenericDescriptor result = pool.findSymbol(name);
-      if (result != null && result instanceof ServiceDescriptor && result.getFile() == this) {
+      if (result instanceof ServiceDescriptor && result.getFile() == this) {
         return (ServiceDescriptor) result;
       } else {
         return null;
@@ -260,7 +260,7 @@ public final class Descriptors {
         name = packageName + '.' + name;
       }
       final GenericDescriptor result = pool.findSymbol(name);
-      if (result != null && result instanceof FieldDescriptor && result.getFile() == this) {
+      if (result instanceof FieldDescriptor && result.getFile() == this) {
         return (FieldDescriptor) result;
       } else {
         return null;
@@ -338,7 +338,7 @@ public final class Descriptors {
         final Class<?> descriptorOuterClass,
         final String[] dependencyClassNames,
         final String[] dependencyFileNames) {
-      List<FileDescriptor> descriptors = new ArrayList<FileDescriptor>();
+      List<FileDescriptor> descriptors = new ArrayList<>();
       for (int i = 0; i < dependencyClassNames.length; i++) {
         try {
           Class<?> clazz = descriptorOuterClass.getClassLoader().loadClass(dependencyClassNames[i]);
@@ -507,11 +507,11 @@ public final class Descriptors {
       this.pool = pool;
       this.proto = proto;
       this.dependencies = dependencies.clone();
-      HashMap<String, FileDescriptor> nameToFileMap = new HashMap<String, FileDescriptor>();
+      HashMap<String, FileDescriptor> nameToFileMap = new HashMap<>();
       for (FileDescriptor file : dependencies) {
         nameToFileMap.put(file.getName(), file);
       }
-      List<FileDescriptor> publicDependencies = new ArrayList<FileDescriptor>();
+      List<FileDescriptor> publicDependencies = new ArrayList<>();
       for (int i = 0; i < proto.getPublicDependencyCount(); i++) {
         int index = proto.getPublicDependency(i);
         if (index < 0 || index >= proto.getDependencyCount()) {
@@ -758,7 +758,7 @@ public final class Descriptors {
      * y" ranges declared on it.
      */
     public boolean isExtendable() {
-      return proto.getExtensionRangeList().size() != 0;
+      return !proto.getExtensionRangeList().isEmpty();
     }
 
     /**
@@ -772,7 +772,7 @@ public final class Descriptors {
      */
     public FieldDescriptor findFieldByName(final String name) {
       final GenericDescriptor result = file.pool.findSymbol(fullName + '.' + name);
-      if (result != null && result instanceof FieldDescriptor) {
+      if (result instanceof FieldDescriptor) {
         return (FieldDescriptor) result;
       } else {
         return null;
@@ -797,7 +797,7 @@ public final class Descriptors {
      */
     public Descriptor findNestedTypeByName(final String name) {
       final GenericDescriptor result = file.pool.findSymbol(fullName + '.' + name);
-      if (result != null && result instanceof Descriptor) {
+      if (result instanceof Descriptor) {
         return (Descriptor) result;
       } else {
         return null;
@@ -812,7 +812,7 @@ public final class Descriptors {
      */
     public EnumDescriptor findEnumTypeByName(final String name) {
       final GenericDescriptor result = file.pool.findSymbol(fullName + '.' + name);
-      if (result != null && result instanceof EnumDescriptor) {
+      if (result instanceof EnumDescriptor) {
         return (EnumDescriptor) result;
       } else {
         return null;
@@ -1701,7 +1701,7 @@ public final class Descriptors {
      */
     public EnumValueDescriptor findValueByName(final String name) {
       final GenericDescriptor result = file.pool.findSymbol(fullName + '.' + name);
-      if (result != null && result instanceof EnumValueDescriptor) {
+      if (result instanceof EnumValueDescriptor) {
         return (EnumValueDescriptor) result;
       } else {
         return null;
@@ -1785,7 +1785,7 @@ public final class Descriptors {
     private final Descriptor containingType;
     private EnumValueDescriptor[] values;
     private final WeakHashMap<Integer, WeakReference<EnumValueDescriptor>> unknownValues =
-        new WeakHashMap<Integer, WeakReference<EnumValueDescriptor>>();
+        new WeakHashMap<>();
 
     private EnumDescriptor(
         final EnumDescriptorProto proto,
@@ -1991,7 +1991,7 @@ public final class Descriptors {
      */
     public MethodDescriptor findMethodByName(final String name) {
       final GenericDescriptor result = file.pool.findSymbol(fullName + '.' + name);
-      if (result != null && result instanceof MethodDescriptor) {
+      if (result instanceof MethodDescriptor) {
         return (MethodDescriptor) result;
       } else {
         return null;
@@ -2265,12 +2265,12 @@ public final class Descriptors {
     }
 
     DescriptorPool(final FileDescriptor[] dependencies, boolean allowUnknownDependencies) {
-      this.dependencies = new HashSet<FileDescriptor>();
+      this.dependencies = new HashSet<>();
       this.allowUnknownDependencies = allowUnknownDependencies;
 
-      for (int i = 0; i < dependencies.length; i++) {
-        this.dependencies.add(dependencies[i]);
-        importPublicDependencies(dependencies[i]);
+      for (Descriptors.FileDescriptor dependency : dependencies) {
+        this.dependencies.add(dependency);
+        importPublicDependencies(dependency);
       }
 
       for (final FileDescriptor dependency : this.dependencies) {
@@ -2297,12 +2297,9 @@ public final class Descriptors {
     private final Set<FileDescriptor> dependencies;
     private boolean allowUnknownDependencies;
 
-    private final Map<String, GenericDescriptor> descriptorsByName =
-        new HashMap<String, GenericDescriptor>();
-    private final Map<DescriptorIntPair, FieldDescriptor> fieldsByNumber =
-        new HashMap<DescriptorIntPair, FieldDescriptor>();
-    private final Map<DescriptorIntPair, EnumValueDescriptor> enumValuesByNumber =
-        new HashMap<DescriptorIntPair, EnumValueDescriptor>();
+    private final Map<String, GenericDescriptor> descriptorsByName = new HashMap<>();
+    private final Map<DescriptorIntPair, FieldDescriptor> fieldsByNumber = new HashMap<>();
+    private final Map<DescriptorIntPair, EnumValueDescriptor> enumValuesByNumber = new HashMap<>();
 
     /** Find a generic descriptor by fully-qualified name. */
     GenericDescriptor findSymbol(final String fullName) {

+ 2 - 0
java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java

@@ -266,12 +266,14 @@ public abstract class GeneratedMessageLite<
     memoizedSerializedSize = size;
   }
 
+  @Override
   public void writeTo(CodedOutputStream output) throws IOException {
     Protobuf.getInstance()
         .schemaFor(this)
         .writeTo(this, CodedOutputStreamWriter.forCodedOutput(output));
   }
 
+  @Override
   public int getSerializedSize() {
     if (memoizedSerializedSize == -1) {
       memoizedSerializedSize = Protobuf.getInstance().schemaFor(this).getSerializedSize(this);

+ 32 - 7
java/core/src/main/java/com/google/protobuf/RawMessageInfo.java

@@ -80,14 +80,15 @@ final class RawMessageInfo implements MessageInfo {
    *   <li>[1]: field type with extra bits:
    *       <ul>
    *         <li>v & 0xFF = field type as defined in the FieldType class
-   *         <li>v & 0x100 = is required?
-   *         <li>v & 0x200 = is checkUtf8?
-   *         <li>v & 0x400 = needs isInitialized check?
-   *         <li>v & 0x800 = is map field with proto2 enum value?
+   *         <li>v & 0x0100 = is required?
+   *         <li>v & 0x0200 = is checkUtf8?
+   *         <li>v & 0x0400 = needs isInitialized check?
+   *         <li>v & 0x0800 = is map field with proto2 enum value?
+   *         <li>v & 0x1000 = supports presence checking?
    *       </ul>
    * </ul>
    *
-   * If the file is proto2 and this is a singular field:
+   * If the (singular) field supports presence checking:
    *
    * <ul>
    *   <li>[2]: hasbits offset
@@ -180,8 +181,32 @@ final class RawMessageInfo implements MessageInfo {
     this.defaultInstance = defaultInstance;
     this.info = info;
     this.objects = objects;
-    int position = 0;
-    int value = (int) info.charAt(position++);
+    int value;
+    try {
+      value = (int) info.charAt(0);
+    } catch (ArrayIndexOutOfBoundsException e) {
+      // This is a fix for issues
+      // that error out on a subset of phones on charAt(0) with an index out of bounds exception.
+      char[] infoChars = info.toCharArray();
+      info = new String(infoChars);
+      try {
+        value = (int) info.charAt(0);
+      } catch (ArrayIndexOutOfBoundsException e2) {
+        try {
+          char[] infoChars2 = new char[info.length()];
+          info.getChars(0, info.length(), infoChars2, 0);
+          info = new String(infoChars2);
+          value = (int) info.charAt(0);
+        } catch (ArrayIndexOutOfBoundsException e3) {
+          throw new IllegalStateException(
+              String.format(
+                  "Failed parsing '%s' with charArray.length of %d", info, infoChars.length),
+              e3);
+        }
+      }
+    }
+    int position = 1;
+
     if (value < 0xD800) {
       flags = value;
     } else {

+ 210 - 158
java/core/src/main/java/com/google/protobuf/UnsafeUtil.java

@@ -332,83 +332,18 @@ final class UnsafeUtil {
     return new JvmMemoryAccessor(UNSAFE);
   }
 
-  /** Indicates whether or not unsafe array operations are supported on this platform. */
   private static boolean supportsUnsafeArrayOperations() {
-    if (UNSAFE == null) {
+    if (MEMORY_ACCESSOR == null) {
       return false;
     }
-    try {
-      Class<?> clazz = UNSAFE.getClass();
-      clazz.getMethod("objectFieldOffset", Field.class);
-      clazz.getMethod("arrayBaseOffset", Class.class);
-      clazz.getMethod("arrayIndexScale", Class.class);
-      clazz.getMethod("getInt", Object.class, long.class);
-      clazz.getMethod("putInt", Object.class, long.class, int.class);
-      clazz.getMethod("getLong", Object.class, long.class);
-      clazz.getMethod("putLong", Object.class, long.class, long.class);
-      clazz.getMethod("getObject", Object.class, long.class);
-      clazz.getMethod("putObject", Object.class, long.class, Object.class);
-      if (Android.isOnAndroidDevice()) {
-        return true;
-      }
-      clazz.getMethod("getByte", Object.class, long.class);
-      clazz.getMethod("putByte", Object.class, long.class, byte.class);
-      clazz.getMethod("getBoolean", Object.class, long.class);
-      clazz.getMethod("putBoolean", Object.class, long.class, boolean.class);
-      clazz.getMethod("getFloat", Object.class, long.class);
-      clazz.getMethod("putFloat", Object.class, long.class, float.class);
-      clazz.getMethod("getDouble", Object.class, long.class);
-      clazz.getMethod("putDouble", Object.class, long.class, double.class);
-
-      return true;
-    } catch (Throwable e) {
-      // Because log statements are fairly sparse in this class, this logger is initialized
-      // non-statically. Static initialization adds undue runtime costs to the first client to
-      // initialize this class.
-      Logger.getLogger(UnsafeUtil.class.getName())
-          .log(
-              Level.WARNING,
-              "platform method missing - proto runtime falling back to safer methods: " + e);
-    }
-    return false;
+    return MEMORY_ACCESSOR.supportsUnsafeArrayOperations();
   }
 
   private static boolean supportsUnsafeByteBufferOperations() {
-    if (UNSAFE == null) {
+    if (MEMORY_ACCESSOR == null) {
       return false;
     }
-    try {
-      Class<?> clazz = UNSAFE.getClass();
-      // Methods for getting direct buffer address.
-      clazz.getMethod("objectFieldOffset", Field.class);
-      clazz.getMethod("getLong", Object.class, long.class);
-
-      if (bufferAddressField() == null) {
-        return false;
-      }
-
-      if (Android.isOnAndroidDevice()) {
-        return false;
-      }
-      clazz.getMethod("getByte", long.class);
-      clazz.getMethod("putByte", long.class, byte.class);
-      clazz.getMethod("getInt", long.class);
-      clazz.getMethod("putInt", long.class, int.class);
-      clazz.getMethod("getLong", long.class);
-      clazz.getMethod("putLong", long.class, long.class);
-      clazz.getMethod("copyMemory", long.class, long.class, long.class);
-      clazz.getMethod("copyMemory", Object.class, long.class, Object.class, long.class, long.class);
-      return true;
-    } catch (Throwable e) {
-      // Because log statements are fairly sparse in this class, this logger is initialized
-      // non-statically. Static initialization adds undue runtime costs to the first client to
-      // initialize this class.
-      Logger.getLogger(UnsafeUtil.class.getName())
-          .log(
-              Level.WARNING,
-              "platform method missing - proto runtime falling back to safer methods: " + e);
-    }
-    return false;
+    return MEMORY_ACCESSOR.supportsUnsafeByteBufferOperations();
   }
 
   private static boolean determineAndroidSupportByAddressSize(Class<?> addressClass) {
@@ -553,6 +488,43 @@ final class UnsafeUtil {
       return unsafe.objectFieldOffset(field);
     }
 
+    public final int arrayBaseOffset(Class<?> clazz) {
+      return unsafe.arrayBaseOffset(clazz);
+    }
+
+    public final int arrayIndexScale(Class<?> clazz) {
+      return unsafe.arrayIndexScale(clazz);
+    }
+
+    public abstract Object getStaticObject(Field field);
+
+    // Relative Address Operations ---------------------------------------------
+
+    // Indicates whether the following relative address operations are supported
+    // by this memory accessor.
+    public boolean supportsUnsafeArrayOperations() {
+      if (unsafe == null) {
+        return false;
+      }
+      try {
+        Class<?> clazz = unsafe.getClass();
+        clazz.getMethod("objectFieldOffset", Field.class);
+        clazz.getMethod("arrayBaseOffset", Class.class);
+        clazz.getMethod("arrayIndexScale", Class.class);
+        clazz.getMethod("getInt", Object.class, long.class);
+        clazz.getMethod("putInt", Object.class, long.class, int.class);
+        clazz.getMethod("getLong", Object.class, long.class);
+        clazz.getMethod("putLong", Object.class, long.class, long.class);
+        clazz.getMethod("getObject", Object.class, long.class);
+        clazz.getMethod("putObject", Object.class, long.class, Object.class);
+
+        return true;
+      } catch (Throwable e) {
+        logMissingMethod(e);
+      }
+      return false;
+    }
+
     public abstract byte getByte(Object target, long offset);
 
     public abstract void putByte(Object target, long offset, byte value);
@@ -593,12 +565,29 @@ final class UnsafeUtil {
       unsafe.putObject(target, offset, value);
     }
 
-    public final int arrayBaseOffset(Class<?> clazz) {
-      return unsafe.arrayBaseOffset(clazz);
-    }
+    // Absolute Address Operations --------------------------------------------
 
-    public final int arrayIndexScale(Class<?> clazz) {
-      return unsafe.arrayIndexScale(clazz);
+    // Indicates whether the following absolute address operations are
+    // supported by this memory accessor.
+    public boolean supportsUnsafeByteBufferOperations() {
+      if (unsafe == null) {
+        return false;
+      }
+      try {
+        Class<?> clazz = unsafe.getClass();
+        // Methods for getting direct buffer address.
+        clazz.getMethod("objectFieldOffset", Field.class);
+        clazz.getMethod("getLong", Object.class, long.class);
+
+        if (bufferAddressField() == null) {
+          return false;
+        }
+
+        return true;
+      } catch (Throwable e) {
+        logMissingMethod(e);
+      }
+      return false;
     }
 
     public abstract byte getByte(long address);
@@ -613,8 +602,6 @@ final class UnsafeUtil {
 
     public abstract void putLong(long address, long value);
 
-    public abstract Object getStaticObject(Field field);
-
     public abstract void copyMemory(long srcOffset, byte[] target, long targetIndex, long length);
 
     public abstract void copyMemory(byte[] src, long srcIndex, long targetOffset, long length);
@@ -627,33 +614,32 @@ final class UnsafeUtil {
     }
 
     @Override
-    public byte getByte(long address) {
-      return unsafe.getByte(address);
-    }
-
-    @Override
-    public void putByte(long address, byte value) {
-      unsafe.putByte(address, value);
-    }
-
-    @Override
-    public int getInt(long address) {
-      return unsafe.getInt(address);
+    public Object getStaticObject(Field field) {
+      return getObject(unsafe.staticFieldBase(field), unsafe.staticFieldOffset(field));
     }
 
     @Override
-    public void putInt(long address, int value) {
-      unsafe.putInt(address, value);
-    }
+    public boolean supportsUnsafeArrayOperations() {
+      if (!super.supportsUnsafeArrayOperations()) {
+        return false;
+      }
 
-    @Override
-    public long getLong(long address) {
-      return unsafe.getLong(address);
-    }
+      try {
+        Class<?> clazz = unsafe.getClass();
+        clazz.getMethod("getByte", Object.class, long.class);
+        clazz.getMethod("putByte", Object.class, long.class, byte.class);
+        clazz.getMethod("getBoolean", Object.class, long.class);
+        clazz.getMethod("putBoolean", Object.class, long.class, boolean.class);
+        clazz.getMethod("getFloat", Object.class, long.class);
+        clazz.getMethod("putFloat", Object.class, long.class, float.class);
+        clazz.getMethod("getDouble", Object.class, long.class);
+        clazz.getMethod("putDouble", Object.class, long.class, double.class);
 
-    @Override
-    public void putLong(long address, long value) {
-      unsafe.putLong(address, value);
+        return true;
+      } catch (Throwable e) {
+        logMissingMethod(e);
+      }
+      return false;
     }
 
     @Override
@@ -697,55 +683,83 @@ final class UnsafeUtil {
     }
 
     @Override
-    public void copyMemory(long srcOffset, byte[] target, long targetIndex, long length) {
-      unsafe.copyMemory(null, srcOffset, target, BYTE_ARRAY_BASE_OFFSET + targetIndex, length);
+    public boolean supportsUnsafeByteBufferOperations() {
+      if (!super.supportsUnsafeByteBufferOperations()) {
+        return false;
+      }
+
+      try {
+        Class<?> clazz = unsafe.getClass();
+        clazz.getMethod("getByte", long.class);
+        clazz.getMethod("putByte", long.class, byte.class);
+        clazz.getMethod("getInt", long.class);
+        clazz.getMethod("putInt", long.class, int.class);
+        clazz.getMethod("getLong", long.class);
+        clazz.getMethod("putLong", long.class, long.class);
+        clazz.getMethod("copyMemory", long.class, long.class, long.class);
+        clazz.getMethod(
+            "copyMemory", Object.class, long.class, Object.class, long.class, long.class);
+        return true;
+      } catch (Throwable e) {
+        logMissingMethod(e);
+      }
+      return false;
     }
 
     @Override
-    public void copyMemory(byte[] src, long srcIndex, long targetOffset, long length) {
-      unsafe.copyMemory(src, BYTE_ARRAY_BASE_OFFSET + srcIndex, null, targetOffset, length);
+    public byte getByte(long address) {
+      return unsafe.getByte(address);
     }
 
     @Override
-    public Object getStaticObject(Field field) {
-      return getObject(unsafe.staticFieldBase(field), unsafe.staticFieldOffset(field));
+    public void putByte(long address, byte value) {
+      unsafe.putByte(address, value);
     }
-  }
-
-  private static final class Android64MemoryAccessor extends MemoryAccessor {
 
-    Android64MemoryAccessor(sun.misc.Unsafe unsafe) {
-      super(unsafe);
+    @Override
+    public int getInt(long address) {
+      return unsafe.getInt(address);
     }
 
     @Override
-    public byte getByte(long address) {
-      throw new UnsupportedOperationException();
+    public void putInt(long address, int value) {
+      unsafe.putInt(address, value);
     }
 
     @Override
-    public void putByte(long address, byte value) {
-      throw new UnsupportedOperationException();
+    public long getLong(long address) {
+      return unsafe.getLong(address);
     }
 
     @Override
-    public int getInt(long address) {
-      throw new UnsupportedOperationException();
+    public void putLong(long address, long value) {
+      unsafe.putLong(address, value);
     }
 
     @Override
-    public void putInt(long address, int value) {
-      throw new UnsupportedOperationException();
+    public void copyMemory(long srcOffset, byte[] target, long targetIndex, long length) {
+      unsafe.copyMemory(null, srcOffset, target, BYTE_ARRAY_BASE_OFFSET + targetIndex, length);
     }
 
     @Override
-    public long getLong(long address) {
-      throw new UnsupportedOperationException();
+    public void copyMemory(byte[] src, long srcIndex, long targetOffset, long length) {
+      unsafe.copyMemory(src, BYTE_ARRAY_BASE_OFFSET + srcIndex, null, targetOffset, length);
+    }
+  }
+
+  private static final class Android64MemoryAccessor extends MemoryAccessor {
+
+    Android64MemoryAccessor(sun.misc.Unsafe unsafe) {
+      super(unsafe);
     }
 
     @Override
-    public void putLong(long address, long value) {
-      throw new UnsupportedOperationException();
+    public Object getStaticObject(Field field) {
+      try {
+        return field.get(null);
+      } catch (IllegalAccessException e) {
+        return null;
+      }
     }
 
     @Override
@@ -805,67 +819,72 @@ final class UnsafeUtil {
     }
 
     @Override
-    public void copyMemory(long srcOffset, byte[] target, long targetIndex, long length) {
-      throw new UnsupportedOperationException();
+    public boolean supportsUnsafeByteBufferOperations() {
+      return false;
     }
 
     @Override
-    public void copyMemory(byte[] src, long srcIndex, long targetOffset, long length) {
+    public byte getByte(long address) {
       throw new UnsupportedOperationException();
     }
 
     @Override
-    public Object getStaticObject(Field field) {
-      try {
-        return field.get(null);
-      } catch (IllegalAccessException e) {
-        return null;
-      }
-    }
-  }
-
-  private static final class Android32MemoryAccessor extends MemoryAccessor {
-
-    /** Mask used to convert a 64 bit memory address to a 32 bit address. */
-    private static final long SMALL_ADDRESS_MASK = 0x00000000FFFFFFFF;
-
-    /** Truncate a {@code long} address into a short {@code int} address. */
-    private static int smallAddress(long address) {
-      return (int) (SMALL_ADDRESS_MASK & address);
+    public void putByte(long address, byte value) {
+      throw new UnsupportedOperationException();
     }
 
-    Android32MemoryAccessor(sun.misc.Unsafe unsafe) {
-      super(unsafe);
+    @Override
+    public int getInt(long address) {
+      throw new UnsupportedOperationException();
     }
 
     @Override
-    public byte getByte(long address) {
+    public void putInt(long address, int value) {
       throw new UnsupportedOperationException();
     }
 
     @Override
-    public void putByte(long address, byte value) {
+    public long getLong(long address) {
       throw new UnsupportedOperationException();
     }
 
     @Override
-    public int getInt(long address) {
+    public void putLong(long address, long value) {
       throw new UnsupportedOperationException();
     }
 
     @Override
-    public void putInt(long address, int value) {
+    public void copyMemory(long srcOffset, byte[] target, long targetIndex, long length) {
       throw new UnsupportedOperationException();
     }
 
     @Override
-    public long getLong(long address) {
+    public void copyMemory(byte[] src, long srcIndex, long targetOffset, long length) {
       throw new UnsupportedOperationException();
     }
+  }
+
+  private static final class Android32MemoryAccessor extends MemoryAccessor {
+
+    /** Mask used to convert a 64 bit memory address to a 32 bit address. */
+    private static final long SMALL_ADDRESS_MASK = 0x00000000FFFFFFFF;
+
+    /** Truncate a {@code long} address into a short {@code int} address. */
+    private static int smallAddress(long address) {
+      return (int) (SMALL_ADDRESS_MASK & address);
+    }
+
+    Android32MemoryAccessor(sun.misc.Unsafe unsafe) {
+      super(unsafe);
+    }
 
     @Override
-    public void putLong(long address, long value) {
-      throw new UnsupportedOperationException();
+    public Object getStaticObject(Field field) {
+      try {
+        return field.get(null);
+      } catch (IllegalAccessException e) {
+        return null;
+      }
     }
 
     @Override
@@ -925,22 +944,48 @@ final class UnsafeUtil {
     }
 
     @Override
-    public void copyMemory(long srcOffset, byte[] target, long targetIndex, long length) {
+    public boolean supportsUnsafeByteBufferOperations() {
+      return false;
+    }
+
+    @Override
+    public byte getByte(long address) {
       throw new UnsupportedOperationException();
     }
 
     @Override
-    public void copyMemory(byte[] src, long srcIndex, long targetOffset, long length) {
+    public void putByte(long address, byte value) {
       throw new UnsupportedOperationException();
     }
 
     @Override
-    public Object getStaticObject(Field field) {
-      try {
-        return field.get(null);
-      } catch (IllegalAccessException e) {
-        return null;
-      }
+    public int getInt(long address) {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void putInt(long address, int value) {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long getLong(long address) {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void putLong(long address, long value) {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void copyMemory(long srcOffset, byte[] target, long targetIndex, long length) {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void copyMemory(byte[] src, long srcIndex, long targetOffset, long length) {
+      throw new UnsupportedOperationException();
     }
   }
 
@@ -981,4 +1026,11 @@ final class UnsafeUtil {
   private static void putBooleanLittleEndian(Object target, long offset, boolean value) {
     putByteLittleEndian(target, offset, (byte) (value ? 1 : 0));
   }
+
+  private static void logMissingMethod(Throwable e) {
+    Logger.getLogger(UnsafeUtil.class.getName())
+        .log(
+            Level.WARNING,
+            "platform method missing - proto runtime falling back to safer methods: " + e);
+  }
 }

+ 12 - 10
java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java

@@ -66,6 +66,11 @@ public class FieldPresenceTest extends TestCase {
     assertFalse(hasMethod(classWithoutFieldPresence, "has" + camelName));
   }
 
+  private static void assertHasMethodExisting(Class<?> clazz, String camelName) {
+    assertTrue(hasMethod(clazz, "get" + camelName));
+    assertTrue(hasMethod(clazz, "has" + camelName));
+  }
+
   public void testHasMethod() {
     // Optional non-message fields don't have a hasFoo() method generated.
     assertHasMethodRemoved(UnittestProto.TestAllTypes.class, TestAllTypes.class, "OptionalInt32");
@@ -87,19 +92,16 @@ public class FieldPresenceTest extends TestCase {
     assertFalse(TestAllTypes.getDefaultInstance().hasOptionalNestedMessage());
     assertFalse(TestAllTypes.newBuilder().hasOptionalNestedMessage());
 
-    // oneof fields don't have hasFoo() methods for non-message types.
-    assertHasMethodRemoved(UnittestProto.TestAllTypes.class, TestAllTypes.class, "OneofUint32");
-    assertHasMethodRemoved(UnittestProto.TestAllTypes.class, TestAllTypes.class, "OneofString");
-    assertHasMethodRemoved(UnittestProto.TestAllTypes.class, TestAllTypes.class, "OneofBytes");
+    // oneof fields support hasFoo() methods for non-message types.
+    assertHasMethodExisting(TestAllTypes.class, "OneofUint32");
+    assertHasMethodExisting(TestAllTypes.class, "OneofString");
+    assertHasMethodExisting(TestAllTypes.class, "OneofBytes");
     assertFalse(TestAllTypes.getDefaultInstance().hasOneofNestedMessage());
     assertFalse(TestAllTypes.newBuilder().hasOneofNestedMessage());
 
-    assertHasMethodRemoved(
-        UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OneofUint32");
-    assertHasMethodRemoved(
-        UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OneofString");
-    assertHasMethodRemoved(
-        UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OneofBytes");
+    assertHasMethodExisting(TestAllTypes.Builder.class, "OneofUint32");
+    assertHasMethodExisting(TestAllTypes.Builder.class, "OneofString");
+    assertHasMethodExisting(TestAllTypes.Builder.class, "OneofBytes");
   }
 
   public void testHasMethodForProto3Optional() throws Exception {

+ 6 - 6
java/core/src/test/java/com/google/protobuf/Proto3MessageLiteInfoFactory.java

@@ -139,12 +139,12 @@ public final class Proto3MessageLiteInfoFactory implements MessageInfoFactory {
     // the content of the generated buildMessageInfo() method here.
     java.lang.String info =
         "\u0000@\u0001\u0000\u0001D@\u0000\u001f\u0000\u0001\u0000\u0002\u0001\u0003\u0002"
-            + "\u0004\u0003\u0005\u0004\u0006\u0005\u0007\u0006\b\u0007\t\u0208\n\t\u000b\n\f\u000b"
-            + "\r\f\u000e\r\u000f\u000e\u0010\u000f\u0011\u0010\u0012\u0012\u0013\u0013\u0014\u0014"
-            + "\u0015\u0015\u0016\u0016\u0017\u0017\u0018\u0018\u0019\u0019\u001a\u021a\u001b\u001b"
-            + "\u001c\u001c\u001d\u001d\u001e\u001e\u001f\u001f  !!\"\"##$$%%&&\'\'(())**++,,--"
-            + "..//0053\u000064\u000075\u000086\u000097\u0000:8\u0000;9\u0000<:\u0000=\u023b\u0000"
-            + "><\u0000?=\u0000@>\u0000A@\u0000BA\u0000CB\u0000DC\u0000";
+        + "\u0004\u0003\u0005\u0004\u0006\u0005\u0007\u0006\b\u0007\t\u0208\n\t\u000b\n\f\u000b"
+        + "\r\f\u000e\r\u000f\u000e\u0010\u000f\u0011\u0010\u0012\u0012\u0013\u0013\u0014\u0014"
+        + "\u0015\u0015\u0016\u0016\u0017\u0017\u0018\u0018\u0019\u0019\u001a\u021a\u001b\u001b"
+        + "\u001c\u001c\u001d\u001d\u001e\u001e\u001f\u001f  !!\"\"##$$%%&&\'\'(())**++,,--"
+        + "..//0053\u000064\u000075\u000086\u000097\u0000:8\u0000;9\u0000<:\u0000=\u023b\u0000"
+        + "><\u0000?=\u0000@>\u0000A@\u0000BA\u0000CB\u0000DC\u0000";
     return new RawMessageInfo(Proto3MessageLite.getDefaultInstance(), info, objects);
   }
 

+ 14 - 14
java/core/src/test/java/com/google/protobuf/TextFormatTest.java

@@ -1507,9 +1507,9 @@ public class TextFormatTest extends TestCase {
             + "  value: -1\n"
             + "}\n";
     TestMap msg = TextFormat.parse(input, TestMap.class);
-    int i1 = msg.getInt32ToInt32Field().get(1);
+    int i1 = msg.getInt32ToInt32FieldMap().get(1);
     TestMap msg2 = TextFormat.parse(msg.toString(), TestMap.class);
-    int i2 = msg2.getInt32ToInt32Field().get(1);
+    int i2 = msg2.getInt32ToInt32FieldMap().get(1);
     assertEquals(i1, i2);
   }
 
@@ -1521,10 +1521,10 @@ public class TextFormatTest extends TestCase {
     TestMap.Builder dest = TestMap.newBuilder();
     parserWithOverwriteForbidden.merge(text, dest);
     TestMap message = dest.build();
-    assertEquals(2, message.getStringToInt32Field().size());
-    assertEquals(2, message.getInt32ToMessageField().size());
-    assertEquals(10, message.getStringToInt32Field().get("x").intValue());
-    assertEquals(200, message.getInt32ToMessageField().get(2).getValue());
+    assertEquals(2, message.getStringToInt32FieldMap().size());
+    assertEquals(2, message.getInt32ToMessageFieldMap().size());
+    assertEquals(10, message.getStringToInt32FieldMap().get("x").intValue());
+    assertEquals(200, message.getInt32ToMessageFieldMap().get(2).getValue());
   }
 
   public void testMapShortFormEmpty() throws Exception {
@@ -1532,8 +1532,8 @@ public class TextFormatTest extends TestCase {
     TestMap.Builder dest = TestMap.newBuilder();
     parserWithOverwriteForbidden.merge(text, dest);
     TestMap message = dest.build();
-    assertEquals(0, message.getStringToInt32Field().size());
-    assertEquals(0, message.getInt32ToMessageField().size());
+    assertEquals(0, message.getStringToInt32FieldMap().size());
+    assertEquals(0, message.getInt32ToMessageFieldMap().size());
   }
 
   public void testMapShortFormTrailingComma() throws Exception {
@@ -1558,8 +1558,8 @@ public class TextFormatTest extends TestCase {
       TestMap.Builder builder = TestMap.newBuilder();
       defaultParser.merge(text, builder);
       TestMap map = builder.build();
-      assertEquals(2, map.getInt32ToInt32Field().size());
-      assertEquals(30, map.getInt32ToInt32Field().get(1).intValue());
+      assertEquals(2, map.getInt32ToInt32FieldMap().size());
+      assertEquals(30, map.getInt32ToInt32FieldMap().get(1).intValue());
     }
 
     {
@@ -1568,8 +1568,8 @@ public class TextFormatTest extends TestCase {
       TestMap.Builder builder = TestMap.newBuilder();
       parserWithOverwriteForbidden.merge(text, builder);
       TestMap map = builder.build();
-      assertEquals(2, map.getInt32ToInt32Field().size());
-      assertEquals(30, map.getInt32ToInt32Field().get(1).intValue());
+      assertEquals(2, map.getInt32ToInt32FieldMap().size());
+      assertEquals(30, map.getInt32ToInt32FieldMap().get(1).intValue());
     }
 
     {
@@ -1580,8 +1580,8 @@ public class TextFormatTest extends TestCase {
       TestMap map =
           TestMap.parseFrom(
               builder.build().toByteString(), ExtensionRegistryLite.getEmptyRegistry());
-      assertEquals(2, map.getInt32ToInt32Field().size());
-      assertEquals(30, map.getInt32ToInt32Field().get(1).intValue());
+      assertEquals(2, map.getInt32ToInt32FieldMap().size());
+      assertEquals(30, map.getInt32ToInt32FieldMap().get(1).intValue());
     }
   }
 

+ 2 - 2
java/pom.xml

@@ -93,12 +93,12 @@
       <dependency>
         <groupId>com.google.guava</groupId>
         <artifactId>guava</artifactId>
-        <version>29.0-android</version>
+        <version>30.0-android</version>
       </dependency>
       <dependency>
         <groupId>com.google.guava</groupId>
         <artifactId>guava-testlib</artifactId>
-        <version>29.0-android</version>
+        <version>30.0-android</version>
         <scope>test</scope>
       </dependency>
       <dependency>

+ 1 - 0
java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java

@@ -1697,6 +1697,7 @@ public class JsonFormatTest extends TestCase {
   public void testJsonException() throws Exception {
     InputStream throwingInputStream =
         new InputStream() {
+          @Override
           public int read() throws IOException {
             throw new IOException("12345");
           }

+ 3 - 0
js/binary/decoder_test.js

@@ -315,6 +315,9 @@ describe('binaryDecoderTest', function() {
         // 64-bit extremes, not in dev guide.
         {original: '9223372036854775807', zigzag: '18446744073709551614'},
         {original: '-9223372036854775808', zigzag: '18446744073709551615'},
+        // None of the above catch: bitsLow < 0 && bitsHigh > 0 && bitsHigh <
+        // 0x1FFFFF. The following used to be broken.
+        {original: '72000000000', zigzag: '144000000000'},
       ];
       var encoder = new jspb.BinaryEncoder();
       testCases.forEach(function(c) {

+ 1 - 1
js/binary/utils.js

@@ -511,7 +511,7 @@ jspb.utils.joinUnsignedDecimalString = function(bitsLow, bitsHigh) {
   // Skip the expensive conversion if the number is small enough to use the
   // built-in conversions.
   if (bitsHigh <= 0x1FFFFF) {
-    return '' + (jspb.BinaryConstants.TWO_TO_32 * bitsHigh + bitsLow);
+    return '' + jspb.utils.joinUint64(bitsLow, bitsHigh);
   }
 
   // What this code is doing is essentially converting the input number from

+ 1 - 1
js/package.json

@@ -1,6 +1,6 @@
 {
   "name": "google-protobuf",
-  "version": "3.13.0",
+  "version": "3.14.0",
   "description": "Protocol Buffers for JavaScript",
   "main": "google-protobuf.js",
   "files": [

+ 15 - 63
kokoro/linux/dockerfile/test/php/Dockerfile

@@ -55,66 +55,6 @@ RUN mv composer.phar /usr/local/bin/composer
 # Download php source code
 RUN git clone https://github.com/php/php-src
 
-# php 5.5
-RUN cd php-src \
-  && git checkout PHP-5.5.38 \
-  && ./buildconf --force
-RUN cd php-src \
-  && ./configure \
-  --enable-bcmath \
-  --with-gmp \
-  --with-openssl \
-  --with-zlib \
-  --prefix=/usr/local/php-5.5 \
-  && make \
-  && make install \
-  && make clean
-RUN cd php-src \
-  && ./configure \
-  --enable-maintainer-zts \
-  --with-gmp \
-  --with-openssl \
-  --with-zlib \
-  --prefix=/usr/local/php-5.5-zts \
-  && make \
-  && make install \
-  && make clean
-
-RUN wget -O phpunit https://phar.phpunit.de/phpunit-4.phar \
-  && chmod +x phpunit \
-  && cp phpunit /usr/local/php-5.5/bin \
-  && mv phpunit /usr/local/php-5.5-zts/bin
-
-# php 5.6
-RUN cd php-src \
-  && git checkout PHP-5.6.39 \
-  && ./buildconf --force
-RUN cd php-src \
-  && ./configure \
-  --enable-bcmath \
-  --with-gmp \
-  --with-openssl \
-  --with-zlib \
-  --prefix=/usr/local/php-5.6 \
-  && make \
-  && make install \
-  && make clean
-RUN cd php-src \
-  && ./configure \
-  --enable-maintainer-zts \
-  --with-gmp \
-  --with-openssl \
-  --with-zlib \
-  --prefix=/usr/local/php-5.6-zts \
-  && make \
-  && make install \
-  && make clean
-
-RUN wget -O phpunit https://phar.phpunit.de/phpunit-5.phar \
-  && chmod +x phpunit \
-  && cp phpunit /usr/local/php-5.6/bin \
-  && mv phpunit /usr/local/php-5.6-zts/bin
-
 # php 7.0
 RUN cd php-src \
   && git checkout PHP-7.0.33 \
@@ -122,6 +62,7 @@ RUN cd php-src \
 RUN cd php-src \
   && ./configure \
   --enable-bcmath \
+  --enable-mbstring \
   --with-gmp \
   --with-openssl \
   --with-zlib \
@@ -132,6 +73,7 @@ RUN cd php-src \
 RUN cd php-src \
   && ./configure \
   --enable-maintainer-zts \
+  --enable-mbstring \
   --with-gmp \
   --with-openssl \
   --with-zlib \
@@ -152,6 +94,7 @@ RUN cd php-src \
 RUN cd php-src \
   && ./configure \
   --enable-bcmath \
+  --enable-mbstring \
   --with-gmp \
   --with-openssl \
   --with-zlib \
@@ -162,6 +105,7 @@ RUN cd php-src \
 RUN cd php-src \
   && ./configure \
   --enable-maintainer-zts \
+  --enable-mbstring \
   --with-gmp \
   --with-openssl \
   --with-zlib \
@@ -170,7 +114,7 @@ RUN cd php-src \
   && make install \
   && make clean
 
-RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.5.0.phar \
   && chmod +x phpunit \
   && cp phpunit /usr/local/php-7.1/bin \
   && mv phpunit /usr/local/php-7.1-zts/bin
@@ -182,6 +126,7 @@ RUN cd php-src \
 RUN cd php-src \
   && ./configure \
   --enable-bcmath \
+  --enable-mbstring \
   --with-gmp \
   --with-openssl \
   --with-zlib \
@@ -192,6 +137,7 @@ RUN cd php-src \
 RUN cd php-src \
   && ./configure \
   --enable-maintainer-zts \
+  --enable-mbstring \
   --with-gmp \
   --with-openssl \
   --with-zlib \
@@ -200,7 +146,7 @@ RUN cd php-src \
   && make install \
   && make clean
 
-RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.5.0.phar \
   && chmod +x phpunit \
   && cp phpunit /usr/local/php-7.2/bin \
   && mv phpunit /usr/local/php-7.2-zts/bin
@@ -212,6 +158,7 @@ RUN cd php-src \
 RUN cd php-src \
   && ./configure \
   --enable-bcmath \
+  --enable-mbstring \
   --with-gmp \
   --with-openssl \
   --with-zlib \
@@ -222,6 +169,7 @@ RUN cd php-src \
 RUN cd php-src \
   && ./configure \
   --enable-maintainer-zts \
+  --enable-mbstring \
   --with-gmp \
   --with-openssl \
   --with-zlib \
@@ -230,7 +178,7 @@ RUN cd php-src \
   && make install \
   && make clean
 
-RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.5.0.phar \
   && chmod +x phpunit \
   && cp phpunit /usr/local/php-7.3/bin \
   && mv phpunit /usr/local/php-7.3-zts/bin
@@ -253,6 +201,8 @@ RUN cd /var/local/php-src-php-7.4.0 \
   && ./buildconf --force \
   && ./configure \
   --enable-bcmath \
+  --enable-mbstring \
+  --disable-mbregex \
   --with-gmp \
   --with-openssl \
   --with-zlib \
@@ -264,6 +214,8 @@ RUN cd /var/local/php-src-php-7.4.0 \
   && ./buildconf --force \
   && ./configure \
   --enable-maintainer-zts \
+  --enable-mbstring \
+  --disable-mbregex \
   --with-gmp \
   --with-openssl \
   --with-zlib \

+ 1 - 1
kokoro/linux/dockerfile/test/php80/Dockerfile

@@ -59,7 +59,7 @@ RUN git clone https://github.com/php/php-src
 
 # php 8.0
 RUN cd php-src \
-  && git checkout php-8.0.0alpha3 \
+  && git checkout php-8.0.0 \
   && ./buildconf --force
 RUN cd php-src \
   && ./configure \

+ 50 - 78
kokoro/linux/dockerfile/test/php_32bit/Dockerfile

@@ -53,78 +53,28 @@ RUN mv composer.phar /usr/local/bin/composer
 # Download php source code
 RUN git clone https://github.com/php/php-src
 
-# php 5.5
-RUN cd php-src \
-  && git checkout PHP-5.5.38 \
-  && ./buildconf --force
-RUN cd php-src \
-  && ./configure \
-  --enable-bcmath \
-  --with-openssl \
-  --with-zlib \
-  --prefix=/usr/local/php-5.5 \
-  && make \
-  && make install \
-  && make clean
-RUN cd php-src \
-  && ./configure \
-  --enable-maintainer-zts \
-  --with-openssl \
-  --with-zlib \
-  --prefix=/usr/local/php-5.5-zts \
-  && make \
-  && make install \
-  && make clean
-
-RUN wget -O phpunit https://phar.phpunit.de/phpunit-4.phar \
-  && chmod +x phpunit \
-  && cp phpunit /usr/local/php-5.5/bin \
-  && mv phpunit /usr/local/php-5.5-zts/bin
-
-# php 5.6
-RUN cd php-src \
-  && git checkout PHP-5.6.39 \
-  && ./buildconf --force
-RUN cd php-src \
-  && ./configure \
-  --enable-bcmath \
-  --with-openssl \
-  --with-zlib \
-  --prefix=/usr/local/php-5.6 \
-  && make \
-  && make install \
-  && make clean
-RUN cd php-src \
-  && ./configure \
-  --enable-maintainer-zts \
-  --with-openssl \
-  --with-zlib \
-  --prefix=/usr/local/php-5.6-zts \
-  && make \
-  && make install \
-  && make clean
+# php 7.0
+RUN wget https://github.com/php/php-src/archive/php-7.0.33.tar.gz -O /var/local/php-7.0.33.tar.gz
 
-RUN wget -O phpunit https://phar.phpunit.de/phpunit-5.phar \
-  && chmod +x phpunit \
-  && cp phpunit /usr/local/php-5.6/bin \
-  && mv phpunit /usr/local/php-5.6-zts/bin
+RUN cd /var/local \
+  && tar -zxvf php-7.0.33.tar.gz
 
-# php 7.0
-RUN cd php-src \
-  && git checkout PHP-7.0.33 \
-  && ./buildconf --force
-RUN cd php-src \
+RUN cd /var/local/php-src-php-7.0.33 \
+  && ./buildconf --force \
   && ./configure \
   --enable-bcmath \
+  --enable-mbstring \
   --with-openssl \
   --with-zlib \
   --prefix=/usr/local/php-7.0 \
   && make \
   && make install \
   && make clean
-RUN cd php-src \
+RUN cd /var/local/php-src-php-7.0.33 \
+  && ./buildconf --force \
   && ./configure \
   --enable-maintainer-zts \
+  --enable-mbstring \
   --with-openssl \
   --with-zlib \
   --prefix=/usr/local/php-7.0-zts \
@@ -138,21 +88,27 @@ RUN wget -O phpunit https://phar.phpunit.de/phpunit-6.phar \
   && mv phpunit /usr/local/php-7.0-zts/bin
 
 # php 7.1
-RUN cd php-src \
-  && git checkout PHP-7.1.25 \
-  && ./buildconf --force
-RUN cd php-src \
+RUN wget https://github.com/php/php-src/archive/php-7.1.25.tar.gz -O /var/local/php-7.1.25.tar.gz
+
+RUN cd /var/local \
+  && tar -zxvf php-7.1.25.tar.gz
+
+RUN cd /var/local/php-src-php-7.1.25 \
+  && ./buildconf --force \
   && ./configure \
   --enable-bcmath \
+  --enable-mbstring \
   --with-openssl \
   --with-zlib \
   --prefix=/usr/local/php-7.1 \
   && make \
   && make install \
   && make clean
-RUN cd php-src \
+RUN cd /var/local/php-src-php-7.1.25 \
+  && ./buildconf --force \
   && ./configure \
   --enable-maintainer-zts \
+  --enable-mbstring \
   --with-openssl \
   --with-zlib \
   --prefix=/usr/local/php-7.1-zts \
@@ -160,27 +116,33 @@ RUN cd php-src \
   && make install \
   && make clean
 
-RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.5.0.phar \
   && chmod +x phpunit \
   && cp phpunit /usr/local/php-7.1/bin \
   && mv phpunit /usr/local/php-7.1-zts/bin
 
 # php 7.2
-RUN cd php-src \
-  && git checkout PHP-7.2.13 \
-  && ./buildconf --force
-RUN cd php-src \
+RUN wget https://github.com/php/php-src/archive/php-7.2.13.tar.gz -O /var/local/php-7.2.13.tar.gz
+
+RUN cd /var/local \
+  && tar -zxvf php-7.2.13.tar.gz
+
+RUN cd /var/local/php-src-php-7.2.13 \
+  && ./buildconf --force \
   && ./configure \
   --enable-bcmath \
+  --enable-mbstring \
   --with-openssl \
   --with-zlib \
   --prefix=/usr/local/php-7.2 \
   && make \
   && make install \
   && make clean
-RUN cd php-src \
+RUN cd /var/local/php-src-php-7.2.13 \
+  && ./buildconf --force \
   && ./configure \
   --enable-maintainer-zts \
+  --enable-mbstring \
   --with-openssl \
   --with-zlib \
   --prefix=/usr/local/php-7.2-zts \
@@ -188,27 +150,33 @@ RUN cd php-src \
   && make install \
   && make clean
 
-RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.5.0.phar \
   && chmod +x phpunit \
   && cp phpunit /usr/local/php-7.2/bin \
   && mv phpunit /usr/local/php-7.2-zts/bin
 
 # php 7.3
-RUN cd php-src \
-  && git checkout PHP-7.3.0 \
-  && ./buildconf --force
-RUN cd php-src \
+RUN wget https://github.com/php/php-src/archive/php-7.3.0.tar.gz -O /var/local/php-7.3.0.tar.gz
+
+RUN cd /var/local \
+  && tar -zxvf php-7.3.0.tar.gz
+
+RUN cd /var/local/php-src-php-7.3.0 \
+  && ./buildconf --force \
   && ./configure \
   --enable-bcmath \
+  --enable-mbstring \
   --with-openssl \
   --with-zlib \
   --prefix=/usr/local/php-7.3 \
   && make \
   && make install \
   && make clean
-RUN cd php-src \
+RUN cd /var/local/php-src-php-7.3.0 \
+  && ./buildconf --force \
   && ./configure \
   --enable-maintainer-zts \
+  --enable-mbstring \
   --with-openssl \
   --with-zlib \
   --prefix=/usr/local/php-7.3-zts \
@@ -216,7 +184,7 @@ RUN cd php-src \
   && make install \
   && make clean
 
-RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.5.0.phar \
   && chmod +x phpunit \
   && cp phpunit /usr/local/php-7.3/bin \
   && mv phpunit /usr/local/php-7.3-zts/bin
@@ -239,6 +207,8 @@ RUN cd /var/local/php-src-php-7.4.0 \
   && ./buildconf --force \
   && ./configure \
   --enable-bcmath \
+  --enable-mbstring \
+  --disable-mbregex \
   --with-openssl \
   --with-zlib \
   --prefix=/usr/local/php-7.4 \
@@ -249,6 +219,8 @@ RUN cd /var/local/php-src-php-7.4.0 \
   && ./buildconf --force \
   && ./configure \
   --enable-maintainer-zts \
+  --enable-mbstring \
+  --disable-mbregex \
   --with-openssl \
   --with-zlib \
   --prefix=/usr/local/php-7.4-zts \

+ 2 - 1
kokoro/linux/dockerfile/test/ruby/Dockerfile

@@ -26,13 +26,14 @@ RUN apt-get update && apt-get install -y \
 RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys \
     409B6B1796C275462A1703113804BB82D39DC0E3 \
     7D2BAF1CF37B13E2069D6956105BD0E739499BDB
-RUN \curl -sSL https://get.rvm.io | bash -s stable
+RUN \curl -sSL https://get.rvm.io | bash -s master
 
 RUN /bin/bash -l -c "rvm install 2.3.8"
 RUN /bin/bash -l -c "rvm install 2.4.5"
 RUN /bin/bash -l -c "rvm install 2.5.1"
 RUN /bin/bash -l -c "rvm install 2.6.0"
 RUN /bin/bash -l -c "rvm install 2.7.0"
+RUN /bin/bash -l -c "rvm install 3.0.0"
 
 RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
 RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc"

+ 1 - 1
kokoro/linux/php80/build.sh

@@ -11,7 +11,7 @@
 cd $(dirname $0)/../../..
 
 export DOCKERHUB_ORGANIZATION=protobuftesting
-export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/php
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/php80
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
 export TEST_SET="php8.0_all"

+ 18 - 0
kokoro/linux/ruby30/build.sh

@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+# This is the top-level script we give to Kokoro as the entry point for
+# running the "pull request" project:
+#
+# This script selects a specific Dockerfile (for building a Docker image) and
+# a script to run inside that image.  Then we delegate to the general
+# build_and_run_docker.sh script.
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/ruby
+export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
+export OUTPUT_DIR=testoutput
+export TEST_SET="ruby30"
+./kokoro/linux/build_and_run_docker.sh

+ 11 - 0
kokoro/linux/ruby30/continuous.cfg

@@ -0,0 +1,11 @@
+# Config file for running tests in Kokoro
+
+# Location of the build script in repository
+build_file: "protobuf/kokoro/linux/ruby30/build.sh"
+timeout_mins: 120
+
+action {
+  define_artifacts {
+    regex: "**/sponge_log.xml"
+  }
+}

+ 11 - 0
kokoro/linux/ruby30/presubmit.cfg

@@ -0,0 +1,11 @@
+# Config file for running tests in Kokoro
+
+# Location of the build script in repository
+build_file: "protobuf/kokoro/linux/ruby30/build.sh"
+timeout_mins: 120
+
+action {
+  define_artifacts {
+    regex: "**/sponge_log.xml"
+  }
+}

+ 5 - 1
kokoro/macos/prepare_build_macos_rc

@@ -37,10 +37,14 @@ sudo rm -rf \
 sudo rm -rf \
     /usr/local/bin/2to3* \
     /usr/local/bin/idle3* \
+    /usr/local/bin/pip3 \
     /usr/local/bin/pydoc3* \
     /usr/local/bin/python3* \
     /usr/local/bin/pyvenv*
 
+git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow
+git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask fetch --unshallow
+
 brew update
 brew upgrade
 
@@ -76,5 +80,5 @@ if [[ "${KOKORO_INSTALL_RVM:-}" == "yes" ]] ; then
   curl -sSL https://rvm.io/mpapis.asc | gpg --import -
   curl -sSL https://rvm.io/pkuczynski.asc | gpg --import -
 
-  curl -sSL https://get.rvm.io | bash -s stable --ruby
+  curl -sSL https://get.rvm.io | bash -s master --ruby
 fi

+ 13 - 0
kokoro/macos/ruby30/build.sh

@@ -0,0 +1,13 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+KOKORO_INSTALL_RUBY=yes
+KOKORO_INSTALL_RVM=yes
+source kokoro/macos/prepare_build_macos_rc
+
+./tests.sh ruby30

+ 5 - 0
kokoro/macos/ruby30/continuous.cfg

@@ -0,0 +1,5 @@
+# Config file for running tests in Kokoro
+
+# Location of the build script in repository
+build_file: "protobuf/kokoro/macos/ruby30/build.sh"
+timeout_mins: 1440

+ 5 - 0
kokoro/macos/ruby30/presubmit.cfg

@@ -0,0 +1,5 @@
+# Config file for running tests in Kokoro
+
+# Location of the build script in repository
+build_file: "protobuf/kokoro/macos/ruby30/build.sh"
+timeout_mins: 1440

+ 10 - 7
kokoro/release/ruby/macos/ruby/ruby_build_environment.sh

@@ -21,13 +21,13 @@ rm -rf ~/.rake-compiler
 
 CROSS_RUBY=$(mktemp tmpfile.XXXXXXXX)
 
-curl https://raw.githubusercontent.com/rake-compiler/rake-compiler/v1.1.0/tasks/bin/cross-ruby.rake > "$CROSS_RUBY"
+curl https://raw.githubusercontent.com/rake-compiler/rake-compiler/72184e51779b6a3b9b8580b036a052fdc3181ced/tasks/bin/cross-ruby.rake > "$CROSS_RUBY"
 
 # See https://github.com/grpc/grpc/issues/12161 for verconf.h patch details
 patch "$CROSS_RUBY" << EOF
---- cross-ruby.rake	2018-04-10 11:32:16.000000000 -0700
-+++ patched	2018-04-10 11:40:25.000000000 -0700
-@@ -141,8 +141,10 @@
+--- cross-ruby.rake	2020-12-11 11:17:53.000000000 +0900
++++ patched	2020-12-11 11:18:52.000000000 +0900
+@@ -111,10 +111,12 @@
      "--host=#{MINGW_HOST}",
      "--target=#{MINGW_TARGET}",
      "--build=#{RUBY_BUILD}",
@@ -36,10 +36,13 @@ patch "$CROSS_RUBY" << EOF
 +    '--disable-shared',
      '--disable-install-doc',
 +    '--without-gmp',
-     '--with-ext='
+     '--with-ext=',
+-    'LDFLAGS=-pipe -s',
++    'LDFLAGS=-pipe',
    ]
 
-@@ -159,6 +161,7 @@
+   # Force Winsock2 for Ruby 1.8, 1.9 defaults to it
+@@ -130,6 +132,7 @@
  # make
  file "#{build_dir}/ruby.exe" => ["#{build_dir}/Makefile"] do |t|
    chdir File.dirname(t.prerequisites.first) do
@@ -55,7 +58,7 @@ set +x # rvm commands are very verbose
 rvm use 2.7.0
 set -x
 ruby --version | grep 'ruby 2.7.0'
-for v in 2.7.0 ; do
+for v in 3.0.0 2.7.0 ; do
   ccache -c
   rake -f "$CROSS_RUBY" cross-ruby VERSION="$v" HOST=x86_64-darwin11 MAKE="$MAKE"
 done

+ 318 - 296
m4/ax_pthread.m4

@@ -1,5 +1,5 @@
 # ===========================================================================
-#        http://www.gnu.org/software/autoconf-archive/ax_pthread.html
+#        https://www.gnu.org/software/autoconf-archive/ax_pthread.html
 # ===========================================================================
 #
 # SYNOPSIS
@@ -55,6 +55,7 @@
 #
 #   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
 #   Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+#   Copyright (c) 2019 Marc Stevens <marc.stevens@cwi.nl>
 #
 #   This program is free software: you can redistribute it and/or modify it
 #   under the terms of the GNU General Public License as published by the
@@ -67,7 +68,7 @@
 #   Public License for more details.
 #
 #   You should have received a copy of the GNU General Public License along
-#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#   with this program. If not, see <https://www.gnu.org/licenses/>.
 #
 #   As a special exception, the respective Autoconf Macro's copyright owner
 #   gives unlimited permission to copy, distribute and modify the configure
@@ -82,7 +83,7 @@
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 22
+#serial 27
 
 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
 AC_DEFUN([AX_PTHREAD], [
@@ -100,22 +101,22 @@ ax_pthread_ok=no
 # etcetera environment variables, and if threads linking works using
 # them:
 if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
-	ax_pthread_save_CC="$CC"
-	ax_pthread_save_CFLAGS="$CFLAGS"
-	ax_pthread_save_LIBS="$LIBS"
-	AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
-	CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-	LIBS="$PTHREAD_LIBS $LIBS"
-	AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
-	AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
-	AC_MSG_RESULT([$ax_pthread_ok])
-	if test "x$ax_pthread_ok" = "xno"; then
-		PTHREAD_LIBS=""
-		PTHREAD_CFLAGS=""
-	fi
-	CC="$ax_pthread_save_CC"
-	CFLAGS="$ax_pthread_save_CFLAGS"
-	LIBS="$ax_pthread_save_LIBS"
+        ax_pthread_save_CC="$CC"
+        ax_pthread_save_CFLAGS="$CFLAGS"
+        ax_pthread_save_LIBS="$LIBS"
+        AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
+        AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
+        AC_MSG_RESULT([$ax_pthread_ok])
+        if test "x$ax_pthread_ok" = "xno"; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        CC="$ax_pthread_save_CC"
+        CFLAGS="$ax_pthread_save_CFLAGS"
+        LIBS="$ax_pthread_save_LIBS"
 fi
 
 # We must check for the threads library under a number of different
@@ -123,10 +124,12 @@ fi
 # (e.g. DEC) have both -lpthread and -lpthreads, where one of the
 # libraries is broken (non-POSIX).
 
-# Create a list of thread flags to try.  Items starting with a "-" are
-# C compiler flags, and other items are library names, except for "none"
-# which indicates that we try without any flags at all, and "pthread-config"
-# which is a program returning the flags for the Pth emulation library.
+# Create a list of thread flags to try. Items with a "," contain both
+# C compiler flags (before ",") and linker flags (after ","). Other items
+# starting with a "-" are C compiler flags, and remaining items are
+# library names, except for "none" which indicates that we try without
+# any flags at all, and "pthread-config" which is a program returning
+# the flags for the Pth emulation library.
 
 ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
 
@@ -152,319 +155,338 @@ ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --
 
 case $host_os in
 
-	freebsd*)
+        freebsd*)
 
-	# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
-	# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+        # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+        # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
 
-	ax_pthread_flags="-kthread lthread $ax_pthread_flags"
-	;;
+        ax_pthread_flags="-kthread lthread $ax_pthread_flags"
+        ;;
 
-	hpux*)
+        hpux*)
 
-	# From the cc(1) man page: "[-mt] Sets various -D flags to enable
-	# multi-threading and also sets -lpthread."
+        # From the cc(1) man page: "[-mt] Sets various -D flags to enable
+        # multi-threading and also sets -lpthread."
 
-	ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
-	;;
+        ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
+        ;;
 
-	openedition*)
+        openedition*)
 
-	# IBM z/OS requires a feature-test macro to be defined in order to
-	# enable POSIX threads at all, so give the user a hint if this is
-	# not set. (We don't define these ourselves, as they can affect
-	# other portions of the system API in unpredictable ways.)
+        # IBM z/OS requires a feature-test macro to be defined in order to
+        # enable POSIX threads at all, so give the user a hint if this is
+        # not set. (We don't define these ourselves, as they can affect
+        # other portions of the system API in unpredictable ways.)
 
-	AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
-	    [
-#	     if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
-	     AX_PTHREAD_ZOS_MISSING
-#	     endif
-	    ],
-	    [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
-	;;
+        AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
+            [
+#            if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
+             AX_PTHREAD_ZOS_MISSING
+#            endif
+            ],
+            [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
+        ;;
 
-	solaris*)
+        solaris*)
 
-	# On Solaris (at least, for some versions), libc contains stubbed
-	# (non-functional) versions of the pthreads routines, so link-based
-	# tests will erroneously succeed. (N.B.: The stubs are missing
-	# pthread_cleanup_push, or rather a function called by this macro,
-	# so we could check for that, but who knows whether they'll stub
-	# that too in a future libc.)  So we'll check first for the
-	# standard Solaris way of linking pthreads (-mt -lpthread).
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed. (N.B.: The stubs are missing
+        # pthread_cleanup_push, or rather a function called by this macro,
+        # so we could check for that, but who knows whether they'll stub
+        # that too in a future libc.)  So we'll check first for the
+        # standard Solaris way of linking pthreads (-mt -lpthread).
 
-	ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags"
-	;;
+        ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags"
+        ;;
 esac
 
+# Are we compiling with Clang?
+
+AC_CACHE_CHECK([whether $CC is Clang],
+    [ax_cv_PTHREAD_CLANG],
+    [ax_cv_PTHREAD_CLANG=no
+     # Note that Autoconf sets GCC=yes for Clang as well as GCC
+     if test "x$GCC" = "xyes"; then
+        AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
+            [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
+#            if defined(__clang__) && defined(__llvm__)
+             AX_PTHREAD_CC_IS_CLANG
+#            endif
+            ],
+            [ax_cv_PTHREAD_CLANG=yes])
+     fi
+    ])
+ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
+
+
 # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
 
+# Note that for GCC and Clang -pthread generally implies -lpthread,
+# except when -nostdlib is passed.
+# This is problematic using libtool to build C++ shared libraries with pthread:
+# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460
+# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333
+# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555
+# To solve this, first try -pthread together with -lpthread for GCC
+
 AS_IF([test "x$GCC" = "xyes"],
-      [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"])
+      [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"])
+
+# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first
+
+AS_IF([test "x$ax_pthread_clang" = "xyes"],
+      [ax_pthread_flags="-pthread,-lpthread -pthread"])
+
 
 # The presence of a feature test macro requesting re-entrant function
 # definitions is, on some systems, a strong hint that pthreads support is
 # correctly enabled
 
 case $host_os in
-	darwin* | hpux* | linux* | osf* | solaris*)
-	ax_pthread_check_macro="_REENTRANT"
-	;;
+        darwin* | hpux* | linux* | osf* | solaris*)
+        ax_pthread_check_macro="_REENTRANT"
+        ;;
 
-	aix* | freebsd*)
-	ax_pthread_check_macro="_THREAD_SAFE"
-	;;
+        aix*)
+        ax_pthread_check_macro="_THREAD_SAFE"
+        ;;
 
-	*)
-	ax_pthread_check_macro="--"
-	;;
+        *)
+        ax_pthread_check_macro="--"
+        ;;
 esac
 AS_IF([test "x$ax_pthread_check_macro" = "x--"],
       [ax_pthread_check_cond=0],
       [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
 
-# Are we compiling with Clang?
 
-AC_CACHE_CHECK([whether $CC is Clang],
-    [ax_cv_PTHREAD_CLANG],
-    [ax_cv_PTHREAD_CLANG=no
-     # Note that Autoconf sets GCC=yes for Clang as well as GCC
-     if test "x$GCC" = "xyes"; then
-	AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
-	    [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
-#	     if defined(__clang__) && defined(__llvm__)
-	     AX_PTHREAD_CC_IS_CLANG
-#	     endif
-	    ],
-	    [ax_cv_PTHREAD_CLANG=yes])
-     fi
-    ])
-ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
+if test "x$ax_pthread_ok" = "xno"; then
+for ax_pthread_try_flag in $ax_pthread_flags; do
+
+        case $ax_pthread_try_flag in
+                none)
+                AC_MSG_CHECKING([whether pthreads work without any flags])
+                ;;
+
+                *,*)
+                PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"`
+                PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"`
+                AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"])
+                ;;
+
+                -*)
+                AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
+                PTHREAD_CFLAGS="$ax_pthread_try_flag"
+                ;;
+
+                pthread-config)
+                AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
+                AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
+                PTHREAD_CFLAGS="`pthread-config --cflags`"
+                PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+                ;;
+
+                *)
+                AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
+                PTHREAD_LIBS="-l$ax_pthread_try_flag"
+                ;;
+        esac
+
+        ax_pthread_save_CFLAGS="$CFLAGS"
+        ax_pthread_save_LIBS="$LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+
+        AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+#                       if $ax_pthread_check_cond
+#                        error "$ax_pthread_check_macro must be defined"
+#                       endif
+                        static void *some_global = NULL;
+                        static void routine(void *a)
+                          {
+                             /* To avoid any unused-parameter or
+                                unused-but-set-parameter warning.  */
+                             some_global = a;
+                          }
+                        static void *start_routine(void *a) { return a; }],
+                       [pthread_t th; pthread_attr_t attr;
+                        pthread_create(&th, 0, start_routine, 0);
+                        pthread_join(th, 0);
+                        pthread_attr_init(&attr);
+                        pthread_cleanup_push(routine, 0);
+                        pthread_cleanup_pop(0) /* ; */])],
+            [ax_pthread_ok=yes],
+            [])
+
+        CFLAGS="$ax_pthread_save_CFLAGS"
+        LIBS="$ax_pthread_save_LIBS"
+
+        AC_MSG_RESULT([$ax_pthread_ok])
+        AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
 
-ax_pthread_clang_warning=no
 
 # Clang needs special handling, because older versions handle the -pthread
 # option in a rather... idiosyncratic way
 
 if test "x$ax_pthread_clang" = "xyes"; then
 
-	# Clang takes -pthread; it has never supported any other flag
-
-	# (Note 1: This will need to be revisited if a system that Clang
-	# supports has POSIX threads in a separate library.  This tends not
-	# to be the way of modern systems, but it's conceivable.)
-
-	# (Note 2: On some systems, notably Darwin, -pthread is not needed
-	# to get POSIX threads support; the API is always present and
-	# active.  We could reasonably leave PTHREAD_CFLAGS empty.  But
-	# -pthread does define _REENTRANT, and while the Darwin headers
-	# ignore this macro, third-party headers might not.)
-
-	PTHREAD_CFLAGS="-pthread"
-	PTHREAD_LIBS=
-
-	ax_pthread_ok=yes
-
-	# However, older versions of Clang make a point of warning the user
-	# that, in an invocation where only linking and no compilation is
-	# taking place, the -pthread option has no effect ("argument unused
-	# during compilation").  They expect -pthread to be passed in only
-	# when source code is being compiled.
-	#
-	# Problem is, this is at odds with the way Automake and most other
-	# C build frameworks function, which is that the same flags used in
-	# compilation (CFLAGS) are also used in linking.  Many systems
-	# supported by AX_PTHREAD require exactly this for POSIX threads
-	# support, and in fact it is often not straightforward to specify a
-	# flag that is used only in the compilation phase and not in
-	# linking.  Such a scenario is extremely rare in practice.
-	#
-	# Even though use of the -pthread flag in linking would only print
-	# a warning, this can be a nuisance for well-run software projects
-	# that build with -Werror.  So if the active version of Clang has
-	# this misfeature, we search for an option to squash it.
-
-	AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
-	    [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
-	    [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
-	     # Create an alternate version of $ac_link that compiles and
-	     # links in two steps (.c -> .o, .o -> exe) instead of one
-	     # (.c -> exe), because the warning occurs only in the second
-	     # step
-	     ax_pthread_save_ac_link="$ac_link"
-	     ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
-	     ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
-	     ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
-	     ax_pthread_save_CFLAGS="$CFLAGS"
-	     for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
-		AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
-		CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
-		ac_link="$ax_pthread_save_ac_link"
-		AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
-		    [ac_link="$ax_pthread_2step_ac_link"
-		     AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
-			 [break])
-		    ])
-	     done
-	     ac_link="$ax_pthread_save_ac_link"
-	     CFLAGS="$ax_pthread_save_CFLAGS"
-	     AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
-	     ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
-	    ])
-
-	case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
-		no | unknown) ;;
-		*) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
-	esac
+        # Clang takes -pthread; it has never supported any other flag
+
+        # (Note 1: This will need to be revisited if a system that Clang
+        # supports has POSIX threads in a separate library.  This tends not
+        # to be the way of modern systems, but it's conceivable.)
+
+        # (Note 2: On some systems, notably Darwin, -pthread is not needed
+        # to get POSIX threads support; the API is always present and
+        # active.  We could reasonably leave PTHREAD_CFLAGS empty.  But
+        # -pthread does define _REENTRANT, and while the Darwin headers
+        # ignore this macro, third-party headers might not.)
+
+        # However, older versions of Clang make a point of warning the user
+        # that, in an invocation where only linking and no compilation is
+        # taking place, the -pthread option has no effect ("argument unused
+        # during compilation").  They expect -pthread to be passed in only
+        # when source code is being compiled.
+        #
+        # Problem is, this is at odds with the way Automake and most other
+        # C build frameworks function, which is that the same flags used in
+        # compilation (CFLAGS) are also used in linking.  Many systems
+        # supported by AX_PTHREAD require exactly this for POSIX threads
+        # support, and in fact it is often not straightforward to specify a
+        # flag that is used only in the compilation phase and not in
+        # linking.  Such a scenario is extremely rare in practice.
+        #
+        # Even though use of the -pthread flag in linking would only print
+        # a warning, this can be a nuisance for well-run software projects
+        # that build with -Werror.  So if the active version of Clang has
+        # this misfeature, we search for an option to squash it.
+
+        AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
+            [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
+            [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
+             # Create an alternate version of $ac_link that compiles and
+             # links in two steps (.c -> .o, .o -> exe) instead of one
+             # (.c -> exe), because the warning occurs only in the second
+             # step
+             ax_pthread_save_ac_link="$ac_link"
+             ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
+             ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
+             ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
+             ax_pthread_save_CFLAGS="$CFLAGS"
+             for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
+                AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
+                CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
+                ac_link="$ax_pthread_save_ac_link"
+                AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
+                    [ac_link="$ax_pthread_2step_ac_link"
+                     AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
+                         [break])
+                    ])
+             done
+             ac_link="$ax_pthread_save_ac_link"
+             CFLAGS="$ax_pthread_save_CFLAGS"
+             AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
+             ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
+            ])
+
+        case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
+                no | unknown) ;;
+                *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
+        esac
 
 fi # $ax_pthread_clang = yes
 
-if test "x$ax_pthread_ok" = "xno"; then
-for ax_pthread_try_flag in $ax_pthread_flags; do
 
-	case $ax_pthread_try_flag in
-		none)
-		AC_MSG_CHECKING([whether pthreads work without any flags])
-		;;
-
-		-mt,pthread)
-		AC_MSG_CHECKING([whether pthreads work with -mt -lpthread])
-		PTHREAD_CFLAGS="-mt"
-		PTHREAD_LIBS="-lpthread"
-		;;
-
-		-*)
-		AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
-		PTHREAD_CFLAGS="$ax_pthread_try_flag"
-		;;
-
-		pthread-config)
-		AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
-		AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
-		PTHREAD_CFLAGS="`pthread-config --cflags`"
-		PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
-		;;
-
-		*)
-		AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
-		PTHREAD_LIBS="-l$ax_pthread_try_flag"
-		;;
-	esac
-
-	ax_pthread_save_CFLAGS="$CFLAGS"
-	ax_pthread_save_LIBS="$LIBS"
-	CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-	LIBS="$PTHREAD_LIBS $LIBS"
-
-	# Check for various functions.  We must include pthread.h,
-	# since some functions may be macros.  (On the Sequent, we
-	# need a special flag -Kthread to make this header compile.)
-	# We check for pthread_join because it is in -lpthread on IRIX
-	# while pthread_create is in libc.  We check for pthread_attr_init
-	# due to DEC craziness with -lpthreads.  We check for
-	# pthread_cleanup_push because it is one of the few pthread
-	# functions on Solaris that doesn't have a non-functional libc stub.
-	# We try pthread_create on general principles.
-
-	AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
-#			if $ax_pthread_check_cond
-#			 error "$ax_pthread_check_macro must be defined"
-#			endif
-			static void routine(void *a) { a = 0; }
-			static void *start_routine(void *a) { return a; }],
-		       [pthread_t th; pthread_attr_t attr;
-			pthread_create(&th, 0, start_routine, 0);
-			pthread_join(th, 0);
-			pthread_attr_init(&attr);
-			pthread_cleanup_push(routine, 0);
-			pthread_cleanup_pop(0) /* ; */])],
-	    [ax_pthread_ok=yes],
-	    [])
-
-	CFLAGS="$ax_pthread_save_CFLAGS"
-	LIBS="$ax_pthread_save_LIBS"
-
-	AC_MSG_RESULT([$ax_pthread_ok])
-	AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
-
-	PTHREAD_LIBS=""
-	PTHREAD_CFLAGS=""
-done
-fi
 
 # Various other checks:
 if test "x$ax_pthread_ok" = "xyes"; then
-	ax_pthread_save_CFLAGS="$CFLAGS"
-	ax_pthread_save_LIBS="$LIBS"
-	CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-	LIBS="$PTHREAD_LIBS $LIBS"
-
-	# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
-	AC_CACHE_CHECK([for joinable pthread attribute],
-	    [ax_cv_PTHREAD_JOINABLE_ATTR],
-	    [ax_cv_PTHREAD_JOINABLE_ATTR=unknown
-	     for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
-		 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
-						 [int attr = $ax_pthread_attr; return attr /* ; */])],
-				[ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
-				[])
-	     done
-	    ])
-	AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
-	       test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
-	       test "x$ax_pthread_joinable_attr_defined" != "xyes"],
-	      [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
-				  [$ax_cv_PTHREAD_JOINABLE_ATTR],
-				  [Define to necessary symbol if this constant
-				   uses a non-standard name on your system.])
-	       ax_pthread_joinable_attr_defined=yes
-	      ])
-
-	AC_CACHE_CHECK([whether more special flags are required for pthreads],
-	    [ax_cv_PTHREAD_SPECIAL_FLAGS],
-	    [ax_cv_PTHREAD_SPECIAL_FLAGS=no
-	     case $host_os in
-	     solaris*)
-	     ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
-	     ;;
-	     esac
-	    ])
-	AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
-	       test "x$ax_pthread_special_flags_added" != "xyes"],
-	      [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
-	       ax_pthread_special_flags_added=yes])
-
-	AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
-	    [ax_cv_PTHREAD_PRIO_INHERIT],
-	    [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
-					     [[int i = PTHREAD_PRIO_INHERIT;]])],
-			    [ax_cv_PTHREAD_PRIO_INHERIT=yes],
-			    [ax_cv_PTHREAD_PRIO_INHERIT=no])
-	    ])
-	AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
-	       test "x$ax_pthread_prio_inherit_defined" != "xyes"],
-	      [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
-	       ax_pthread_prio_inherit_defined=yes
-	      ])
-
-	CFLAGS="$ax_pthread_save_CFLAGS"
-	LIBS="$ax_pthread_save_LIBS"
-
-	# More AIX lossage: compile with *_r variant
-	if test "x$GCC" != "xyes"; then
-	    case $host_os in
-		aix*)
-		AS_CASE(["x/$CC"],
-		    [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
-		    [#handle absolute path differently from PATH based program lookup
-		     AS_CASE(["x$CC"],
-			 [x/*],
-			 [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
-			 [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
-		;;
-	    esac
-	fi
+        ax_pthread_save_CFLAGS="$CFLAGS"
+        ax_pthread_save_LIBS="$LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+        AC_CACHE_CHECK([for joinable pthread attribute],
+            [ax_cv_PTHREAD_JOINABLE_ATTR],
+            [ax_cv_PTHREAD_JOINABLE_ATTR=unknown
+             for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+                 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
+                                                 [int attr = $ax_pthread_attr; return attr /* ; */])],
+                                [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
+                                [])
+             done
+            ])
+        AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
+               test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
+               test "x$ax_pthread_joinable_attr_defined" != "xyes"],
+              [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
+                                  [$ax_cv_PTHREAD_JOINABLE_ATTR],
+                                  [Define to necessary symbol if this constant
+                                   uses a non-standard name on your system.])
+               ax_pthread_joinable_attr_defined=yes
+              ])
+
+        AC_CACHE_CHECK([whether more special flags are required for pthreads],
+            [ax_cv_PTHREAD_SPECIAL_FLAGS],
+            [ax_cv_PTHREAD_SPECIAL_FLAGS=no
+             case $host_os in
+             solaris*)
+             ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
+             ;;
+             esac
+            ])
+        AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
+               test "x$ax_pthread_special_flags_added" != "xyes"],
+              [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
+               ax_pthread_special_flags_added=yes])
+
+        AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
+            [ax_cv_PTHREAD_PRIO_INHERIT],
+            [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
+                                             [[int i = PTHREAD_PRIO_INHERIT;
+                                               return i;]])],
+                            [ax_cv_PTHREAD_PRIO_INHERIT=yes],
+                            [ax_cv_PTHREAD_PRIO_INHERIT=no])
+            ])
+        AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
+               test "x$ax_pthread_prio_inherit_defined" != "xyes"],
+              [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
+               ax_pthread_prio_inherit_defined=yes
+              ])
+
+        CFLAGS="$ax_pthread_save_CFLAGS"
+        LIBS="$ax_pthread_save_LIBS"
+
+        # More AIX lossage: compile with *_r variant
+        if test "x$GCC" != "xyes"; then
+            case $host_os in
+                aix*)
+                AS_CASE(["x/$CC"],
+                    [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
+                    [#handle absolute path differently from PATH based program lookup
+                     AS_CASE(["x$CC"],
+                         [x/*],
+                         [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
+                         [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
+                ;;
+            esac
+        fi
 fi
 
 test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
@@ -475,11 +497,11 @@ AC_SUBST([PTHREAD_CC])
 
 # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
 if test "x$ax_pthread_ok" = "xyes"; then
-	ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
-	:
+        ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
+        :
 else
-	ax_pthread_ok=no
-	$2
+        ax_pthread_ok=no
+        $2
 fi
 AC_LANG_POP
 ])dnl AX_PTHREAD

+ 1 - 1
objectivec/GPBMessage.m

@@ -82,7 +82,7 @@ static NSString *const kGPBDataCoderKey = @"GPBData";
   GPBExtensionDescriptor *autocreatorExtension_;
 
   // Message can only be mutated from one thread. But some *readonly* operations
-  // modifify internal state because they autocreate things. The
+  // modify internal state because they autocreate things. The
   // autocreatedExtensionMap_ is one such structure. Access during readonly
   // operations is protected via this semaphore.
   // NOTE: OSSpinLock may seem like a good fit here but Apple engineers have

+ 2 - 2
php/composer.json

@@ -6,10 +6,10 @@
   "homepage": "https://developers.google.com/protocol-buffers/",
   "license": "BSD-3-Clause",
   "require": {
-    "php": ">=5.5.0"
+    "php": ">=7.0.0"
   },
   "require-dev": {
-    "phpunit/phpunit": "^5|^4.8.0"
+    "phpunit/phpunit": ">=6.0.0"
   },
   "autoload": {
     "psr-4": {

+ 4 - 3
php/ext/google/protobuf/array.c

@@ -453,9 +453,6 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetSet, 0, 0, 2)
   ZEND_ARG_INFO(0, newval)
 ZEND_END_ARG_INFO()
 
-ZEND_BEGIN_ARG_INFO(arginfo_void, 0)
-ZEND_END_ARG_INFO()
-
 static zend_function_entry repeated_field_methods[] = {
   PHP_ME(RepeatedField, __construct,  arginfo_construct, ZEND_ACC_PUBLIC)
   PHP_ME(RepeatedField, append,       arginfo_append,    ZEND_ACC_PUBLIC)
@@ -636,7 +633,11 @@ void Array_ModuleInit() {
   h = &RepeatedField_object_handlers;
   memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
   h->dtor_obj = RepeatedField_destructor;
+#if PHP_VERSION_ID < 80000
   h->compare_objects = RepeatedField_compare_objects;
+#else
+  h->compare = RepeatedField_compare_objects;
+#endif
   h->get_properties = RepeatedField_GetProperties;
   h->get_property_ptr_ptr = RepeatedField_GetPropertyPtrPtr;
 

+ 33 - 28
php/ext/google/protobuf/def.c

@@ -103,8 +103,8 @@ PHP_METHOD(EnumValueDescriptor, getNumber) {
 }
 
 static zend_function_entry EnumValueDescriptor_methods[] = {
-  PHP_ME(EnumValueDescriptor, getName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(EnumValueDescriptor, getNumber, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(EnumValueDescriptor, getName, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(EnumValueDescriptor, getNumber, arginfo_void, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -224,9 +224,9 @@ PHP_METHOD(EnumDescriptor, getPublicDescriptor) {
 }
 
 static zend_function_entry EnumDescriptor_methods[] = {
-  PHP_ME(EnumDescriptor, getPublicDescriptor, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(EnumDescriptor, getValueCount, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(EnumDescriptor, getValue, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(EnumDescriptor, getPublicDescriptor, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(EnumDescriptor, getValueCount, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(EnumDescriptor, getValue, arginfo_void, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -316,9 +316,9 @@ PHP_METHOD(OneofDescriptor, getFieldCount) {
 }
 
 static zend_function_entry OneofDescriptor_methods[] = {
-  PHP_ME(OneofDescriptor, getName,  NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(OneofDescriptor, getField, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(OneofDescriptor, getFieldCount, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(OneofDescriptor, getName,  arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(OneofDescriptor, getField, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(OneofDescriptor, getFieldCount, arginfo_void, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -480,13 +480,13 @@ PHP_METHOD(FieldDescriptor, getMessageType) {
 }
 
 static zend_function_entry FieldDescriptor_methods[] = {
-  PHP_ME(FieldDescriptor, getName,   NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(FieldDescriptor, getNumber, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(FieldDescriptor, getLabel,  NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(FieldDescriptor, getType,   NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(FieldDescriptor, isMap,     NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(FieldDescriptor, getEnumType, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(FieldDescriptor, getMessageType, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(FieldDescriptor, getName,   arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(FieldDescriptor, getNumber, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(FieldDescriptor, getLabel,  arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(FieldDescriptor, getType,   arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(FieldDescriptor, isMap,     arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(FieldDescriptor, getEnumType, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(FieldDescriptor, getMessageType, arginfo_void, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -700,13 +700,13 @@ PHP_METHOD(Descriptor, getClass) {
 
 
 static zend_function_entry Descriptor_methods[] = {
-  PHP_ME(Descriptor, getClass, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Descriptor, getFullName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Descriptor, getField, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Descriptor, getFieldCount, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Descriptor, getOneofDecl, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Descriptor, getOneofDeclCount, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Descriptor, getPublicDescriptor, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(Descriptor, getClass, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(Descriptor, getFullName, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(Descriptor, getField, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(Descriptor, getFieldCount, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(Descriptor, getOneofDecl, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(Descriptor, getOneofDeclCount, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(Descriptor, getPublicDescriptor, arginfo_void, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -1000,13 +1000,18 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) {
   upb_arena_free(arena);
 }
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_addgeneratedfile, 0, 0, 2)
+  ZEND_ARG_INFO(0, data)
+  ZEND_ARG_INFO(0, data_len)
+ZEND_END_ARG_INFO()
+
 static zend_function_entry DescriptorPool_methods[] = {
-  PHP_ME(DescriptorPool, getGeneratedPool, NULL,
+  PHP_ME(DescriptorPool, getGeneratedPool, arginfo_void,
          ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-  PHP_ME(DescriptorPool, getDescriptorByClassName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(DescriptorPool, getDescriptorByProtoName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(DescriptorPool, getEnumDescriptorByClassName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(DescriptorPool, internalAddGeneratedFile, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(DescriptorPool, getDescriptorByClassName, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(DescriptorPool, getDescriptorByProtoName, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(DescriptorPool, getEnumDescriptorByClassName, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(DescriptorPool, internalAddGeneratedFile, arginfo_addgeneratedfile, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -1034,7 +1039,7 @@ PHP_METHOD(InternalDescriptorPool, getGeneratedPool) {
 }
 
 static zend_function_entry InternalDescriptorPool_methods[] = {
-  PHP_ME(InternalDescriptorPool, getGeneratedPool, NULL,
+  PHP_ME(InternalDescriptorPool, getGeneratedPool, arginfo_void,
          ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
   ZEND_FE_END
 };

+ 4 - 3
php/ext/google/protobuf/map.c

@@ -437,9 +437,6 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetSet, 0, 0, 2)
   ZEND_ARG_INFO(0, newval)
 ZEND_END_ARG_INFO()
 
-ZEND_BEGIN_ARG_INFO(arginfo_void, 0)
-ZEND_END_ARG_INFO()
-
 static zend_function_entry MapField_methods[] = {
   PHP_ME(MapField, __construct,  arginfo_construct, ZEND_ACC_PUBLIC)
   PHP_ME(MapField, offsetExists, arginfo_offsetGet, ZEND_ACC_PUBLIC)
@@ -622,7 +619,11 @@ void Map_ModuleInit() {
   h = &MapField_object_handlers;
   memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
   h->dtor_obj = MapField_destructor;
+#if PHP_VERSION_ID < 80000
   h->compare_objects = MapField_compare_objects;
+#else
+  h->compare = MapField_compare_objects;
+#endif
   h->get_properties = Map_GetProperties;
   h->get_property_ptr_ptr = Map_GetPropertyPtrPtr;
 

+ 13 - 8
php/ext/google/protobuf/message.c

@@ -968,6 +968,10 @@ PHP_METHOD(Message, readOneof) {
                      (int)field_num);
   }
 
+  if (upb_fielddef_issubmsg(f) && !upb_msg_has(intern->msg, f)) {
+    RETURN_NULL();
+  }
+
   {
     upb_msgval msgval = upb_msg_get(intern->msg, f);
     const Descriptor *subdesc = Descriptor_GetFromFieldDef(f);
@@ -1021,9 +1025,6 @@ PHP_METHOD(Message, writeOneof) {
   upb_msg_set(intern->msg, f, msgval, arena);
 }
 
-ZEND_BEGIN_ARG_INFO_EX(arginfo_void, 0, 0, 0)
-ZEND_END_ARG_INFO()
-
 ZEND_BEGIN_ARG_INFO_EX(arginfo_mergeFrom, 0, 0, 1)
   ZEND_ARG_INFO(0, data)
 ZEND_END_ARG_INFO()
@@ -1106,7 +1107,7 @@ PHP_METHOD(google_protobuf_Any, unpack) {
   if (!TryStripUrlPrefix(&type_url)) {
     zend_throw_exception(
         NULL, "Type url needs to be type.googleapis.com/fully-qualified",
-        0 TSRMLS_CC);
+        0);
     return;
   }
 
@@ -1115,7 +1116,7 @@ PHP_METHOD(google_protobuf_Any, unpack) {
   if (m == NULL) {
     zend_throw_exception(
         NULL, "Specified message in any hasn't been added to descriptor pool",
-        0 TSRMLS_CC);
+        0);
     return;
   }
 
@@ -1149,7 +1150,7 @@ PHP_METHOD(google_protobuf_Any, pack) {
   const char *full_name;
   char *buf;
 
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &val) ==
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &val) ==
       FAILURE) {
     return;
   }
@@ -1182,7 +1183,7 @@ PHP_METHOD(google_protobuf_Any, is) {
   zend_class_entry *klass = NULL;
   const upb_msgdef *m;
 
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "C", &klass) ==
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "C", &klass) ==
       FAILURE) {
     return;
   }
@@ -1209,7 +1210,7 @@ PHP_METHOD(google_protobuf_Timestamp, fromDateTime) {
     return;
   }
 
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &datetime,
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &datetime,
                             date_interface_ce) == FAILURE) {
     zend_error(E_USER_ERROR, "Expect DatetimeInterface.");
     return;
@@ -1326,7 +1327,11 @@ void Message_ModuleInit() {
 
   memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
   h->dtor_obj = Message_dtor;
+#if PHP_VERSION_ID < 80000
   h->compare_objects = Message_compare_objects;
+#else
+  h->compare = Message_compare_objects;
+#endif
   h->read_property = Message_read_property;
   h->write_property = Message_write_property;
   h->has_property = Message_has_property;

+ 1 - 0
php/ext/google/protobuf/protobuf.c

@@ -297,6 +297,7 @@ static PHP_MINIT_FUNCTION(protobuf) {
 }
 
 static PHP_MSHUTDOWN_FUNCTION(protobuf) {
+  UNREGISTER_INI_ENTRIES();
   return SUCCESS;
 }
 

+ 7 - 0
php/ext/google/protobuf/protobuf.h

@@ -69,6 +69,13 @@ const zval *get_generated_pool();
 #define PROTO_STRLEN_P(obj) ZSTR_LEN(obj)
 #endif
 
+ZEND_BEGIN_ARG_INFO(arginfo_void, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_setter, 0, 0, 1)
+  ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
 #define PHP_PROTOBUF_VERSION "3.14.0"
 
 // ptr -> PHP object cache. This is a weak map that caches lazily-created

+ 205 - 197
php/ext/google/protobuf/wkt.inc

@@ -37,7 +37,7 @@ static PHP_METHOD(GPBMetadata_Google_Protobuf_Any, initOnce) {
 }
 
 static zend_function_entry GPBMetadata_Google_Protobuf_Any_methods[] = {
-  PHP_ME(GPBMetadata_Google_Protobuf_Any, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(GPBMetadata_Google_Protobuf_Any, initOnce, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   ZEND_FE_END
 };
 
@@ -103,15 +103,19 @@ static PHP_METHOD(google_protobuf_Any, setValue) {
   RETURN_ZVAL(getThis(), 1, 0);
 }
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_is, 0, 0, 1)
+  ZEND_ARG_INFO(0, proto)
+ZEND_END_ARG_INFO()
+
 static zend_function_entry google_protobuf_Any_phpmethods[] = {
-  PHP_ME(google_protobuf_Any, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Any, getTypeUrl, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Any, setTypeUrl, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Any, getValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Any, setValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Any, is, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Any, pack, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Any, unpack, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Any, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Any, getTypeUrl, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Any, setTypeUrl, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Any, getValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Any, setValue, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Any, is, arginfo_is, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Any, pack, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Any, unpack, arginfo_void, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -178,7 +182,7 @@ static PHP_METHOD(GPBMetadata_Google_Protobuf_Api, initOnce) {
 }
 
 static zend_function_entry GPBMetadata_Google_Protobuf_Api_methods[] = {
-  PHP_ME(GPBMetadata_Google_Protobuf_Api, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(GPBMetadata_Google_Protobuf_Api, initOnce, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   ZEND_FE_END
 };
 
@@ -355,21 +359,21 @@ static PHP_METHOD(google_protobuf_Api, setSyntax) {
 }
 
 static zend_function_entry google_protobuf_Api_phpmethods[] = {
-  PHP_ME(google_protobuf_Api, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Api, getName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Api, setName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Api, getMethods, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Api, setMethods, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Api, getOptions, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Api, setOptions, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Api, getVersion, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Api, setVersion, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Api, getSourceContext, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Api, setSourceContext, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Api, getMixins, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Api, setMixins, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Api, getSyntax, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Api, setSyntax, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Api, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Api, getName, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Api, setName, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Api, getMethods, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Api, setMethods, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Api, getOptions, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Api, setOptions, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Api, getVersion, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Api, setVersion, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Api, getSourceContext, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Api, setSourceContext, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Api, getMixins, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Api, setMixins, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Api, getSyntax, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Api, setSyntax, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -549,21 +553,21 @@ static PHP_METHOD(google_protobuf_Method, setSyntax) {
 }
 
 static zend_function_entry google_protobuf_Method_phpmethods[] = {
-  PHP_ME(google_protobuf_Method, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Method, getName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Method, setName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Method, getRequestTypeUrl, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Method, setRequestTypeUrl, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Method, getRequestStreaming, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Method, setRequestStreaming, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Method, getResponseTypeUrl, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Method, setResponseTypeUrl, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Method, getResponseStreaming, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Method, setResponseStreaming, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Method, getOptions, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Method, setOptions, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Method, getSyntax, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Method, setSyntax, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Method, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Method, getName, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Method, setName, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Method, getRequestTypeUrl, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Method, setRequestTypeUrl, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Method, getRequestStreaming, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Method, setRequestStreaming, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Method, getResponseTypeUrl, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Method, setResponseTypeUrl, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Method, getResponseStreaming, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Method, setResponseStreaming, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Method, getOptions, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Method, setOptions, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Method, getSyntax, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Method, setSyntax, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -633,11 +637,11 @@ static PHP_METHOD(google_protobuf_Mixin, setRoot) {
 }
 
 static zend_function_entry google_protobuf_Mixin_phpmethods[] = {
-  PHP_ME(google_protobuf_Mixin, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Mixin, getName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Mixin, setName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Mixin, getRoot, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Mixin, setRoot, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Mixin, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Mixin, getName, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Mixin, setName, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Mixin, getRoot, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Mixin, setRoot, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -681,7 +685,7 @@ static PHP_METHOD(GPBMetadata_Google_Protobuf_Duration, initOnce) {
 }
 
 static zend_function_entry GPBMetadata_Google_Protobuf_Duration_methods[] = {
-  PHP_ME(GPBMetadata_Google_Protobuf_Duration, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(GPBMetadata_Google_Protobuf_Duration, initOnce, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   ZEND_FE_END
 };
 
@@ -748,11 +752,11 @@ static PHP_METHOD(google_protobuf_Duration, setNanos) {
 }
 
 static zend_function_entry google_protobuf_Duration_phpmethods[] = {
-  PHP_ME(google_protobuf_Duration, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Duration, getSeconds, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Duration, setSeconds, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Duration, getNanos, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Duration, setNanos, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Duration, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Duration, getSeconds, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Duration, setSeconds, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Duration, getNanos, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Duration, setNanos, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -794,7 +798,7 @@ static PHP_METHOD(GPBMetadata_Google_Protobuf_GPBEmpty, initOnce) {
 }
 
 static zend_function_entry GPBMetadata_Google_Protobuf_GPBEmpty_methods[] = {
-  PHP_ME(GPBMetadata_Google_Protobuf_GPBEmpty, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(GPBMetadata_Google_Protobuf_GPBEmpty, initOnce, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   ZEND_FE_END
 };
 
@@ -817,7 +821,7 @@ static PHP_METHOD(google_protobuf_Empty, __construct) {
 }
 
 static zend_function_entry google_protobuf_Empty_phpmethods[] = {
-  PHP_ME(google_protobuf_Empty, __construct, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Empty, __construct, arginfo_void, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -860,7 +864,7 @@ static PHP_METHOD(GPBMetadata_Google_Protobuf_FieldMask, initOnce) {
 }
 
 static zend_function_entry GPBMetadata_Google_Protobuf_FieldMask_methods[] = {
-  PHP_ME(GPBMetadata_Google_Protobuf_FieldMask, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(GPBMetadata_Google_Protobuf_FieldMask, initOnce, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   ZEND_FE_END
 };
 
@@ -905,9 +909,9 @@ static PHP_METHOD(google_protobuf_FieldMask, setPaths) {
 }
 
 static zend_function_entry google_protobuf_FieldMask_phpmethods[] = {
-  PHP_ME(google_protobuf_FieldMask, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_FieldMask, getPaths, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_FieldMask, setPaths, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_FieldMask, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_FieldMask, getPaths, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_FieldMask, setPaths, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -951,7 +955,7 @@ static PHP_METHOD(GPBMetadata_Google_Protobuf_SourceContext, initOnce) {
 }
 
 static zend_function_entry GPBMetadata_Google_Protobuf_SourceContext_methods[] = {
-  PHP_ME(GPBMetadata_Google_Protobuf_SourceContext, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(GPBMetadata_Google_Protobuf_SourceContext, initOnce, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   ZEND_FE_END
 };
 
@@ -996,9 +1000,9 @@ static PHP_METHOD(google_protobuf_SourceContext, setFileName) {
 }
 
 static zend_function_entry google_protobuf_SourceContext_phpmethods[] = {
-  PHP_ME(google_protobuf_SourceContext, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_SourceContext, getFileName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_SourceContext, setFileName, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_SourceContext, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_SourceContext, getFileName, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_SourceContext, setFileName, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -1058,7 +1062,7 @@ static PHP_METHOD(GPBMetadata_Google_Protobuf_Struct, initOnce) {
 }
 
 static zend_function_entry GPBMetadata_Google_Protobuf_Struct_methods[] = {
-  PHP_ME(GPBMetadata_Google_Protobuf_Struct, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(GPBMetadata_Google_Protobuf_Struct, initOnce, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   ZEND_FE_END
 };
 
@@ -1103,9 +1107,9 @@ static PHP_METHOD(google_protobuf_Struct, setFields) {
 }
 
 static zend_function_entry google_protobuf_Struct_phpmethods[] = {
-  PHP_ME(google_protobuf_Struct, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Struct, getFields, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Struct, setFields, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Struct, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Struct, getFields, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Struct, setFields, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -1175,11 +1179,11 @@ static PHP_METHOD(google_protobuf_Struct_FieldsEntry, setValue) {
 }
 
 static zend_function_entry google_protobuf_Struct_FieldsEntry_phpmethods[] = {
-  PHP_ME(google_protobuf_Struct_FieldsEntry, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Struct_FieldsEntry, getKey, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Struct_FieldsEntry, setKey, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Struct_FieldsEntry, getValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Struct_FieldsEntry, setValue, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Struct_FieldsEntry, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Struct_FieldsEntry, getKey, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Struct_FieldsEntry, setKey, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Struct_FieldsEntry, getValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Struct_FieldsEntry, setValue, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -1344,20 +1348,20 @@ static PHP_METHOD(google_protobuf_Value, getKind) {
   RETURN_STRING(field ? upb_fielddef_name(field) : "");
 }
 static zend_function_entry google_protobuf_Value_phpmethods[] = {
-  PHP_ME(google_protobuf_Value, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Value, getNullValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Value, setNullValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Value, getNumberValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Value, setNumberValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Value, getStringValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Value, setStringValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Value, getBoolValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Value, setBoolValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Value, getStructValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Value, setStructValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Value, getListValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Value, setListValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Value, getKind, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Value, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Value, getNullValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Value, setNullValue, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Value, getNumberValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Value, setNumberValue, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Value, getStringValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Value, setStringValue, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Value, getBoolValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Value, setBoolValue, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Value, getStructValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Value, setStructValue, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Value, getListValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Value, setListValue, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Value, getKind, arginfo_void, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -1405,9 +1409,9 @@ static PHP_METHOD(google_protobuf_ListValue, setValues) {
 }
 
 static zend_function_entry google_protobuf_ListValue_phpmethods[] = {
-  PHP_ME(google_protobuf_ListValue, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_ListValue, getValues, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_ListValue, setValues, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_ListValue, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_ListValue, getValues, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_ListValue, setValues, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -1433,7 +1437,7 @@ PHP_METHOD(google_protobuf_NullValue, name) {
   const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.NullValue");
   const char *name;
   zend_long value;
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) ==
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &value) ==
       FAILURE) {
     return;
   }
@@ -1455,7 +1459,7 @@ PHP_METHOD(google_protobuf_NullValue, value) {
   char *name = NULL;
   size_t name_len;
   int32_t num;
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name,
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name,
                             &name_len) == FAILURE) {
     return;
   }
@@ -1470,8 +1474,8 @@ PHP_METHOD(google_protobuf_NullValue, value) {
 }
 
 static zend_function_entry google_protobuf_NullValue_phpmethods[] = {
-  PHP_ME(google_protobuf_NullValue, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-  PHP_ME(google_protobuf_NullValue, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(google_protobuf_NullValue, name, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(google_protobuf_NullValue, value, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   ZEND_FE_END
 };
 
@@ -1570,7 +1574,7 @@ static PHP_METHOD(GPBMetadata_Google_Protobuf_Type, initOnce) {
 }
 
 static zend_function_entry GPBMetadata_Google_Protobuf_Type_methods[] = {
-  PHP_ME(GPBMetadata_Google_Protobuf_Type, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(GPBMetadata_Google_Protobuf_Type, initOnce, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   ZEND_FE_END
 };
 
@@ -1725,19 +1729,19 @@ static PHP_METHOD(google_protobuf_Type, setSyntax) {
 }
 
 static zend_function_entry google_protobuf_Type_phpmethods[] = {
-  PHP_ME(google_protobuf_Type, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Type, getName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Type, setName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Type, getFields, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Type, setFields, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Type, getOneofs, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Type, setOneofs, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Type, getOptions, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Type, setOptions, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Type, getSourceContext, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Type, setSourceContext, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Type, getSyntax, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Type, setSyntax, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Type, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Type, getName, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Type, setName, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Type, getFields, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Type, setFields, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Type, getOneofs, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Type, setOneofs, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Type, getOptions, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Type, setOptions, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Type, getSourceContext, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Type, setSourceContext, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Type, getSyntax, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Type, setSyntax, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -1983,27 +1987,27 @@ static PHP_METHOD(google_protobuf_Field, setDefaultValue) {
 }
 
 static zend_function_entry google_protobuf_Field_phpmethods[] = {
-  PHP_ME(google_protobuf_Field, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, getKind, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, setKind, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, getCardinality, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, setCardinality, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, getNumber, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, setNumber, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, getName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, setName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, getTypeUrl, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, setTypeUrl, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, getOneofIndex, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, setOneofIndex, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, getPacked, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, setPacked, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, getOptions, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, setOptions, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, getJsonName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, setJsonName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, getDefaultValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Field, setDefaultValue, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, getKind, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, setKind, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, getCardinality, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, setCardinality, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, getNumber, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, setNumber, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, getName, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, setName, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, getTypeUrl, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, setTypeUrl, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, getOneofIndex, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, setOneofIndex, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, getPacked, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, setPacked, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, getOptions, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, setOptions, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, getJsonName, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, setJsonName, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, getDefaultValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Field, setDefaultValue, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -2029,7 +2033,7 @@ PHP_METHOD(google_protobuf_Field_Kind, name) {
   const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Kind");
   const char *name;
   zend_long value;
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) ==
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &value) ==
       FAILURE) {
     return;
   }
@@ -2051,7 +2055,7 @@ PHP_METHOD(google_protobuf_Field_Kind, value) {
   char *name = NULL;
   size_t name_len;
   int32_t num;
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name,
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name,
                             &name_len) == FAILURE) {
     return;
   }
@@ -2066,8 +2070,8 @@ PHP_METHOD(google_protobuf_Field_Kind, value) {
 }
 
 static zend_function_entry google_protobuf_Field_Kind_phpmethods[] = {
-  PHP_ME(google_protobuf_Field_Kind, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-  PHP_ME(google_protobuf_Field_Kind, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(google_protobuf_Field_Kind, name, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(google_protobuf_Field_Kind, value, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   ZEND_FE_END
 };
 
@@ -2128,7 +2132,7 @@ PHP_METHOD(google_protobuf_Field_Cardinality, name) {
   const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Cardinality");
   const char *name;
   zend_long value;
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) ==
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &value) ==
       FAILURE) {
     return;
   }
@@ -2150,7 +2154,7 @@ PHP_METHOD(google_protobuf_Field_Cardinality, value) {
   char *name = NULL;
   size_t name_len;
   int32_t num;
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name,
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name,
                             &name_len) == FAILURE) {
     return;
   }
@@ -2165,8 +2169,8 @@ PHP_METHOD(google_protobuf_Field_Cardinality, value) {
 }
 
 static zend_function_entry google_protobuf_Field_Cardinality_phpmethods[] = {
-  PHP_ME(google_protobuf_Field_Cardinality, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-  PHP_ME(google_protobuf_Field_Cardinality, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(google_protobuf_Field_Cardinality, name, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(google_protobuf_Field_Cardinality, value, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   ZEND_FE_END
 };
 
@@ -2307,17 +2311,17 @@ static PHP_METHOD(google_protobuf_Enum, setSyntax) {
 }
 
 static zend_function_entry google_protobuf_Enum_phpmethods[] = {
-  PHP_ME(google_protobuf_Enum, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Enum, getName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Enum, setName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Enum, getEnumvalue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Enum, setEnumvalue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Enum, getOptions, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Enum, setOptions, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Enum, getSourceContext, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Enum, setSourceContext, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Enum, getSyntax, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Enum, setSyntax, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Enum, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Enum, getName, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Enum, setName, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Enum, getEnumvalue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Enum, setEnumvalue, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Enum, getOptions, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Enum, setOptions, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Enum, getSourceContext, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Enum, setSourceContext, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Enum, getSyntax, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Enum, setSyntax, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -2409,13 +2413,13 @@ static PHP_METHOD(google_protobuf_EnumValue, setOptions) {
 }
 
 static zend_function_entry google_protobuf_EnumValue_phpmethods[] = {
-  PHP_ME(google_protobuf_EnumValue, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_EnumValue, getName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_EnumValue, setName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_EnumValue, getNumber, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_EnumValue, setNumber, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_EnumValue, getOptions, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_EnumValue, setOptions, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_EnumValue, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_EnumValue, getName, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_EnumValue, setName, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_EnumValue, getNumber, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_EnumValue, setNumber, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_EnumValue, getOptions, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_EnumValue, setOptions, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -2485,11 +2489,11 @@ static PHP_METHOD(google_protobuf_Option, setValue) {
 }
 
 static zend_function_entry google_protobuf_Option_phpmethods[] = {
-  PHP_ME(google_protobuf_Option, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Option, getName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Option, setName, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Option, getValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Option, setValue, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Option, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Option, getName, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Option, setName, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Option, getValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Option, setValue, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -2515,7 +2519,7 @@ PHP_METHOD(google_protobuf_Syntax, name) {
   const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Syntax");
   const char *name;
   zend_long value;
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) ==
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &value) ==
       FAILURE) {
     return;
   }
@@ -2537,7 +2541,7 @@ PHP_METHOD(google_protobuf_Syntax, value) {
   char *name = NULL;
   size_t name_len;
   int32_t num;
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name,
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name,
                             &name_len) == FAILURE) {
     return;
   }
@@ -2552,8 +2556,8 @@ PHP_METHOD(google_protobuf_Syntax, value) {
 }
 
 static zend_function_entry google_protobuf_Syntax_phpmethods[] = {
-  PHP_ME(google_protobuf_Syntax, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-  PHP_ME(google_protobuf_Syntax, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(google_protobuf_Syntax, name, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(google_protobuf_Syntax, value, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   ZEND_FE_END
 };
 
@@ -2598,7 +2602,7 @@ static PHP_METHOD(GPBMetadata_Google_Protobuf_Timestamp, initOnce) {
 }
 
 static zend_function_entry GPBMetadata_Google_Protobuf_Timestamp_methods[] = {
-  PHP_ME(GPBMetadata_Google_Protobuf_Timestamp, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(GPBMetadata_Google_Protobuf_Timestamp, initOnce, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   ZEND_FE_END
 };
 
@@ -2664,14 +2668,18 @@ static PHP_METHOD(google_protobuf_Timestamp, setNanos) {
   RETURN_ZVAL(getThis(), 1, 0);
 }
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_timestamp_fromdatetime, 0, 0, 1)
+  ZEND_ARG_INFO(0, datetime)
+ZEND_END_ARG_INFO()
+
 static zend_function_entry google_protobuf_Timestamp_phpmethods[] = {
-  PHP_ME(google_protobuf_Timestamp, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Timestamp, getSeconds, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Timestamp, setSeconds, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Timestamp, getNanos, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Timestamp, setNanos, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Timestamp, fromDateTime, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Timestamp, toDateTime, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Timestamp, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Timestamp, getSeconds, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Timestamp, setSeconds, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Timestamp, getNanos, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Timestamp, setNanos, arginfo_setter, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Timestamp, fromDateTime, arginfo_timestamp_fromdatetime, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Timestamp, toDateTime, arginfo_void, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -2724,7 +2732,7 @@ static PHP_METHOD(GPBMetadata_Google_Protobuf_Wrappers, initOnce) {
 }
 
 static zend_function_entry GPBMetadata_Google_Protobuf_Wrappers_methods[] = {
-  PHP_ME(GPBMetadata_Google_Protobuf_Wrappers, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(GPBMetadata_Google_Protobuf_Wrappers, initOnce, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   ZEND_FE_END
 };
 
@@ -2769,9 +2777,9 @@ static PHP_METHOD(google_protobuf_DoubleValue, setValue) {
 }
 
 static zend_function_entry google_protobuf_DoubleValue_phpmethods[] = {
-  PHP_ME(google_protobuf_DoubleValue, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_DoubleValue, getValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_DoubleValue, setValue, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_DoubleValue, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_DoubleValue, getValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_DoubleValue, setValue, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -2819,9 +2827,9 @@ static PHP_METHOD(google_protobuf_FloatValue, setValue) {
 }
 
 static zend_function_entry google_protobuf_FloatValue_phpmethods[] = {
-  PHP_ME(google_protobuf_FloatValue, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_FloatValue, getValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_FloatValue, setValue, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_FloatValue, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_FloatValue, getValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_FloatValue, setValue, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -2869,9 +2877,9 @@ static PHP_METHOD(google_protobuf_Int64Value, setValue) {
 }
 
 static zend_function_entry google_protobuf_Int64Value_phpmethods[] = {
-  PHP_ME(google_protobuf_Int64Value, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Int64Value, getValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Int64Value, setValue, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Int64Value, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Int64Value, getValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Int64Value, setValue, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -2919,9 +2927,9 @@ static PHP_METHOD(google_protobuf_UInt64Value, setValue) {
 }
 
 static zend_function_entry google_protobuf_UInt64Value_phpmethods[] = {
-  PHP_ME(google_protobuf_UInt64Value, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_UInt64Value, getValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_UInt64Value, setValue, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_UInt64Value, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_UInt64Value, getValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_UInt64Value, setValue, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -2969,9 +2977,9 @@ static PHP_METHOD(google_protobuf_Int32Value, setValue) {
 }
 
 static zend_function_entry google_protobuf_Int32Value_phpmethods[] = {
-  PHP_ME(google_protobuf_Int32Value, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Int32Value, getValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_Int32Value, setValue, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Int32Value, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Int32Value, getValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_Int32Value, setValue, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -3019,9 +3027,9 @@ static PHP_METHOD(google_protobuf_UInt32Value, setValue) {
 }
 
 static zend_function_entry google_protobuf_UInt32Value_phpmethods[] = {
-  PHP_ME(google_protobuf_UInt32Value, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_UInt32Value, getValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_UInt32Value, setValue, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_UInt32Value, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_UInt32Value, getValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_UInt32Value, setValue, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -3069,9 +3077,9 @@ static PHP_METHOD(google_protobuf_BoolValue, setValue) {
 }
 
 static zend_function_entry google_protobuf_BoolValue_phpmethods[] = {
-  PHP_ME(google_protobuf_BoolValue, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_BoolValue, getValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_BoolValue, setValue, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_BoolValue, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_BoolValue, getValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_BoolValue, setValue, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -3119,9 +3127,9 @@ static PHP_METHOD(google_protobuf_StringValue, setValue) {
 }
 
 static zend_function_entry google_protobuf_StringValue_phpmethods[] = {
-  PHP_ME(google_protobuf_StringValue, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_StringValue, getValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_StringValue, setValue, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_StringValue, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_StringValue, getValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_StringValue, setValue, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -3169,9 +3177,9 @@ static PHP_METHOD(google_protobuf_BytesValue, setValue) {
 }
 
 static zend_function_entry google_protobuf_BytesValue_phpmethods[] = {
-  PHP_ME(google_protobuf_BytesValue, __construct, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_BytesValue, getValue, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(google_protobuf_BytesValue, setValue, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_BytesValue, __construct, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_BytesValue, getValue, arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(google_protobuf_BytesValue, setValue, arginfo_setter, ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 

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

@@ -271,7 +271,7 @@ class Api extends \Google\Protobuf\Internal\Message
      * message.
      *
      * Generated from protobuf field <code>.google.protobuf.SourceContext source_context = 5;</code>
-     * @return \Google\Protobuf\SourceContext
+     * @return \Google\Protobuf\SourceContext|null
      */
     public function getSourceContext()
     {

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

@@ -151,7 +151,7 @@ class Enum extends \Google\Protobuf\Internal\Message
      * The source context.
      *
      * Generated from protobuf field <code>.google.protobuf.SourceContext source_context = 4;</code>
-     * @return \Google\Protobuf\SourceContext
+     * @return \Google\Protobuf\SourceContext|null
      */
     public function getSourceContext()
     {

+ 1 - 1
php/src/Google/Protobuf/Internal/DescriptorProto.php

@@ -252,7 +252,7 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message
 
     /**
      * Generated from protobuf field <code>optional .google.protobuf.MessageOptions options = 7;</code>
-     * @return \Google\Protobuf\Internal\MessageOptions
+     * @return \Google\Protobuf\Internal\MessageOptions|null
      */
     public function getOptions()
     {

+ 1 - 1
php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php

@@ -124,7 +124,7 @@ class ExtensionRange extends \Google\Protobuf\Internal\Message
 
     /**
      * Generated from protobuf field <code>optional .google.protobuf.ExtensionRangeOptions options = 3;</code>
-     * @return \Google\Protobuf\Internal\ExtensionRangeOptions
+     * @return \Google\Protobuf\Internal\ExtensionRangeOptions|null
      */
     public function getOptions()
     {

+ 1 - 1
php/src/Google/Protobuf/Internal/EnumDescriptorProto.php

@@ -124,7 +124,7 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message
 
     /**
      * Generated from protobuf field <code>optional .google.protobuf.EnumOptions options = 3;</code>
-     * @return \Google\Protobuf\Internal\EnumOptions
+     * @return \Google\Protobuf\Internal\EnumOptions|null
      */
     public function getOptions()
     {

+ 1 - 1
php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php

@@ -112,7 +112,7 @@ class EnumValueDescriptorProto extends \Google\Protobuf\Internal\Message
 
     /**
      * Generated from protobuf field <code>optional .google.protobuf.EnumValueOptions options = 3;</code>
-     * @return \Google\Protobuf\Internal\EnumValueOptions
+     * @return \Google\Protobuf\Internal\EnumValueOptions|null
      */
     public function getOptions()
     {

+ 1 - 1
php/src/Google/Protobuf/Internal/FieldDescriptorProto.php

@@ -511,7 +511,7 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message
 
     /**
      * Generated from protobuf field <code>optional .google.protobuf.FieldOptions options = 8;</code>
-     * @return \Google\Protobuf\Internal\FieldOptions
+     * @return \Google\Protobuf\Internal\FieldOptions|null
      */
     public function getOptions()
     {

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

@@ -371,7 +371,7 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message
 
     /**
      * Generated from protobuf field <code>optional .google.protobuf.FileOptions options = 8;</code>
-     * @return \Google\Protobuf\Internal\FileOptions
+     * @return \Google\Protobuf\Internal\FileOptions|null
      */
     public function getOptions()
     {
@@ -408,7 +408,7 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message
      * development tools.
      *
      * Generated from protobuf field <code>optional .google.protobuf.SourceCodeInfo source_code_info = 9;</code>
-     * @return \Google\Protobuf\Internal\SourceCodeInfo
+     * @return \Google\Protobuf\Internal\SourceCodeInfo|null
      */
     public function getSourceCodeInfo()
     {

+ 1 - 1
php/src/Google/Protobuf/Internal/GPBUtil.php

@@ -168,7 +168,7 @@ class GPBUtil
     public static function checkFloat(&$var)
     {
         if (is_float($var) || is_numeric($var)) {
-            $var = floatval($var);
+            $var = unpack("f", pack("f", $var))[1];
         } else {
             throw new \Exception("Expect float.");
         }

+ 1 - 1
php/src/Google/Protobuf/Internal/MapField.php

@@ -129,7 +129,7 @@ class MapField implements \ArrayAccess, \IteratorAggregate, \Countable
      *
      * This will also be called for: $ele = $arr[$key]
      *
-     * @param object $key The key of the element to be fetched.
+     * @param int|bool|string $key The key of the element to be fetched.
      * @return object The stored element at given key.
      * @throws \ErrorException Invalid type for index.
      * @throws \ErrorException Non-existing index.

+ 1 - 1
php/src/Google/Protobuf/Internal/MethodDescriptorProto.php

@@ -176,7 +176,7 @@ class MethodDescriptorProto extends \Google\Protobuf\Internal\Message
 
     /**
      * Generated from protobuf field <code>optional .google.protobuf.MethodOptions options = 4;</code>
-     * @return \Google\Protobuf\Internal\MethodOptions
+     * @return \Google\Protobuf\Internal\MethodOptions|null
      */
     public function getOptions()
     {

+ 1 - 1
php/src/Google/Protobuf/Internal/OneofDescriptorProto.php

@@ -75,7 +75,7 @@ class OneofDescriptorProto extends \Google\Protobuf\Internal\Message
 
     /**
      * Generated from protobuf field <code>optional .google.protobuf.OneofOptions options = 2;</code>
-     * @return \Google\Protobuf\Internal\OneofOptions
+     * @return \Google\Protobuf\Internal\OneofOptions|null
      */
     public function getOptions()
     {

+ 1 - 1
php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php

@@ -102,7 +102,7 @@ class ServiceDescriptorProto extends \Google\Protobuf\Internal\Message
 
     /**
      * Generated from protobuf field <code>optional .google.protobuf.ServiceOptions options = 3;</code>
-     * @return \Google\Protobuf\Internal\ServiceOptions
+     * @return \Google\Protobuf\Internal\ServiceOptions|null
      */
     public function getOptions()
     {

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

@@ -97,7 +97,7 @@ class Option extends \Google\Protobuf\Internal\Message
      * value using the google.protobuf.Int32Value type.
      *
      * Generated from protobuf field <code>.google.protobuf.Any value = 2;</code>
-     * @return \Google\Protobuf\Any
+     * @return \Google\Protobuf\Any|null
      */
     public function getValue()
     {

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

@@ -185,7 +185,7 @@ class Type extends \Google\Protobuf\Internal\Message
      * The source context.
      *
      * Generated from protobuf field <code>.google.protobuf.SourceContext source_context = 5;</code>
-     * @return \Google\Protobuf\SourceContext
+     * @return \Google\Protobuf\SourceContext|null
      */
     public function getSourceContext()
     {

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

@@ -174,7 +174,7 @@ class Value extends \Google\Protobuf\Internal\Message
      * Represents a structured value.
      *
      * Generated from protobuf field <code>.google.protobuf.Struct struct_value = 5;</code>
-     * @return \Google\Protobuf\Struct
+     * @return \Google\Protobuf\Struct|null
      */
     public function getStructValue()
     {
@@ -205,7 +205,7 @@ class Value extends \Google\Protobuf\Internal\Message
      * Represents a repeated `Value`.
      *
      * Generated from protobuf field <code>.google.protobuf.ListValue list_value = 6;</code>
-     * @return \Google\Protobuf\ListValue
+     * @return \Google\Protobuf\ListValue|null
      */
     public function getListValue()
     {

+ 20 - 17
php/tests/ArrayTest.php

@@ -1,5 +1,6 @@
 <?php
 
+require_once('test_base.php');
 require_once('test_util.php');
 
 use Google\Protobuf\Internal\RepeatedField;
@@ -7,7 +8,7 @@ use Google\Protobuf\Internal\GPBType;
 use Foo\TestMessage;
 use Foo\TestMessage\Sub;
 
-class ArrayTest extends \PHPUnit\Framework\TestCase
+class ArrayTest extends TestBase
 {
 
     #########################################################
@@ -296,15 +297,15 @@ class ArrayTest extends \PHPUnit\Framework\TestCase
 
         // Test append.
         $arr[] = 1;
-        $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(1.0, $arr[0], MAX_FLOAT_DIFF);
 
         $arr[] = 1.1;
-        $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(1.1, $arr[1], MAX_FLOAT_DIFF);
 
         $arr[] = '2';
-        $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(2.0, $arr[2], MAX_FLOAT_DIFF);
         $arr[] = '3.1';
-        $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(3.1, $arr[3], MAX_FLOAT_DIFF);
 
         $this->assertEquals(4, count($arr));
 
@@ -315,15 +316,15 @@ class ArrayTest extends \PHPUnit\Framework\TestCase
 
         // Test set.
         $arr[0] = 1;
-        $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(1.0, $arr[0], MAX_FLOAT_DIFF);
 
         $arr[1] = 1.1;
-        $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(1.1, $arr[1], MAX_FLOAT_DIFF);
 
         $arr[2] = '2';
-        $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(2.0, $arr[2], MAX_FLOAT_DIFF);
         $arr[3] = '3.1';
-        $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(3.1, $arr[3], MAX_FLOAT_DIFF);
     }
 
     #########################################################
@@ -336,15 +337,15 @@ class ArrayTest extends \PHPUnit\Framework\TestCase
 
         // Test append.
         $arr[] = 1;
-        $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(1.0, $arr[0], MAX_FLOAT_DIFF);
 
         $arr[] = 1.1;
-        $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(1.1, $arr[1], MAX_FLOAT_DIFF);
 
         $arr[] = '2';
-        $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(2.0, $arr[2], MAX_FLOAT_DIFF);
         $arr[] = '3.1';
-        $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(3.1, $arr[3], MAX_FLOAT_DIFF);
 
         $this->assertEquals(4, count($arr));
 
@@ -355,15 +356,15 @@ class ArrayTest extends \PHPUnit\Framework\TestCase
 
         // Test set.
         $arr[0] = 1;
-        $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(1.0, $arr[0], MAX_FLOAT_DIFF);
 
         $arr[1] = 1.1;
-        $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(1.1, $arr[1], MAX_FLOAT_DIFF);
 
         $arr[2] = '2';
-        $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(2.0, $arr[2], MAX_FLOAT_DIFF);
         $arr[3] = '3.1';
-        $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(3.1, $arr[3], MAX_FLOAT_DIFF);
     }
 
     #########################################################
@@ -566,6 +567,8 @@ class ArrayTest extends \PHPUnit\Framework\TestCase
             $sub = new Sub(['a' => $sub]);
         }
         $m->setRepeatedMessage($subs);
+
+        $this->assertTrue(true);
     }
 
     #########################################################

+ 4 - 6
php/tests/DescriptorsTest.php

@@ -205,22 +205,20 @@ class DescriptorsTest extends TestBase
         $this->assertSame(self::GPBTYPE_ENUM, $mapDesc->getField(1)->getType());
     }
 
-    /**
-     * @expectedException \Exception
-     */
     public function testFieldDescriptorEnumException()
     {
+        $this->expectException(Exception::class);
+
         $pool = DescriptorPool::getGeneratedPool();
         $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
         $fieldDesc = $desc->getField(0);
         $fieldDesc->getEnumType();
     }
 
-    /**
-     * @expectedException \Exception
-     */
     public function testFieldDescriptorMessageException()
     {
+        $this->expectException(Exception::class);
+
         $pool = DescriptorPool::getGeneratedPool();
         $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
         $fieldDesc = $desc->getField(0);

+ 47 - 70
php/tests/EncodeDecodeTest.php

@@ -212,7 +212,7 @@ class EncodeDecodeTest extends TestBase
     public function generateRandomString($length = 10) {
         $randomString = str_repeat("+", $length);
         for ($i = 0; $i < $length; $i++) {
-            $randomString[$i] = rand(0, 255);
+            $randomString[$i] = chr(rand(0, 255));
         }
         return $randomString;
     }
@@ -529,200 +529,178 @@ class EncodeDecodeTest extends TestBase
         $this->assertSame("", $data);
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidInt32()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('08'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidSubMessage()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('9A010108'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidInt64()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('10'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidUInt32()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('18'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidUInt64()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('20'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidSInt32()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('28'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidSInt64()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('30'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidFixed32()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('3D'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidFixed64()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('41'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidSFixed32()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('4D'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidSFixed64()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('51'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidFloat()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('5D'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidDouble()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('61'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidBool()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('68'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidStringLengthMiss()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('72'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidStringDataMiss()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('7201'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidBytesLengthMiss()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('7A'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidBytesDataMiss()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('7A01'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidEnum()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('8001'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidMessageLengthMiss()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('8A01'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidMessageDataMiss()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage();
         $m->mergeFromString(hex2bin('8A0101'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeInvalidPackedMessageLength()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestPackedMessage();
         $m->mergeFromString(hex2bin('D205'));
     }
@@ -1143,11 +1121,10 @@ class EncodeDecodeTest extends TestBase
         $this->assertSame("0801", bin2hex($m1->getAny()->getValue()));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testDecodeAnyWithUnknownPacked()
     {
+        $this->expectException(Exception::class);
+
         $m = new TestAny();
         $m->mergeFromJsonString(
             "{\"any\":" .

+ 28 - 19
php/tests/GeneratedClassTest.php

@@ -260,21 +260,21 @@ class GeneratedClassTest extends TestBase
         $this->assertEquals(1, TestEnum::value('ONE'));
     }
 
-    /**
-     * @expectedException UnexpectedValueException
-     * @expectedExceptionMessage Enum Foo\TestEnum has no name defined for value -1
-     */
     public function testInvalidEnumValueThrowsException()
     {
+        $this->expectException(UnexpectedValueException::class);
+        $this->expectExceptionMessage(
+            'Enum Foo\TestEnum has no name defined for value -1');
+
         TestEnum::name(-1);
     }
 
-    /**
-     * @expectedException UnexpectedValueException
-     * @expectedExceptionMessage Enum Foo\TestEnum has no value defined for name DOES_NOT_EXIST
-     */
     public function testInvalidEnumNameThrowsException()
     {
+        $this->expectException(UnexpectedValueException::class);
+        $this->expectExceptionMessage(
+            'Enum Foo\TestEnum has no value defined for name DOES_NOT_EXIST');
+
         TestEnum::value('DOES_NOT_EXIST');
     }
 
@@ -313,17 +313,17 @@ class GeneratedClassTest extends TestBase
 
         // Set integer.
         $m->setOptionalFloat(1);
-        $this->assertEquals(1.0, $m->getOptionalFloat(), '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(1.0, $m->getOptionalFloat(), MAX_FLOAT_DIFF);
 
         // Set float.
         $m->setOptionalFloat(1.1);
-        $this->assertEquals(1.1, $m->getOptionalFloat(), '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(1.1, $m->getOptionalFloat(), MAX_FLOAT_DIFF);
 
         // Set string.
         $m->setOptionalFloat('2');
-        $this->assertEquals(2.0, $m->getOptionalFloat(), '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(2.0, $m->getOptionalFloat(), MAX_FLOAT_DIFF);
         $m->setOptionalFloat('3.1');
-        $this->assertEquals(3.1, $m->getOptionalFloat(), '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(3.1, $m->getOptionalFloat(), MAX_FLOAT_DIFF);
     }
 
     #########################################################
@@ -336,17 +336,17 @@ class GeneratedClassTest extends TestBase
 
         // Set integer.
         $m->setOptionalDouble(1);
-        $this->assertEquals(1.0, $m->getOptionalDouble(), '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(1.0, $m->getOptionalDouble(), MAX_FLOAT_DIFF);
 
         // Set float.
         $m->setOptionalDouble(1.1);
-        $this->assertEquals(1.1, $m->getOptionalDouble(), '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(1.1, $m->getOptionalDouble(), MAX_FLOAT_DIFF);
 
         // Set string.
         $m->setOptionalDouble('2');
-        $this->assertEquals(2.0, $m->getOptionalDouble(), '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(2.0, $m->getOptionalDouble(), MAX_FLOAT_DIFF);
         $m->setOptionalDouble('3.1');
-        $this->assertEquals(3.1, $m->getOptionalDouble(), '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(3.1, $m->getOptionalDouble(), MAX_FLOAT_DIFF);
     }
 
     #########################################################
@@ -1467,6 +1467,8 @@ class GeneratedClassTest extends TestBase
             }
             $key = new TestMessage($key);
         }
+
+        $this->assertTrue(true);
     }
 
     public function testOneofMessageInArrayConstructor()
@@ -1476,6 +1478,8 @@ class GeneratedClassTest extends TestBase
         ]);
         $this->assertSame('oneof_message', $m->getMyOneof());
         $this->assertNotNull($m->getOneofMessage());
+
+        $this->assertTrue(true);
     }
 
     public function testOneofStringInArrayConstructor()
@@ -1483,6 +1487,8 @@ class GeneratedClassTest extends TestBase
         $m = new TestMessage([
             'oneof_string' => 'abc',
         ]);
+
+        $this->assertTrue(true);
     }
 
     #########################################################
@@ -1527,6 +1533,8 @@ class GeneratedClassTest extends TestBase
         array_walk($values, function (&$value) {});
         $m = new TestMessage();
         $m->setOptionalString($values[0]);
+
+        $this->assertTrue(true);
     }
 
     #########################################################
@@ -1697,11 +1705,10 @@ class GeneratedClassTest extends TestBase
         throw new Exception('Intended');
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testNoSegfaultWithError()
     {
+        $this->expectException(Exception::class);
+
         new TestMessage(['optional_int32' => $this->throwIntendedException()]);
     }
 
@@ -1724,5 +1731,7 @@ class GeneratedClassTest extends TestBase
          * The value we are passing to var_dump() appears to be corrupt somehow.
          */
         /* var_dump($m); */
+
+        $this->assertTrue(true);
     }
 }

+ 4 - 4
php/tests/GeneratedPhpdocTest.php

@@ -13,15 +13,15 @@ class GeneratedPhpdocTest extends TestBase
     {
         $class = new ReflectionClass('Foo\TestMessage');
         $doc = $class->getDocComment();
-        $this->assertContains('foo.TestMessage', $doc);
+        $this->assertStringContains('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);
+        $this->assertStringContains('@param array $data', $doc);
+        $this->assertStringContains('@type int $optional_int32', $doc);
     }
 
     /**
@@ -32,7 +32,7 @@ class GeneratedPhpdocTest extends TestBase
         $class = new ReflectionClass('Foo\TestMessage');
         foreach ($methods as $method) {
             $doc = $class->getMethod($method)->getDocComment();
-            $this->assertContains($expectedDoc, $doc);
+            $this->assertStringContains($expectedDoc, $doc);
         }
     }
 

+ 35 - 18
php/tests/GeneratedServiceTest.php

@@ -30,10 +30,13 @@ class GeneratedServiceTest extends TestBase
         'sayHelloAgain'
     ];
 
-    public function setUp()
+    /**
+     * Avoid calling setUp, which has void return type (not avalialbe in php7.0).
+     *
+     * @before
+     */
+    public function setUpTest()
     {
-        parent::setUp();
-
         $this->serviceClass = new ReflectionClass('Foo\GreeterInterface');
 
         $this->namespacedServiceClass = new ReflectionClass('Bar\OtherGreeterInterface');
@@ -46,17 +49,20 @@ class GeneratedServiceTest extends TestBase
 
     public function testPhpDocForClass()
     {
-        $this->assertContains('foo.Greeter', $this->serviceClass->getDocComment());
+        $this->assertStringContains(
+            'foo.Greeter', $this->serviceClass->getDocComment());
     }
 
     public function testPhpDocForNamespacedClass()
     {
-        $this->assertContains('foo.OtherGreeter', $this->namespacedServiceClass->getDocComment());
+        $this->assertStringContains(
+            'foo.OtherGreeter', $this->namespacedServiceClass->getDocComment());
     }
 
     public function testServiceMethodsAreGenerated()
     {
-        $this->assertCount(count($this->methodNames), $this->serviceClass->getMethods());
+        $this->assertCount(
+            count($this->methodNames), $this->serviceClass->getMethods());
         foreach ($this->methodNames as $methodName) {
             $this->assertTrue($this->serviceClass->hasMethod($methodName));
         }
@@ -65,20 +71,27 @@ class GeneratedServiceTest extends TestBase
     public function testPhpDocForServiceMethod()
     {
         foreach ($this->methodNames as $methodName) {
-            $docComment = $this->serviceClass->getMethod($methodName)->getDocComment();
-            $this->assertContains($methodName, $docComment);
-            $this->assertContains('@param \Foo\HelloRequest $request', $docComment);
-            $this->assertContains('@return \Foo\HelloReply', $docComment);
+            $docComment =
+                $this->serviceClass->getMethod($methodName)->getDocComment();
+            $this->assertStringContains($methodName, $docComment);
+            $this->assertStringContains(
+                '@param \Foo\HelloRequest $request', $docComment);
+            $this->assertStringContains(
+                '@return \Foo\HelloReply', $docComment);
         }
     }
 
     public function testPhpDocForServiceMethodInNamespacedClass()
     {
         foreach ($this->methodNames as $methodName) {
-            $docComment = $this->namespacedServiceClass->getMethod($methodName)->getDocComment();
-            $this->assertContains($methodName, $docComment);
-            $this->assertContains('@param \Foo\HelloRequest $request', $docComment);
-            $this->assertContains('@return \Foo\HelloReply', $docComment);
+            $docComment =
+                $this->namespacedServiceClass->getMethod(
+                    $methodName)->getDocComment();
+            $this->assertStringContains($methodName, $docComment);
+            $this->assertStringContains(
+                '@param \Foo\HelloRequest $request', $docComment);
+            $this->assertStringContains(
+                '@return \Foo\HelloReply', $docComment);
         }
     }
 
@@ -90,8 +103,10 @@ class GeneratedServiceTest extends TestBase
             $param = $method->getParameters()[0];
             $this->assertFalse($param->isOptional());
             $this->assertSame('request', $param->getName());
-            // ReflectionParameter::getType only exists in PHP 7+, so get the type from __toString
-            $this->assertContains('Foo\HelloRequest $request', (string) $param);
+	    // ReflectionParameter::getType only exists in PHP 7+, so get the
+	    // type from __toString
+            $this->assertStringContains(
+                'Foo\HelloRequest $request', (string) $param);
         }
     }
 
@@ -103,8 +118,10 @@ class GeneratedServiceTest extends TestBase
             $param = $method->getParameters()[0];
             $this->assertFalse($param->isOptional());
             $this->assertSame('request', $param->getName());
-            // ReflectionParameter::getType only exists in PHP 7+, so get the type from __toString
-            $this->assertContains('Foo\HelloRequest $request', (string) $param);
+	    // ReflectionParameter::getType only exists in PHP 7+, so get the
+	    // type from __toString
+            $this->assertStringContains(
+                'Foo\HelloRequest $request', (string) $param);
         }
     }
 }

+ 12 - 9
php/tests/MapFieldTest.php

@@ -1,5 +1,6 @@
 <?php
 
+require_once('test_base.php');
 require_once('test_util.php');
 
 use Google\Protobuf\Internal\GPBType;
@@ -7,7 +8,7 @@ use Google\Protobuf\Internal\MapField;
 use Foo\TestMessage;
 use Foo\TestMessage\Sub;
 
-class MapFieldTest extends \PHPUnit\Framework\TestCase {
+class MapFieldTest extends TestBase {
 
     #########################################################
     # Test int32 field.
@@ -257,15 +258,15 @@ class MapFieldTest extends \PHPUnit\Framework\TestCase {
 
         // Test set.
         $arr[0] = 1;
-        $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(1.0, $arr[0], MAX_FLOAT_DIFF);
 
         $arr[1] = 1.1;
-        $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(1.1, $arr[1], MAX_FLOAT_DIFF);
 
         $arr[2] = '2';
-        $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(2.0, $arr[2], MAX_FLOAT_DIFF);
         $arr[3] = '3.1';
-        $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(3.1, $arr[3], MAX_FLOAT_DIFF);
 
         $this->assertEquals(4, count($arr));
     }
@@ -279,15 +280,15 @@ class MapFieldTest extends \PHPUnit\Framework\TestCase {
 
         // Test set.
         $arr[0] = 1;
-        $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(1.0, $arr[0], MAX_FLOAT_DIFF);
 
         $arr[1] = 1.1;
-        $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(1.1, $arr[1], MAX_FLOAT_DIFF);
 
         $arr[2] = '2';
-        $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(2.0, $arr[2], MAX_FLOAT_DIFF);
         $arr[3] = '3.1';
-        $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
+        $this->assertFloatEquals(3.1, $arr[3], MAX_FLOAT_DIFF);
 
         $this->assertEquals(4, count($arr));
     }
@@ -477,6 +478,8 @@ class MapFieldTest extends \PHPUnit\Framework\TestCase {
         array_walk($values, function (&$value) {});
         $m = new TestMessage();
         $m->setMapInt32Message($values);
+
+        $this->assertTrue(true);
     }
 
     #########################################################

+ 17 - 10
php/tests/PhpImplementationTest.php

@@ -20,7 +20,11 @@ use Google\Protobuf\Internal\CodedOutputStream;
  */
 class ImplementationTest extends TestBase
 {
-    public function setUp()
+    /**
+     * Avoid calling setUp, which has void return type (not avalialbe in php7.0).
+     * @before
+     */
+    public function skipTestsForExtension()
     {
         if (extension_loaded('protobuf')) {
             $this->markTestSkipped();
@@ -306,6 +310,8 @@ class ImplementationTest extends TestBase
         $m = new TestMessage();
         $m->mergeFromString(TestUtil::getGoldenTestMessage());
         TestUtil::assertTestMessage($m);
+
+        $this->assertTrue(true);
     }
 
     public function testDescriptorDecode()
@@ -525,23 +531,23 @@ class ImplementationTest extends TestBase
         $this->assertSame(166, $m->byteSize());
     }
 
-    /**
-     * @expectedException UnexpectedValueException
-     * @expectedExceptionMessage Invalid message property: optionalInt32
-     */
     public function testArrayConstructorJsonCaseThrowsException()
     {
+        $this->expectException(UnexpectedValueException::class);
+        $this->expectExceptionMessage(
+            'Invalid message property: optionalInt32');
+
         $m = new TestMessage([
             'optionalInt32' => -42,
         ]);
     }
 
-    /**
-     * @expectedException Exception
-     * @expectedExceptionMessage Expect Foo\TestMessage\Sub.
-     */
     public function testArraysForMessagesThrowsException()
     {
+        $this->expectException(Exception::class);
+        $this->expectExceptionMessage(
+            'Expect Foo\TestMessage\Sub.');
+
         $m = new TestMessage([
             'optional_message' => [
                 'a' => 33
@@ -568,10 +574,11 @@ class ImplementationTest extends TestBase
 
     /**
      * @dataProvider provideArrayConstructorWithNullValuesThrowsException
-     * @expectedException Exception
      */
     public function testArrayConstructorWithNullValuesThrowsException($requestData)
     {
+        $this->expectException(Exception::class);
+
         $m = new TestMessage($requestData);
     }
 

+ 6 - 9
php/tests/WellKnownTest.php

@@ -86,31 +86,28 @@ class WellKnownTest extends TestBase {
         $this->assertFalse($any->is(Any::class));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testAnyUnpackInvalidTypeUrl()
     {
+        $this->expectException(Exception::class);
+
         $any = new Any();
         $any->setTypeUrl("invalid");
         $any->unpack();
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testAnyUnpackMessageNotAdded()
     {
+        $this->expectException(Exception::class);
+
         $any = new Any();
         $any->setTypeUrl("type.googleapis.com/MessageNotAdded");
         $any->unpack();
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testAnyUnpackDecodeError()
     {
+        $this->expectException(Exception::class);
+
         $any = new Any();
         $any->setTypeUrl("type.googleapis.com/foo.TestMessage");
         $any->setValue("abc");

+ 5 - 1
php/tests/WrapperTypeSettersTest.php

@@ -148,10 +148,10 @@ class WrapperTypeSettersTest extends TestBase
 
     /**
      * @dataProvider invalidSettersDataProvider
-     * @expectedException \Exception
      */
     public function testInvalidSetters($class, $setter, $value)
     {
+        $this->expectException(Exception::class);
         (new $class())->$setter($value);
     }
 
@@ -243,6 +243,8 @@ class WrapperTypeSettersTest extends TestBase
             }
             $this->assertEquals($expectedInnerValue, $actualInnerValue);
         }
+
+        $this->assertTrue(true);
     }
 
     public function constructorWithRepeatedWrapperTypeDataProvider()
@@ -286,6 +288,8 @@ class WrapperTypeSettersTest extends TestBase
             }
             $this->assertEquals($expectedInnerValue, $actualInnerValue);
         }
+
+        $this->assertTrue(true);
     }
 
     public function constructorWithMapWrapperTypeDataProvider()

+ 5 - 3
php/tests/test.sh

@@ -11,9 +11,11 @@ PHP_VERSION=$(php -r "echo PHP_VERSION;")
 
 # Each version of PHPUnit supports a fairly narrow range of PHP versions.
 case "$PHP_VERSION" in
-  7.0.*|7.1.*|7.2.*)
-    # Oddly older than for 5.6. Not sure the reason.
-    PHPUNIT=phpunit-5.6.0.phar
+  7.0.*)
+    PHPUNIT=phpunit-6.phar
+    ;;
+  7.1.*|7.2.*)
+    PHPUNIT=phpunit-7.5.0.phar
     ;;
   7.3.*|7.4.*)
     PHPUNIT=phpunit-8.phar

+ 24 - 0
php/tests/test_base.php

@@ -12,6 +12,30 @@ class TestBase extends \PHPUnit\Framework\TestCase
         TestUtil::setTestMessage($m);
     }
 
+    /**
+     * Polyfill for phpunit6.
+     */
+    static public function assertStringContains($needle, $haystack)
+    {
+        if (function_exists('PHPUnit\Framework\assertStringContainsString')) {
+            parent::assertStringContainsString($needle, $haystack);
+        } else {
+            parent::assertContains($needle, $haystack);
+        }
+    }
+
+    /**
+     * Polyfill for phpunit6.
+     */
+    static public function assertFloatEquals($expected, $actual, $delta)
+    {
+        if (function_exists('PHPUnit\Framework\assertEqualsWithDelta')) {
+            parent::assertEqualsWithDelta($expected, $actual, $delta);
+        } else {
+            parent::assertEquals($expected, $actual, '', $delta);
+        }
+    }
+
     public function setFields2(TestMessage $m)
     {
         TestUtil::setTestMessage2($m);

+ 1 - 1
python/google/protobuf/__init__.py

@@ -30,4 +30,4 @@
 
 # Copyright 2007 Google Inc. All Rights Reserved.
 
-__version__ = '3.13.0'
+__version__ = '3.14.0'

+ 32 - 9
python/google/protobuf/descriptor.py

@@ -287,12 +287,26 @@ class Descriptor(_NestedDescriptorBase):
   if _USE_C_DESCRIPTORS:
     _C_DESCRIPTOR_CLASS = _message.Descriptor
 
-    def __new__(cls, name, full_name, filename, containing_type, fields,
-                nested_types, enum_types, extensions, options=None,
-                serialized_options=None,
-                is_extendable=True, extension_ranges=None, oneofs=None,
-                file=None, serialized_start=None, serialized_end=None,  # pylint: disable=redefined-builtin
-                syntax=None, create_key=None):
+    def __new__(
+        cls,
+        name=None,
+        full_name=None,
+        filename=None,
+        containing_type=None,
+        fields=None,
+        nested_types=None,
+        enum_types=None,
+        extensions=None,
+        options=None,
+        serialized_options=None,
+        is_extendable=True,
+        extension_ranges=None,
+        oneofs=None,
+        file=None,  # pylint: disable=redefined-builtin
+        serialized_start=None,
+        serialized_end=None,
+        syntax=None,
+        create_key=None):
       _message.Message._CheckCalledFromGeneratedFile()
       return _message.default_pool.FindMessageTypeByName(full_name)
 
@@ -799,9 +813,18 @@ class ServiceDescriptor(_NestedDescriptorBase):
   if _USE_C_DESCRIPTORS:
     _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor
 
-    def __new__(cls, name, full_name, index, methods, options=None,
-                serialized_options=None, file=None,  # pylint: disable=redefined-builtin
-                serialized_start=None, serialized_end=None, create_key=None):
+    def __new__(
+        cls,
+        name=None,
+        full_name=None,
+        index=None,
+        methods=None,
+        options=None,
+        serialized_options=None,
+        file=None,  # pylint: disable=redefined-builtin
+        serialized_start=None,
+        serialized_end=None,
+        create_key=None):
       _message.Message._CheckCalledFromGeneratedFile()  # pylint: disable=protected-access
       return _message.default_pool.FindServiceByName(full_name)
 

+ 1 - 3
python/google/protobuf/internal/factory_test1.proto

@@ -34,7 +34,6 @@ syntax = "proto2";
 
 package google.protobuf.python.internal;
 
-
 enum Factory1Enum {
   FACTORY_1_VALUE_0 = 0;
   FACTORY_1_VALUE_1 = 1;
@@ -67,6 +66,5 @@ message Factory1MethodResponse {
 
 service Factory1Service {
   // Dummy method for this dummy service.
-  rpc Factory1Method(Factory1MethodRequest) returns (Factory1MethodResponse) {
-  }
+  rpc Factory1Method(Factory1MethodRequest) returns (Factory1MethodResponse) {}
 }

+ 17 - 0
python/google/protobuf/internal/message_factory_test.py

@@ -106,6 +106,23 @@ class MessageFactoryTest(unittest.TestCase):
         'google.protobuf.python.internal.Factory2Message'))
     self.assertTrue(cls is cls2)
 
+  def testCreatePrototypeOverride(self):
+    class MyMessageFactory(message_factory.MessageFactory):
+
+      def CreatePrototype(self, descriptor):
+        cls = super(MyMessageFactory, self).CreatePrototype(descriptor)
+        cls.additional_field = 'Some value'
+        return cls
+
+    db = descriptor_database.DescriptorDatabase()
+    pool = descriptor_pool.DescriptorPool(db)
+    db.Add(self.factory_test1_fd)
+    db.Add(self.factory_test2_fd)
+    factory = MyMessageFactory()
+    cls = factory.GetPrototype(pool.FindMessageTypeByName(
+        'google.protobuf.python.internal.Factory2Message'))
+    self.assertTrue(hasattr(cls, 'additional_field'))
+
   def testGetMessages(self):
     # performed twice because multiple calls with the same input must be allowed
     for _ in range(2):

+ 27 - 0
python/google/protobuf/internal/unknown_fields_test.py

@@ -39,6 +39,7 @@ try:
   import unittest2 as unittest  #PY26
 except ImportError:
   import unittest
+import sys
 from google.protobuf import map_unittest_pb2
 from google.protobuf import unittest_mset_pb2
 from google.protobuf import unittest_pb2
@@ -53,6 +54,12 @@ from google.protobuf.internal import type_checkers
 from google.protobuf.internal import wire_format
 from google.protobuf import descriptor
 
+try:
+  import tracemalloc  # pylint: disable=g-import-not-at-top
+except ImportError:
+  # Requires python 3.4+
+  pass
+
 
 @testing_refleaks.TestCase
 class UnknownFieldsTest(unittest.TestCase):
@@ -312,6 +319,26 @@ class UnknownFieldsAccessorsTest(unittest.TestCase):
     self.assertIn('UnknownFields does not exist.',
                   str(context.exception))
 
+  @unittest.skipIf((sys.version_info.major, sys.version_info.minor) < (3, 4),
+                   'tracemalloc requires python 3.4+')
+  def testUnknownFieldsNoMemoryLeak(self):
+    # Call to UnknownFields must not leak memory
+    nb_leaks = 1234
+
+    def leaking_function():
+      for _ in range(nb_leaks):
+        self.empty_message.UnknownFields()
+
+    tracemalloc.start()
+    snapshot1 = tracemalloc.take_snapshot()
+    leaking_function()
+    snapshot2 = tracemalloc.take_snapshot()
+    top_stats = snapshot2.compare_to(snapshot1, 'lineno')
+    tracemalloc.stop()
+    # There's no easy way to look for a precise leak source.
+    # Rely on a "marker" count value while checking allocated memory.
+    self.assertEqual([], [x for x in top_stats if x.count_diff == nb_leaks])
+
   def testSubUnknownFields(self):
     message = unittest_pb2.TestAllTypes()
     message.optionalgroup.a = 123

+ 44 - 19
python/google/protobuf/message_factory.py

@@ -64,7 +64,7 @@ class MessageFactory(object):
     self._classes = {}
 
   def GetPrototype(self, descriptor):
-    """Builds a proto2 message class based on the passed in descriptor.
+    """Obtains a proto2 message class based on the passed in descriptor.
 
     Passing a descriptor with a fully qualified name matching a previous
     invocation will cause the same class to be returned.
@@ -76,27 +76,52 @@ class MessageFactory(object):
       A class describing the passed in descriptor.
     """
     if descriptor not in self._classes:
-      descriptor_name = descriptor.name
-      if str is bytes:  # PY2
-        descriptor_name = descriptor.name.encode('ascii', 'ignore')
-      result_class = _GENERATED_PROTOCOL_MESSAGE_TYPE(
-          descriptor_name,
-          (message.Message,),
-          {'DESCRIPTOR': descriptor, '__module__': None})
-      # pylint: disable=protected-access
-      result_class._FACTORY = self
-      # If module not set, it wrongly points to message_factory module.
+      result_class = self.CreatePrototype(descriptor)
+      # The assignment to _classes is redundant for the base implementation, but
+      # might avoid confusion in cases where CreatePrototype gets overridden and
+      # does not call the base implementation.
       self._classes[descriptor] = result_class
-      for field in descriptor.fields:
-        if field.message_type:
-          self.GetPrototype(field.message_type)
-      for extension in result_class.DESCRIPTOR.extensions:
-        if extension.containing_type not in self._classes:
-          self.GetPrototype(extension.containing_type)
-        extended_class = self._classes[extension.containing_type]
-        extended_class.RegisterExtension(extension)
+      return result_class
     return self._classes[descriptor]
 
+  def CreatePrototype(self, descriptor):
+    """Builds a proto2 message class based on the passed in descriptor.
+
+    Don't call this function directly, it always creates a new class. Call
+    GetPrototype() instead. This method is meant to be overridden in subblasses
+    to perform additional operations on the newly constructed class.
+
+    Args:
+      descriptor: The descriptor to build from.
+
+    Returns:
+      A class describing the passed in descriptor.
+    """
+    descriptor_name = descriptor.name
+    if str is bytes:  # PY2
+      descriptor_name = descriptor.name.encode('ascii', 'ignore')
+    result_class = _GENERATED_PROTOCOL_MESSAGE_TYPE(
+        descriptor_name,
+        (message.Message,),
+        {
+            'DESCRIPTOR': descriptor,
+            # If module not set, it wrongly points to message_factory module.
+            '__module__': None,
+        })
+    result_class._FACTORY = self  # pylint: disable=protected-access
+    # Assign in _classes before doing recursive calls to avoid infinite
+    # recursion.
+    self._classes[descriptor] = result_class
+    for field in descriptor.fields:
+      if field.message_type:
+        self.GetPrototype(field.message_type)
+    for extension in result_class.DESCRIPTOR.extensions:
+      if extension.containing_type not in self._classes:
+        self.GetPrototype(extension.containing_type)
+      extended_class = self._classes[extension.containing_type]
+      extended_class.RegisterExtension(extension)
+    return result_class
+
   def GetMessages(self, files):
     """Gets all the messages from a specified file.
 

+ 26 - 0
python/google/protobuf/proto_api.h

@@ -82,6 +82,32 @@ struct PyProto_API {
   // to create Python-compatible message.
   virtual const DescriptorPool* GetDefaultDescriptorPool() const = 0;
   virtual MessageFactory* GetDefaultMessageFactory() const = 0;
+
+  // Allocate a new protocol buffer as a python object for the provided
+  // descriptor. This function works even if no Python module has been imported
+  // for the corresponding protocol buffer class.
+  // The factory is usually null; when provided, it is the MessageFactory which
+  // owns the Python class, and will be used to find and create Extensions for
+  // this message.
+  // When null is returned, a python error has already been set.
+  virtual PyObject* NewMessage(const Descriptor* descriptor,
+                               PyObject* py_message_factory) const = 0;
+
+  // Allocate a new protocol buffer where the underlying object is owned by C++.
+  // The factory must currently be null.  This function works even if no Python
+  // module has been imported for the corresponding protocol buffer class.
+  // When null is returned, a python error has already been set.
+  //
+  // Since this call returns a python object owned by C++, some operations
+  // are risky, and it must be used carefully. In particular:
+  // * Avoid modifying the returned object from the C++ side while there are
+  // existing python references to it or it's subobjects.
+  // * Avoid using python references to this object or any subobjects after the
+  // C++ object has been freed.
+  // * Calling this with the same C++ pointer will result in multiple distinct
+  // python objects referencing the same C++ object.
+  virtual PyObject* NewMessageOwnedExternally(
+      Message* msg, PyObject* py_message_factory) const = 0;
 };
 
 inline const char* PyProtoAPICapsuleName() {

+ 114 - 103
python/google/protobuf/pyext/message.cc

@@ -121,7 +121,7 @@ inline void LowerString(std::string* s) {
     if ('A' <= *i && *i <= 'Z') *i += 'a' - 'A';
   }
 }
-}
+}  // namespace
 
 // Finalize the creation of the Message class.
 static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) {
@@ -145,7 +145,7 @@ static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) {
         PyEnumDescriptor_FromDescriptor(enum_descriptor));
     if (enum_type == NULL) {
       return -1;
-     }
+    }
     // Add wrapped enum type to message class.
     ScopedPyObjectPtr wrapped(PyObject_CallFunctionObjArgs(
         EnumTypeWrapper_class, enum_type.get(), NULL));
@@ -195,8 +195,7 @@ static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) {
   return 0;
 }
 
-static PyObject* New(PyTypeObject* type,
-                     PyObject* args, PyObject* kwargs) {
+static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) {
   static char *kwlist[] = {"name", "bases", "dict", 0};
   PyObject *bases, *dict;
   const char* name;
@@ -219,41 +218,20 @@ static PyObject* New(PyTypeObject* type,
   }
 
   // Check dict['DESCRIPTOR']
-  PyObject* descriptor_or_name = PyDict_GetItem(dict, kDESCRIPTOR);
-  if (descriptor_or_name == nullptr) {
+  PyObject* py_descriptor = PyDict_GetItem(dict, kDESCRIPTOR);
+  if (py_descriptor == nullptr) {
     PyErr_SetString(PyExc_TypeError, "Message class has no DESCRIPTOR");
-    return NULL;
+    return nullptr;
   }
-
-  Py_ssize_t name_size;
-  char* full_name;
-  const Descriptor* message_descriptor;
-  PyObject* py_descriptor;
-
-  if (PyObject_TypeCheck(descriptor_or_name, &PyMessageDescriptor_Type)) {
-    py_descriptor = descriptor_or_name;
-    message_descriptor = PyMessageDescriptor_AsDescriptor(py_descriptor);
-    if (message_descriptor == nullptr) {
-      return nullptr;
-    }
-  } else {
-    if (PyString_AsStringAndSize(descriptor_or_name, &full_name, &name_size) <
-        0) {
-      return nullptr;
-    }
-    message_descriptor =
-        GetDefaultDescriptorPool()->pool->FindMessageTypeByName(
-            StringParam(full_name, name_size));
-    if (message_descriptor == nullptr) {
-      PyErr_Format(PyExc_KeyError,
-                   "Can not find message descriptor %s "
-                   "from pool",
-                   full_name);
-      return nullptr;
-    }
-    py_descriptor = PyMessageDescriptor_FromDescriptor(message_descriptor);
-    // reset the dict['DESCRIPTOR'] to py_descriptor.
-    PyDict_SetItem(dict, kDESCRIPTOR, py_descriptor);
+  if (!PyObject_TypeCheck(py_descriptor, &PyMessageDescriptor_Type)) {
+    PyErr_Format(PyExc_TypeError, "Expected a message Descriptor, got %s",
+                 py_descriptor->ob_type->tp_name);
+    return nullptr;
+  }
+  const Descriptor* message_descriptor =
+      PyMessageDescriptor_AsDescriptor(py_descriptor);
+  if (message_descriptor == nullptr) {
+    return nullptr;
   }
 
   // Messages have no __dict__
@@ -603,15 +581,15 @@ bool VerifyIntegerCastAndRange(PyObject* arg, ValueType value) {
       OutOfRangeError(arg);
     }  // Otherwise propagate existing error.
     return false;
-    }
-    if (PROTOBUF_PREDICT_FALSE(!IsValidNumericCast<RangeType>(value))) {
-      OutOfRangeError(arg);
-      return false;
-    }
+  }
+  if (PROTOBUF_PREDICT_FALSE(!IsValidNumericCast<RangeType>(value))) {
+    OutOfRangeError(arg);
+    return false;
+  }
   return true;
 }
 
-template<class T>
+template <class T>
 bool CheckAndGetInteger(PyObject* arg, T* value) {
   // The fast path.
 #if PY_MAJOR_VERSION < 3
@@ -631,10 +609,10 @@ bool CheckAndGetInteger(PyObject* arg, T* value) {
   // an integer and can be used as an ordinal number".
   // This definition includes everything that implements numbers.Integral
   // and shouldn't cast the net too wide.
-    if (PROTOBUF_PREDICT_FALSE(!PyIndex_Check(arg))) {
-      FormatTypeError(arg, "int, long");
-      return false;
-    }
+  if (PROTOBUF_PREDICT_FALSE(!PyIndex_Check(arg))) {
+    FormatTypeError(arg, "int, long");
+    return false;
+  }
 
   // Now we have an integral number so we can safely use PyLong_ functions.
   // We need to treat the signed and unsigned cases differently in case arg is
@@ -651,7 +629,7 @@ bool CheckAndGetInteger(PyObject* arg, T* value) {
       if (PROTOBUF_PREDICT_FALSE(casted == nullptr)) {
         // Propagate existing error.
         return false;
-        }
+      }
       ulong_result = PyLong_AsUnsignedLongLong(casted);
       Py_DECREF(casted);
     }
@@ -676,7 +654,7 @@ bool CheckAndGetInteger(PyObject* arg, T* value) {
       if (PROTOBUF_PREDICT_FALSE(casted == nullptr)) {
         // Propagate existing error.
         return false;
-        }
+      }
       long_result = PyLong_AsLongLong(casted);
       Py_DECREF(casted);
     }
@@ -702,7 +680,7 @@ bool CheckAndGetDouble(PyObject* arg, double* value) {
   if (PROTOBUF_PREDICT_FALSE(*value == -1 && PyErr_Occurred())) {
     FormatTypeError(arg, "int, long, float");
     return false;
-    }
+  }
   return true;
 }
 
@@ -928,9 +906,9 @@ int AssureWritable(CMessage* self) {
   // Toplevel messages are always mutable.
   GOOGLE_DCHECK(self->parent);
 
-  if (AssureWritable(self->parent) == -1)
+  if (AssureWritable(self->parent) == -1) {
     return -1;
-
+  }
   // If this message is part of a oneof, there might be a field to release in
   // the parent.
   if (MaybeReleaseOverlappingOneofField(self->parent,
@@ -1279,32 +1257,41 @@ CMessage* NewEmptyMessage(CMessageClass* type) {
 
 // The __new__ method of Message classes.
 // Creates a new C++ message and takes ownership.
-static PyObject* New(PyTypeObject* cls,
-                     PyObject* unused_args, PyObject* unused_kwargs) {
-  CMessageClass* type = CheckMessageClass(cls);
-  if (type == NULL) {
-    return NULL;
-  }
+static CMessage* NewCMessage(CMessageClass* type) {
   // Retrieve the message descriptor and the default instance (=prototype).
   const Descriptor* message_descriptor = type->message_descriptor;
-  if (message_descriptor == NULL) {
-    return NULL;
+  if (message_descriptor == nullptr) {
+    // This would be very unexpected since the CMessageClass has already
+    // been checked.
+    PyErr_Format(PyExc_TypeError,
+                 "CMessageClass object '%s' has no descriptor.",
+                 Py_TYPE(type)->tp_name);
+    return nullptr;
   }
   const Message* prototype =
       type->py_message_factory->message_factory->GetPrototype(
           message_descriptor);
-  if (prototype == NULL) {
+  if (prototype == nullptr) {
     PyErr_SetString(PyExc_TypeError, message_descriptor->full_name().c_str());
-    return NULL;
+    return nullptr;
   }
 
   CMessage* self = NewEmptyMessage(type);
-  if (self == NULL) {
-    return NULL;
+  if (self == nullptr) {
+    return nullptr;
   }
   self->message = prototype->New();
   self->parent = nullptr;  // This message owns its data.
-  return reinterpret_cast<PyObject*>(self);
+  return self;
+}
+
+static PyObject* New(PyTypeObject* cls, PyObject* unused_args,
+                     PyObject* unused_kwargs) {
+  CMessageClass* type = CheckMessageClass(cls);
+  if (type == nullptr) {
+    return nullptr;
+  }
+  return reinterpret_cast<PyObject*>(NewCMessage(type));
 }
 
 // The __init__ method of Message classes.
@@ -2866,28 +2853,57 @@ Message* PyMessage_GetMutableMessagePointer(PyObject* msg) {
   return cmsg->message;
 }
 
+PyObject* PyMessage_New(const Descriptor* descriptor,
+                        PyObject* py_message_factory) {
+  PyMessageFactory* factory = nullptr;
+  if (py_message_factory == nullptr) {
+    factory = GetDescriptorPool_FromPool(descriptor->file()->pool())
+                  ->py_message_factory;
+  } else if (PyObject_TypeCheck(py_message_factory, &PyMessageFactory_Type)) {
+    factory = reinterpret_cast<PyMessageFactory*>(py_message_factory);
+  } else {
+    PyErr_SetString(PyExc_TypeError, "Expected a MessageFactory");
+    return nullptr;
+  }
+  auto* message_class =
+      message_factory::GetOrCreateMessageClass(factory, descriptor);
+  if (message_class == nullptr) {
+    return nullptr;
+  }
+
+  CMessage* self = cmessage::NewCMessage(message_class);
+  Py_DECREF(message_class);
+  if (self == nullptr) {
+    return nullptr;
+  }
+  return self->AsPyObject();
+}
+
 PyObject* PyMessage_NewMessageOwnedExternally(Message* message,
-                                              PyObject* message_factory) {
-  if (message_factory) {
+                                              PyObject* py_message_factory) {
+  if (py_message_factory) {
     PyErr_SetString(PyExc_NotImplementedError,
                     "Default message_factory=NULL is the only supported value");
-    return NULL;
+    return nullptr;
   }
   if (message->GetReflection()->GetMessageFactory() !=
       MessageFactory::generated_factory()) {
     PyErr_SetString(PyExc_TypeError,
                     "Message pointer was not created from the default factory");
-    return NULL;
+    return nullptr;
   }
 
   CMessageClass* message_class = message_factory::GetOrCreateMessageClass(
       GetDefaultDescriptorPool()->py_message_factory, message->GetDescriptor());
+  if (message_class == nullptr) {
+    return nullptr;
+  }
 
   CMessage* self = cmessage::NewEmptyMessage(message_class);
-  if (self == NULL) {
-    return NULL;
-  }
   Py_DECREF(message_class);
+  if (self == nullptr) {
+    return nullptr;
+  }
   self->message = message;
   Py_INCREF(Py_None);
   self->parent = reinterpret_cast<CMessage*>(Py_None);
@@ -2954,9 +2970,9 @@ bool InitProto2MessageModule(PyObject *m) {
       return false;
     }
 
-    PyModule_AddObject(m, "RepeatedScalarContainer",
-                       reinterpret_cast<PyObject*>(
-                           &RepeatedScalarContainer_Type));
+    PyModule_AddObject(
+        m, "RepeatedScalarContainer",
+        reinterpret_cast<PyObject*>(&RepeatedScalarContainer_Type));
 
     if (PyType_Ready(&RepeatedCompositeContainer_Type) < 0) {
       return false;
@@ -2964,8 +2980,7 @@ bool InitProto2MessageModule(PyObject *m) {
 
     PyModule_AddObject(
         m, "RepeatedCompositeContainer",
-        reinterpret_cast<PyObject*>(
-            &RepeatedCompositeContainer_Type));
+        reinterpret_cast<PyObject*>(&RepeatedCompositeContainer_Type));
 
     // Register them as MutableSequence.
 #if PY_MAJOR_VERSION >= 3
@@ -2998,16 +3013,14 @@ bool InitProto2MessageModule(PyObject *m) {
   }
 
   PyModule_AddObject(m, "UnknownFieldSet",
-                     reinterpret_cast<PyObject*>(
-                         &PyUnknownFields_Type));
+                     reinterpret_cast<PyObject*>(&PyUnknownFields_Type));
 
   if (PyType_Ready(&PyUnknownFieldRef_Type) < 0) {
     return false;
   }
 
   PyModule_AddObject(m, "UnknownField",
-                     reinterpret_cast<PyObject*>(
-                         &PyUnknownFieldRef_Type));
+                     reinterpret_cast<PyObject*>(&PyUnknownFieldRef_Type));
 
   // Initialize Map container types.
   if (!InitMapContainers()) {
@@ -3023,9 +3036,8 @@ bool InitProto2MessageModule(PyObject *m) {
   if (PyType_Ready(&ExtensionDict_Type) < 0) {
     return false;
   }
-  PyModule_AddObject(
-      m, "ExtensionDict",
-      reinterpret_cast<PyObject*>(&ExtensionDict_Type));
+  PyModule_AddObject(m, "ExtensionDict",
+                     reinterpret_cast<PyObject*>(&ExtensionDict_Type));
   if (PyType_Ready(&ExtensionIterator_Type) < 0) {
     return false;
   }
@@ -3039,25 +3051,24 @@ bool InitProto2MessageModule(PyObject *m) {
   PyModule_AddObject(m, "default_pool",
                      reinterpret_cast<PyObject*>(GetDefaultDescriptorPool()));
 
-  PyModule_AddObject(m, "DescriptorPool", reinterpret_cast<PyObject*>(
-      &PyDescriptorPool_Type));
-
-  PyModule_AddObject(m, "Descriptor", reinterpret_cast<PyObject*>(
-      &PyMessageDescriptor_Type));
-  PyModule_AddObject(m, "FieldDescriptor", reinterpret_cast<PyObject*>(
-      &PyFieldDescriptor_Type));
-  PyModule_AddObject(m, "EnumDescriptor", reinterpret_cast<PyObject*>(
-      &PyEnumDescriptor_Type));
-  PyModule_AddObject(m, "EnumValueDescriptor", reinterpret_cast<PyObject*>(
-      &PyEnumValueDescriptor_Type));
-  PyModule_AddObject(m, "FileDescriptor", reinterpret_cast<PyObject*>(
-      &PyFileDescriptor_Type));
-  PyModule_AddObject(m, "OneofDescriptor", reinterpret_cast<PyObject*>(
-      &PyOneofDescriptor_Type));
-  PyModule_AddObject(m, "ServiceDescriptor", reinterpret_cast<PyObject*>(
-      &PyServiceDescriptor_Type));
-  PyModule_AddObject(m, "MethodDescriptor", reinterpret_cast<PyObject*>(
-      &PyMethodDescriptor_Type));
+  PyModule_AddObject(m, "DescriptorPool",
+                     reinterpret_cast<PyObject*>(&PyDescriptorPool_Type));
+  PyModule_AddObject(m, "Descriptor",
+                     reinterpret_cast<PyObject*>(&PyMessageDescriptor_Type));
+  PyModule_AddObject(m, "FieldDescriptor",
+                     reinterpret_cast<PyObject*>(&PyFieldDescriptor_Type));
+  PyModule_AddObject(m, "EnumDescriptor",
+                     reinterpret_cast<PyObject*>(&PyEnumDescriptor_Type));
+  PyModule_AddObject(m, "EnumValueDescriptor",
+                     reinterpret_cast<PyObject*>(&PyEnumValueDescriptor_Type));
+  PyModule_AddObject(m, "FileDescriptor",
+                     reinterpret_cast<PyObject*>(&PyFileDescriptor_Type));
+  PyModule_AddObject(m, "OneofDescriptor",
+                     reinterpret_cast<PyObject*>(&PyOneofDescriptor_Type));
+  PyModule_AddObject(m, "ServiceDescriptor",
+                     reinterpret_cast<PyObject*>(&PyServiceDescriptor_Type));
+  PyModule_AddObject(m, "MethodDescriptor",
+                     reinterpret_cast<PyObject*>(&PyMethodDescriptor_Type));
 
   PyObject* enum_type_wrapper = PyImport_ImportModule(
       "google.protobuf.internal.enum_type_wrapper");

+ 46 - 45
python/google/protobuf/pyext/message.h

@@ -282,51 +282,50 @@ PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg);
 /* Is 64bit */
 #define IS_64BIT (SIZEOF_LONG == 8)
 
-#define FIELD_IS_REPEATED(field_descriptor)                 \
-    ((field_descriptor)->label() == FieldDescriptor::LABEL_REPEATED)
-
-#define GOOGLE_CHECK_GET_INT32(arg, value, err)                        \
-    int32 value;                                            \
-    if (!CheckAndGetInteger(arg, &value)) { \
-      return err;                                          \
-    }
-
-#define GOOGLE_CHECK_GET_INT64(arg, value, err)                        \
-    int64 value;                                            \
-    if (!CheckAndGetInteger(arg, &value)) { \
-      return err;                                          \
-    }
-
-#define GOOGLE_CHECK_GET_UINT32(arg, value, err)                       \
-    uint32 value;                                           \
-    if (!CheckAndGetInteger(arg, &value)) { \
-      return err;                                          \
-    }
-
-#define GOOGLE_CHECK_GET_UINT64(arg, value, err)                       \
-    uint64 value;                                           \
-    if (!CheckAndGetInteger(arg, &value)) { \
-      return err;                                          \
-    }
-
-#define GOOGLE_CHECK_GET_FLOAT(arg, value, err)                        \
-    float value;                                            \
-    if (!CheckAndGetFloat(arg, &value)) {                   \
-      return err;                                          \
-    }                                                       \
-
-#define GOOGLE_CHECK_GET_DOUBLE(arg, value, err)                       \
-    double value;                                           \
-    if (!CheckAndGetDouble(arg, &value)) {                  \
-      return err;                                          \
-    }
-
-#define GOOGLE_CHECK_GET_BOOL(arg, value, err)                         \
-    bool value;                                             \
-    if (!CheckAndGetBool(arg, &value)) {                    \
-      return err;                                          \
-    }
+#define FIELD_IS_REPEATED(field_descriptor) \
+  ((field_descriptor)->label() == FieldDescriptor::LABEL_REPEATED)
 
+#define GOOGLE_CHECK_GET_INT32(arg, value, err)  \
+  int32 value;                            \
+  if (!CheckAndGetInteger(arg, &value)) { \
+    return err;                           \
+  }
+
+#define GOOGLE_CHECK_GET_INT64(arg, value, err)  \
+  int64 value;                            \
+  if (!CheckAndGetInteger(arg, &value)) { \
+    return err;                           \
+  }
+
+#define GOOGLE_CHECK_GET_UINT32(arg, value, err) \
+  uint32 value;                           \
+  if (!CheckAndGetInteger(arg, &value)) { \
+    return err;                           \
+  }
+
+#define GOOGLE_CHECK_GET_UINT64(arg, value, err) \
+  uint64 value;                           \
+  if (!CheckAndGetInteger(arg, &value)) { \
+    return err;                           \
+  }
+
+#define GOOGLE_CHECK_GET_FLOAT(arg, value, err) \
+  float value;                           \
+  if (!CheckAndGetFloat(arg, &value)) {  \
+    return err;                          \
+  }
+
+#define GOOGLE_CHECK_GET_DOUBLE(arg, value, err) \
+  double value;                           \
+  if (!CheckAndGetDouble(arg, &value)) {  \
+    return err;                           \
+  }
+
+#define GOOGLE_CHECK_GET_BOOL(arg, value, err) \
+  bool value;                           \
+  if (!CheckAndGetBool(arg, &value)) {  \
+    return err;                         \
+  }
 
 #define FULL_MODULE_NAME "google.protobuf.pyext._message"
 
@@ -353,10 +352,12 @@ bool CheckFieldBelongsToMessage(const FieldDescriptor* field_descriptor,
 
 extern PyObject* PickleError_class;
 
+PyObject* PyMessage_New(const Descriptor* descriptor,
+                        PyObject* py_message_factory);
 const Message* PyMessage_GetMessagePointer(PyObject* msg);
 Message* PyMessage_GetMutableMessagePointer(PyObject* msg);
 PyObject* PyMessage_NewMessageOwnedExternally(Message* message,
-                                              PyObject* message_factory);
+                                              PyObject* py_message_factory);
 
 bool InitProto2MessageModule(PyObject *m);
 

+ 10 - 2
python/google/protobuf/pyext/message_module.cc

@@ -30,13 +30,12 @@
 
 #include <Python.h>
 
+#include <google/protobuf/message_lite.h>
 #include <google/protobuf/pyext/descriptor_pool.h>
 #include <google/protobuf/pyext/message.h>
 #include <google/protobuf/pyext/message_factory.h>
 #include <google/protobuf/proto_api.h>
 
-#include <google/protobuf/message_lite.h>
-
 namespace {
 
 // C++ API.  Clients get at this via proto_api.h
@@ -55,6 +54,15 @@ struct ApiImplementation : google::protobuf::python::PyProto_API {
     return google::protobuf::python::GetDefaultDescriptorPool()
         ->py_message_factory->message_factory;
   }
+  PyObject* NewMessage(const google::protobuf::Descriptor* descriptor,
+                       PyObject* py_message_factory) const override {
+    return google::protobuf::python::PyMessage_New(descriptor, py_message_factory);
+  }
+  PyObject* NewMessageOwnedExternally(
+      google::protobuf::Message* msg, PyObject* py_message_factory) const override {
+    return google::protobuf::python::PyMessage_NewMessageOwnedExternally(
+        msg, py_message_factory);
+  }
 };
 
 }  // namespace

+ 4 - 0
python/google/protobuf/pyext/repeated_composite_container.cc

@@ -567,7 +567,11 @@ PyTypeObject RepeatedCompositeContainer_Type = {
     sizeof(RepeatedCompositeContainer),         // tp_basicsize
     0,                                          //  tp_itemsize
     repeated_composite_container::Dealloc,      //  tp_dealloc
+#if PY_VERSION_HEX >= 0x03080000
+    0,                                          //  tp_vectorcall_offset
+#else
     nullptr,                                    //  tp_print
+#endif
     nullptr,                                    //  tp_getattr
     nullptr,                                    //  tp_setattr
     nullptr,                                    //  tp_compare

+ 4 - 0
python/google/protobuf/pyext/repeated_scalar_container.cc

@@ -753,7 +753,11 @@ PyTypeObject RepeatedScalarContainer_Type = {
     sizeof(RepeatedScalarContainer),         // tp_basicsize
     0,                                       //  tp_itemsize
     repeated_scalar_container::Dealloc,      //  tp_dealloc
+#if PY_VERSION_HEX >= 0x03080000
+    0,                                       //  tp_vectorcall_offset
+#else
     nullptr,                                 //  tp_print
+#endif
     nullptr,                                 //  tp_getattr
     nullptr,                                 //  tp_setattr
     nullptr,                                 //  tp_compare

+ 1 - 0
python/google/protobuf/pyext/unknown_fields.cc

@@ -142,6 +142,7 @@ static void Dealloc(PyObject* pself) {
   }
   Py_CLEAR(self->parent);
   self->~PyUnknownFields();
+  Py_TYPE(pself)->tp_free(pself);
 }
 
 static PySequenceMethods SqMethods = {

+ 1 - 14
python/google/protobuf/service_reflection.py

@@ -38,12 +38,6 @@ compiler at compile-time.
 
 __author__ = 'petar@google.com (Petar Petrov)'
 
-from google.protobuf.internal import api_implementation
-
-if api_implementation.Type() == 'cpp':
-  # pylint: disable=g-import-not-at-top
-  from google.protobuf.pyext import _message
-
 
 class GeneratedServiceType(type):
 
@@ -84,10 +78,6 @@ class GeneratedServiceType(type):
       return
 
     descriptor = dictionary[GeneratedServiceType._DESCRIPTOR_KEY]
-    if isinstance(descriptor, str):
-      descriptor = _message.default_pool.FindServiceByName(descriptor)
-      dictionary[GeneratedServiceType._DESCRIPTOR_KEY] = descriptor
-
     service_builder = _ServiceBuilder(descriptor)
     service_builder.BuildService(cls)
     cls.DESCRIPTOR = descriptor
@@ -113,16 +103,13 @@ class GeneratedServiceStubType(GeneratedServiceType):
         dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object
         describing this protocol service type.
     """
-    descriptor = dictionary.get(cls._DESCRIPTOR_KEY)
-    if isinstance(descriptor, str):
-      descriptor = _message.default_pool.FindServiceByName(descriptor)
-      dictionary[GeneratedServiceStubType._DESCRIPTOR_KEY] = descriptor
     super(GeneratedServiceStubType, cls).__init__(name, bases, dictionary)
     # Don't do anything if this class doesn't have a descriptor. This happens
     # when a service stub is subclassed.
     if GeneratedServiceStubType._DESCRIPTOR_KEY not in dictionary:
       return
 
+    descriptor = dictionary[GeneratedServiceStubType._DESCRIPTOR_KEY]
     service_stub_builder = _ServiceStubBuilder(descriptor)
     service_stub_builder.BuildServiceStub(cls)
 

+ 4 - 1
python/google/protobuf/text_format.py

@@ -541,7 +541,7 @@ class _Printer(object):
         # For groups, use the capitalized name.
         out.write(field.message_type.name)
       else:
-        out.write(field.name)
+          out.write(field.name)
 
     if (self.force_colon or
         field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE):
@@ -902,6 +902,8 @@ class _Parser(object):
       # pylint: disable=protected-access
       field = message.Extensions._FindExtensionByName(name)
       # pylint: enable=protected-access
+
+
       if not field:
         if self.allow_unknown_extension:
           field = None
@@ -988,6 +990,7 @@ class _Parser(object):
     if not tokenizer.TryConsume(','):
       tokenizer.TryConsume(';')
 
+
   def _ConsumeAnyTypeUrl(self, tokenizer):
     """Consumes a google.protobuf.Any type URL and returns the type name."""
     # Consume "type.googleapis.com/".

+ 14 - 2
ruby/Rakefile

@@ -51,6 +51,12 @@ if RUBY_PLATFORM == "java"
     system("mvn --batch-mode package")
   end
 else
+  unless ENV['IN_DOCKER'] == 'true'
+    # We need wyhash in-tree.
+    FileUtils.mkdir_p("ext/google/protobuf_c/third_party/wyhash")
+    FileUtils.cp("../third_party/wyhash/wyhash.h", "ext/google/protobuf_c/third_party/wyhash/wyhash.h")
+  end
+
   Rake::ExtensionTask.new("protobuf_c", spec) do |ext|
     unless RUBY_PLATFORM =~ /darwin/
       # TODO: also set "no_native to true" for mac if possible. As is,
@@ -73,7 +79,7 @@ else
     ['x86-mingw32', 'x64-mingw32', 'x86_64-linux', 'x86-linux'].each do |plat|
       RakeCompilerDock.sh <<-"EOT", platform: plat
         bundle && \
-        IN_DOCKER=true rake native:#{plat} pkg/#{spec.full_name}-#{plat}.gem RUBY_CC_VERSION=2.7.0:2.6.0:2.5.0:2.4.0:2.3.0
+        IN_DOCKER=true rake native:#{plat} pkg/#{spec.full_name}-#{plat}.gem RUBY_CC_VERSION=3.0.0:2.7.0:2.6.0:2.5.0:2.4.0:2.3.0
       EOT
     end
   end
@@ -81,7 +87,7 @@ else
   if RUBY_PLATFORM =~ /darwin/
     task 'gem:native' do
       system "rake genproto"
-      system "rake cross native gem RUBY_CC_VERSION=2.7.0:2.6.0:2.5.1:2.4.0:2.3.0"
+      system "rake cross native gem RUBY_CC_VERSION=3.0.0:2.7.0:2.6.0:2.5.1:2.4.0:2.3.0"
     end
   else
     task 'gem:native' => [:genproto, 'gem:windows']
@@ -98,7 +104,9 @@ genproto_output << "tests/test_ruby_package.rb"
 genproto_output << "tests/test_ruby_package_proto2.rb"
 genproto_output << "tests/basic_test.rb"
 genproto_output << "tests/basic_test_proto2.rb"
+genproto_output << "tests/multi_level_nesting_test.rb"
 genproto_output << "tests/wrappers.rb"
+
 file "tests/generated_code.rb" => "tests/generated_code.proto" do |file_task|
   sh "../src/protoc --ruby_out=. tests/generated_code.proto"
 end
@@ -131,6 +139,10 @@ file "tests/basic_test_proto2.rb" => "tests/basic_test_proto2.proto" do |file_ta
   sh "../src/protoc -I../src -I. --ruby_out=. tests/basic_test_proto2.proto"
 end
 
+file "tests/multi_level_nesting_test.rb" => "tests/multi_level_nesting_test.proto" do |file_task|
+  sh "../src/protoc -I../src -I. --ruby_out=. tests/multi_level_nesting_test.proto"
+end
+
 file "tests/wrappers.rb" => "../src/google/protobuf/wrappers.proto" do |file_task|
   sh "../src/protoc -I../src -I. --ruby_out=tests ../src/google/protobuf/wrappers.proto"
 end

+ 3 - 3
ruby/compatibility_tests/v3.0.0/tests/basic.rb

@@ -1264,10 +1264,10 @@ module BasicTest
       m = MapMessage.new(:map_string_int32 => {"a" => 1})
       expected = '{"mapStringInt32":{"a":1},"mapStringMsg":{}}'
       expected_preserve = '{"map_string_int32":{"a":1},"map_string_msg":{}}'
-      assert MapMessage.encode_json(m) == expected
+      assert_equal expected, MapMessage.encode_json(m, :emit_defaults => true)
 
-      json = MapMessage.encode_json(m, :preserve_proto_fieldnames => true)
-      assert json == expected_preserve
+      json = MapMessage.encode_json(m, :preserve_proto_fieldnames => true, :emit_defaults => true)
+      assert_equal expected_preserve, json
 
       m2 = MapMessage.decode_json(MapMessage.encode_json(m))
       assert m == m2

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است