Merge master into 3.4.x
diff --git a/.gitignore b/.gitignore
index b835611..798559d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -138,6 +138,8 @@
 # php test output
 composer.lock
 php/tests/generated/
+php/tests/old_protoc
+php/tests/protobuf/
 php/ext/google/protobuf/.libs/
 php/ext/google/protobuf/Makefile.fragments
 php/ext/google/protobuf/Makefile.global
@@ -165,3 +167,6 @@
 js/node_modules/
 js/testproto_libs1.js
 js/testproto_libs2.js
+
+# Ignore the bazel symlinks
+/bazel-*
diff --git a/.travis.yml b/.travis.yml
index 8f6f90d..d49e0a7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -55,7 +55,10 @@
     # autogenerated matrix.
     - os: linux
       env: CONFIG=csharp
+      language: csharp
       dist: trusty
+      dotnet: 1.0.1
+      mono: none
     # This test is kept on travis because it doesn't play nicely with other
     # tests on jenkins running in parallel.
     - os: linux
diff --git a/BUILD b/BUILD
index e5662c4..5102d6f 100644
--- a/BUILD
+++ b/BUILD
@@ -8,15 +8,35 @@
 # Protobuf Runtime Library
 ################################################################################
 
-COPTS = [
-    "-DHAVE_PTHREAD",
-    "-Wall",
-    "-Wwrite-strings",
-    "-Woverloaded-virtual",
-    "-Wno-sign-compare",
-    "-Wno-unused-function",
+WIN_COPTS = [
+    "/DHAVE_PTHREAD",
+    "/wd4018", # -Wno-sign-compare
+    "/wd4514", # -Wno-unused-function
 ]
 
+COPTS = select({
+    ":windows" : WIN_COPTS,
+    ":windows_msvc" : WIN_COPTS,
+    "//conditions:default": [
+        "-DHAVE_PTHREAD",
+        "-Wall",
+        "-Wwrite-strings",
+        "-Woverloaded-virtual",
+        "-Wno-sign-compare",
+        "-Wno-unused-function",
+    ],
+})
+
+config_setting(
+    name = "windows",
+    values = { "cpu": "x64_windows" },
+)
+
+config_setting(
+    name = "windows_msvc",
+    values = { "cpu": "x64_windows_msvc" },
+)
+
 config_setting(
     name = "android",
     values = {
@@ -60,7 +80,7 @@
     },
 )
 
-IOS_ARM_COPTS = COPTS + [
+IOS_ARM_COPTS = [
     "-DOS_IOS",
     "-miphoneos-version-min=7.0",
     "-arch armv7",
@@ -103,8 +123,8 @@
         ":ios_armv7": IOS_ARM_COPTS,
         ":ios_armv7s": IOS_ARM_COPTS,
         ":ios_arm64": IOS_ARM_COPTS,
-        "//conditions:default": COPTS,
-    }),
+        "//conditions:default": [],
+    }) + COPTS,
     includes = ["src/"],
     linkopts = LINK_OPTS,
     visibility = ["//visibility:public"],
@@ -174,8 +194,8 @@
         ":ios_armv7": IOS_ARM_COPTS,
         ":ios_armv7s": IOS_ARM_COPTS,
         ":ios_arm64": IOS_ARM_COPTS,
-        "//conditions:default": COPTS,
-    }),
+        "//conditions:default": [],
+    }) + COPTS,
     includes = ["src/"],
     linkopts = LINK_OPTS,
     visibility = ["//visibility:public"],
@@ -580,7 +600,7 @@
     ]) + [
         ":gen_well_known_protos_java",
     ],
-    javacopts = ["-source 6"],
+    javacopts = ["-source 6", "-target 6"],
     visibility = ["//visibility:public"],
 )
 
@@ -589,6 +609,7 @@
     srcs = glob([
         "java/util/src/main/java/com/google/protobuf/util/*.java",
     ]),
+    javacopts = ["-source 6", "-target 6"],
     visibility = ["//visibility:public"],
     deps = [
         "protobuf_java",
@@ -807,3 +828,84 @@
     runtime = ":protobuf_java",
     visibility = ["//visibility:public"],
 )
+
+OBJC_HDRS = [
+    "objectivec/GPBArray.h",
+    "objectivec/GPBBootstrap.h",
+    "objectivec/GPBCodedInputStream.h",
+    "objectivec/GPBCodedOutputStream.h",
+    "objectivec/GPBDescriptor.h",
+    "objectivec/GPBDictionary.h",
+    "objectivec/GPBExtensionInternals.h",
+    "objectivec/GPBExtensionRegistry.h",
+    "objectivec/GPBMessage.h",
+    "objectivec/GPBProtocolBuffers.h",
+    "objectivec/GPBProtocolBuffers_RuntimeSupport.h",
+    "objectivec/GPBRootObject.h",
+    "objectivec/GPBRuntimeTypes.h",
+    "objectivec/GPBUnknownField.h",
+    "objectivec/GPBUnknownFieldSet.h",
+    "objectivec/GPBUtilities.h",
+    "objectivec/GPBWellKnownTypes.h",
+    "objectivec/GPBWireFormat.h",
+    "objectivec/google/protobuf/Any.pbobjc.h",
+    "objectivec/google/protobuf/Api.pbobjc.h",
+    "objectivec/google/protobuf/Duration.pbobjc.h",
+    "objectivec/google/protobuf/Empty.pbobjc.h",
+    "objectivec/google/protobuf/FieldMask.pbobjc.h",
+    "objectivec/google/protobuf/SourceContext.pbobjc.h",
+    "objectivec/google/protobuf/Struct.pbobjc.h",
+    "objectivec/google/protobuf/Timestamp.pbobjc.h",
+    "objectivec/google/protobuf/Type.pbobjc.h",
+    "objectivec/google/protobuf/Wrappers.pbobjc.h",
+]
+
+OBJC_PRIVATE_HDRS = [
+    "objectivec/GPBArray_PackagePrivate.h",
+    "objectivec/GPBCodedInputStream_PackagePrivate.h",
+    "objectivec/GPBCodedOutputStream_PackagePrivate.h",
+    "objectivec/GPBDescriptor_PackagePrivate.h",
+    "objectivec/GPBDictionary_PackagePrivate.h",
+    "objectivec/GPBMessage_PackagePrivate.h",
+    "objectivec/GPBRootObject_PackagePrivate.h",
+    "objectivec/GPBUnknownFieldSet_PackagePrivate.h",
+    "objectivec/GPBUnknownField_PackagePrivate.h",
+    "objectivec/GPBUtilities_PackagePrivate.h",
+]
+
+OBJC_SRCS = [
+    "objectivec/GPBArray.m",
+    "objectivec/GPBCodedInputStream.m",
+    "objectivec/GPBCodedOutputStream.m",
+    "objectivec/GPBDescriptor.m",
+    "objectivec/GPBDictionary.m",
+    "objectivec/GPBExtensionInternals.m",
+    "objectivec/GPBExtensionRegistry.m",
+    "objectivec/GPBMessage.m",
+    "objectivec/GPBRootObject.m",
+    "objectivec/GPBUnknownField.m",
+    "objectivec/GPBUnknownFieldSet.m",
+    "objectivec/GPBUtilities.m",
+    "objectivec/GPBWellKnownTypes.m",
+    "objectivec/GPBWireFormat.m",
+    "objectivec/google/protobuf/Any.pbobjc.m",
+    "objectivec/google/protobuf/Api.pbobjc.m",
+    "objectivec/google/protobuf/Duration.pbobjc.m",
+    "objectivec/google/protobuf/Empty.pbobjc.m",
+    "objectivec/google/protobuf/FieldMask.pbobjc.m",
+    "objectivec/google/protobuf/SourceContext.pbobjc.m",
+    "objectivec/google/protobuf/Struct.pbobjc.m",
+    "objectivec/google/protobuf/Timestamp.pbobjc.m",
+    "objectivec/google/protobuf/Type.pbobjc.m",
+    "objectivec/google/protobuf/Wrappers.pbobjc.m",
+]
+
+objc_library(
+    name = "objectivec",
+    hdrs = OBJC_HDRS + OBJC_PRIVATE_HDRS,
+    includes = [
+        "objectivec",
+    ],
+    non_arc_srcs = OBJC_SRCS,
+    visibility = ["//visibility:public"],
+)
diff --git a/Makefile.am b/Makefile.am
index 8a34c5f..dd8202f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -57,6 +57,7 @@
   csharp/build_tools.sh                                                      \
   csharp/buildall.sh                                                         \
   csharp/generate_protos.sh                                                  \
+  csharp/global.json                                                         \
   csharp/keys/Google.Protobuf.public.snk                                     \
   csharp/keys/Google.Protobuf.snk                                            \
   csharp/keys/README.md                                                      \
@@ -64,18 +65,15 @@
   csharp/protos/unittest_issues.proto                                        \
   csharp/src/AddressBook/AddPerson.cs                                        \
   csharp/src/AddressBook/Addressbook.cs                                      \
-  csharp/src/AddressBook/AddressBook.xproj                                   \
+  csharp/src/AddressBook/AddressBook.csproj                                  \
   csharp/src/AddressBook/ListPeople.cs                                       \
   csharp/src/AddressBook/Program.cs                                          \
   csharp/src/AddressBook/SampleUsage.cs                                      \
-  csharp/src/AddressBook/project.json                                        \
   csharp/src/Google.Protobuf.Conformance/Conformance.cs                      \
-  csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.xproj   \
+  csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj  \
   csharp/src/Google.Protobuf.Conformance/Program.cs                          \
-  csharp/src/Google.Protobuf.Conformance/project.json                        \
-  csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.xproj         \
+  csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj        \
   csharp/src/Google.Protobuf.JsonDump/Program.cs                             \
-  csharp/src/Google.Protobuf.JsonDump/project.json                           \
   csharp/src/Google.Protobuf.Test/ByteStringTest.cs                          \
   csharp/src/Google.Protobuf.Test/CodedInputStreamExtensions.cs              \
   csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs                    \
@@ -89,11 +87,12 @@
   csharp/src/Google.Protobuf.Test/EqualityTester.cs                          \
   csharp/src/Google.Protobuf.Test/FieldCodecTest.cs                          \
   csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs                    \
-  csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.xproj                 \
+  csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj                \
   csharp/src/Google.Protobuf.Test/IssuesTest.cs                              \
   csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs                       \
   csharp/src/Google.Protobuf.Test/JsonParserTest.cs                          \
   csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs                       \
+  csharp/src/Google.Protobuf.Test/Program.cs                                 \
   csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs            \
   csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs              \
   csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs              \
@@ -115,7 +114,6 @@
   csharp/src/Google.Protobuf.Test/WellKnownTypes/FieldMaskTest.cs            \
   csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs            \
   csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs             \
-  csharp/src/Google.Protobuf.Test/project.json                               \
   csharp/src/Google.Protobuf.sln                                             \
   csharp/src/Google.Protobuf/ByteArray.cs                                    \
   csharp/src/Google.Protobuf/ByteString.cs                                   \
@@ -130,7 +128,7 @@
   csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs                 \
   csharp/src/Google.Protobuf/FieldCodec.cs                                   \
   csharp/src/Google.Protobuf/FrameworkPortability.cs                         \
-  csharp/src/Google.Protobuf/Google.Protobuf.xproj                           \
+  csharp/src/Google.Protobuf/Google.Protobuf.csproj                          \
   csharp/src/Google.Protobuf/ICustomDiagnosticMessage.cs                     \
   csharp/src/Google.Protobuf/IDeepCloneable.cs                               \
   csharp/src/Google.Protobuf/IMessage.cs                                     \
@@ -190,10 +188,7 @@
   csharp/src/Google.Protobuf/WellKnownTypes/ValuePartial.cs                  \
   csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs                      \
   csharp/src/Google.Protobuf/WellKnownTypes/WrappersPartial.cs               \
-  csharp/src/Google.Protobuf/WireFormat.cs                                   \
-  csharp/src/Google.Protobuf/project.json                                    \
-  csharp/src/global.json                                                     \
-  csharp/src/packages/repositories.config
+  csharp/src/Google.Protobuf/WireFormat.cs
 
 java_EXTRA_DIST=                                                                   \
   java/README.md                                                                   \
@@ -535,6 +530,7 @@
   objectivec/Tests/GPBDictionaryTests+UInt64.m                               \
   objectivec/Tests/GPBDictionaryTests.m                                      \
   objectivec/Tests/GPBDictionaryTests.pddm                                   \
+  objectivec/Tests/GPBExtensionRegistryTest.m                                \
   objectivec/Tests/GPBMessageTests+Merge.m                                   \
   objectivec/Tests/GPBMessageTests+Runtime.m                                 \
   objectivec/Tests/GPBMessageTests+Serialization.m                           \
@@ -601,75 +597,93 @@
   php/ext/google/protobuf/upb.c                                       \
   php/ext/google/protobuf/protobuf.c                                  \
   php/src/phpdoc.dist.xml                                             \
+  php/src/Google/Protobuf/Internal/CodedInputStream.php               \
+  php/src/Google/Protobuf/Internal/CodedOutputStream.php              \
   php/src/Google/Protobuf/Internal/DescriptorPool.php                 \
-  php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php              \
-  php/src/Google/Protobuf/Internal/OneofField.php                     \
-  php/src/Google/Protobuf/Internal/MessageOptions.php                 \
-  php/src/Google/Protobuf/Internal/FileDescriptorProto.php            \
-  php/src/Google/Protobuf/Internal/MapEntry.php                       \
-  php/src/Google/Protobuf/Internal/FieldDescriptorProto.php           \
-  php/src/Google/Protobuf/Internal/InputStream.php                    \
-  php/src/Google/Protobuf/Internal/UninterpretedOption.php            \
-  php/src/Google/Protobuf/Internal/ServiceOptions.php                 \
-  php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php \
-  php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php         \
-  php/src/Google/Protobuf/Internal/OneofDescriptorProto.php           \
-  php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php   \
-  php/src/Google/Protobuf/Internal/OutputStream.php                   \
-  php/src/Google/Protobuf/Internal/MessageBuilderContext.php          \
-  php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php       \
-  php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php       \
-  php/src/Google/Protobuf/Internal/DescriptorProto.php                \
-  php/src/Google/Protobuf/Internal/MapField.php                       \
-  php/src/Google/Protobuf/Internal/MethodDescriptorProto.php          \
   php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php \
   php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php  \
-  php/src/Google/Protobuf/Internal/RepeatedField.php                  \
-  php/src/Google/Protobuf/Internal/EnumValueOptions.php               \
-  php/src/Google/Protobuf/Internal/MethodOptions.php                  \
-  php/src/Google/Protobuf/Internal/OneofOptions.php                   \
-  php/src/Google/Protobuf/Internal/Message.php                        \
-  php/src/Google/Protobuf/Internal/FileOptions.php                    \
-  php/src/Google/Protobuf/Internal/FileDescriptorSet.php              \
+  php/src/Google/Protobuf/Internal/DescriptorProto.php                \
+  php/src/Google/Protobuf/Internal/Descriptor.php                     \
+  php/src/Google/Protobuf/Internal/EnumBuilderContext.php             \
+  php/src/Google/Protobuf/Internal/EnumDescriptor.php                 \
   php/src/Google/Protobuf/Internal/EnumDescriptorProto.php            \
-  php/src/Google/Protobuf/Internal/GPBWire.php                        \
+  php/src/Google/Protobuf/Internal/EnumOptions.php                    \
+  php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php       \
+  php/src/Google/Protobuf/Internal/EnumValueDescriptor.php            \
+  php/src/Google/Protobuf/Internal/EnumValueOptions.php               \
   php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php     \
-  php/src/Google/Protobuf/Internal/FieldOptions.php                   \
-  php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php   \
+  php/src/Google/Protobuf/Internal/FieldDescriptorProto.php           \
+  php/src/Google/Protobuf/Internal/FieldDescriptor.php                \
   php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php      \
-  php/src/Google/Protobuf/Internal/GPBType.php                        \
+  php/src/Google/Protobuf/Internal/FieldOptions_CType.php             \
   php/src/Google/Protobuf/Internal/FieldOptions_JSType.php            \
+  php/src/Google/Protobuf/Internal/FieldOptions.php                   \
+  php/src/Google/Protobuf/Internal/FileDescriptorProto.php            \
+  php/src/Google/Protobuf/Internal/FileDescriptorSet.php              \
+  php/src/Google/Protobuf/Internal/FileDescriptor.php                 \
+  php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php       \
+  php/src/Google/Protobuf/Internal/FileOptions.php                    \
+  php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php   \
+  php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php              \
+  php/src/Google/Protobuf/Internal/GPBDecodeException.php             \
+  php/src/Google/Protobuf/Internal/GPBJsonWire.php                    \
+  php/src/Google/Protobuf/Internal/GPBLabel.php                       \
+  php/src/Google/Protobuf/Internal/GPBType.php                        \
+  php/src/Google/Protobuf/Internal/GPBUtil.php                        \
+  php/src/Google/Protobuf/Internal/GPBWireType.php                    \
+  php/src/Google/Protobuf/Internal/GPBWire.php                        \
+  php/src/Google/Protobuf/Internal/MapEntry.php                       \
+  php/src/Google/Protobuf/Internal/MapFieldIter.php                   \
+  php/src/Google/Protobuf/Internal/MapField.php                       \
+  php/src/Google/Protobuf/Internal/MessageBuilderContext.php          \
+  php/src/Google/Protobuf/Internal/MessageOptions.php                 \
+  php/src/Google/Protobuf/Internal/Message.php                        \
+  php/src/Google/Protobuf/Internal/MethodDescriptorProto.php          \
+  php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php \
+  php/src/Google/Protobuf/Internal/MethodOptions.php                  \
+  php/src/Google/Protobuf/Internal/OneofDescriptorProto.php           \
+  php/src/Google/Protobuf/Internal/OneofDescriptor.php                \
+  php/src/Google/Protobuf/Internal/OneofField.php                     \
+  php/src/Google/Protobuf/Internal/OneofOptions.php                   \
+  php/src/Google/Protobuf/Internal/RawInputStream.php                 \
+  php/src/Google/Protobuf/Internal/RepeatedFieldIter.php              \
+  php/src/Google/Protobuf/Internal/RepeatedField.php                  \
+  php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php         \
+  php/src/Google/Protobuf/Internal/ServiceOptions.php                 \
   php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php        \
   php/src/Google/Protobuf/Internal/SourceCodeInfo.php                 \
-  php/src/Google/Protobuf/Internal/EnumOptions.php                    \
-  php/src/Google/Protobuf/Internal/GPBLabel.php                       \
-  php/src/Google/Protobuf/Internal/EnumBuilderContext.php             \
-  php/src/Google/Protobuf/Internal/GPBUtil.php                        \
-  php/src/Google/Protobuf/Internal/FieldOptions_CType.php             \
-  php/src/Google/Protobuf/Internal/GPBDecodeException.php             \
-  php/src/Google/Protobuf/descriptor.php                              \
+  php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php   \
+  php/src/Google/Protobuf/Internal/UninterpretedOption.php            \
   php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php         \
   php/tests/array_test.php                                            \
   php/tests/autoload.php                                              \
+  php/tests/compatibility_test.sh                                     \
   php/tests/encode_decode_test.php                                    \
   php/tests/gdb_test.sh                                               \
   php/tests/generated_class_test.php                                  \
+  php/tests/generated_phpdoc_test.php                                 \
+  php/tests/generated_service_test.php                                \
   php/tests/map_field_test.php                                        \
   php/tests/memory_leak_test.php                                      \
   php/tests/php_implementation_test.php                               \
+  php/tests/proto/test_empty_php_namespace.proto                      \
   php/tests/proto/test_import_descriptor_proto.proto                  \
   php/tests/proto/test_include.proto                                  \
   php/tests/proto/test.proto                                          \
-  php/tests/proto/test_prefix.proto                                   \
   php/tests/proto/test_no_namespace.proto                             \
+  php/tests/proto/test_php_namespace.proto                            \
+  php/tests/proto/test_prefix.proto                                   \
+  php/tests/proto/test_service.proto                                  \
+  php/tests/proto/test_service_namespace.proto                        \
   php/tests/test.sh                                                   \
   php/tests/test_base.php                                             \
   php/tests/test_util.php                                             \
   php/tests/well_known_test.php                                       \
+  php/tests/undefined_test.php                                        \
   php/README.md                                                       \
-  php/phpunit.xml                                                     \
   php/composer.json                                                   \
   php/generate_descriptor_protos.sh                                   \
+  php/phpunit.xml                                                     \
   composer.json
 
 python_EXTRA_DIST=                                                           \
@@ -955,9 +969,14 @@
   examples/list_people.py                \
   examples/list_people_test.go           \
   protobuf.bzl                           \
+  python/release/wheel/build_wheel_manylinux.sh  \
+  python/release/wheel/Dockerfile                \
+  python/release/wheel/protobuf_optimized_pip.sh \
+  python/release/wheel/README.md         \
   six.BUILD                              \
   util/python/BUILD
 
+
 # Deletes all the files generated by autogen.sh.
 MAINTAINERCLEANFILES =   \
   aclocal.m4             \
diff --git a/Protobuf.podspec b/Protobuf.podspec
index 649f3ae..af2e952 100644
--- a/Protobuf.podspec
+++ b/Protobuf.podspec
@@ -36,6 +36,7 @@
 
   s.ios.deployment_target = '7.0'
   s.osx.deployment_target = '10.9'
+  s.tvos.deployment_target = '9.0'
   s.watchos.deployment_target = '2.0'
   s.requires_arc = false
 end
diff --git a/README.md b/README.md
index e456863..653f663 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@
 If you are looking for an old version that is not available in the release
 page, check out the maven repo here:
 
-  [http://repo1.maven.org/maven2/com/google/protobuf/protoc/](http://repo1.maven.org/maven2/com/google/protobuf/protoc/)
+  [https://repo1.maven.org/maven2/com/google/protobuf/protoc/](https://repo1.maven.org/maven2/com/google/protobuf/protoc/)
 
 These pre-built binaries are only provided for released versions. If you want
 to use the github master version at HEAD, or you need to modify protobuf code,
diff --git a/appveyor.bat b/appveyor.bat
index 916f443..ca88b25 100644
--- a/appveyor.bat
+++ b/appveyor.bat
@@ -19,11 +19,15 @@
 :build_csharp
 echo Building C#
 cd csharp\src
+REM The platform environment variable is implicitly used by msbuild;
+REM we don't want it.
+set platform=
 dotnet restore
-dotnet build -c %configuration% Google.Protobuf Google.Protobuf.Test Google.Protobuf.Conformance || goto error
+dotnet build -c %configuration% || goto error
 
 echo Testing C#
-dotnet test -c %configuration% Google.Protobuf.Test || goto error
+dotnet run -c %configuration% -f netcoreapp1.0 -p Google.Protobuf.Test\Google.Protobuf.Test.csproj || goto error
+dotnet run -c %configuration% -f net451 -p Google.Protobuf.Test\Google.Protobuf.Test.csproj || goto error
 
 goto :EOF
 
diff --git a/appveyor.yml b/appveyor.yml
index 08d087b..8b440b6 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -14,6 +14,7 @@
       UNICODE: ON
 
     - language: csharp
+      image: Visual Studio 2017
 
 # Our build scripts run tests automatically; we don't want AppVeyor
 # to try to detect them itself.
@@ -29,8 +30,6 @@
   - del /Q release-1.7.0.zip
   - rename googletest-release-1.7.0 gtest
   - move gtest gmock
-  - curl -L -o dotnetsdk.exe "https://go.microsoft.com/fwlink/?LinkID=809122"
-  - dotnetsdk.exe /install /quiet /norestart
 
 before_build:
   - if %platform%==Win32 set generator=Visual Studio 12
diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in
index 0359b54..baafeb9 100644
--- a/cmake/extract_includes.bat.in
+++ b/cmake/extract_includes.bat.in
@@ -51,6 +51,7 @@
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_reflection.h" include\google\protobuf\generated_message_reflection.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_table_driven.h" include\google\protobuf\generated_message_table_driven.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_util.h" include\google\protobuf\generated_message_util.h
+copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_table_driven.h" include\google\protobuf\generated_message_table_driven.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\has_bits.h" include\google\protobuf\has_bits.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\coded_stream.h" include\google\protobuf\io\coded_stream.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\gzip_stream.h" include\google\protobuf\io\gzip_stream.h
diff --git a/cmake/libprotobuf-lite.cmake b/cmake/libprotobuf-lite.cmake
index 036b051..1ee9b9c 100644
--- a/cmake/libprotobuf-lite.cmake
+++ b/cmake/libprotobuf-lite.cmake
@@ -24,8 +24,32 @@
   ${protobuf_source_dir}/src/google/protobuf/wire_format_lite.cc
 )
 
+set(libprotobuf_lite_includes
+  ${protobuf_source_dir}/src/google/protobuf/arena.h
+  ${protobuf_source_dir}/src/google/protobuf/arenastring.h
+  ${protobuf_source_dir}/src/google/protobuf/extension_set.h
+  ${protobuf_source_dir}/src/google/protobuf/generated_message_util.h
+  ${protobuf_source_dir}/src/google/protobuf/io/coded_stream.h
+  ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream.h
+  ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_impl_lite.h
+  ${protobuf_source_dir}/src/google/protobuf/message_lite.h
+  ${protobuf_source_dir}/src/google/protobuf/repeated_field.h
+  ${protobuf_source_dir}/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h
+  ${protobuf_source_dir}/src/google/protobuf/stubs/bytestream.h
+  ${protobuf_source_dir}/src/google/protobuf/stubs/common.h
+  ${protobuf_source_dir}/src/google/protobuf/stubs/int128.h
+  ${protobuf_source_dir}/src/google/protobuf/stubs/once.h
+  ${protobuf_source_dir}/src/google/protobuf/stubs/status.h
+  ${protobuf_source_dir}/src/google/protobuf/stubs/statusor.h
+  ${protobuf_source_dir}/src/google/protobuf/stubs/stringpiece.h
+  ${protobuf_source_dir}/src/google/protobuf/stubs/stringprintf.h
+  ${protobuf_source_dir}/src/google/protobuf/stubs/strutil.h
+  ${protobuf_source_dir}/src/google/protobuf/stubs/time.h
+  ${protobuf_source_dir}/src/google/protobuf/wire_format_lite.h
+)
+
 add_library(libprotobuf-lite ${protobuf_SHARED_OR_STATIC}
-  ${libprotobuf_lite_files})
+  ${libprotobuf_lite_files} ${libprotobuf_lite_includes})
 target_link_libraries(libprotobuf-lite ${CMAKE_THREAD_LIBS_INIT})
 target_include_directories(libprotobuf-lite PUBLIC ${protobuf_source_dir}/src)
 if(MSVC AND protobuf_BUILD_SHARED_LIBS)
diff --git a/cmake/libprotobuf.cmake b/cmake/libprotobuf.cmake
index 5313d39..030924d 100644
--- a/cmake/libprotobuf.cmake
+++ b/cmake/libprotobuf.cmake
@@ -55,8 +55,64 @@
   ${protobuf_source_dir}/src/google/protobuf/wrappers.pb.cc
 )
 
+set(libprotobuf_includes
+  ${protobuf_source_dir}/src/google/protobuf/any.h
+  ${protobuf_source_dir}/src/google/protobuf/any.pb.h
+  ${protobuf_source_dir}/src/google/protobuf/api.pb.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/importer.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/parser.h
+  ${protobuf_source_dir}/src/google/protobuf/descriptor.h
+  ${protobuf_source_dir}/src/google/protobuf/descriptor.pb.h
+  ${protobuf_source_dir}/src/google/protobuf/descriptor_database.h
+  ${protobuf_source_dir}/src/google/protobuf/duration.pb.h
+  ${protobuf_source_dir}/src/google/protobuf/dynamic_message.h
+  ${protobuf_source_dir}/src/google/protobuf/empty.pb.h
+  ${protobuf_source_dir}/src/google/protobuf/field_mask.pb.h
+  ${protobuf_source_dir}/src/google/protobuf/generated_message_reflection.h
+  ${protobuf_source_dir}/src/google/protobuf/io/gzip_stream.h
+  ${protobuf_source_dir}/src/google/protobuf/io/printer.h
+  ${protobuf_source_dir}/src/google/protobuf/io/strtod.h
+  ${protobuf_source_dir}/src/google/protobuf/io/tokenizer.h
+  ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_impl.h
+  ${protobuf_source_dir}/src/google/protobuf/map_field.h
+  ${protobuf_source_dir}/src/google/protobuf/message.h
+  ${protobuf_source_dir}/src/google/protobuf/reflection_ops.h
+  ${protobuf_source_dir}/src/google/protobuf/service.h
+  ${protobuf_source_dir}/src/google/protobuf/source_context.pb.h
+  ${protobuf_source_dir}/src/google/protobuf/struct.pb.h
+  ${protobuf_source_dir}/src/google/protobuf/stubs/mathlimits.h
+  ${protobuf_source_dir}/src/google/protobuf/stubs/substitute.h
+  ${protobuf_source_dir}/src/google/protobuf/text_format.h
+  ${protobuf_source_dir}/src/google/protobuf/timestamp.pb.h
+  ${protobuf_source_dir}/src/google/protobuf/type.pb.h
+  ${protobuf_source_dir}/src/google/protobuf/unknown_field_set.h
+  ${protobuf_source_dir}/src/google/protobuf/util/delimited_message_util.h
+  ${protobuf_source_dir}/src/google/protobuf/util/field_comparator.h
+  ${protobuf_source_dir}/src/google/protobuf/util/field_mask_util.h
+  ${protobuf_source_dir}/src/google/protobuf/util/internal/datapiece.h
+  ${protobuf_source_dir}/src/google/protobuf/util/internal/default_value_objectwriter.h
+  ${protobuf_source_dir}/src/google/protobuf/util/internal/error_listener.h
+  ${protobuf_source_dir}/src/google/protobuf/util/internal/field_mask_utility.h
+  ${protobuf_source_dir}/src/google/protobuf/util/internal/json_escaping.h
+  ${protobuf_source_dir}/src/google/protobuf/util/internal/json_objectwriter.h
+  ${protobuf_source_dir}/src/google/protobuf/util/internal/json_stream_parser.h
+  ${protobuf_source_dir}/src/google/protobuf/util/internal/object_writer.h
+  ${protobuf_source_dir}/src/google/protobuf/util/internal/proto_writer.h
+  ${protobuf_source_dir}/src/google/protobuf/util/internal/protostream_objectsource.h
+  ${protobuf_source_dir}/src/google/protobuf/util/internal/protostream_objectwriter.h
+  ${protobuf_source_dir}/src/google/protobuf/util/internal/type_info.h
+  ${protobuf_source_dir}/src/google/protobuf/util/internal/type_info_test_helper.h
+  ${protobuf_source_dir}/src/google/protobuf/util/internal/utility.h
+  ${protobuf_source_dir}/src/google/protobuf/util/json_util.h
+  ${protobuf_source_dir}/src/google/protobuf/util/message_differencer.h
+  ${protobuf_source_dir}/src/google/protobuf/util/time_util.h
+  ${protobuf_source_dir}/src/google/protobuf/util/type_resolver_util.h
+  ${protobuf_source_dir}/src/google/protobuf/wire_format.h
+  ${protobuf_source_dir}/src/google/protobuf/wrappers.pb.h
+)
+
 add_library(libprotobuf ${protobuf_SHARED_OR_STATIC}
-  ${libprotobuf_lite_files} ${libprotobuf_files})
+  ${libprotobuf_lite_files} ${libprotobuf_files} ${libprotobuf_includes})
 target_link_libraries(libprotobuf ${CMAKE_THREAD_LIBS_INIT})
 if(protobuf_WITH_ZLIB)
     target_link_libraries(libprotobuf ${ZLIB_LIBRARIES})
diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake
index 29b3253..eb40857 100644
--- a/cmake/libprotoc.cmake
+++ b/cmake/libprotoc.cmake
@@ -94,6 +94,115 @@
   ${protobuf_source_dir}/src/google/protobuf/compiler/zip_writer.cc
 )
 
+set(libprotoc_headers
+  ${protobuf_source_dir}/src/google/protobuf/compiler/code_generator.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/command_line_interface.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/importer.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/mock_code_generator.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/package_info.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/parser.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.pb.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/profile.pb.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/subprocess.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/zip_writer.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_enum.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_enum_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_extension.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_file.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_generator.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_helpers.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_map_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_message.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_message_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_options.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_service.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_string_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_unittest.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_doc_comment.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_enum.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_enum_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_field_base.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_generator.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_helpers.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_map_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_message.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_message_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_names.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_options.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_primitive_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_reflection_class.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_source_generator_base.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_context.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_doc_comment.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_field_lite.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_lite.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_extension.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_extension_lite.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_file.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_generator.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_generator_factory.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_helpers.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_lazy_message_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_map_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_map_field_lite.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_message.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_message_builder.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_message_builder_lite.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_message_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_message_field_lite.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_message_lite.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_names.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_name_resolver.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_options.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_primitive_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_primitive_field_lite.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_service.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_shared_code_generator.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_string_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_string_field_lite.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/javanano/javanano_enum.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/javanano/javanano_enum_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/javanano/javanano_extension.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/javanano/javanano_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/javanano/javanano_file.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/javanano/javanano_generator.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/javanano/javanano_helpers.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/javanano/javanano_map_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/javanano/javanano_message.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/javanano/javanano_message_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/javanano/javanano_params.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/javanano/javanano_primitive_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/js/js_generator.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/js/well_known_types_embed.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_enum.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_extension.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_file.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_generator.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_map_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_message.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_message_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_oneof.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/php/php_generator.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/python/python_generator.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/ruby/ruby_generator.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.pb.h
+)
+
 set(js_well_known_types_sources
   ${protobuf_source_dir}/src/google/protobuf/compiler/js/well_known_types/any.js
   ${protobuf_source_dir}/src/google/protobuf/compiler/js/well_known_types/struct.js
@@ -107,7 +216,7 @@
 )
 
 add_library(libprotoc ${protobuf_SHARED_OR_STATIC}
-  ${libprotoc_files})
+  ${libprotoc_files} ${libprotoc_headers})
 target_link_libraries(libprotoc libprotobuf)
 if(MSVC AND protobuf_BUILD_SHARED_LIBS)
   target_compile_definitions(libprotoc
diff --git a/cmake/protobuf-config-version.cmake.in b/cmake/protobuf-config-version.cmake.in
index 0036c9e..ca6da09 100644
--- a/cmake/protobuf-config-version.cmake.in
+++ b/cmake/protobuf-config-version.cmake.in
@@ -17,30 +17,32 @@
 
 set(PACKAGE_VERSION_COMPATIBLE TRUE) #Assume true until shown otherwise
 
-if(NOT PACKAGE_FIND_VERSION_MAJOR EQUAL "@protobuf_VERSION_MAJOR@")
-  set(PACKAGE_VERSION_COMPATIBLE FALSE)
-elseif(PACKAGE_FIND_VERSION VERSION_GREATER PACKAGE_VERSION)
-  set(PACKAGE_VERSION_COMPATIBLE FALSE)
-elseif(PACKAGE_FIND_VERSION VERSION_EQUAL PACKAGE_VERSION)
-  # Do not match prerelease versions to non-prerelease version requests.
-  if(NOT "@protobuf_VERSION_PRERELEASE@" STREQUAL "" AND PACKAGE_FIND_VERSION_PRERELEASE STREQUAL "")
-    message(AUTHOR_WARNING "To use this prerelease version of ${PACKAGE_FIND_NAME}, set ${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE to '@protobuf_VERSION_PRERELEASE@' or greater.")
+if(PACKAGE_FIND_VERSION) #Only perform version checks if one is given
+  if(NOT PACKAGE_FIND_VERSION_MAJOR EQUAL "@protobuf_VERSION_MAJOR@")
     set(PACKAGE_VERSION_COMPATIBLE FALSE)
-  endif()
+  elseif(PACKAGE_FIND_VERSION VERSION_GREATER PACKAGE_VERSION)
+    set(PACKAGE_VERSION_COMPATIBLE FALSE)
+  elseif(PACKAGE_FIND_VERSION VERSION_EQUAL PACKAGE_VERSION)
+    # Do not match prerelease versions to non-prerelease version requests.
+      if(NOT "@protobuf_VERSION_PRERELEASE@" STREQUAL "" AND PACKAGE_FIND_VERSION_PRERELEASE STREQUAL "")
+      message(AUTHOR_WARNING "To use this prerelease version of ${PACKAGE_FIND_NAME}, set ${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE to '@protobuf_VERSION_PRERELEASE@' or greater.")
+      set(PACKAGE_VERSION_COMPATIBLE FALSE)
+    endif()
 
-  # Not robustly SemVer compliant, but protobuf never uses '.' separated prerelease identifiers.
-  if(PACKAGE_FIND_VERSION_PRERELEASE STRGREATER "@protobuf_VERSION_PRERELEASE@")
-    set(PACKAGE_VERSION_COMPATIBLE FALSE)
+    # Not robustly SemVer compliant, but protobuf never uses '.' separated prerelease identifiers.
+    if(PACKAGE_FIND_VERSION_PRERELEASE STRGREATER "@protobuf_VERSION_PRERELEASE@")
+      set(PACKAGE_VERSION_COMPATIBLE FALSE)
+    endif()
   endif()
 endif()
 
 # Check and save build options used to create this package
 macro(_check_and_save_build_option OPTION VALUE)
   if(DEFINED ${PACKAGE_FIND_NAME}_${OPTION} AND
-    NOT ${PACKAGE_FIND_NAME}_${OPTION} EQUAL VALUE)
+    NOT ${PACKAGE_FIND_NAME}_${OPTION} STREQUAL ${VALUE})
     set(PACKAGE_VERSION_UNSUITABLE TRUE)
   endif()
-  set(${PACKAGE_FIND_NAME}_${OPTION} ${VALUE})
+  set(${PACKAGE_FIND_NAME}_${OPTION} ${VALUE} PARENT_SCOPE)
 endmacro()
 _check_and_save_build_option(WITH_ZLIB @protobuf_WITH_ZLIB@)
 _check_and_save_build_option(MSVC_STATIC_RUNTIME @protobuf_MSVC_STATIC_RUNTIME@)
diff --git a/cmake/protobuf-config.cmake.in b/cmake/protobuf-config.cmake.in
index a044fe5..8321354 100644
--- a/cmake/protobuf-config.cmake.in
+++ b/cmake/protobuf-config.cmake.in
@@ -7,6 +7,105 @@
 # Imported targets
 include("${CMAKE_CURRENT_LIST_DIR}/protobuf-targets.cmake")
 
+function(protobuf_generate)
+  include(CMakeParseArguments)
+  set(_singleargs LANGUAGE OUT_VAR)
+  if(COMMAND target_sources)
+    list(APPEND _singleargs TARGET)
+  endif()
+
+  cmake_parse_arguments(protobuf_generate "APPEND_PATH" "${_singleargs}" "PROTOS IMPORT_DIRS GENERATE_EXTENSIONS" "${ARGN}")
+
+  if(protobuf_generate_PROTOS AND NOT protobuf_generate_TARGET)
+    message(SEND_ERROR "Error: protobuf_generate called without any targets or source files")
+    return()
+  endif()
+
+  if(NOT protobuf_generate_OUT_VAR AND NOT protobuf_generate_TARGET)
+    message(SEND_ERROR "Error: protobuf_generate called without a target or output variable")
+    return()
+  endif()
+
+  if(NOT protobuf_generate_LANGUAGE)
+    set(protobuf_generate_LANGUAGE cpp)
+  endif()
+  string(TOLOWER ${protobuf_generate_LANGUAGE} protobuf_generate_LANGUAGE)
+
+  if(NOT protobuf_GENERATE_EXTENSIONS)
+    if(protobuf_generate_LANGUAGE STREQUAL cpp)
+      set(protobuf_GENERATE_EXTENSIONS .pb.h .pb.cc)
+    elseif(protobuf_generate_LANGUAGE STREQUAL python)
+      set(protobuf_GENERATE_EXTENSIONS _pb2.py)
+    else()
+      message(SEND_ERROR "Error: protobuf_generate given unknown Language ${LANGUAGE}, please provide a value for GENERATE_EXTENSIONS")
+      return()
+    endif()
+  endif()
+
+  if(protobuf_generate_APPEND_PATH)
+    # Create an include path for each file specified
+    foreach(_file ${ARGN})
+      get_filename_component(_abs_file ${_file} ABSOLUTE)
+      get_filename_component(_abs_path ${_abs_file} PATH)
+      list(FIND _protobuf_include_path ${_abs_path} _contains_already)
+      if(${_contains_already} EQUAL -1)
+          list(APPEND _protobuf_include_path -I ${_abs_path})
+      endif()
+    endforeach()
+  else()
+    set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
+  endif()
+
+  foreach(DIR ${protobuf_generate_IMPORT_DIRS})
+    get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
+    list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
+    if(${_contains_already} EQUAL -1)
+        list(APPEND _protobuf_include_path -I ${ABS_PATH})
+    endif()
+  endforeach()
+
+  if(protobuf_generate_TARGET)
+    get_target_property(_source_list ${protobuf_generate_TARGET} SOURCES)
+    foreach(_file ${_source_list})
+      if(_file MATCHES "proto$")
+        list(APPEND protobuf_generate_PROTOS ${_file})
+      endif()
+    endforeach()
+  endif()
+
+  if(NOT protobuf_generate_PROTOS)
+    message(SEND_ERROR "Error: protobuf_generate could not find any .proto files")
+    return()
+  endif()
+
+  set(_generated_srcs)
+  foreach(_proto ${protobuf_generate_PROTOS})
+    get_filename_component(_abs_file ${_proto} ABSOLUTE)
+    get_filename_component(_basename ${_proto} NAME_WE)
+
+    foreach(_ext ${_output_extensions})
+      list(APPEND _generated_srcs "${CMAKE_CURRENT_BINARY_DIR}/${_basename}${_ext}")
+    endforeach()
+
+    add_custom_command(
+      OUTPUT ${_generated_srcs}
+      COMMAND  protobuf::protoc
+      ARGS --${protobuf_generate_LANGUAGE}_out  ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${_abs_file}
+      DEPENDS ${ABS_FIL} protobuf::protoc
+      COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}"
+      VERBATIM )
+  endforeach()
+
+  set_source_files_properties(${_generated_srcs} PROPERTIES GENERATED TRUE)
+  if(protobuf_generate_OUT_VAR)
+    set(${protobuf_generate_OUT_VAR} ${_generated_srcs} PARENT_SCOPE)
+  endif()
+  if(protobuf_generate_TARGET)
+    target_sources(${protobuf_generate_TARGET} PUBLIC ${_generated_srcs})
+  endif()
+
+endfunction()
+
 # CMake FindProtobuf module compatible file
 if(protobuf_MODULE_COMPATIBLE)
   include("${CMAKE_CURRENT_LIST_DIR}/protobuf-module.cmake")
diff --git a/cmake/protobuf-module.cmake.in b/cmake/protobuf-module.cmake.in
index 614e4c0..8e4920a 100644
--- a/cmake/protobuf-module.cmake.in
+++ b/cmake/protobuf-module.cmake.in
@@ -1,3 +1,4 @@
+# This file contains backwards compatibility patches for various legacy functions and variables
 # Functions
 
 function(PROTOBUF_GENERATE_CPP SRCS HDRS)
@@ -7,49 +8,25 @@
   endif()
 
   if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
-    # Create an include path for each file specified
-    foreach(FIL ${ARGN})
-      get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
-      get_filename_component(ABS_PATH ${ABS_FIL} PATH)
-      list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
-      if(${_contains_already} EQUAL -1)
-          list(APPEND _protobuf_include_path -I ${ABS_PATH})
-      endif()
-    endforeach()
-  else()
-    set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
+    set(_append_arg APPEND_PATH)
   endif()
 
   if(DEFINED Protobuf_IMPORT_DIRS)
-    foreach(DIR ${Protobuf_IMPORT_DIRS})
-      get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
-      list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
-      if(${_contains_already} EQUAL -1)
-          list(APPEND _protobuf_include_path -I ${ABS_PATH})
-      endif()
-    endforeach()
+    set(_import_arg IMPORT_DIRS ${Protobuf_IMPORT_DIRS})
   endif()
 
+  set(_outvar)
+  protobuf_generate(${append_arg} LANGUAGE cpp OUT_VAR _outvar ${_import_arg} PROTOS ${ARGN})
+
   set(${SRCS})
   set(${HDRS})
-  foreach(FIL ${ARGN})
-    get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
-    get_filename_component(FIL_WE ${FIL} NAME_WE)
-
-    list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
-    list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
-
-    add_custom_command(
-      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
-             "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
-      COMMAND  ${Protobuf_PROTOC_EXECUTABLE}
-      ARGS --cpp_out  ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL}
-      DEPENDS ${ABS_FIL} ${Protobuf_PROTOC_EXECUTABLE}
-      COMMENT "Running C++ protocol buffer compiler on ${FIL}"
-      VERBATIM )
+  foreach(_file ${_outvar})
+    if(_file MATCHES "cc$")
+      list(APPEND ${SRCS} ${_file})
+    else()
+      list(APPEND ${HDRS} ${_file})
+    endif()
   endforeach()
-
-  set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
   set(${SRCS} ${${SRCS}} PARENT_SCOPE)
   set(${HDRS} ${${HDRS}} PARENT_SCOPE)
 endfunction()
@@ -61,44 +38,16 @@
   endif()
 
   if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
-    # Create an include path for each file specified
-    foreach(FIL ${ARGN})
-      get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
-      get_filename_component(ABS_PATH ${ABS_FIL} PATH)
-      list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
-      if(${_contains_already} EQUAL -1)
-          list(APPEND _protobuf_include_path -I ${ABS_PATH})
-      endif()
-    endforeach()
-  else()
-    set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
+    set(_append_arg APPEND_PATH)
   endif()
 
   if(DEFINED Protobuf_IMPORT_DIRS)
-    foreach(DIR ${Protobuf_IMPORT_DIRS})
-      get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
-      list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
-      if(${_contains_already} EQUAL -1)
-          list(APPEND _protobuf_include_path -I ${ABS_PATH})
-      endif()
-    endforeach()
+    set(_import_arg IMPORT_DIRS ${Protobuf_IMPORT_DIRS})
   endif()
 
-  set(${SRCS})
-  foreach(FIL ${ARGN})
-    get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
-    get_filename_component(FIL_WE ${FIL} NAME_WE)
-
-    list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py")
-    add_custom_command(
-      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py"
-      COMMAND  ${Protobuf_PROTOC_EXECUTABLE} --python_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL}
-      DEPENDS ${ABS_FIL} ${Protobuf_PROTOC_EXECUTABLE}
-      COMMENT "Running Python protocol buffer compiler on ${FIL}"
-      VERBATIM )
-  endforeach()
-
-  set(${SRCS} ${${SRCS}} PARENT_SCOPE)
+  set(_outvar)
+  protobuf_generate(${append_arg} LANGUAGE cpp OUT_VAR _outvar ${_import_arg} PROTOS ${ARGN})
+  set(${SRCS} ${_outvar} PARENT_SCOPE)
 endfunction()
 
 # Environment
diff --git a/composer.json b/composer.json
index 2b04e07..5b6c7ee 100644
--- a/composer.json
+++ b/composer.json
@@ -15,9 +15,6 @@
     "psr-4": {
       "Google\\Protobuf\\Internal\\": "php/src/Google/Protobuf/Internal",
       "GPBMetadata\\Google\\Protobuf\\Internal\\": "php/src/GPBMetadata/Google/Protobuf/Internal"
-    },
-    "files": [
-      "php/src/Google/Protobuf/descriptor.php"
-    ]
+    }
   }
 }
diff --git a/conformance/Makefile.am b/conformance/Makefile.am
index 1a8b574..fe60437 100644
--- a/conformance/Makefile.am
+++ b/conformance/Makefile.am
@@ -305,7 +305,7 @@
 conformance-php:
 	@echo "Writing shortcut script conformance-php..."
 	@echo '#! /bin/sh' > conformance-php
-	@echo 'php  ./conformance_php.php' >> conformance-php
+	@echo 'php -d auto_prepend_file=autoload.php ./conformance_php.php' >> conformance-php
 	@chmod +x conformance-php
 
 conformance-php-c:
@@ -336,6 +336,9 @@
 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 ./conformance-php-c
 
+test_php_zts_c: protoc_middleman conformance-test-runner conformance-php-c $(other_language_protoc_outputs)
+	./conformance-test-runner --enforce_recommended --failure_list failure_list_php_zts_c.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
diff --git a/conformance/autoload.php b/conformance/autoload.php
new file mode 100644
index 0000000..2cee31c
--- /dev/null
+++ b/conformance/autoload.php
@@ -0,0 +1,21 @@
+<?php
+
+define("GOOGLE_INTERNAL_NAMESPACE", "Google\\Protobuf\\Internal\\");
+define("GOOGLE_NAMESPACE", "Google\\Protobuf\\");
+define("GOOGLE_GPBMETADATA_NAMESPACE", "GPBMetadata\\Google\\Protobuf\\Internal\\");
+
+function protobuf_autoloader_impl($class, $prefix) {
+    $length = strlen($prefix);
+    if ((substr($class, 0, $length) === $prefix)) {
+        $path = '../php/src/' . implode('/', array_map('ucwords', explode('\\', $class))) . '.php';
+        include_once $path;
+    }
+}
+
+function protobuf_autoloader($class) {
+    protobuf_autoloader_impl($class, GOOGLE_INTERNAL_NAMESPACE);
+    protobuf_autoloader_impl($class, GOOGLE_NAMESPACE);
+    protobuf_autoloader_impl($class, GOOGLE_GPBMETADATA_NAMESPACE);
+}
+
+spl_autoload_register('protobuf_autoloader');
diff --git a/conformance/conformance_php.php b/conformance/conformance_php.php
index 20fb508..d5e9125 100755
--- a/conformance/conformance_php.php
+++ b/conformance/conformance_php.php
@@ -53,7 +53,7 @@
       }
     } elseif ($request->getPayload() == "json_payload") {
       try {
-          $test_message->jsonDecode($request->getJsonPayload());
+          $test_message->mergeFromJsonString($request->getJsonPayload());
       } catch (Exception $e) {
           $response->setParseError($e->getMessage());
           return $response;
@@ -67,7 +67,7 @@
     } elseif ($request->getRequestedOutputFormat() == WireFormat::PROTOBUF) {
       $response->setProtobufPayload($test_message->serializeToString());
     } elseif ($request->getRequestedOutputFormat() == WireFormat::JSON) {
-      $response->setJsonPayload($test_message->jsonEncode());
+      $response->setJsonPayload($test_message->serializeToJsonString());
     }
 
     return $response;
@@ -79,7 +79,8 @@
     if (strlen($length_bytes) == 0) {
       return false;   # EOF
     } elseif (strlen($length_bytes) != 4) {
-      trigger_error("I/O error", E_USER_ERROR);
+      fwrite(STDERR, "I/O error\n");
+      return false;
     }
 
     $length = unpack("V", $length_bytes)[1];
diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc
index 3f73595..91b6101 100644
--- a/conformance/conformance_test.cc
+++ b/conformance/conformance_test.cc
@@ -677,7 +677,7 @@
             std::inserter(expected_to_fail_, expected_to_fail_.end()));
 }
 
-bool ConformanceTestSuite::CheckSetEmpty(const set<string>& set_to_check,
+bool ConformanceTestSuite::CheckSetEmpty(const std::set<string>& set_to_check,
                                          const std::string& write_to_file,
                                          const std::string& msg) {
   if (set_to_check.empty()) {
@@ -685,7 +685,7 @@
   } else {
     StringAppendF(&output_, "\n");
     StringAppendF(&output_, "%s\n\n", msg.c_str());
-    for (set<string>::const_iterator iter = set_to_check.begin();
+    for (std::set<string>::const_iterator iter = set_to_check.begin();
          iter != set_to_check.end(); ++iter) {
       StringAppendF(&output_, "  %s\n", iter->c_str());
     }
@@ -694,7 +694,7 @@
     if (!write_to_file.empty()) {
       std::ofstream os(write_to_file);
       if (os) {
-        for (set<string>::const_iterator iter = set_to_check.begin();
+        for (std::set<string>::const_iterator iter = set_to_check.begin();
              iter != set_to_check.end(); ++iter) {
           os << *iter << "\n";
         }
@@ -759,6 +759,7 @@
   });
   TestValidDataForType(FieldDescriptor::TYPE_FLOAT, {
     {flt(0.1), "0.1"},
+    {flt(1.00000075e-36), "1.00000075e-36"},
     {flt(3.402823e+38), "3.402823e+38"},  // 3.40282347e+38
     {flt(1.17549435e-38f), "1.17549435e-38"}
   });
@@ -1232,7 +1233,7 @@
       "Int32FieldNegativeWithLeadingZero", REQUIRED,
       R"({"optionalInt32": -01})");
   // String values must follow the same syntax rule. Specifically leading
-  // or traling spaces are not allowed.
+  // or trailing spaces are not allowed.
   ExpectParseFailureForJson(
       "Int32FieldLeadingSpace", REQUIRED,
       R"({"optionalInt32": " 1"})");
diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h
index 4e40a6a..581c747 100644
--- a/conformance/conformance_test.h
+++ b/conformance/conformance_test.h
@@ -205,7 +205,7 @@
   void TestValidDataForType(
       google::protobuf::FieldDescriptor::Type,
       std::vector<std::pair<std::string, std::string>> values);
-  bool CheckSetEmpty(const set<string>& set_to_check,
+  bool CheckSetEmpty(const std::set<string>& set_to_check,
                      const std::string& write_to_file, const std::string& msg);
   ConformanceTestRunner* runner_;
   int successes_;
diff --git a/conformance/failure_list_objc.txt b/conformance/failure_list_objc.txt
index 6e0da6c..e34501e 100644
--- a/conformance/failure_list_objc.txt
+++ b/conformance/failure_list_objc.txt
@@ -1,6 +1,2 @@
 # JSON input or output tests are skipped (in conformance_objc.m) as mobile
 # platforms don't support JSON wire format to avoid code bloat.
-Required.ProtobufInput.IllegalZeroFieldNum_Case_0
-Required.ProtobufInput.IllegalZeroFieldNum_Case_1
-Required.ProtobufInput.IllegalZeroFieldNum_Case_2
-Required.ProtobufInput.IllegalZeroFieldNum_Case_3
diff --git a/conformance/failure_list_php.txt b/conformance/failure_list_php.txt
index 6dd9391..2bf9bb1 100644
--- a/conformance/failure_list_php.txt
+++ b/conformance/failure_list_php.txt
@@ -1,117 +1,17 @@
 Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
 Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
 Recommended.FieldMaskTooManyUnderscore.JsonOutput
-Recommended.JsonInput.BoolFieldAllCapitalFalse
-Recommended.JsonInput.BoolFieldAllCapitalTrue
-Recommended.JsonInput.BoolFieldCamelCaseFalse
-Recommended.JsonInput.BoolFieldCamelCaseTrue
-Recommended.JsonInput.BoolFieldDoubleQuotedFalse
-Recommended.JsonInput.BoolFieldDoubleQuotedTrue
-Recommended.JsonInput.BoolFieldIntegerOne
-Recommended.JsonInput.BoolFieldIntegerZero
-Recommended.JsonInput.BoolMapFieldKeyNotQuoted
-Recommended.JsonInput.DoubleFieldInfinityNotQuoted
-Recommended.JsonInput.DoubleFieldNanNotQuoted
-Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
 Recommended.JsonInput.DurationHas3FractionalDigits.Validator
 Recommended.JsonInput.DurationHas6FractionalDigits.Validator
 Recommended.JsonInput.DurationHas9FractionalDigits.Validator
 Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator
-Recommended.JsonInput.FieldMaskInvalidCharacter
-Recommended.JsonInput.FieldNameDuplicate
-Recommended.JsonInput.FieldNameDuplicateDifferentCasing1
-Recommended.JsonInput.FieldNameDuplicateDifferentCasing2
-Recommended.JsonInput.FieldNameNotQuoted
-Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
-Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
-Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
-Recommended.JsonInput.FloatFieldInfinityNotQuoted
-Recommended.JsonInput.FloatFieldNanNotQuoted
-Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
-Recommended.JsonInput.Int32MapFieldKeyNotQuoted
-Recommended.JsonInput.Int64FieldBeString.Validator
-Recommended.JsonInput.Int64MapFieldKeyNotQuoted
-Recommended.JsonInput.JsonWithComments
-Recommended.JsonInput.MapFieldKeyIsNull
-Recommended.JsonInput.MapFieldValueIsNull
-Recommended.JsonInput.MissingCommaMultiline
-Recommended.JsonInput.MissingCommaOneLine
-Recommended.JsonInput.MultilineNoSpaces.JsonOutput
-Recommended.JsonInput.MultilineNoSpaces.ProtobufOutput
-Recommended.JsonInput.MultilineWithSpaces.JsonOutput
-Recommended.JsonInput.MultilineWithSpaces.ProtobufOutput
-Recommended.JsonInput.OneLineNoSpaces.JsonOutput
-Recommended.JsonInput.OneLineNoSpaces.ProtobufOutput
-Recommended.JsonInput.OneLineWithSpaces.JsonOutput
-Recommended.JsonInput.OneLineWithSpaces.ProtobufOutput
-Recommended.JsonInput.OneofZeroBool.JsonOutput
-Recommended.JsonInput.OneofZeroBool.ProtobufOutput
-Recommended.JsonInput.OneofZeroBytes.JsonOutput
-Recommended.JsonInput.OneofZeroBytes.ProtobufOutput
-Recommended.JsonInput.OneofZeroDouble.JsonOutput
-Recommended.JsonInput.OneofZeroDouble.ProtobufOutput
-Recommended.JsonInput.OneofZeroEnum.JsonOutput
-Recommended.JsonInput.OneofZeroEnum.ProtobufOutput
-Recommended.JsonInput.OneofZeroFloat.JsonOutput
-Recommended.JsonInput.OneofZeroFloat.ProtobufOutput
-Recommended.JsonInput.OneofZeroMessage.JsonOutput
-Recommended.JsonInput.OneofZeroMessage.ProtobufOutput
-Recommended.JsonInput.OneofZeroString.JsonOutput
-Recommended.JsonInput.OneofZeroString.ProtobufOutput
-Recommended.JsonInput.OneofZeroUint32.JsonOutput
-Recommended.JsonInput.OneofZeroUint32.ProtobufOutput
-Recommended.JsonInput.OneofZeroUint64.JsonOutput
-Recommended.JsonInput.OneofZeroUint64.ProtobufOutput
-Recommended.JsonInput.RepeatedFieldMessageElementIsNull
-Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull
-Recommended.JsonInput.RepeatedFieldTrailingComma
-Recommended.JsonInput.RepeatedFieldTrailingCommaWithNewlines
-Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpace
-Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace
-Recommended.JsonInput.StringEndsWithEscapeChar
-Recommended.JsonInput.StringFieldInvalidEscape
-Recommended.JsonInput.StringFieldSingleQuoteBoth
-Recommended.JsonInput.StringFieldSingleQuoteKey
-Recommended.JsonInput.StringFieldSingleQuoteValue
-Recommended.JsonInput.StringFieldSurrogateInWrongOrder
-Recommended.JsonInput.StringFieldUnpairedHighSurrogate
-Recommended.JsonInput.StringFieldUnpairedLowSurrogate
-Recommended.JsonInput.StringFieldUnterminatedEscape
-Recommended.JsonInput.StringFieldUppercaseEscapeLetter
 Recommended.JsonInput.TimestampHas3FractionalDigits.Validator
 Recommended.JsonInput.TimestampHas6FractionalDigits.Validator
 Recommended.JsonInput.TimestampHas9FractionalDigits.Validator
 Recommended.JsonInput.TimestampHasZeroFractionalDigit.Validator
 Recommended.JsonInput.TimestampZeroNormalized.Validator
-Recommended.JsonInput.TrailingCommaInAnObject
-Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines
-Recommended.JsonInput.TrailingCommaInAnObjectWithSpace
-Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
-Recommended.JsonInput.Uint32MapFieldKeyNotQuoted
-Recommended.JsonInput.Uint64FieldBeString.Validator
-Recommended.JsonInput.Uint64MapFieldKeyNotQuoted
-Recommended.ProtobufInput.OneofZeroBool.JsonOutput
-Recommended.ProtobufInput.OneofZeroBool.ProtobufOutput
-Recommended.ProtobufInput.OneofZeroBytes.JsonOutput
-Recommended.ProtobufInput.OneofZeroBytes.ProtobufOutput
-Recommended.ProtobufInput.OneofZeroDouble.JsonOutput
-Recommended.ProtobufInput.OneofZeroDouble.ProtobufOutput
-Recommended.ProtobufInput.OneofZeroEnum.JsonOutput
-Recommended.ProtobufInput.OneofZeroEnum.ProtobufOutput
-Recommended.ProtobufInput.OneofZeroFloat.JsonOutput
-Recommended.ProtobufInput.OneofZeroFloat.ProtobufOutput
-Recommended.ProtobufInput.OneofZeroMessage.JsonOutput
-Recommended.ProtobufInput.OneofZeroMessage.ProtobufOutput
-Recommended.ProtobufInput.OneofZeroString.JsonOutput
-Recommended.ProtobufInput.OneofZeroString.ProtobufOutput
-Recommended.ProtobufInput.OneofZeroUint32.JsonOutput
-Recommended.ProtobufInput.OneofZeroUint32.ProtobufOutput
-Recommended.ProtobufInput.OneofZeroUint64.JsonOutput
-Recommended.ProtobufInput.OneofZeroUint64.ProtobufOutput
 Required.DurationProtoInputTooLarge.JsonOutput
 Required.DurationProtoInputTooSmall.JsonOutput
-Required.JsonInput.AllFieldAcceptNull.JsonOutput
-Required.JsonInput.AllFieldAcceptNull.ProtobufOutput
 Required.JsonInput.Any.JsonOutput
 Required.JsonInput.Any.ProtobufOutput
 Required.JsonInput.AnyNested.JsonOutput
@@ -132,141 +32,14 @@
 Required.JsonInput.AnyWithValueForInteger.ProtobufOutput
 Required.JsonInput.AnyWithValueForJsonObject.JsonOutput
 Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
-Required.JsonInput.BoolFieldFalse.JsonOutput
-Required.JsonInput.BoolFieldFalse.ProtobufOutput
-Required.JsonInput.BoolFieldTrue.JsonOutput
-Required.JsonInput.BoolFieldTrue.ProtobufOutput
-Required.JsonInput.BoolMapEscapedKey.JsonOutput
-Required.JsonInput.BoolMapEscapedKey.ProtobufOutput
-Required.JsonInput.BoolMapField.JsonOutput
-Required.JsonInput.BoolMapField.ProtobufOutput
-Required.JsonInput.BytesField.JsonOutput
-Required.JsonInput.BytesField.ProtobufOutput
-Required.JsonInput.BytesFieldInvalidBase64Characters
-Required.JsonInput.BytesRepeatedField.JsonOutput
-Required.JsonInput.BytesRepeatedField.ProtobufOutput
-Required.JsonInput.DoubleFieldInfinity.JsonOutput
-Required.JsonInput.DoubleFieldInfinity.ProtobufOutput
-Required.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
-Required.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
-Required.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
-Required.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput
-Required.JsonInput.DoubleFieldMinNegativeValue.JsonOutput
-Required.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput
-Required.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
-Required.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
-Required.JsonInput.DoubleFieldNan.JsonOutput
-Required.JsonInput.DoubleFieldNan.ProtobufOutput
-Required.JsonInput.DoubleFieldNegativeInfinity.JsonOutput
-Required.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput
-Required.JsonInput.DoubleFieldQuotedValue.JsonOutput
-Required.JsonInput.DoubleFieldQuotedValue.ProtobufOutput
-Required.JsonInput.DoubleFieldTooLarge
-Required.JsonInput.DoubleFieldTooSmall
-Required.JsonInput.DurationJsonInputTooLarge
-Required.JsonInput.DurationJsonInputTooSmall
 Required.JsonInput.DurationMaxValue.JsonOutput
 Required.JsonInput.DurationMaxValue.ProtobufOutput
 Required.JsonInput.DurationMinValue.JsonOutput
 Required.JsonInput.DurationMinValue.ProtobufOutput
-Required.JsonInput.DurationMissingS
 Required.JsonInput.DurationRepeatedValue.JsonOutput
 Required.JsonInput.DurationRepeatedValue.ProtobufOutput
-Required.JsonInput.EnumField.JsonOutput
-Required.JsonInput.EnumField.ProtobufOutput
-Required.JsonInput.EnumFieldNotQuoted
-Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput
-Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
-Required.JsonInput.EnumFieldNumericValueZero.JsonOutput
-Required.JsonInput.EnumFieldNumericValueZero.ProtobufOutput
-Required.JsonInput.EnumFieldUnknownValue.Validator
-Required.JsonInput.EnumRepeatedField.JsonOutput
-Required.JsonInput.EnumRepeatedField.ProtobufOutput
 Required.JsonInput.FieldMask.JsonOutput
 Required.JsonInput.FieldMask.ProtobufOutput
-Required.JsonInput.FieldNameEscaped.JsonOutput
-Required.JsonInput.FieldNameEscaped.ProtobufOutput
-Required.JsonInput.FieldNameInLowerCamelCase.Validator
-Required.JsonInput.FieldNameInSnakeCase.JsonOutput
-Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
-Required.JsonInput.FieldNameWithMixedCases.JsonOutput
-Required.JsonInput.FieldNameWithMixedCases.ProtobufOutput
-Required.JsonInput.FieldNameWithMixedCases.Validator
-Required.JsonInput.FieldNameWithNumbers.JsonOutput
-Required.JsonInput.FieldNameWithNumbers.ProtobufOutput
-Required.JsonInput.FieldNameWithNumbers.Validator
-Required.JsonInput.FloatFieldInfinity.JsonOutput
-Required.JsonInput.FloatFieldInfinity.ProtobufOutput
-Required.JsonInput.FloatFieldMaxNegativeValue.JsonOutput
-Required.JsonInput.FloatFieldMaxNegativeValue.ProtobufOutput
-Required.JsonInput.FloatFieldMaxPositiveValue.JsonOutput
-Required.JsonInput.FloatFieldMaxPositiveValue.ProtobufOutput
-Required.JsonInput.FloatFieldMinNegativeValue.JsonOutput
-Required.JsonInput.FloatFieldMinNegativeValue.ProtobufOutput
-Required.JsonInput.FloatFieldMinPositiveValue.JsonOutput
-Required.JsonInput.FloatFieldMinPositiveValue.ProtobufOutput
-Required.JsonInput.FloatFieldNan.JsonOutput
-Required.JsonInput.FloatFieldNan.ProtobufOutput
-Required.JsonInput.FloatFieldNegativeInfinity.JsonOutput
-Required.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput
-Required.JsonInput.FloatFieldQuotedValue.JsonOutput
-Required.JsonInput.FloatFieldQuotedValue.ProtobufOutput
-Required.JsonInput.FloatFieldTooLarge
-Required.JsonInput.FloatFieldTooSmall
-Required.JsonInput.HelloWorld.JsonOutput
-Required.JsonInput.HelloWorld.ProtobufOutput
-Required.JsonInput.Int32FieldExponentialFormat.JsonOutput
-Required.JsonInput.Int32FieldExponentialFormat.ProtobufOutput
-Required.JsonInput.Int32FieldFloatTrailingZero.JsonOutput
-Required.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
-Required.JsonInput.Int32FieldLeadingSpace
-Required.JsonInput.Int32FieldLeadingZero
-Required.JsonInput.Int32FieldMaxFloatValue.JsonOutput
-Required.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
-Required.JsonInput.Int32FieldMaxValue.JsonOutput
-Required.JsonInput.Int32FieldMaxValue.ProtobufOutput
-Required.JsonInput.Int32FieldMinFloatValue.JsonOutput
-Required.JsonInput.Int32FieldMinFloatValue.ProtobufOutput
-Required.JsonInput.Int32FieldMinValue.JsonOutput
-Required.JsonInput.Int32FieldMinValue.ProtobufOutput
-Required.JsonInput.Int32FieldNegativeWithLeadingZero
-Required.JsonInput.Int32FieldNotInteger
-Required.JsonInput.Int32FieldNotNumber
-Required.JsonInput.Int32FieldPlusSign
-Required.JsonInput.Int32FieldStringValue.JsonOutput
-Required.JsonInput.Int32FieldStringValue.ProtobufOutput
-Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput
-Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
-Required.JsonInput.Int32FieldTooLarge
-Required.JsonInput.Int32FieldTooSmall
-Required.JsonInput.Int32FieldTrailingSpace
-Required.JsonInput.Int32MapEscapedKey.JsonOutput
-Required.JsonInput.Int32MapEscapedKey.ProtobufOutput
-Required.JsonInput.Int32MapField.JsonOutput
-Required.JsonInput.Int32MapField.ProtobufOutput
-Required.JsonInput.Int64FieldMaxValue.JsonOutput
-Required.JsonInput.Int64FieldMaxValue.ProtobufOutput
-Required.JsonInput.Int64FieldMaxValueNotQuoted.JsonOutput
-Required.JsonInput.Int64FieldMaxValueNotQuoted.ProtobufOutput
-Required.JsonInput.Int64FieldMinValue.JsonOutput
-Required.JsonInput.Int64FieldMinValue.ProtobufOutput
-Required.JsonInput.Int64FieldMinValueNotQuoted.JsonOutput
-Required.JsonInput.Int64FieldMinValueNotQuoted.ProtobufOutput
-Required.JsonInput.Int64FieldNotInteger
-Required.JsonInput.Int64FieldNotNumber
-Required.JsonInput.Int64FieldTooLarge
-Required.JsonInput.Int64FieldTooSmall
-Required.JsonInput.Int64MapEscapedKey.JsonOutput
-Required.JsonInput.Int64MapEscapedKey.ProtobufOutput
-Required.JsonInput.Int64MapField.JsonOutput
-Required.JsonInput.Int64MapField.ProtobufOutput
-Required.JsonInput.MessageField.JsonOutput
-Required.JsonInput.MessageField.ProtobufOutput
-Required.JsonInput.MessageMapField.JsonOutput
-Required.JsonInput.MessageMapField.ProtobufOutput
-Required.JsonInput.MessageRepeatedField.JsonOutput
-Required.JsonInput.MessageRepeatedField.ProtobufOutput
-Required.JsonInput.OneofFieldDuplicate
 Required.JsonInput.OptionalBoolWrapper.JsonOutput
 Required.JsonInput.OptionalBoolWrapper.ProtobufOutput
 Required.JsonInput.OptionalBytesWrapper.JsonOutput
@@ -287,25 +60,12 @@
 Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput
 Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
 Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
-Required.JsonInput.OriginalProtoFieldName.JsonOutput
-Required.JsonInput.OriginalProtoFieldName.ProtobufOutput
-Required.JsonInput.PrimitiveRepeatedField.JsonOutput
-Required.JsonInput.PrimitiveRepeatedField.ProtobufOutput
 Required.JsonInput.RepeatedBoolWrapper.JsonOutput
 Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput
 Required.JsonInput.RepeatedBytesWrapper.JsonOutput
 Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput
 Required.JsonInput.RepeatedDoubleWrapper.JsonOutput
 Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput
-Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
-Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotMessage
-Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotString
-Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotBool
-Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotInt
-Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotString
-Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
-Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
-Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotMessage
 Required.JsonInput.RepeatedFloatWrapper.JsonOutput
 Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput
 Required.JsonInput.RepeatedInt32Wrapper.JsonOutput
@@ -318,29 +78,8 @@
 Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput
 Required.JsonInput.RepeatedUint64Wrapper.JsonOutput
 Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput
-Required.JsonInput.StringField.JsonOutput
-Required.JsonInput.StringField.ProtobufOutput
-Required.JsonInput.StringFieldEscape.JsonOutput
-Required.JsonInput.StringFieldEscape.ProtobufOutput
-Required.JsonInput.StringFieldNotAString
-Required.JsonInput.StringFieldSurrogatePair.JsonOutput
-Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput
-Required.JsonInput.StringFieldUnicode.JsonOutput
-Required.JsonInput.StringFieldUnicode.ProtobufOutput
-Required.JsonInput.StringFieldUnicodeEscape.JsonOutput
-Required.JsonInput.StringFieldUnicodeEscape.ProtobufOutput
-Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput
-Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput
-Required.JsonInput.StringRepeatedField.JsonOutput
-Required.JsonInput.StringRepeatedField.ProtobufOutput
 Required.JsonInput.Struct.JsonOutput
 Required.JsonInput.Struct.ProtobufOutput
-Required.JsonInput.TimestampJsonInputLowercaseT
-Required.JsonInput.TimestampJsonInputLowercaseZ
-Required.JsonInput.TimestampJsonInputMissingT
-Required.JsonInput.TimestampJsonInputMissingZ
-Required.JsonInput.TimestampJsonInputTooLarge
-Required.JsonInput.TimestampJsonInputTooSmall
 Required.JsonInput.TimestampMaxValue.JsonOutput
 Required.JsonInput.TimestampMaxValue.ProtobufOutput
 Required.JsonInput.TimestampMinValue.JsonOutput
@@ -351,24 +90,6 @@
 Required.JsonInput.TimestampWithNegativeOffset.ProtobufOutput
 Required.JsonInput.TimestampWithPositiveOffset.JsonOutput
 Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput
-Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput
-Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
-Required.JsonInput.Uint32FieldMaxValue.JsonOutput
-Required.JsonInput.Uint32FieldMaxValue.ProtobufOutput
-Required.JsonInput.Uint32FieldNotInteger
-Required.JsonInput.Uint32FieldNotNumber
-Required.JsonInput.Uint32FieldTooLarge
-Required.JsonInput.Uint32MapField.JsonOutput
-Required.JsonInput.Uint32MapField.ProtobufOutput
-Required.JsonInput.Uint64FieldMaxValue.JsonOutput
-Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput
-Required.JsonInput.Uint64FieldMaxValueNotQuoted.JsonOutput
-Required.JsonInput.Uint64FieldMaxValueNotQuoted.ProtobufOutput
-Required.JsonInput.Uint64FieldNotInteger
-Required.JsonInput.Uint64FieldNotNumber
-Required.JsonInput.Uint64FieldTooLarge
-Required.JsonInput.Uint64MapField.JsonOutput
-Required.JsonInput.Uint64MapField.ProtobufOutput
 Required.JsonInput.ValueAcceptBool.JsonOutput
 Required.JsonInput.ValueAcceptBool.ProtobufOutput
 Required.JsonInput.ValueAcceptFloat.JsonOutput
@@ -383,229 +104,15 @@
 Required.JsonInput.ValueAcceptObject.ProtobufOutput
 Required.JsonInput.ValueAcceptString.JsonOutput
 Required.JsonInput.ValueAcceptString.ProtobufOutput
-Required.JsonInput.WrapperTypesWithNullValue.JsonOutput
-Required.JsonInput.WrapperTypesWithNullValue.ProtobufOutput
-Required.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
-Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
-Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
-Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BOOL
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BYTES
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.DOUBLE
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.ENUM
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED32
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED64
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FLOAT
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT32
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT64
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.MESSAGE
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED32
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED64
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT32
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT64
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.STRING
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT32
-Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT64
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BOOL
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BYTES
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.DOUBLE
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.ENUM
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED32
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED64
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FLOAT
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT32
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT64
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED32
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED64
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT32
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT64
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.STRING
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT32
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT64
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.BOOL
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.BYTES
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.DOUBLE
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.ENUM
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED32
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED64
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.FLOAT
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT32
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT64
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.MESSAGE
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED32
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED64
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT32
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT64
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.STRING
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT32
-Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT64
-Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.BYTES
-Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
-Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.STRING
-Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.BYTES
-Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
-Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.STRING
-Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.BYTES
-Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.MESSAGE
-Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.STRING
-Required.ProtobufInput.PrematureEofInPackedField.BOOL
-Required.ProtobufInput.PrematureEofInPackedField.DOUBLE
-Required.ProtobufInput.PrematureEofInPackedField.ENUM
-Required.ProtobufInput.PrematureEofInPackedField.FIXED32
-Required.ProtobufInput.PrematureEofInPackedField.FIXED64
-Required.ProtobufInput.PrematureEofInPackedField.FLOAT
-Required.ProtobufInput.PrematureEofInPackedField.INT32
-Required.ProtobufInput.PrematureEofInPackedField.INT64
-Required.ProtobufInput.PrematureEofInPackedField.SFIXED32
-Required.ProtobufInput.PrematureEofInPackedField.SFIXED64
-Required.ProtobufInput.PrematureEofInPackedField.SINT32
-Required.ProtobufInput.PrematureEofInPackedField.SINT64
-Required.ProtobufInput.PrematureEofInPackedField.UINT32
-Required.ProtobufInput.PrematureEofInPackedField.UINT64
-Required.ProtobufInput.PrematureEofInPackedFieldValue.BOOL
-Required.ProtobufInput.PrematureEofInPackedFieldValue.DOUBLE
-Required.ProtobufInput.PrematureEofInPackedFieldValue.ENUM
-Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED32
-Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED64
-Required.ProtobufInput.PrematureEofInPackedFieldValue.FLOAT
-Required.ProtobufInput.PrematureEofInPackedFieldValue.INT32
-Required.ProtobufInput.PrematureEofInPackedFieldValue.INT64
-Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED32
-Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED64
-Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT32
-Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT64
-Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT32
-Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT64
-Required.ProtobufInput.PrematureEofInSubmessageValue.MESSAGE
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BOOL
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BYTES
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.DOUBLE
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.ENUM
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED32
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED64
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FLOAT
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT32
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT64
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.MESSAGE
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED32
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED64
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT32
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT64
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.STRING
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT32
-Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT64
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BOOL
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BYTES
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.DOUBLE
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.ENUM
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED32
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED64
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FLOAT
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT32
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT64
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED32
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED64
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT32
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT64
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.STRING
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT32
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT64
-Required.ProtobufInput.PrematureEofInsideUnknownValue.BOOL
-Required.ProtobufInput.PrematureEofInsideUnknownValue.BYTES
-Required.ProtobufInput.PrematureEofInsideUnknownValue.DOUBLE
-Required.ProtobufInput.PrematureEofInsideUnknownValue.ENUM
-Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED32
-Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED64
-Required.ProtobufInput.PrematureEofInsideUnknownValue.FLOAT
-Required.ProtobufInput.PrematureEofInsideUnknownValue.INT32
-Required.ProtobufInput.PrematureEofInsideUnknownValue.INT64
-Required.ProtobufInput.PrematureEofInsideUnknownValue.MESSAGE
-Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED32
-Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED64
-Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT32
-Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT64
-Required.ProtobufInput.PrematureEofInsideUnknownValue.STRING
-Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT32
-Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT64
-Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.JsonOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.ProtobufOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.JsonOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.ProtobufOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.JsonOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.ProtobufOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.JsonOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.JsonOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.ProtobufOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.JsonOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.ProtobufOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.JsonOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.ProtobufOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.JsonOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.ProtobufOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.JsonOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.ProtobufOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.JsonOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.ProtobufOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.JsonOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.ProtobufOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.JsonOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.ProtobufOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.JsonOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput
-Required.ProtobufInput.ValidDataRepeated.BOOL.JsonOutput
-Required.ProtobufInput.ValidDataRepeated.BOOL.ProtobufOutput
-Required.ProtobufInput.ValidDataRepeated.DOUBLE.JsonOutput
-Required.ProtobufInput.ValidDataRepeated.DOUBLE.ProtobufOutput
-Required.ProtobufInput.ValidDataRepeated.FIXED32.JsonOutput
-Required.ProtobufInput.ValidDataRepeated.FIXED32.ProtobufOutput
-Required.ProtobufInput.ValidDataRepeated.FIXED64.JsonOutput
-Required.ProtobufInput.ValidDataRepeated.FIXED64.ProtobufOutput
-Required.ProtobufInput.ValidDataRepeated.FLOAT.JsonOutput
-Required.ProtobufInput.ValidDataRepeated.FLOAT.ProtobufOutput
-Required.ProtobufInput.ValidDataRepeated.INT32.JsonOutput
-Required.ProtobufInput.ValidDataRepeated.INT32.ProtobufOutput
-Required.ProtobufInput.ValidDataRepeated.INT64.JsonOutput
-Required.ProtobufInput.ValidDataRepeated.INT64.ProtobufOutput
-Required.ProtobufInput.ValidDataRepeated.SFIXED32.JsonOutput
-Required.ProtobufInput.ValidDataRepeated.SFIXED32.ProtobufOutput
-Required.ProtobufInput.ValidDataRepeated.SFIXED64.JsonOutput
-Required.ProtobufInput.ValidDataRepeated.SFIXED64.ProtobufOutput
-Required.ProtobufInput.ValidDataRepeated.SINT32.JsonOutput
-Required.ProtobufInput.ValidDataRepeated.SINT32.ProtobufOutput
-Required.ProtobufInput.ValidDataRepeated.SINT64.JsonOutput
-Required.ProtobufInput.ValidDataRepeated.SINT64.ProtobufOutput
-Required.ProtobufInput.ValidDataRepeated.UINT32.JsonOutput
-Required.ProtobufInput.ValidDataRepeated.UINT32.ProtobufOutput
-Required.ProtobufInput.ValidDataRepeated.UINT64.JsonOutput
-Required.ProtobufInput.ValidDataRepeated.UINT64.ProtobufOutput
-Required.ProtobufInput.ValidDataScalar.BOOL.JsonOutput
-Required.ProtobufInput.ValidDataScalar.BOOL.ProtobufOutput
-Required.ProtobufInput.ValidDataScalar.DOUBLE.JsonOutput
-Required.ProtobufInput.ValidDataScalar.DOUBLE.ProtobufOutput
-Required.ProtobufInput.ValidDataScalar.FIXED32.JsonOutput
-Required.ProtobufInput.ValidDataScalar.FIXED32.ProtobufOutput
-Required.ProtobufInput.ValidDataScalar.FIXED64.JsonOutput
-Required.ProtobufInput.ValidDataScalar.FIXED64.ProtobufOutput
-Required.ProtobufInput.ValidDataScalar.FLOAT.JsonOutput
-Required.ProtobufInput.ValidDataScalar.FLOAT.ProtobufOutput
-Required.ProtobufInput.ValidDataScalar.INT32.JsonOutput
-Required.ProtobufInput.ValidDataScalar.INT32.ProtobufOutput
-Required.ProtobufInput.ValidDataScalar.INT64.JsonOutput
-Required.ProtobufInput.ValidDataScalar.INT64.ProtobufOutput
-Required.ProtobufInput.ValidDataScalar.SFIXED32.JsonOutput
-Required.ProtobufInput.ValidDataScalar.SFIXED32.ProtobufOutput
-Required.ProtobufInput.ValidDataScalar.SFIXED64.JsonOutput
-Required.ProtobufInput.ValidDataScalar.SFIXED64.ProtobufOutput
-Required.ProtobufInput.ValidDataScalar.SINT32.JsonOutput
-Required.ProtobufInput.ValidDataScalar.SINT32.ProtobufOutput
-Required.ProtobufInput.ValidDataScalar.SINT64.JsonOutput
-Required.ProtobufInput.ValidDataScalar.SINT64.ProtobufOutput
-Required.ProtobufInput.ValidDataScalar.UINT32.JsonOutput
-Required.ProtobufInput.ValidDataScalar.UINT32.ProtobufOutput
-Required.ProtobufInput.ValidDataScalar.UINT64.JsonOutput
-Required.ProtobufInput.ValidDataScalar.UINT64.ProtobufOutput
 Required.TimestampProtoInputTooLarge.JsonOutput
 Required.TimestampProtoInputTooSmall.JsonOutput
+Required.JsonInput.FloatFieldTooLarge
+Required.JsonInput.FloatFieldTooSmall
+Required.JsonInput.DoubleFieldTooSmall
+Required.JsonInput.Int32FieldNotInteger
+Required.JsonInput.Int64FieldNotInteger
+Required.JsonInput.Uint32FieldNotInteger
+Required.JsonInput.Uint64FieldNotInteger
+Required.JsonInput.Int32FieldLeadingSpace
+Required.JsonInput.OneofFieldDuplicate
+Required.ProtobufInput.ValidDataRepeated.FLOAT.JsonOutput
diff --git a/conformance/failure_list_php_c.txt b/conformance/failure_list_php_c.txt
index f53449f..591997e 100644
--- a/conformance/failure_list_php_c.txt
+++ b/conformance/failure_list_php_c.txt
@@ -9,22 +9,10 @@
 Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator
 Recommended.JsonInput.Int64FieldBeString.Validator
 Recommended.JsonInput.MapFieldValueIsNull
-Recommended.JsonInput.OneofZeroBool.JsonOutput
-Recommended.JsonInput.OneofZeroBool.ProtobufOutput
 Recommended.JsonInput.OneofZeroBytes.JsonOutput
 Recommended.JsonInput.OneofZeroBytes.ProtobufOutput
-Recommended.JsonInput.OneofZeroDouble.JsonOutput
-Recommended.JsonInput.OneofZeroDouble.ProtobufOutput
-Recommended.JsonInput.OneofZeroEnum.JsonOutput
-Recommended.JsonInput.OneofZeroEnum.ProtobufOutput
-Recommended.JsonInput.OneofZeroFloat.JsonOutput
-Recommended.JsonInput.OneofZeroFloat.ProtobufOutput
 Recommended.JsonInput.OneofZeroString.JsonOutput
 Recommended.JsonInput.OneofZeroString.ProtobufOutput
-Recommended.JsonInput.OneofZeroUint32.JsonOutput
-Recommended.JsonInput.OneofZeroUint32.ProtobufOutput
-Recommended.JsonInput.OneofZeroUint64.JsonOutput
-Recommended.JsonInput.OneofZeroUint64.ProtobufOutput
 Recommended.JsonInput.RepeatedFieldMessageElementIsNull
 Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull
 Recommended.JsonInput.StringEndsWithEscapeChar
@@ -37,25 +25,12 @@
 Recommended.JsonInput.TimestampHasZeroFractionalDigit.Validator
 Recommended.JsonInput.TimestampZeroNormalized.Validator
 Recommended.JsonInput.Uint64FieldBeString.Validator
-Recommended.ProtobufInput.OneofZeroBool.JsonOutput
-Recommended.ProtobufInput.OneofZeroBool.ProtobufOutput
 Recommended.ProtobufInput.OneofZeroBytes.JsonOutput
 Recommended.ProtobufInput.OneofZeroBytes.ProtobufOutput
-Recommended.ProtobufInput.OneofZeroDouble.JsonOutput
-Recommended.ProtobufInput.OneofZeroDouble.ProtobufOutput
-Recommended.ProtobufInput.OneofZeroEnum.JsonOutput
-Recommended.ProtobufInput.OneofZeroEnum.ProtobufOutput
-Recommended.ProtobufInput.OneofZeroFloat.JsonOutput
-Recommended.ProtobufInput.OneofZeroFloat.ProtobufOutput
 Recommended.ProtobufInput.OneofZeroString.JsonOutput
 Recommended.ProtobufInput.OneofZeroString.ProtobufOutput
-Recommended.ProtobufInput.OneofZeroUint32.JsonOutput
-Recommended.ProtobufInput.OneofZeroUint32.ProtobufOutput
-Recommended.ProtobufInput.OneofZeroUint64.JsonOutput
-Recommended.ProtobufInput.OneofZeroUint64.ProtobufOutput
 Required.DurationProtoInputTooLarge.JsonOutput
 Required.DurationProtoInputTooSmall.JsonOutput
-Required.JsonInput.AllFieldAcceptNull.ProtobufOutput
 Required.JsonInput.Any.JsonOutput
 Required.JsonInput.Any.ProtobufOutput
 Required.JsonInput.AnyNested.JsonOutput
@@ -76,7 +51,6 @@
 Required.JsonInput.AnyWithValueForInteger.ProtobufOutput
 Required.JsonInput.AnyWithValueForJsonObject.JsonOutput
 Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
-Required.JsonInput.BoolFieldFalse.ProtobufOutput
 Required.JsonInput.BoolMapField.JsonOutput
 Required.JsonInput.DoubleFieldInfinity.JsonOutput
 Required.JsonInput.DoubleFieldInfinity.ProtobufOutput
@@ -100,7 +74,6 @@
 Required.JsonInput.DurationMinValue.ProtobufOutput
 Required.JsonInput.DurationRepeatedValue.JsonOutput
 Required.JsonInput.DurationRepeatedValue.ProtobufOutput
-Required.JsonInput.EnumField.ProtobufOutput
 Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput
 Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
 Required.JsonInput.EnumFieldNumericValueZero.JsonOutput
@@ -215,13 +188,10 @@
 Required.JsonInput.ValueAcceptObject.ProtobufOutput
 Required.JsonInput.ValueAcceptString.JsonOutput
 Required.JsonInput.ValueAcceptString.ProtobufOutput
-Required.JsonInput.WrapperTypesWithNullValue.ProtobufOutput
 Required.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
 Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
 Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
 Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.ProtobufOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput
-Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.FLOAT.JsonOutput
 Required.TimestampProtoInputTooLarge.JsonOutput
 Required.TimestampProtoInputTooSmall.JsonOutput
diff --git a/conformance/failure_list_php_zts_c.txt b/conformance/failure_list_php_zts_c.txt
new file mode 100644
index 0000000..d9a8fe3
--- /dev/null
+++ b/conformance/failure_list_php_zts_c.txt
@@ -0,0 +1,225 @@
+Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
+Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
+Recommended.FieldMaskTooManyUnderscore.JsonOutput
+Recommended.JsonInput.BoolFieldIntegerOne
+Recommended.JsonInput.BoolFieldIntegerZero
+Recommended.JsonInput.DurationHas3FractionalDigits.Validator
+Recommended.JsonInput.DurationHas6FractionalDigits.Validator
+Recommended.JsonInput.DurationHas9FractionalDigits.Validator
+Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator
+Recommended.JsonInput.Int64FieldBeString.Validator
+Recommended.JsonInput.OneofZeroBytes.JsonOutput
+Recommended.JsonInput.OneofZeroBytes.ProtobufOutput
+Recommended.JsonInput.OneofZeroDouble.JsonOutput
+Recommended.JsonInput.OneofZeroDouble.ProtobufOutput
+Recommended.JsonInput.OneofZeroFloat.JsonOutput
+Recommended.JsonInput.OneofZeroFloat.ProtobufOutput
+Recommended.JsonInput.OneofZeroString.JsonOutput
+Recommended.JsonInput.OneofZeroString.ProtobufOutput
+Recommended.JsonInput.OneofZeroUint32.JsonOutput
+Recommended.JsonInput.OneofZeroUint32.ProtobufOutput
+Recommended.JsonInput.OneofZeroUint64.JsonOutput
+Recommended.JsonInput.OneofZeroUint64.ProtobufOutput
+Recommended.JsonInput.StringEndsWithEscapeChar
+Recommended.JsonInput.StringFieldSurrogateInWrongOrder
+Recommended.JsonInput.StringFieldUnpairedHighSurrogate
+Recommended.JsonInput.StringFieldUnpairedLowSurrogate
+Recommended.JsonInput.TimestampHas3FractionalDigits.Validator
+Recommended.JsonInput.TimestampHas6FractionalDigits.Validator
+Recommended.JsonInput.TimestampHas9FractionalDigits.Validator
+Recommended.JsonInput.TimestampHasZeroFractionalDigit.Validator
+Recommended.JsonInput.TimestampZeroNormalized.Validator
+Recommended.JsonInput.Uint64FieldBeString.Validator
+Recommended.ProtobufInput.OneofZeroBytes.JsonOutput
+Recommended.ProtobufInput.OneofZeroBytes.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroString.JsonOutput
+Recommended.ProtobufInput.OneofZeroString.ProtobufOutput
+Required.DurationProtoInputTooLarge.JsonOutput
+Required.DurationProtoInputTooSmall.JsonOutput
+Required.JsonInput.AllFieldAcceptNull.ProtobufOutput
+Required.JsonInput.Any.JsonOutput
+Required.JsonInput.Any.ProtobufOutput
+Required.JsonInput.AnyNested.JsonOutput
+Required.JsonInput.AnyNested.ProtobufOutput
+Required.JsonInput.AnyUnorderedTypeTag.JsonOutput
+Required.JsonInput.AnyUnorderedTypeTag.ProtobufOutput
+Required.JsonInput.AnyWithDuration.JsonOutput
+Required.JsonInput.AnyWithDuration.ProtobufOutput
+Required.JsonInput.AnyWithFieldMask.JsonOutput
+Required.JsonInput.AnyWithFieldMask.ProtobufOutput
+Required.JsonInput.AnyWithInt32ValueWrapper.JsonOutput
+Required.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
+Required.JsonInput.AnyWithStruct.JsonOutput
+Required.JsonInput.AnyWithStruct.ProtobufOutput
+Required.JsonInput.AnyWithTimestamp.JsonOutput
+Required.JsonInput.AnyWithTimestamp.ProtobufOutput
+Required.JsonInput.AnyWithValueForInteger.JsonOutput
+Required.JsonInput.AnyWithValueForInteger.ProtobufOutput
+Required.JsonInput.AnyWithValueForJsonObject.JsonOutput
+Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
+Required.JsonInput.BoolFieldFalse.ProtobufOutput
+Required.JsonInput.BoolMapField.JsonOutput
+Required.JsonInput.DoubleFieldInfinity.JsonOutput
+Required.JsonInput.DoubleFieldInfinity.ProtobufOutput
+Required.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
+Required.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
+Required.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
+Required.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput
+Required.JsonInput.DoubleFieldMinNegativeValue.JsonOutput
+Required.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput
+Required.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
+Required.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
+Required.JsonInput.DoubleFieldNan.JsonOutput
+Required.JsonInput.DoubleFieldNan.ProtobufOutput
+Required.JsonInput.DoubleFieldNegativeInfinity.JsonOutput
+Required.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput
+Required.JsonInput.DoubleFieldQuotedValue.JsonOutput
+Required.JsonInput.DoubleFieldQuotedValue.ProtobufOutput
+Required.JsonInput.DurationMaxValue.JsonOutput
+Required.JsonInput.DurationMaxValue.ProtobufOutput
+Required.JsonInput.DurationMinValue.JsonOutput
+Required.JsonInput.DurationMinValue.ProtobufOutput
+Required.JsonInput.DurationRepeatedValue.JsonOutput
+Required.JsonInput.DurationRepeatedValue.ProtobufOutput
+Required.JsonInput.EnumField.ProtobufOutput
+Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput
+Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
+Required.JsonInput.EnumFieldNumericValueZero.JsonOutput
+Required.JsonInput.EnumFieldNumericValueZero.ProtobufOutput
+Required.JsonInput.EnumFieldUnknownValue.Validator
+Required.JsonInput.FieldMask.JsonOutput
+Required.JsonInput.FieldMask.ProtobufOutput
+Required.JsonInput.FloatFieldInfinity.JsonOutput
+Required.JsonInput.FloatFieldInfinity.ProtobufOutput
+Required.JsonInput.FloatFieldNan.JsonOutput
+Required.JsonInput.FloatFieldNan.ProtobufOutput
+Required.JsonInput.FloatFieldNegativeInfinity.JsonOutput
+Required.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput
+Required.JsonInput.FloatFieldQuotedValue.JsonOutput
+Required.JsonInput.FloatFieldQuotedValue.ProtobufOutput
+Required.JsonInput.FloatFieldTooLarge
+Required.JsonInput.FloatFieldTooSmall
+Required.JsonInput.Int32FieldExponentialFormat.JsonOutput
+Required.JsonInput.Int32FieldExponentialFormat.ProtobufOutput
+Required.JsonInput.Int32FieldFloatTrailingZero.JsonOutput
+Required.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
+Required.JsonInput.Int32FieldMaxFloatValue.JsonOutput
+Required.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
+Required.JsonInput.Int32FieldMinFloatValue.JsonOutput
+Required.JsonInput.Int32FieldMinFloatValue.ProtobufOutput
+Required.JsonInput.Int32FieldStringValue.JsonOutput
+Required.JsonInput.Int32FieldStringValue.ProtobufOutput
+Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput
+Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
+Required.JsonInput.Int32MapEscapedKey.JsonOutput
+Required.JsonInput.Int32MapEscapedKey.ProtobufOutput
+Required.JsonInput.Int32MapField.JsonOutput
+Required.JsonInput.Int32MapField.ProtobufOutput
+Required.JsonInput.Int64FieldMaxValue.JsonOutput
+Required.JsonInput.Int64FieldMaxValue.ProtobufOutput
+Required.JsonInput.Int64FieldMinValue.JsonOutput
+Required.JsonInput.Int64FieldMinValue.ProtobufOutput
+Required.JsonInput.Int64MapEscapedKey.JsonOutput
+Required.JsonInput.Int64MapEscapedKey.ProtobufOutput
+Required.JsonInput.Int64MapField.JsonOutput
+Required.JsonInput.Int64MapField.ProtobufOutput
+Required.JsonInput.MessageField.JsonOutput
+Required.JsonInput.MessageField.ProtobufOutput
+Required.JsonInput.MessageMapField.JsonOutput
+Required.JsonInput.MessageMapField.ProtobufOutput
+Required.JsonInput.MessageRepeatedField.JsonOutput
+Required.JsonInput.MessageRepeatedField.ProtobufOutput
+Required.JsonInput.OptionalBoolWrapper.JsonOutput
+Required.JsonInput.OptionalBoolWrapper.ProtobufOutput
+Required.JsonInput.OptionalBytesWrapper.JsonOutput
+Required.JsonInput.OptionalBytesWrapper.ProtobufOutput
+Required.JsonInput.OptionalDoubleWrapper.JsonOutput
+Required.JsonInput.OptionalDoubleWrapper.ProtobufOutput
+Required.JsonInput.OptionalFloatWrapper.JsonOutput
+Required.JsonInput.OptionalFloatWrapper.ProtobufOutput
+Required.JsonInput.OptionalInt32Wrapper.JsonOutput
+Required.JsonInput.OptionalInt32Wrapper.ProtobufOutput
+Required.JsonInput.OptionalInt64Wrapper.JsonOutput
+Required.JsonInput.OptionalInt64Wrapper.ProtobufOutput
+Required.JsonInput.OptionalStringWrapper.JsonOutput
+Required.JsonInput.OptionalStringWrapper.ProtobufOutput
+Required.JsonInput.OptionalUint32Wrapper.JsonOutput
+Required.JsonInput.OptionalUint32Wrapper.ProtobufOutput
+Required.JsonInput.OptionalUint64Wrapper.JsonOutput
+Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput
+Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
+Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
+Required.JsonInput.PrimitiveRepeatedField.JsonOutput
+Required.JsonInput.PrimitiveRepeatedField.ProtobufOutput
+Required.JsonInput.RepeatedBoolWrapper.JsonOutput
+Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput
+Required.JsonInput.RepeatedBytesWrapper.JsonOutput
+Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput
+Required.JsonInput.RepeatedDoubleWrapper.JsonOutput
+Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
+Required.JsonInput.RepeatedFloatWrapper.JsonOutput
+Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput
+Required.JsonInput.RepeatedInt32Wrapper.JsonOutput
+Required.JsonInput.RepeatedInt32Wrapper.ProtobufOutput
+Required.JsonInput.RepeatedInt64Wrapper.JsonOutput
+Required.JsonInput.RepeatedInt64Wrapper.ProtobufOutput
+Required.JsonInput.RepeatedStringWrapper.JsonOutput
+Required.JsonInput.RepeatedStringWrapper.ProtobufOutput
+Required.JsonInput.RepeatedUint32Wrapper.JsonOutput
+Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput
+Required.JsonInput.RepeatedUint64Wrapper.JsonOutput
+Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput
+Required.JsonInput.StringFieldEscape.JsonOutput
+Required.JsonInput.StringFieldEscape.ProtobufOutput
+Required.JsonInput.StringFieldNotAString
+Required.JsonInput.StringFieldSurrogatePair.JsonOutput
+Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput
+Required.JsonInput.StringFieldUnicodeEscape.JsonOutput
+Required.JsonInput.StringFieldUnicodeEscape.ProtobufOutput
+Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput
+Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput
+Required.JsonInput.Struct.JsonOutput
+Required.JsonInput.Struct.ProtobufOutput
+Required.JsonInput.TimestampMaxValue.JsonOutput
+Required.JsonInput.TimestampMaxValue.ProtobufOutput
+Required.JsonInput.TimestampMinValue.JsonOutput
+Required.JsonInput.TimestampMinValue.ProtobufOutput
+Required.JsonInput.TimestampRepeatedValue.JsonOutput
+Required.JsonInput.TimestampRepeatedValue.ProtobufOutput
+Required.JsonInput.TimestampWithNegativeOffset.JsonOutput
+Required.JsonInput.TimestampWithNegativeOffset.ProtobufOutput
+Required.JsonInput.TimestampWithPositiveOffset.JsonOutput
+Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput
+Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput
+Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
+Required.JsonInput.Uint32MapField.JsonOutput
+Required.JsonInput.Uint32MapField.ProtobufOutput
+Required.JsonInput.Uint64FieldMaxValue.JsonOutput
+Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput
+Required.JsonInput.Uint64MapField.JsonOutput
+Required.JsonInput.Uint64MapField.ProtobufOutput
+Required.JsonInput.ValueAcceptBool.JsonOutput
+Required.JsonInput.ValueAcceptBool.ProtobufOutput
+Required.JsonInput.ValueAcceptFloat.JsonOutput
+Required.JsonInput.ValueAcceptFloat.ProtobufOutput
+Required.JsonInput.ValueAcceptInteger.JsonOutput
+Required.JsonInput.ValueAcceptInteger.ProtobufOutput
+Required.JsonInput.ValueAcceptList.JsonOutput
+Required.JsonInput.ValueAcceptList.ProtobufOutput
+Required.JsonInput.ValueAcceptNull.JsonOutput
+Required.JsonInput.ValueAcceptNull.ProtobufOutput
+Required.JsonInput.ValueAcceptObject.JsonOutput
+Required.JsonInput.ValueAcceptObject.ProtobufOutput
+Required.JsonInput.ValueAcceptString.JsonOutput
+Required.JsonInput.ValueAcceptString.ProtobufOutput
+Required.JsonInput.WrapperTypesWithNullValue.ProtobufOutput
+Required.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
+Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
+Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
+Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput
+Required.TimestampProtoInputTooLarge.JsonOutput
+Required.TimestampProtoInputTooSmall.JsonOutput
diff --git a/conformance/failure_list_ruby.txt b/conformance/failure_list_ruby.txt
index 1de6c43..d899ee4 100644
--- a/conformance/failure_list_ruby.txt
+++ b/conformance/failure_list_ruby.txt
@@ -1,21 +1,14 @@
 Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
 Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
 Recommended.FieldMaskTooManyUnderscore.JsonOutput
-Recommended.JsonInput.BoolFieldIntegerOne
-Recommended.JsonInput.BoolFieldIntegerZero
 Recommended.JsonInput.DurationHas3FractionalDigits.Validator
 Recommended.JsonInput.DurationHas6FractionalDigits.Validator
 Recommended.JsonInput.DurationHas9FractionalDigits.Validator
 Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator
 Recommended.JsonInput.Int64FieldBeString.Validator
-Recommended.JsonInput.OneofZeroDouble.JsonOutput
-Recommended.JsonInput.OneofZeroDouble.ProtobufOutput
-Recommended.JsonInput.OneofZeroFloat.JsonOutput
-Recommended.JsonInput.OneofZeroFloat.ProtobufOutput
-Recommended.JsonInput.OneofZeroUint32.JsonOutput
-Recommended.JsonInput.OneofZeroUint32.ProtobufOutput
-Recommended.JsonInput.OneofZeroUint64.JsonOutput
-Recommended.JsonInput.OneofZeroUint64.ProtobufOutput
+Recommended.JsonInput.MapFieldValueIsNull
+Recommended.JsonInput.RepeatedFieldMessageElementIsNull
+Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull
 Recommended.JsonInput.StringEndsWithEscapeChar
 Recommended.JsonInput.StringFieldSurrogateInWrongOrder
 Recommended.JsonInput.StringFieldUnpairedHighSurrogate
@@ -48,75 +41,25 @@
 Required.JsonInput.AnyWithValueForInteger.ProtobufOutput
 Required.JsonInput.AnyWithValueForJsonObject.JsonOutput
 Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
-Required.JsonInput.DoubleFieldInfinity.JsonOutput
-Required.JsonInput.DoubleFieldInfinity.ProtobufOutput
 Required.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
 Required.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
-Required.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
-Required.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput
-Required.JsonInput.DoubleFieldMinNegativeValue.JsonOutput
-Required.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput
 Required.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
 Required.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
 Required.JsonInput.DoubleFieldNan.JsonOutput
-Required.JsonInput.DoubleFieldNan.ProtobufOutput
-Required.JsonInput.DoubleFieldNegativeInfinity.JsonOutput
-Required.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput
-Required.JsonInput.DoubleFieldQuotedValue.JsonOutput
-Required.JsonInput.DoubleFieldQuotedValue.ProtobufOutput
 Required.JsonInput.DurationMaxValue.JsonOutput
 Required.JsonInput.DurationMaxValue.ProtobufOutput
 Required.JsonInput.DurationMinValue.JsonOutput
 Required.JsonInput.DurationMinValue.ProtobufOutput
 Required.JsonInput.DurationRepeatedValue.JsonOutput
 Required.JsonInput.DurationRepeatedValue.ProtobufOutput
-Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput
-Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
-Required.JsonInput.EnumFieldNumericValueZero.JsonOutput
-Required.JsonInput.EnumFieldNumericValueZero.ProtobufOutput
-Required.JsonInput.EnumFieldUnknownValue.Validator
 Required.JsonInput.FieldMask.JsonOutput
 Required.JsonInput.FieldMask.ProtobufOutput
 Required.JsonInput.FloatFieldInfinity.JsonOutput
-Required.JsonInput.FloatFieldInfinity.ProtobufOutput
 Required.JsonInput.FloatFieldNan.JsonOutput
-Required.JsonInput.FloatFieldNan.ProtobufOutput
 Required.JsonInput.FloatFieldNegativeInfinity.JsonOutput
-Required.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput
-Required.JsonInput.FloatFieldQuotedValue.JsonOutput
-Required.JsonInput.FloatFieldQuotedValue.ProtobufOutput
 Required.JsonInput.FloatFieldTooLarge
 Required.JsonInput.FloatFieldTooSmall
-Required.JsonInput.Int32FieldExponentialFormat.JsonOutput
-Required.JsonInput.Int32FieldExponentialFormat.ProtobufOutput
-Required.JsonInput.Int32FieldFloatTrailingZero.JsonOutput
-Required.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
-Required.JsonInput.Int32FieldMaxFloatValue.JsonOutput
-Required.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
-Required.JsonInput.Int32FieldMinFloatValue.JsonOutput
-Required.JsonInput.Int32FieldMinFloatValue.ProtobufOutput
-Required.JsonInput.Int32FieldStringValue.JsonOutput
-Required.JsonInput.Int32FieldStringValue.ProtobufOutput
-Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput
-Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
-Required.JsonInput.Int32MapEscapedKey.JsonOutput
-Required.JsonInput.Int32MapEscapedKey.ProtobufOutput
-Required.JsonInput.Int32MapField.JsonOutput
-Required.JsonInput.Int32MapField.ProtobufOutput
-Required.JsonInput.Int64FieldMaxValue.JsonOutput
-Required.JsonInput.Int64FieldMaxValue.ProtobufOutput
-Required.JsonInput.Int64FieldMinValue.JsonOutput
-Required.JsonInput.Int64FieldMinValue.ProtobufOutput
-Required.JsonInput.Int64MapEscapedKey.JsonOutput
-Required.JsonInput.Int64MapEscapedKey.ProtobufOutput
-Required.JsonInput.Int64MapField.JsonOutput
-Required.JsonInput.Int64MapField.ProtobufOutput
-Required.JsonInput.MessageField.JsonOutput
-Required.JsonInput.MessageField.ProtobufOutput
-Required.JsonInput.MessageMapField.JsonOutput
-Required.JsonInput.MessageMapField.ProtobufOutput
-Required.JsonInput.MessageRepeatedField.JsonOutput
-Required.JsonInput.MessageRepeatedField.ProtobufOutput
+Required.JsonInput.OneofFieldDuplicate
 Required.JsonInput.OptionalBoolWrapper.JsonOutput
 Required.JsonInput.OptionalBoolWrapper.ProtobufOutput
 Required.JsonInput.OptionalBytesWrapper.JsonOutput
@@ -137,15 +80,12 @@
 Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput
 Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
 Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
-Required.JsonInput.PrimitiveRepeatedField.JsonOutput
-Required.JsonInput.PrimitiveRepeatedField.ProtobufOutput
 Required.JsonInput.RepeatedBoolWrapper.JsonOutput
 Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput
 Required.JsonInput.RepeatedBytesWrapper.JsonOutput
 Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput
 Required.JsonInput.RepeatedDoubleWrapper.JsonOutput
 Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput
-Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
 Required.JsonInput.RepeatedFloatWrapper.JsonOutput
 Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput
 Required.JsonInput.RepeatedInt32Wrapper.JsonOutput
@@ -158,7 +98,6 @@
 Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput
 Required.JsonInput.RepeatedUint64Wrapper.JsonOutput
 Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput
-Required.JsonInput.StringFieldNotAString
 Required.JsonInput.StringFieldSurrogatePair.JsonOutput
 Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput
 Required.JsonInput.Struct.JsonOutput
@@ -173,14 +112,6 @@
 Required.JsonInput.TimestampWithNegativeOffset.ProtobufOutput
 Required.JsonInput.TimestampWithPositiveOffset.JsonOutput
 Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput
-Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput
-Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
-Required.JsonInput.Uint32MapField.JsonOutput
-Required.JsonInput.Uint32MapField.ProtobufOutput
-Required.JsonInput.Uint64FieldMaxValue.JsonOutput
-Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput
-Required.JsonInput.Uint64MapField.JsonOutput
-Required.JsonInput.Uint64MapField.ProtobufOutput
 Required.JsonInput.ValueAcceptBool.JsonOutput
 Required.JsonInput.ValueAcceptBool.ProtobufOutput
 Required.JsonInput.ValueAcceptFloat.JsonOutput
@@ -199,5 +130,6 @@
 Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
 Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
 Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.FLOAT.JsonOutput
 Required.TimestampProtoInputTooLarge.JsonOutput
 Required.TimestampProtoInputTooSmall.JsonOutput
diff --git a/csharp/README.md b/csharp/README.md
index 65d2311..c1d1241 100644
--- a/csharp/README.md
+++ b/csharp/README.md
@@ -31,28 +31,23 @@
 Building
 ========
 
-Open the `src/Google.Protobuf.sln` solution in Visual Studio 2015 or
+Open the `src/Google.Protobuf.sln` solution in Visual Studio 2017 or
 later.
 
 Although *users* of this project are only expected to have Visual
 Studio 2012 or later, *developers* of the library are required to
-have Visual Studio 2015 or later, as the library uses C# 6 features
-in its implementation. These features have no impact when using the
-compiled code - they're only relevant when building the
-`Google.Protobuf` assembly.
+have Visual Studio 2017 or later, as the library uses C# 6 features
+in its implementation, as well as the new Visual Studio 2017 csproj 
+format. These features have no impact when using the compiled code - 
+they're only relevant when building the `Google.Protobuf` assembly.
 
 Testing
 =======
 
-The unit tests use [NUnit 3](https://github.com/nunit/nunit). Vanilla NUnit doesn't 
-support .NET Core, so to run the tests you'll need to use 
-[dotnet-test-nunit](https://github.com/nunit/dotnet-test-nunit). 
-`dotnet-test-nunit` can also run tests for .NET 4.5+, so to run the tests 
-for both .NET Core and .NET 4.5, you can simply open the 
-`Package Manager Console` in Visual Studio and execute:
-```
-dotnet test Google.Protobuf.Test
-```
+The unit tests use [NUnit 3](https://github.com/nunit/nunit). NUnit doesn't yet
+support `dotnet test`, so for now the test project is a console application 
+using NUnitLite. Simply run `Google.Protobuf.Test.exe` to run the unit tests 
+directly, or else use `dotnet run`.
 
 .NET 3.5
 ========
@@ -62,35 +57,15 @@
 There's no guarantee that this will continue in the future, so rely on .NET 
 3.5 support at your peril.
 
-To enable .NET 3.5 support:
+To enable .NET 3.5 support, you must edit the `TargetFrameworks` elements of 
+[src/Google.Protobuf/Google.Protobuf.csproj](src/Google.Protobuf/Google.Protobuf.csproj) 
+(and [src/Google.Protobuf.Test/Google.Protobuf.Test.csproj](src/Google.Protobuf.Test/Google.Protobuf.Test.csproj) 
+if you want to run the unit tests): 
 
-1. Modify [src/Google.Protobuf/project.json](src/Google.Protobuf/project.json) to add `"net35": {}` to `"frameworks"`.
-2. Modify [src/Google.Protobuf.Test/project.json](src/Google.Protobuf/project.json):
-  1. Add `"net35": {}` to `"frameworks"`.
-  2. `dotnet-test-nunit` doesn't support .NET 3.5, so remove it from 
-  the project-wide `"dependencies"` and add it to the framework-specific 
-  dependencies under `"net451"` and `"netcoreapp1.0"`.
-
-Note that `dotnet-test-nunit` doesn't support .NET 3.5. You can instead run the 
-tests with [NUnit 3 console](https://github.com/nunit/nunit-console) 
-by running something like: 
-```
-nunit3-console.exe "Google.Protobuf.Test\bin\Debug\net35\win7-x64\Google.Protobuf.Test.dll" --inprocess
-```
-
-The exact path may differ depending on your environment (e.g., the `win7-x64` 
-directory may be called something else). The `--inprocess` flag seems to be a 
-necessary workaround for a bug in NUnit; otherwise, you'll receive 
-an error "Exception has been thrown by the target of an invocation" 
-([possibly related issue](https://github.com/nunit/nunit/issues/1480)).
-
-If you still want to run the .NET 4.5 and .NET Core tests, you can do so by 
-specifying the framework when using `dotnet-test-nunit`, i.e. from 
-`Package Manager Console` in Visual Studio:
-```
-dotnet test Google.Protobuf.Test --framework netcoreapp1.0
-dotnet test Google.Protobuf.Test --framework net451
-```
+Open the .csproj file in a text editor and simply add `net35` to the list of 
+target frameworks, noting that the `TargetFrameworks` element appears twice in 
+the file (once in the first `PropertyGroup` element, and again in the second 
+`PropertyGroup` element, i.e., the one with the conditional).
 
 History of C# protobufs
 =======================
diff --git a/csharp/build_packages.bat b/csharp/build_packages.bat
index 37732e7..d720565 100644
--- a/csharp/build_packages.bat
+++ b/csharp/build_packages.bat
@@ -1,7 +1,7 @@
 @rem Builds Google.Protobuf NuGet packages
 
-dotnet restore src
-dotnet pack -c Release src\Google.Protobuf || goto :error
+dotnet restore src/Google.Protobuf.sln
+dotnet pack -c Release src/Google.Protobuf.sln || goto :error
 
 goto :EOF
 
diff --git a/csharp/buildall.sh b/csharp/buildall.sh
index cab3222..dd4b463 100755
--- a/csharp/buildall.sh
+++ b/csharp/buildall.sh
@@ -6,11 +6,12 @@
 set -ex
 
 echo Building relevant projects.
-dotnet build -c $CONFIG $SRC/Google.Protobuf $SRC/Google.Protobuf.Test $SRC/Google.Protobuf.Conformance
+dotnet restore $SRC/Google.Protobuf.sln
+dotnet build -c $CONFIG $SRC/Google.Protobuf.sln
 
 echo Running tests.
 # Only test netcoreapp1.0, which uses the .NET Core runtime.
 # If we want to test the .NET 4.5 version separately, we could
 # run Mono explicitly. However, we don't have any differences between
 # the .NET 4.5 and netstandard1.0 assemblies.
-dotnet test -c $CONFIG -f netcoreapp1.0 $SRC/Google.Protobuf.Test
+dotnet run -c $CONFIG -f netcoreapp1.0 -p $SRC/Google.Protobuf.Test/Google.Protobuf.Test.csproj
diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedInputStreamTest.cs b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedInputStreamTest.cs
index c0a9ffd..ff44895 100644
--- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedInputStreamTest.cs
+++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedInputStreamTest.cs
@@ -403,7 +403,7 @@
                 output.Flush();

 

                 ms.Position = 0;

-                CodedInputStream input = new CodedInputStream(ms, new byte[ms.Length / 2], 0, 0);

+                CodedInputStream input = new CodedInputStream(ms, new byte[ms.Length / 2], 0, 0, false);

 

                 uint tag = input.ReadTag();

                 Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag));

diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
index 48bf6d6..01bd321 100644
--- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
+++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
@@ -334,7 +334,7 @@
             }

             // Now test Input stream:

             {

-                CodedInputStream cin = new CodedInputStream(new MemoryStream(bytes), new byte[50], 0, 0);

+                CodedInputStream cin = new CodedInputStream(new MemoryStream(bytes), new byte[50], 0, 0, false);

                 Assert.AreEqual(0, cin.Position);

                 // Field 1:

                 uint tag = cin.ReadTag();

diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
new file mode 100644
index 0000000..06d07b9
--- /dev/null
+++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
@@ -0,0 +1,30 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFrameworks>net451;netcoreapp1.0</TargetFrameworks>
+    <AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
+    <SignAssembly>true</SignAssembly>
+    <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
+    <IsPackable>False</IsPackable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="NUnit" Version="3.6.1" />
+    <PackageReference Include="NUnitLite" Version="3.6.1" />
+  </ItemGroup>
+
+  <!-- 
+    - Override target frameworks on non-Windows to just .NET Core
+    - Doing this conditionally in the initial PropertyGroup confuses
+    - Visual Studio.
+    -->
+  <PropertyGroup Condition="'$(OS)' != 'Windows_NT'">
+    <TargetFrameworks>netcoreapp1.0</TargetFrameworks>
+  </PropertyGroup>
+  
+</Project>
diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.xproj b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.xproj
deleted file mode 100644
index a9a1cc0..0000000
--- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.xproj
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>580eb013-d3c7-4578-b845-015f4a3b0591</ProjectGuid>
-    <RootNamespace>Google.Protobuf.Test</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Program.cs b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Program.cs
new file mode 100644
index 0000000..9078e59
--- /dev/null
+++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Program.cs
@@ -0,0 +1,47 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2017 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+using NUnitLite;
+using System.Reflection;
+
+// Note: this file wasn't in the actual 3.0, but is required due to build
+// system changes
+
+namespace Google.Protobuf.Test
+{
+    class Program
+    {
+        public static int Main(string[] args)
+        {
+            return new AutoRun(typeof(Program).GetTypeInfo().Assembly).Execute(args);
+        }
+    }
+}
\ No newline at end of file
diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/project.json b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/project.json
deleted file mode 100644
index 87b732c..0000000
--- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/project.json
+++ /dev/null
@@ -1,44 +0,0 @@
-{
-  "buildOptions": {
-    "debugType": "portable",
-    "keyFile": "../../keys/Google.Protobuf.snk"
-  },
-
-  "configurations": {
-    "Debug": {
-      "buildOptions": {
-        "define": [ "DEBUG", "TRACE" ]
-      }
-    },
-    "Release": {
-      "buildOptions": {
-        "define": [ "RELEASE", "TRACE" ],
-        "optimize": true
-      }
-    }
-  },
-
-  "dependencies": {
-    "Google.Protobuf": { "target": "project" },
-    "NUnit": "3.4.0",
-    "dotnet-test-nunit": "3.4.0-alpha-2",
-  },
-
-  "testRunner": "nunit",
-
-  "frameworks": {
-    "netcoreapp1.0": {
-      "imports" : [ "dnxcore50", "netcoreapp1.0", "portable-net45+win8" ],
-      "buildOptions": {
-        "define": [ "PCL" ]
-      },
-      "dependencies": {
-        "Microsoft.NETCore.App": { 
-          "version": "1.0.0",
-          "type": "platform"
-        },
-        "System.Console": "4.0.0"
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/csharp/compatibility_tests/v3.0.0/test.sh b/csharp/compatibility_tests/v3.0.0/test.sh
index bb04fc2..54d28df 100755
--- a/csharp/compatibility_tests/v3.0.0/test.sh
+++ b/csharp/compatibility_tests/v3.0.0/test.sh
@@ -18,8 +18,11 @@
     protos/src/google/protobuf/map_unittest_proto3.proto
 
   # Build and test.
-  dotnet build -c release src/Google.Protobuf src/Google.Protobuf.Test
-  dotnet test -c release -f netcoreapp1.0 src/Google.Protobuf.Test
+  dotnet restore src/Google.Protobuf/Google.Protobuf.csproj
+  dotnet restore src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
+  dotnet build -c Release src/Google.Protobuf/Google.Protobuf.csproj
+  dotnet build -c Release src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
+  dotnet run -c Release -f netcoreapp1.0 -p src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
 }
 
 set -ex
@@ -72,7 +75,6 @@
 # Copy the new runtime and keys.
 cp ../../src/Google.Protobuf src/Google.Protobuf -r
 cp ../../keys . -r
-dotnet restore
 
 # Test A.1:
 #   proto set 1: use old version
diff --git a/csharp/global.json b/csharp/global.json
new file mode 100644
index 0000000..3622b56
--- /dev/null
+++ b/csharp/global.json
@@ -0,0 +1,5 @@
+{
+  "sdk": {
+    "version": "1.0.0"
+  }
+}
diff --git a/csharp/src/AddressBook/AddressBook.csproj b/csharp/src/AddressBook/AddressBook.csproj
new file mode 100644
index 0000000..6edfdca
--- /dev/null
+++ b/csharp/src/AddressBook/AddressBook.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp1.0</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <StartupObject>Google.Protobuf.Examples.AddressBook.Program</StartupObject>
+    <IsPackable>False</IsPackable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj" />
+  </ItemGroup>
+
+</Project>
diff --git a/csharp/src/AddressBook/AddressBook.xproj b/csharp/src/AddressBook/AddressBook.xproj
deleted file mode 100644
index 4c9925e..0000000
--- a/csharp/src/AddressBook/AddressBook.xproj
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>afb63919-1e05-43b4-802a-8fb8c9b2f463</ProjectGuid>
-    <RootNamespace>AddressBook</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/csharp/src/AddressBook/project.json b/csharp/src/AddressBook/project.json
deleted file mode 100644
index c500bdc..0000000
--- a/csharp/src/AddressBook/project.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "buildOptions": {
-    "debugType": "portable",
-    "emitEntryPoint": true,
-    "additionalArguments": [ "/main:Google.Protobuf.Examples.AddressBook.Program" ]
-  },
-  "dependencies": {
-    "Google.Protobuf": { "target": "project" }
-  },
-  "frameworks": {
-    "netcoreapp1.0": {
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.0"
-        }
-      }
-    }
-  }
-}
diff --git a/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj b/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj
new file mode 100644
index 0000000..b654c0b
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp1.0</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <IsPackable>False</IsPackable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj" />
+    <ProjectReference Include="..\Google.Protobuf.Test\Google.Protobuf.Test.csproj" />
+  </ItemGroup>
+
+</Project>
diff --git a/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.xproj b/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.xproj
deleted file mode 100644
index 99ff146..0000000
--- a/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.xproj
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>dddc055b-e185-4181-bab0-072f0f984569</ProjectGuid>
-    <RootNamespace>Google.Protobuf.Conformance</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Conformance/project.json b/csharp/src/Google.Protobuf.Conformance/project.json
deleted file mode 100644
index 4cf0523..0000000
--- a/csharp/src/Google.Protobuf.Conformance/project.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "buildOptions": {
-    "debugType": "portable",
-    "emitEntryPoint": true
-  },
-  "dependencies": {
-    "Google.Protobuf": { "target": "project" },
-    "Google.Protobuf.Test": { "target": "project" }
-  },
-  "frameworks": {
-    "netcoreapp1.0": {
-      "imports": [ "dnxcore50", "netcoreapp1.0", "portable-net45+win8" ],
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.0"
-        }
-      }
-    }
-  }
-}
diff --git a/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj b/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj
new file mode 100644
index 0000000..4eda641
--- /dev/null
+++ b/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp1.0</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <IsPackable>False</IsPackable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj" />
+  </ItemGroup>
+
+</Project>
diff --git a/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.xproj b/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.xproj
deleted file mode 100644
index 27095be..0000000
--- a/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.xproj
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>9695e08f-9829-497d-b95c-b38f28d48690</ProjectGuid>
-    <RootNamespace>Google.Protobuf.JsonDump</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.JsonDump/project.json b/csharp/src/Google.Protobuf.JsonDump/project.json
deleted file mode 100644
index 84b23c4..0000000
--- a/csharp/src/Google.Protobuf.JsonDump/project.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "buildOptions": {
-    "debugType": "portable",
-    "emitEntryPoint": true
-  },
-  "dependencies": {
-    "Google.Protobuf": { "target": "project" }
-  },
-  "frameworks": {
-    "netcoreapp1.0": {
-      "dependencies": {
-        "Microsoft.NETCore.App": {
-          "type": "platform",
-          "version": "1.0.0"
-        }
-      }
-    }
-  }
-}
diff --git a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
index c0a9ffd..e719d2a 100644
--- a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
+++ b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
@@ -403,7 +403,7 @@
                 output.Flush();

 

                 ms.Position = 0;

-                CodedInputStream input = new CodedInputStream(ms, new byte[ms.Length / 2], 0, 0);

+                CodedInputStream input = new CodedInputStream(ms, new byte[ms.Length / 2], 0, 0, false);

 

                 uint tag = input.ReadTag();

                 Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag));

@@ -594,5 +594,12 @@
             }

             Assert.IsTrue(memoryStream.CanRead); // We left the stream open

         }

+

+        [Test]

+        public void Dispose_FromByteArray()

+        {

+            var stream = new CodedInputStream(new byte[10]);

+            stream.Dispose();

+        }

     }

 }
\ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs b/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
index 48bf6d6..98cabd5 100644
--- a/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
+++ b/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
@@ -334,7 +334,7 @@
             }

             // Now test Input stream:

             {

-                CodedInputStream cin = new CodedInputStream(new MemoryStream(bytes), new byte[50], 0, 0);

+                CodedInputStream cin = new CodedInputStream(new MemoryStream(bytes), new byte[50], 0, 0, false);

                 Assert.AreEqual(0, cin.Position);

                 // Field 1:

                 uint tag = cin.ReadTag();

@@ -415,5 +415,12 @@
             Assert.AreEqual(1, memoryStream.Position); // Flushed data from CodedOutputStream to MemoryStream

             Assert.IsTrue(memoryStream.CanWrite); // We left the stream open

         }

+

+        [Test]

+        public void Dispose_FromByteArray()

+        {

+            var stream = new CodedOutputStream(new byte[10]);

+            stream.Dispose();

+        }

     }

 }
\ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
index 9d3d69a..68b4de4 100644
--- a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
@@ -540,6 +540,22 @@
             Assert.Throws<ArgumentException>(() => map.ToString());
         }
 
+#if !NET35
+        [Test]
+        public void IDictionaryKeys_Equals_IReadOnlyDictionaryKeys()
+        {
+            var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
+            CollectionAssert.AreEquivalent(((IDictionary<string, string>)map).Keys, ((IReadOnlyDictionary<string, string>)map).Keys);
+        }
+
+        [Test]
+        public void IDictionaryValues_Equals_IReadOnlyDictionaryValues()
+        {
+            var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
+            CollectionAssert.AreEquivalent(((IDictionary<string, string>)map).Values, ((IReadOnlyDictionary<string, string>)map).Values);
+        }
+#endif
+
         private static KeyValuePair<TKey, TValue> NewKeyValuePair<TKey, TValue>(TKey key, TValue value)
         {
             return new KeyValuePair<TKey, TValue>(key, value);
diff --git a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
new file mode 100644
index 0000000..06d07b9
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
@@ -0,0 +1,30 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFrameworks>net451;netcoreapp1.0</TargetFrameworks>
+    <AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
+    <SignAssembly>true</SignAssembly>
+    <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
+    <IsPackable>False</IsPackable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="NUnit" Version="3.6.1" />
+    <PackageReference Include="NUnitLite" Version="3.6.1" />
+  </ItemGroup>
+
+  <!-- 
+    - Override target frameworks on non-Windows to just .NET Core
+    - Doing this conditionally in the initial PropertyGroup confuses
+    - Visual Studio.
+    -->
+  <PropertyGroup Condition="'$(OS)' != 'Windows_NT'">
+    <TargetFrameworks>netcoreapp1.0</TargetFrameworks>
+  </PropertyGroup>
+  
+</Project>
diff --git a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.xproj b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.xproj
deleted file mode 100644
index 6370441..0000000
--- a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.xproj
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>580eb013-d3c7-4578-b845-015f4a3b0591</ProjectGuid>
-    <RootNamespace>Google.Protobuf.Test</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
-  </ItemGroup>
-  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/Program.cs b/csharp/src/Google.Protobuf.Test/Program.cs
new file mode 100755
index 0000000..954c02b
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Test/Program.cs
@@ -0,0 +1,48 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2017 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+using NUnitLite;
+using System.Reflection;
+
+namespace Google.Protobuf.Test
+{
+    class Program
+    {
+        public static int Main(string[] args)
+        {
+            #if NET35
+                return new AutoRun(typeof(Program).Assembly).Execute(args);

+            #else
+                return new AutoRun(typeof(Program).GetTypeInfo().Assembly).Execute(args);
+            #endif
+        }
+    }
+}
\ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
index 4aecc99..a3edd59 100644
--- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
@@ -91,6 +91,24 @@
         }
 
         [Test]
+        public void TryUnpack_WrongType()
+        {
+            var message = SampleMessages.CreateFullTestAllTypes();
+            var any = Any.Pack(message);
+            Assert.False(any.TryUnpack(out TestOneof unpacked));
+            Assert.Null(unpacked);
+        }
+
+        [Test]
+        public void TryUnpack_RightType()
+        {
+            var message = SampleMessages.CreateFullTestAllTypes();
+            var any = Any.Pack(message);
+            Assert.IsTrue(any.TryUnpack(out TestAllTypes unpacked));
+            Assert.AreEqual(message, unpacked);
+        }
+
+        [Test]
         public void ToString_WithValues()
         {
             var message = SampleMessages.CreateFullTestAllTypes();
@@ -100,6 +118,16 @@
         }
 
         [Test]
+        [TestCase("proto://foo.bar", "foo.bar")]
+        [TestCase("/foo/bar/baz", "baz")]
+        [TestCase("foobar", "")]
+        public void GetTypeName(string typeUrl, string expectedTypeName)
+        {
+            var any = new Any { TypeUrl = typeUrl };
+            Assert.AreEqual(expectedTypeName, Any.GetTypeName(typeUrl));
+        }
+
+        [Test]
         public void ToString_Empty()
         {
             var any = new Any();
diff --git a/csharp/src/Google.Protobuf.Test/project.json b/csharp/src/Google.Protobuf.Test/project.json
deleted file mode 100644
index dff0ab7..0000000
--- a/csharp/src/Google.Protobuf.Test/project.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
-  "buildOptions": {
-    "debugType": "portable",
-    "keyFile": "../../keys/Google.Protobuf.snk"
-  },
-
-  "configurations": {
-    "Debug": {
-      "buildOptions": {
-        "define": [ "DEBUG", "TRACE" ]
-      }
-    },
-    "Release": {
-      "buildOptions": {
-        "define": [ "RELEASE", "TRACE" ],
-        "optimize": true
-      }
-    }
-  },
-
-  "dependencies": {
-    "Google.Protobuf": { "target": "project" },
-    "dotnet-test-nunit": "3.4.0-beta-3",
-    "NUnit": "3.6.0"
-  },
-
-  "testRunner": "nunit",
-
-  "frameworks": {
-    "net451": {},
-    "netcoreapp1.0": {
-      "imports" : [ "dnxcore50", "netcoreapp1.0", "portable-net45+win8" ],
-      "buildOptions": {
-        "define": [ "PCL" ]
-      },
-      "dependencies": {
-        "Microsoft.NETCore.App": { 
-          "version": "1.0.0",
-          "type": "platform"
-        },
-        "System.Console": "4.0.0"
-      }
-    }
-  }
-}
diff --git a/csharp/src/Google.Protobuf.sln b/csharp/src/Google.Protobuf.sln
index 3c62bba..443ee3e 100644
--- a/csharp/src/Google.Protobuf.sln
+++ b/csharp/src/Google.Protobuf.sln
@@ -1,16 +1,16 @@
 Microsoft Visual Studio Solution File, Format Version 12.00

-# Visual Studio 14

-VisualStudioVersion = 14.0.25420.1

-MinimumVisualStudioVersion = 14.0.24720.0

-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "AddressBook", "AddressBook\AddressBook.xproj", "{AFB63919-1E05-43B4-802A-8FB8C9B2F463}"

+# Visual Studio 15

+VisualStudioVersion = 15.0.26114.2

+MinimumVisualStudioVersion = 10.0.40219.1

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddressBook", "AddressBook\AddressBook.csproj", "{AFB63919-1E05-43B4-802A-8FB8C9B2F463}"

 EndProject

-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Google.Protobuf", "Google.Protobuf\Google.Protobuf.xproj", "{9B576380-726D-4142-8238-60A43AB0E35A}"

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf", "Google.Protobuf\Google.Protobuf.csproj", "{9B576380-726D-4142-8238-60A43AB0E35A}"

 EndProject

-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Google.Protobuf.Test", "Google.Protobuf.Test\Google.Protobuf.Test.xproj", "{580EB013-D3C7-4578-B845-015F4A3B0591}"

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Test", "Google.Protobuf.Test\Google.Protobuf.Test.csproj", "{580EB013-D3C7-4578-B845-015F4A3B0591}"

 EndProject

-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Google.Protobuf.Conformance", "Google.Protobuf.Conformance\Google.Protobuf.Conformance.xproj", "{DDDC055B-E185-4181-BAB0-072F0F984569}"

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Conformance", "Google.Protobuf.Conformance\Google.Protobuf.Conformance.csproj", "{DDDC055B-E185-4181-BAB0-072F0F984569}"

 EndProject

-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Google.Protobuf.JsonDump", "Google.Protobuf.JsonDump\Google.Protobuf.JsonDump.xproj", "{9695E08F-9829-497D-B95C-B38F28D48690}"

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.JsonDump", "Google.Protobuf.JsonDump\Google.Protobuf.JsonDump.csproj", "{9695E08F-9829-497D-B95C-B38F28D48690}"

 EndProject

 Global

 	GlobalSection(SolutionConfigurationPlatforms) = preSolution

diff --git a/csharp/src/Google.Protobuf/CodedInputStream.cs b/csharp/src/Google.Protobuf/CodedInputStream.cs
index 072e2e1..84f90a2 100644
--- a/csharp/src/Google.Protobuf/CodedInputStream.cs
+++ b/csharp/src/Google.Protobuf/CodedInputStream.cs
@@ -121,7 +121,7 @@
         /// <summary>

         /// Creates a new CodedInputStream reading data from the given byte array.

         /// </summary>

-        public CodedInputStream(byte[] buffer) : this(null, ProtoPreconditions.CheckNotNull(buffer, "buffer"), 0, buffer.Length)

+        public CodedInputStream(byte[] buffer) : this(null, ProtoPreconditions.CheckNotNull(buffer, "buffer"), 0, buffer.Length, true)

         {            

         }

 

@@ -129,7 +129,7 @@
         /// Creates a new <see cref="CodedInputStream"/> that reads from the given byte array slice.

         /// </summary>

         public CodedInputStream(byte[] buffer, int offset, int length)

-            : this(null, ProtoPreconditions.CheckNotNull(buffer, "buffer"), offset, offset + length)

+            : this(null, ProtoPreconditions.CheckNotNull(buffer, "buffer"), offset, offset + length, true)

         {            

             if (offset < 0 || offset > buffer.Length)

             {

@@ -158,16 +158,15 @@
         /// <c cref="CodedInputStream"/> is disposed; <c>false</c> to dispose of the given stream when the

         /// returned object is disposed.</param>

         public CodedInputStream(Stream input, bool leaveOpen)

-            : this(ProtoPreconditions.CheckNotNull(input, "input"), new byte[BufferSize], 0, 0)

+            : this(ProtoPreconditions.CheckNotNull(input, "input"), new byte[BufferSize], 0, 0, leaveOpen)

         {

-            this.leaveOpen = leaveOpen;

         }

         

         /// <summary>

         /// Creates a new CodedInputStream reading data from the given

         /// stream and buffer, using the default limits.

         /// </summary>

-        internal CodedInputStream(Stream input, byte[] buffer, int bufferPos, int bufferSize)

+        internal CodedInputStream(Stream input, byte[] buffer, int bufferPos, int bufferSize, bool leaveOpen)

         {

             this.input = input;

             this.buffer = buffer;

@@ -175,6 +174,7 @@
             this.bufferSize = bufferSize;

             this.sizeLimit = DefaultSizeLimit;

             this.recursionLimit = DefaultRecursionLimit;

+            this.leaveOpen = leaveOpen;

         }

 

         /// <summary>

@@ -185,8 +185,8 @@
         /// This chains to the version with the default limits instead of vice versa to avoid

         /// having to check that the default values are valid every time.

         /// </remarks>

-        internal CodedInputStream(Stream input, byte[] buffer, int bufferPos, int bufferSize, int sizeLimit, int recursionLimit)

-            : this(input, buffer, bufferPos, bufferSize)

+        internal CodedInputStream(Stream input, byte[] buffer, int bufferPos, int bufferSize, int sizeLimit, int recursionLimit, bool leaveOpen)

+            : this(input, buffer, bufferPos, bufferSize, leaveOpen)

         {

             if (sizeLimit <= 0)

             {

@@ -217,7 +217,8 @@
         /// and recursion limits.</returns>

         public static CodedInputStream CreateWithLimits(Stream input, int sizeLimit, int recursionLimit)

         {

-            return new CodedInputStream(input, new byte[BufferSize], 0, 0, sizeLimit, recursionLimit);

+            // Note: we may want an overload accepting leaveOpen

+            return new CodedInputStream(input, new byte[BufferSize], 0, 0, sizeLimit, recursionLimit, false);

         }

 

         /// <summary>

diff --git a/csharp/src/Google.Protobuf/Collections/MapField.cs b/csharp/src/Google.Protobuf/Collections/MapField.cs
index ef5651c..8dac8e3 100644
--- a/csharp/src/Google.Protobuf/Collections/MapField.cs
+++ b/csharp/src/Google.Protobuf/Collections/MapField.cs
@@ -67,6 +67,9 @@
     /// </para>
     /// </remarks>
     public sealed class MapField<TKey, TValue> : IDeepCloneable<MapField<TKey, TValue>>, IDictionary<TKey, TValue>, IEquatable<MapField<TKey, TValue>>, IDictionary
+#if !NET35
+        , IReadOnlyDictionary<TKey, TValue>
+#endif
     {
         // TODO: Don't create the map/list until we have an entry. (Assume many maps will be empty.)
         private readonly Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>> map =
@@ -548,6 +551,14 @@
         }
         #endregion
 
+        #region IReadOnlyDictionary explicit interface implementation
+#if !NET35
+        IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys => Keys;
+
+        IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values => Values;
+#endif
+        #endregion
+
         private class DictionaryEnumerator : IDictionaryEnumerator
         {
             private readonly IEnumerator<KeyValuePair<TKey, TValue>> enumerator;
diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
new file mode 100644
index 0000000..46418e3
--- /dev/null
+++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
@@ -0,0 +1,33 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <Description>C# runtime library for Protocol Buffers - Google's data interchange format.</Description>
+    <Copyright>Copyright 2015, Google Inc.</Copyright>
+    <AssemblyTitle>Google Protocol Buffers</AssemblyTitle>
+    <VersionPrefix>3.3.0</VersionPrefix>
+    <Authors>Google Inc.</Authors>
+    <TargetFrameworks>netstandard1.0;net451</TargetFrameworks>
+    <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/google/protobuf</PackageProjectUrl>
+    <PackageLicenseUrl>https://github.com/google/protobuf/blob/master/LICENSE</PackageLicenseUrl>
+    <RepositoryType>git</RepositoryType>
+    <RepositoryUrl>https://github.com/google/protobuf.git</RepositoryUrl>
+    <IncludeSymbols>true</IncludeSymbols>
+    <IncludeSource>true</IncludeSource>
+  </PropertyGroup>
+
+  <!-- 
+    - Override target frameworks on non-Windows to just .NET Core
+    - Doing this conditionally in the initial PropertyGroup confuses
+    - Visual Studio.
+    -->
+  <PropertyGroup Condition="'$(OS)' != 'Windows_NT'">
+    <TargetFrameworks>netstandard1.0</TargetFrameworks>
+  </PropertyGroup>
+
+</Project>
diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.xproj b/csharp/src/Google.Protobuf/Google.Protobuf.xproj
deleted file mode 100644
index c68e0db..0000000
--- a/csharp/src/Google.Protobuf/Google.Protobuf.xproj
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>9b576380-726d-4142-8238-60a43ab0e35a</ProjectGuid>
-    <RootNamespace>Google.Protobuf</RootNamespace>
-    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
-    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
-  </PropertyGroup>
-
-  <PropertyGroup>
-    <SchemaVersion>2.0</SchemaVersion>
-  </PropertyGroup>
-  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
-</Project>
\ No newline at end of file
diff --git a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
index 472310d..8311a2c 100644
--- a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
@@ -83,7 +83,7 @@
             "bmFtZRgBIAEoCRISCgppbnB1dF90eXBlGAIgASgJEhMKC291dHB1dF90eXBl",
             "GAMgASgJEi8KB29wdGlvbnMYBCABKAsyHi5nb29nbGUucHJvdG9idWYuTWV0",
             "aG9kT3B0aW9ucxIfChBjbGllbnRfc3RyZWFtaW5nGAUgASgIOgVmYWxzZRIf",
-            "ChBzZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVmYWxzZSK0BQoLRmlsZU9wdGlv",
+            "ChBzZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVmYWxzZSLwBQoLRmlsZU9wdGlv",
             "bnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwKFGphdmFfb3V0ZXJfY2xhc3Nu",
             "YW1lGAggASgJEiIKE2phdmFfbXVsdGlwbGVfZmlsZXMYCiABKAg6BWZhbHNl",
             "EikKHWphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoGBQgASgIQgIYARIl",
@@ -92,64 +92,66 @@
             "T3B0aW1pemVNb2RlOgVTUEVFRBISCgpnb19wYWNrYWdlGAsgASgJEiIKE2Nj",
             "X2dlbmVyaWNfc2VydmljZXMYECABKAg6BWZhbHNlEiQKFWphdmFfZ2VuZXJp",
             "Y19zZXJ2aWNlcxgRIAEoCDoFZmFsc2USIgoTcHlfZ2VuZXJpY19zZXJ2aWNl",
-            "cxgSIAEoCDoFZmFsc2USGQoKZGVwcmVjYXRlZBgXIAEoCDoFZmFsc2USHwoQ",
-            "Y2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoFZmFsc2USGQoRb2JqY19jbGFzc19w",
-            "cmVmaXgYJCABKAkSGAoQY3NoYXJwX25hbWVzcGFjZRglIAEoCRIUCgxzd2lm",
-            "dF9wcmVmaXgYJyABKAkSGAoQcGhwX2NsYXNzX3ByZWZpeBgoIAEoCRJDChR1",
-            "bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYu",
-            "VW5pbnRlcnByZXRlZE9wdGlvbiI6CgxPcHRpbWl6ZU1vZGUSCQoFU1BFRUQQ",
-            "ARINCglDT0RFX1NJWkUQAhIQCgxMSVRFX1JVTlRJTUUQAyoJCOgHEICAgIAC",
-            "SgQIJhAnIvIBCg5NZXNzYWdlT3B0aW9ucxImChdtZXNzYWdlX3NldF93aXJl",
-            "X2Zvcm1hdBgBIAEoCDoFZmFsc2USLgofbm9fc3RhbmRhcmRfZGVzY3JpcHRv",
-            "cl9hY2Nlc3NvchgCIAEoCDoFZmFsc2USGQoKZGVwcmVjYXRlZBgDIAEoCDoF",
-            "ZmFsc2USEQoJbWFwX2VudHJ5GAcgASgIEkMKFHVuaW50ZXJwcmV0ZWRfb3B0",
+            "cxgSIAEoCDoFZmFsc2USIwoUcGhwX2dlbmVyaWNfc2VydmljZXMYEyABKAg6",
+            "BWZhbHNlEhkKCmRlcHJlY2F0ZWQYFyABKAg6BWZhbHNlEh8KEGNjX2VuYWJs",
+            "ZV9hcmVuYXMYHyABKAg6BWZhbHNlEhkKEW9iamNfY2xhc3NfcHJlZml4GCQg",
+            "ASgJEhgKEGNzaGFycF9uYW1lc3BhY2UYJSABKAkSFAoMc3dpZnRfcHJlZml4",
+            "GCcgASgJEhgKEHBocF9jbGFzc19wcmVmaXgYKCABKAkSFQoNcGhwX25hbWVz",
+            "cGFjZRgpIAEoCRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5n",
+            "b29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiI6CgxPcHRpbWl6",
+            "ZU1vZGUSCQoFU1BFRUQQARINCglDT0RFX1NJWkUQAhIQCgxMSVRFX1JVTlRJ",
+            "TUUQAyoJCOgHEICAgIACSgQIJhAnIvIBCg5NZXNzYWdlT3B0aW9ucxImChdt",
+            "ZXNzYWdlX3NldF93aXJlX2Zvcm1hdBgBIAEoCDoFZmFsc2USLgofbm9fc3Rh",
+            "bmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2USGQoKZGVw",
+            "cmVjYXRlZBgDIAEoCDoFZmFsc2USEQoJbWFwX2VudHJ5GAcgASgIEkMKFHVu",
+            "aW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5V",
+            "bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgIEAlKBAgJEAoingMK",
+            "DEZpZWxkT3B0aW9ucxI6CgVjdHlwZRgBIAEoDjIjLmdvb2dsZS5wcm90b2J1",
+            "Zi5GaWVsZE9wdGlvbnMuQ1R5cGU6BlNUUklORxIOCgZwYWNrZWQYAiABKAgS",
+            "PwoGanN0eXBlGAYgASgOMiQuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9u",
+            "cy5KU1R5cGU6CUpTX05PUk1BTBITCgRsYXp5GAUgASgIOgVmYWxzZRIZCgpk",
+            "ZXByZWNhdGVkGAMgASgIOgVmYWxzZRITCgR3ZWFrGAogASgIOgVmYWxzZRJD",
+            "ChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9i",
+            "dWYuVW5pbnRlcnByZXRlZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABII",
+            "CgRDT1JEEAESEAoMU1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05P",
+            "Uk1BTBAAEg0KCUpTX1NUUklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICA",
+            "gAJKBAgEEAUiXgoMT25lb2ZPcHRpb25zEkMKFHVuaW50ZXJwcmV0ZWRfb3B0",
             "aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0",
-            "aW9uKgkI6AcQgICAgAJKBAgIEAlKBAgJEAoingMKDEZpZWxkT3B0aW9ucxI6",
-            "CgVjdHlwZRgBIAEoDjIjLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMu",
-            "Q1R5cGU6BlNUUklORxIOCgZwYWNrZWQYAiABKAgSPwoGanN0eXBlGAYgASgO",
-            "MiQuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5KU1R5cGU6CUpTX05P",
-            "Uk1BTBITCgRsYXp5GAUgASgIOgVmYWxzZRIZCgpkZXByZWNhdGVkGAMgASgI",
-            "OgVmYWxzZRITCgR3ZWFrGAogASgIOgVmYWxzZRJDChR1bmludGVycHJldGVk",
-            "X29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRl",
-            "ZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABIICgRDT1JEEAESEAoMU1RS",
-            "SU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05PUk1BTBAAEg0KCUpTX1NU",
-            "UklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICAgAJKBAgEEAUiXgoMT25l",
-            "b2ZPcHRpb25zEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdv",
-            "b2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIi",
-            "kwEKC0VudW1PcHRpb25zEhMKC2FsbG93X2FsaWFzGAIgASgIEhkKCmRlcHJl",
-            "Y2F0ZWQYAyABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcH",
-            "IAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI",
-            "6AcQgICAgAJKBAgFEAYifQoQRW51bVZhbHVlT3B0aW9ucxIZCgpkZXByZWNh",
-            "dGVkGAEgASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByAD",
-            "KAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgH",
-            "EICAgIACInsKDlNlcnZpY2VPcHRpb25zEhkKCmRlcHJlY2F0ZWQYISABKAg6",
-            "BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2ds",
-            "ZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIirQIK",
-            "DU1ldGhvZE9wdGlvbnMSGQoKZGVwcmVjYXRlZBghIAEoCDoFZmFsc2USXwoR",
-            "aWRlbXBvdGVuY3lfbGV2ZWwYIiABKA4yLy5nb29nbGUucHJvdG9idWYuTWV0",
-            "aG9kT3B0aW9ucy5JZGVtcG90ZW5jeUxldmVsOhNJREVNUE9URU5DWV9VTktO",
-            "T1dOEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5w",
-            "cm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIlAKEElkZW1wb3RlbmN5TGV2",
-            "ZWwSFwoTSURFTVBPVEVOQ1lfVU5LTk9XThAAEhMKD05PX1NJREVfRUZGRUNU",
-            "UxABEg4KCklERU1QT1RFTlQQAioJCOgHEICAgIACIp4CChNVbmludGVycHJl",
-            "dGVkT3B0aW9uEjsKBG5hbWUYAiADKAsyLS5nb29nbGUucHJvdG9idWYuVW5p",
-            "bnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydBIYChBpZGVudGlmaWVyX3ZhbHVl",
-            "GAMgASgJEhoKEnBvc2l0aXZlX2ludF92YWx1ZRgEIAEoBBIaChJuZWdhdGl2",
-            "ZV9pbnRfdmFsdWUYBSABKAMSFAoMZG91YmxlX3ZhbHVlGAYgASgBEhQKDHN0",
-            "cmluZ192YWx1ZRgHIAEoDBIXCg9hZ2dyZWdhdGVfdmFsdWUYCCABKAkaMwoI",
-            "TmFtZVBhcnQSEQoJbmFtZV9wYXJ0GAEgAigJEhQKDGlzX2V4dGVuc2lvbhgC",
-            "IAIoCCLVAQoOU291cmNlQ29kZUluZm8SOgoIbG9jYXRpb24YASADKAsyKC5n",
-            "b29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ahgEKCExv",
-            "Y2F0aW9uEhAKBHBhdGgYASADKAVCAhABEhAKBHNwYW4YAiADKAVCAhABEhgK",
-            "EGxlYWRpbmdfY29tbWVudHMYAyABKAkSGQoRdHJhaWxpbmdfY29tbWVudHMY",
-            "BCABKAkSIQoZbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMoCSKnAQoR",
-            "R2VuZXJhdGVkQ29kZUluZm8SQQoKYW5ub3RhdGlvbhgBIAMoCzItLmdvb2ds",
-            "ZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uGk8KCkFu",
-            "bm90YXRpb24SEAoEcGF0aBgBIAMoBUICEAESEwoLc291cmNlX2ZpbGUYAiAB",
-            "KAkSDQoFYmVnaW4YAyABKAUSCwoDZW5kGAQgASgFQowBChNjb20uZ29vZ2xl",
-            "LnByb3RvYnVmQhBEZXNjcmlwdG9yUHJvdG9zSAFaPmdpdGh1Yi5jb20vZ29s",
-            "YW5nL3Byb3RvYnVmL3Byb3RvYy1nZW4tZ28vZGVzY3JpcHRvcjtkZXNjcmlw",
-            "dG9yogIDR1BCqgIaR29vZ2xlLlByb3RvYnVmLlJlZmxlY3Rpb24="));
+            "aW9uKgkI6AcQgICAgAIikwEKC0VudW1PcHRpb25zEhMKC2FsbG93X2FsaWFz",
+            "GAIgASgIEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEkMKFHVuaW50ZXJw",
+            "cmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVy",
+            "cHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgFEAYifQoQRW51bVZhbHVlT3B0",
+            "aW9ucxIZCgpkZXByZWNhdGVkGAEgASgIOgVmYWxzZRJDChR1bmludGVycHJl",
+            "dGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnBy",
+            "ZXRlZE9wdGlvbioJCOgHEICAgIACInsKDlNlcnZpY2VPcHRpb25zEhkKCmRl",
+            "cHJlY2F0ZWQYISABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9u",
+            "GOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9u",
+            "KgkI6AcQgICAgAIirQIKDU1ldGhvZE9wdGlvbnMSGQoKZGVwcmVjYXRlZBgh",
+            "IAEoCDoFZmFsc2USXwoRaWRlbXBvdGVuY3lfbGV2ZWwYIiABKA4yLy5nb29n",
+            "bGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucy5JZGVtcG90ZW5jeUxldmVsOhNJ",
+            "REVNUE9URU5DWV9VTktOT1dOEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcH",
+            "IAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIlAK",
+            "EElkZW1wb3RlbmN5TGV2ZWwSFwoTSURFTVBPVEVOQ1lfVU5LTk9XThAAEhMK",
+            "D05PX1NJREVfRUZGRUNUUxABEg4KCklERU1QT1RFTlQQAioJCOgHEICAgIAC",
+            "Ip4CChNVbmludGVycHJldGVkT3B0aW9uEjsKBG5hbWUYAiADKAsyLS5nb29n",
+            "bGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydBIYChBp",
+            "ZGVudGlmaWVyX3ZhbHVlGAMgASgJEhoKEnBvc2l0aXZlX2ludF92YWx1ZRgE",
+            "IAEoBBIaChJuZWdhdGl2ZV9pbnRfdmFsdWUYBSABKAMSFAoMZG91YmxlX3Zh",
+            "bHVlGAYgASgBEhQKDHN0cmluZ192YWx1ZRgHIAEoDBIXCg9hZ2dyZWdhdGVf",
+            "dmFsdWUYCCABKAkaMwoITmFtZVBhcnQSEQoJbmFtZV9wYXJ0GAEgAigJEhQK",
+            "DGlzX2V4dGVuc2lvbhgCIAIoCCLVAQoOU291cmNlQ29kZUluZm8SOgoIbG9j",
+            "YXRpb24YASADKAsyKC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8u",
+            "TG9jYXRpb24ahgEKCExvY2F0aW9uEhAKBHBhdGgYASADKAVCAhABEhAKBHNw",
+            "YW4YAiADKAVCAhABEhgKEGxlYWRpbmdfY29tbWVudHMYAyABKAkSGQoRdHJh",
+            "aWxpbmdfY29tbWVudHMYBCABKAkSIQoZbGVhZGluZ19kZXRhY2hlZF9jb21t",
+            "ZW50cxgGIAMoCSKnAQoRR2VuZXJhdGVkQ29kZUluZm8SQQoKYW5ub3RhdGlv",
+            "bhgBIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5B",
+            "bm5vdGF0aW9uGk8KCkFubm90YXRpb24SEAoEcGF0aBgBIAMoBUICEAESEwoL",
+            "c291cmNlX2ZpbGUYAiABKAkSDQoFYmVnaW4YAyABKAUSCwoDZW5kGAQgASgF",
+            "QowBChNjb20uZ29vZ2xlLnByb3RvYnVmQhBEZXNjcmlwdG9yUHJvdG9zSAFa",
+            "PmdpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvYy1nZW4tZ28vZGVz",
+            "Y3JpcHRvcjtkZXNjcmlwdG9yogIDR1BCqgIaR29vZ2xlLlByb3RvYnVmLlJl",
+            "ZmxlY3Rpb24="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
@@ -164,7 +166,7 @@
             new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueDescriptorProto), global::Google.Protobuf.Reflection.EnumValueDescriptorProto.Parser, new[]{ "Name", "Number", "Options" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceDescriptorProto), global::Google.Protobuf.Reflection.ServiceDescriptorProto.Parser, new[]{ "Name", "Method", "Options" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodDescriptorProto), global::Google.Protobuf.Reflection.MethodDescriptorProto.Parser, new[]{ "Name", "InputType", "OutputType", "Options", "ClientStreaming", "ServerStreaming" }, null, null, null),
-            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "SwiftPrefix", "PhpClassPrefix", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "PhpGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "SwiftPrefix", "PhpClassPrefix", "PhpNamespace", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MessageOptions), global::Google.Protobuf.Reflection.MessageOptions.Parser, new[]{ "MessageSetWireFormat", "NoStandardDescriptorAccessor", "Deprecated", "MapEntry", "UninterpretedOption" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions), global::Google.Protobuf.Reflection.FieldOptions.Parser, new[]{ "Ctype", "Packed", "Jstype", "Lazy", "Deprecated", "Weak", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.CType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.JSType) }, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofOptions), global::Google.Protobuf.Reflection.OneofOptions.Parser, new[]{ "UninterpretedOption" }, null, null, null),
@@ -2954,12 +2956,14 @@
       ccGenericServices_ = other.ccGenericServices_;
       javaGenericServices_ = other.javaGenericServices_;
       pyGenericServices_ = other.pyGenericServices_;
+      phpGenericServices_ = other.phpGenericServices_;
       deprecated_ = other.deprecated_;
       ccEnableArenas_ = other.ccEnableArenas_;
       objcClassPrefix_ = other.objcClassPrefix_;
       csharpNamespace_ = other.csharpNamespace_;
       swiftPrefix_ = other.swiftPrefix_;
       phpClassPrefix_ = other.phpClassPrefix_;
+      phpNamespace_ = other.phpNamespace_;
       uninterpretedOption_ = other.uninterpretedOption_.Clone();
     }
 
@@ -3130,6 +3134,17 @@
       }
     }
 
+    /// <summary>Field number for the "php_generic_services" field.</summary>
+    public const int PhpGenericServicesFieldNumber = 19;
+    private bool phpGenericServices_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool PhpGenericServices {
+      get { return phpGenericServices_; }
+      set {
+        phpGenericServices_ = value;
+      }
+    }
+
     /// <summary>Field number for the "deprecated" field.</summary>
     public const int DeprecatedFieldNumber = 23;
     private bool deprecated_;
@@ -3223,6 +3238,22 @@
       }
     }
 
+    /// <summary>Field number for the "php_namespace" field.</summary>
+    public const int PhpNamespaceFieldNumber = 41;
+    private string phpNamespace_ = "";
+    /// <summary>
+    /// Use this option to change the namespace of php generated classes. Default
+    /// is empty. When this option is empty, the package name will be used for
+    /// determining the namespace.
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string PhpNamespace {
+      get { return phpNamespace_; }
+      set {
+        phpNamespace_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
     /// <summary>Field number for the "uninterpreted_option" field.</summary>
     public const int UninterpretedOptionFieldNumber = 999;
     private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption> _repeated_uninterpretedOption_codec
@@ -3259,12 +3290,14 @@
       if (CcGenericServices != other.CcGenericServices) return false;
       if (JavaGenericServices != other.JavaGenericServices) return false;
       if (PyGenericServices != other.PyGenericServices) return false;
+      if (PhpGenericServices != other.PhpGenericServices) return false;
       if (Deprecated != other.Deprecated) return false;
       if (CcEnableArenas != other.CcEnableArenas) return false;
       if (ObjcClassPrefix != other.ObjcClassPrefix) return false;
       if (CsharpNamespace != other.CsharpNamespace) return false;
       if (SwiftPrefix != other.SwiftPrefix) return false;
       if (PhpClassPrefix != other.PhpClassPrefix) return false;
+      if (PhpNamespace != other.PhpNamespace) return false;
       if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false;
       return true;
     }
@@ -3282,12 +3315,14 @@
       if (CcGenericServices != false) hash ^= CcGenericServices.GetHashCode();
       if (JavaGenericServices != false) hash ^= JavaGenericServices.GetHashCode();
       if (PyGenericServices != false) hash ^= PyGenericServices.GetHashCode();
+      if (PhpGenericServices != false) hash ^= PhpGenericServices.GetHashCode();
       if (Deprecated != false) hash ^= Deprecated.GetHashCode();
       if (CcEnableArenas != false) hash ^= CcEnableArenas.GetHashCode();
       if (ObjcClassPrefix.Length != 0) hash ^= ObjcClassPrefix.GetHashCode();
       if (CsharpNamespace.Length != 0) hash ^= CsharpNamespace.GetHashCode();
       if (SwiftPrefix.Length != 0) hash ^= SwiftPrefix.GetHashCode();
       if (PhpClassPrefix.Length != 0) hash ^= PhpClassPrefix.GetHashCode();
+      if (PhpNamespace.Length != 0) hash ^= PhpNamespace.GetHashCode();
       hash ^= uninterpretedOption_.GetHashCode();
       return hash;
     }
@@ -3331,6 +3366,10 @@
         output.WriteRawTag(144, 1);
         output.WriteBool(PyGenericServices);
       }
+      if (PhpGenericServices != false) {
+        output.WriteRawTag(152, 1);
+        output.WriteBool(PhpGenericServices);
+      }
       if (JavaGenerateEqualsAndHash != false) {
         output.WriteRawTag(160, 1);
         output.WriteBool(JavaGenerateEqualsAndHash);
@@ -3363,6 +3402,10 @@
         output.WriteRawTag(194, 2);
         output.WriteString(PhpClassPrefix);
       }
+      if (PhpNamespace.Length != 0) {
+        output.WriteRawTag(202, 2);
+        output.WriteString(PhpNamespace);
+      }
       uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
     }
 
@@ -3399,6 +3442,9 @@
       if (PyGenericServices != false) {
         size += 2 + 1;
       }
+      if (PhpGenericServices != false) {
+        size += 2 + 1;
+      }
       if (Deprecated != false) {
         size += 2 + 1;
       }
@@ -3417,6 +3463,9 @@
       if (PhpClassPrefix.Length != 0) {
         size += 2 + pb::CodedOutputStream.ComputeStringSize(PhpClassPrefix);
       }
+      if (PhpNamespace.Length != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeStringSize(PhpNamespace);
+      }
       size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
       return size;
     }
@@ -3456,6 +3505,9 @@
       if (other.PyGenericServices != false) {
         PyGenericServices = other.PyGenericServices;
       }
+      if (other.PhpGenericServices != false) {
+        PhpGenericServices = other.PhpGenericServices;
+      }
       if (other.Deprecated != false) {
         Deprecated = other.Deprecated;
       }
@@ -3474,6 +3526,9 @@
       if (other.PhpClassPrefix.Length != 0) {
         PhpClassPrefix = other.PhpClassPrefix;
       }
+      if (other.PhpNamespace.Length != 0) {
+        PhpNamespace = other.PhpNamespace;
+      }
       uninterpretedOption_.Add(other.uninterpretedOption_);
     }
 
@@ -3517,6 +3572,10 @@
             PyGenericServices = input.ReadBool();
             break;
           }
+          case 152: {
+            PhpGenericServices = input.ReadBool();
+            break;
+          }
           case 160: {
             JavaGenerateEqualsAndHash = input.ReadBool();
             break;
@@ -3549,6 +3608,10 @@
             PhpClassPrefix = input.ReadString();
             break;
           }
+          case 330: {
+            PhpNamespace = input.ReadString();
+            break;
+          }
           case 7994: {
             uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
             break;
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
index f4fac73..fca689d 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
@@ -44,17 +44,25 @@
             prefix.EndsWith("/") ? prefix + descriptor.FullName : prefix + "/" + descriptor.FullName;
 
         /// <summary>
-        /// Retrieves the type name for a type URL. This is always just the last part of the URL,
-        /// after the trailing slash. No validation of anything before the trailing slash is performed.
-        /// If the type URL does not include a slash, an empty string is returned rather than an exception
-        /// being thrown; this won't match any types, and the calling code is probably in a better position
-        /// to give a meaningful error.
-        /// There is no handling of fragments or queries  at the moment.
+        /// Retrieves the type name for a type URL, matching the <see cref="DescriptorBase.FullName"/>
+        /// of the packed message type.
         /// </summary>
+        /// <remarks>
+        /// <para>
+        /// This is always just the last part of the URL, after the final slash. No validation of 
+        /// anything before the trailing slash is performed. If the type URL does not include a slash,
+        /// an empty string is returned rather than an exception being thrown; this won't match any types,
+        /// and the calling code is probably in a better position to give a meaningful error.
+        /// </para>
+        /// <para>
+        /// There is no handling of fragments or queries  at the moment.
+        /// </para>
+        /// </remarks>
         /// <param name="typeUrl">The URL to extract the type name from</param>
         /// <returns>The type name</returns>
-        internal static string GetTypeName(string typeUrl)
+        public static string GetTypeName(string typeUrl)
         {
+            ProtoPreconditions.CheckNotNull(typeUrl, nameof(typeUrl));
             int lastSlash = typeUrl.LastIndexOf('/');
             return lastSlash == -1 ? "" : typeUrl.Substring(lastSlash + 1);
         }
@@ -81,6 +89,27 @@
         }
 
         /// <summary>
+        /// Attempts to unpack the content of this Any message into the target message type,
+        /// if it matches the type URL within this Any message.
+        /// </summary>
+        /// <typeparam name="T">The type of message to attempt to unpack the content into.</typeparam>
+        /// <returns><c>true</c> if the message was successfully unpacked; <c>false</c> if the type name didn't match</returns>
+        public bool TryUnpack<T>(out T result) where T : IMessage, new()
+        {
+            // Note: deliberately avoid writing anything to result until the end, in case it's being
+            // monitored by other threads. (That would be a bug in the calling code, but let's not make it worse.)
+            T target = new T();
+            if (GetTypeName(TypeUrl) != target.Descriptor.FullName)
+            {
+                result = default(T); // Can't use null as there's no class constraint, but this always *will* be null in real usage.
+                return false;
+            }
+            target.MergeFrom(Value);
+            result = target;
+            return true;
+        }
+
+        /// <summary>
         /// Packs the specified message into an Any message using a type URL prefix of "type.googleapis.com".
         /// </summary>
         /// <param name="message">The message to pack.</param>
diff --git a/csharp/src/Google.Protobuf/project.json b/csharp/src/Google.Protobuf/project.json
deleted file mode 100644
index f437623..0000000
--- a/csharp/src/Google.Protobuf/project.json
+++ /dev/null
@@ -1,65 +0,0 @@
-{
-  "version": "3.3.0",
-  "title": "Google Protocol Buffers",
-  "description": "See project site for more info.",
-  "authors": [ "Google Inc." ],
-  "copyright": "Copyright 2015, Google Inc.",
-
-  "packOptions": {
-    "summary": "C# runtime library for Protocol Buffers - Google's data interchange format.",
-    "tags": [ "Protocol", "Buffers", "Binary", "Serialization", "Format", "Google", "proto", "proto3" ],
-    "owners": [ "protobuf-packages" ],
-    "licenseUrl": "https://github.com/google/protobuf/blob/master/LICENSE",
-    "projectUrl": "https://github.com/google/protobuf",
-    "releaseNotes": "C# proto3 support",
-    "requireLicenseAcceptance": false,
-    "repository": {
-      "url": "https://github.com/nodatime/nodatime.git"
-    }
-  },
-
-  "buildOptions": {
-    "debugType": "portable",
-    "keyFile": "../../keys/Google.Protobuf.snk",
-    "xmlDoc": true
-  },
-
-  "configurations": {
-    "Debug": {
-      "buildOptions": {
-        "define": [ "DEBUG", "TRACE" ]
-      }
-    },
-    "Release": {
-      "buildOptions": {
-        "define": [ "RELEASE", "TRACE" ],
-        "optimize": true
-      }
-    }
-  },
-
-  "frameworks": {
-    // This target allows the package to be installed in a .NET 4.5+
-    // project without asking for myriad other dependencies.
-    "net45": {
-    },
-    "netstandard1.0": {
-      "dependencies": {
-        "System.Collections": "4.0.11",
-        "System.Diagnostics.Debug": "4.0.11",
-        "System.Globalization": "4.0.11",
-        "System.IO": "4.1.0",
-        "System.Linq": "4.1.0",
-        "System.Linq.Expressions": "4.1.0",
-        "System.ObjectModel": "4.0.12",
-        "System.Reflection": "4.1.0",
-        "System.Reflection.Extensions": "4.0.1",
-        "System.Runtime": "4.1.0",
-        "System.Runtime.Extensions": "4.1.0",
-        "System.Text.Encoding": "4.0.11",
-        "System.Text.RegularExpressions": "4.1.0",
-        "System.Threading": "4.0.11"
-      }
-    }
-  }
-}
diff --git a/csharp/src/global.json b/csharp/src/global.json
deleted file mode 100644
index 9d5558b..0000000
--- a/csharp/src/global.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "sdk": {
-    "version": "1.0.0-preview2-003131"
-  }
-}
diff --git a/csharp/src/packages/repositories.config b/csharp/src/packages/repositories.config
deleted file mode 100644
index 7037941..0000000
--- a/csharp/src/packages/repositories.config
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<repositories>
-  <repository path="..\Google.Protobuf.Test\packages.config" />
-</repositories>
\ No newline at end of file
diff --git a/docs/third_party.md b/docs/third_party.md
index 3def003..30dbd81 100644
--- a/docs/third_party.md
+++ b/docs/third_party.md
@@ -116,6 +116,7 @@
 * https://github.com/thesamet/rpcz (C++/Python, based on ZeroMQ)
 * https://github.com/w359405949/libmaid (C++, Python)
 * https://github.com/madwyn/libpbrpc (C++)
+* https://github.com/SeriousMa/grpc-protobuf-validation (Java)
 
 ## Other Utilities
 
diff --git a/editors/protobuf-mode.el b/editors/protobuf-mode.el
index 1cef413..d3bdcde 100644
--- a/editors/protobuf-mode.el
+++ b/editors/protobuf-mode.el
@@ -64,9 +64,11 @@
 ;;; Code:
 
 (require 'cc-mode)
-(require 'cl)
 
 (eval-when-compile
+  (and (= emacs-major-version 24)
+       (>= emacs-minor-version 4)
+       (require 'cl))
   (require 'cc-langs)
   (require 'cc-fonts))
 
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 2cd2acc..3e8e654 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -32,22 +32,6 @@
   if(protobuf_MODULE_COMPATIBLE) #Legacy Support
     protobuf_generate_cpp(${example}_PROTO_SRCS ${example}_PROTO_HDRS ${${example}_PROTOS})
     list(APPEND ${example}_SRCS ${${example}_PROTO_SRCS} ${${example}_PROTO_HDRS})
-  else()
-
-    foreach(proto_file ${${example}_PROTOS})
-      get_filename_component(proto_file_abs ${proto_file} ABSOLUTE)
-      get_filename_component(basename ${proto_file} NAME_WE)
-      set(generated_files ${basename}.pb.cc ${basename}.pb.h)
-      list(APPEND ${example}_SRCS ${generated_files})
-
-      add_custom_command(
-        OUTPUT ${generated_files}
-        COMMAND protobuf::protoc
-        ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} -I ${CMAKE_CURRENT_SOURCE_DIR} ${proto_file_abs}
-        COMMENT "Generating ${generated_files} from ${proto_file}"
-        VERBATIM
-      )
-    endforeach()
   endif()
 
   #Executable setup
@@ -58,6 +42,7 @@
     target_link_libraries(${executable_name} ${PROTOBUF_LIBRARIES})
   else()
     target_link_libraries(${executable_name} protobuf::libprotobuf)
+    protobuf_generate(TARGET ${executable_name})
   endif()
 
 endforeach()
diff --git a/jenkins/buildcmds/pull_request_32.sh b/jenkins/buildcmds/pull_request_32.sh
index 99df297..bf0fb7f 100755
--- a/jenkins/buildcmds/pull_request_32.sh
+++ b/jenkins/buildcmds/pull_request_32.sh
@@ -12,5 +12,5 @@
 export DOCKERFILE_DIR=jenkins/docker32
 export DOCKER_RUN_SCRIPT=jenkins/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
-export TEST_SET="php_all"
+export TEST_SET="php_all_32"
 ./jenkins/build_and_run_docker.sh
diff --git a/jenkins/docker/Dockerfile b/jenkins/docker/Dockerfile
index 9c9ee56..fcebe16 100644
--- a/jenkins/docker/Dockerfile
+++ b/jenkins/docker/Dockerfile
@@ -30,7 +30,7 @@
 # Install dotnet SDK based on https://www.microsoft.com/net/core#debian
 # (Ubuntu instructions need apt to support https)
 RUN apt-get update && apt-get install -y --force-yes curl libunwind8 gettext && \
-  curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 &&  \
+  curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=847105 &&  \
   mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet && \
   ln -s /opt/dotnet/dotnet /usr/local/bin
 
@@ -145,7 +145,7 @@
 RUN tar -xvf php-5.5.38.tar.bz2
 RUN cd php-5.5.38 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-5.5-zts && \
     make && make install && cd ..
-RUN cd php-5.5.38 && make clean && ./configure --prefix=/usr/local/php-5.5 && \
+RUN cd php-5.5.38 && make clean && ./configure --enable-bcmath --prefix=/usr/local/php-5.5 && \
     make && make install && cd ..
 
 RUN wget http://am1.php.net/get/php-5.6.30.tar.bz2/from/this/mirror
@@ -153,7 +153,7 @@
 RUN tar -xvf php-5.6.30.tar.bz2
 RUN cd php-5.6.30 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-5.6-zts && \
     make && make install && cd ..
-RUN cd php-5.6.30 && make clean && ./configure --prefix=/usr/local/php-5.6 && \
+RUN cd php-5.6.30 && make clean && ./configure --enable-bcmath --prefix=/usr/local/php-5.6 && \
     make && make install && cd ..
 
 RUN wget http://am1.php.net/get/php-7.0.18.tar.bz2/from/this/mirror
@@ -161,7 +161,7 @@
 RUN tar -xvf php-7.0.18.tar.bz2
 RUN cd php-7.0.18 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-7.0-zts && \
     make && make install && cd ..
-RUN cd php-7.0.18 && make clean && ./configure --prefix=/usr/local/php-7.0 && \
+RUN cd php-7.0.18 && make clean && ./configure --enable-bcmath --prefix=/usr/local/php-7.0 && \
     make && make install && cd ..
 
 RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
@@ -174,7 +174,7 @@
   rm -rf protobuf && \
   git clone https://github.com/google/protobuf.git && \
   cd protobuf && \
-  git reset --hard 6b27c1f981a9a93918e4039f236ead27165a8e91 && \
+  git reset --hard 8d97b3d8b5a33650e822460b3b561802c969e86e && \
   cd php && \
   ln -sfn /usr/local/php-5.5/bin/php /usr/bin/php && \
   ln -sfn /usr/local/php-5.5/bin/php-config /usr/bin/php-config && \
diff --git a/jenkins/docker32/Dockerfile b/jenkins/docker32/Dockerfile
index ab3fd95..d9925d8 100644
--- a/jenkins/docker32/Dockerfile
+++ b/jenkins/docker32/Dockerfile
@@ -64,7 +64,7 @@
 RUN cd /tmp && \
   git clone https://github.com/google/protobuf.git && \
   cd protobuf/php && \
-  git reset --hard 6b27c1f981a9a93918e4039f236ead27165a8e91 && \
+  git reset --hard 8d97b3d8b5a33650e822460b3b561802c969e86e && \
   ln -sfn /usr/bin/php5.5 /usr/bin/php && \
   ln -sfn /usr/bin/php-config5.5 /usr/bin/php-config && \
   ln -sfn /usr/bin/phpize5.5 /usr/bin/phpize && \
diff --git a/js/README.md b/js/README.md
index f418462..24386dc 100644
--- a/js/README.md
+++ b/js/README.md
@@ -19,7 +19,9 @@
 To use Protocol Buffers with JavaScript, you need two main components:
 
 1. The protobuf runtime library.  You can install this with
-   `npm install google-protobuf`, or use the files in this directory.
+   `npm install google-protobuf`, or use the files in this directory.  
+    If npm is not being used, as of 3.3.0, the files needed are located in binary subdirectory; 
+    arith.js, constants.js, decoder.js, encoder.js, map.js, message.js, reader.js, utils.js, writer.js
 2. The Protocol Compiler `protoc`.  This translates `.proto` files
    into `.js` files.  The compiler is not currently available via
    npm, but you can download a pre-built binary
@@ -93,6 +95,12 @@
 
     var message = proto.my.package.MyMessage();
 
+If unfamiliar with Closure or it's compiler, consider reviewing Closure documentation
+https://developers.google.com/closure/library/docs/tutorial
+https://developers.google.com/closure/library/docs/closurebuilder
+https://developers.google.com/closure/library/docs/depswriter
+At a high level, closurebuilder.py can walk dependencies, and compile your code, and all dependencies for Protobuf into a single .js file.  Using depsbuilder.py to generate a dependency file can also be considered for non-production dev environments.
+
 CommonJS imports
 ----------------
 
diff --git a/js/binary/decoder.js b/js/binary/decoder.js
index ad9cb01..6db28e7 100644
--- a/js/binary/decoder.js
+++ b/js/binary/decoder.js
@@ -994,7 +994,7 @@
       codeUnits.length = 0;
     }
   }
-  result += String.fromCharCode.apply(null, codeUnits);
+  result += goog.crypt.byteArrayToString(codeUnits);
   this.cursor_ = cursor;
   return result;
 };
diff --git a/js/binary/utils.js b/js/binary/utils.js
index 25131b0..58f11b5 100644
--- a/js/binary/utils.js
+++ b/js/binary/utils.js
@@ -613,7 +613,7 @@
     muladd(1, 1);
   }
 
-  return String.fromCharCode.apply(null, resultBytes);
+  return goog.crypt.byteArrayToString(resultBytes);
 };
 
 
diff --git a/js/binary/utils_test.js b/js/binary/utils_test.js
index d27e5ea..0a2f4f0 100644
--- a/js/binary/utils_test.js
+++ b/js/binary/utils_test.js
@@ -205,31 +205,31 @@
     var convert = jspb.utils.decimalStringToHash64;
 
     result = convert('0');
-    assertEquals(String.fromCharCode.apply(null,
+    assertEquals(goog.crypt.byteArrayToString(
       [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result);
 
     result = convert('-1');
-    assertEquals(String.fromCharCode.apply(null,
+    assertEquals(goog.crypt.byteArrayToString(
       [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result);
 
     result = convert('18446744073709551615');
-    assertEquals(String.fromCharCode.apply(null,
+    assertEquals(goog.crypt.byteArrayToString(
       [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result);
 
     result = convert('9223372036854775808');
-    assertEquals(String.fromCharCode.apply(null,
+    assertEquals(goog.crypt.byteArrayToString(
       [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), result);
 
     result = convert('-9223372036854775808');
-    assertEquals(String.fromCharCode.apply(null,
+    assertEquals(goog.crypt.byteArrayToString(
       [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), result);
 
     result = convert('123456789123456789');
-    assertEquals(String.fromCharCode.apply(null,
+    assertEquals(goog.crypt.byteArrayToString(
       [0x15, 0x5F, 0xD0, 0xAC, 0x4B, 0x9B, 0xB6, 0x01]), result);
 
     result = convert('-123456789123456789');
-    assertEquals(String.fromCharCode.apply(null,
+    assertEquals(goog.crypt.byteArrayToString(
       [0xEB, 0xA0, 0x2F, 0x53, 0xB4, 0x64, 0x49, 0xFE]), result);
   });
 
@@ -259,21 +259,21 @@
     var convert = jspb.utils.hexStringToHash64;
 
     result = convert('0x0000000000000000');
-    assertEquals(String.fromCharCode.apply(null,
+    assertEquals(goog.crypt.byteArrayToString(
         [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result);
 
     result = convert('0xffffffffffffffff');
-    assertEquals(String.fromCharCode.apply(null,
+    assertEquals(goog.crypt.byteArrayToString(
         [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result);
 
     // Hex string is big-endian, hash string is little-endian.
     result = convert('0x123456789ABCDEF0');
-    assertEquals(String.fromCharCode.apply(null,
+    assertEquals(goog.crypt.byteArrayToString(
         [0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]), result);
 
     // Capitalization should not matter.
     result = convert('0x0000abcdefABCDEF');
-    assertEquals(String.fromCharCode.apply(null,
+    assertEquals(goog.crypt.byteArrayToString(
         [0xEF, 0xCD, 0xAB, 0xEF, 0xCD, 0xAB, 0x00, 0x00]), result);
   });
 
@@ -643,7 +643,7 @@
     var sourceBytes = new Uint8Array(sourceData);
     var sourceBuffer = sourceBytes.buffer;
     var sourceBase64 = goog.crypt.base64.encodeByteArray(sourceData);
-    var sourceString = String.fromCharCode.apply(null, sourceData);
+    var sourceString = goog.crypt.byteArrayToString(sourceData);
 
     function check(result) {
       assertEquals(Uint8Array, result.constructor);
diff --git a/kokoro/README.md b/kokoro/README.md
new file mode 100644
index 0000000..0791c92
--- /dev/null
+++ b/kokoro/README.md
@@ -0,0 +1,6 @@
+
+Kokoro Infrastructure
+----------------------
+
+The files in this directory serve as plumbing for running Protobuf
+tests under Kokoro, our internal CI.
\ No newline at end of file
diff --git a/kokoro/linux/cpp_distcheck/build.sh b/kokoro/linux/cpp_distcheck/build.sh
new file mode 100755
index 0000000..b8b57e3
--- /dev/null
+++ b/kokoro/linux/cpp_distcheck/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/linux/prepare_build_linux_rc
+
+./tests.sh cpp_distcheck
diff --git a/kokoro/linux/cpp_distcheck/continuous.cfg b/kokoro/linux/cpp_distcheck/continuous.cfg
new file mode 100644
index 0000000..4289f6a
--- /dev/null
+++ b/kokoro/linux/cpp_distcheck/continuous.cfg
@@ -0,0 +1,5 @@
+# Config file for running tests in Kokoro
+
+# Location of the build script in repository
+build_file: "protobuf/kokoro/linux/cpp_distcheck/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/linux/cpp_distcheck/presubmit.cfg b/kokoro/linux/cpp_distcheck/presubmit.cfg
new file mode 100644
index 0000000..4289f6a
--- /dev/null
+++ b/kokoro/linux/cpp_distcheck/presubmit.cfg
@@ -0,0 +1,5 @@
+# Config file for running tests in Kokoro
+
+# Location of the build script in repository
+build_file: "protobuf/kokoro/linux/cpp_distcheck/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/linux/csharp/build.sh b/kokoro/linux/csharp/build.sh
new file mode 100755
index 0000000..de178b8
--- /dev/null
+++ b/kokoro/linux/csharp/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/linux/prepare_build_linux_rc
+
+./tests.sh csharp
diff --git a/kokoro/linux/csharp/continuous.cfg b/kokoro/linux/csharp/continuous.cfg
new file mode 100644
index 0000000..3d17767
--- /dev/null
+++ b/kokoro/linux/csharp/continuous.cfg
@@ -0,0 +1,5 @@
+# Config file for running tests in Kokoro
+
+# Location of the build script in repository
+build_file: "protobuf/kokoro/linux/csharp/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/linux/csharp/presubmit.cfg b/kokoro/linux/csharp/presubmit.cfg
new file mode 100644
index 0000000..3d17767
--- /dev/null
+++ b/kokoro/linux/csharp/presubmit.cfg
@@ -0,0 +1,5 @@
+# Config file for running tests in Kokoro
+
+# Location of the build script in repository
+build_file: "protobuf/kokoro/linux/csharp/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/linux/java_compatibility/build.sh b/kokoro/linux/java_compatibility/build.sh
new file mode 100755
index 0000000..b1ef279
--- /dev/null
+++ b/kokoro/linux/java_compatibility/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/linux/prepare_build_linux_rc
+
+./tests.sh java_compatibility
diff --git a/kokoro/linux/java_compatibility/continuous.cfg b/kokoro/linux/java_compatibility/continuous.cfg
new file mode 100644
index 0000000..4897f5c
--- /dev/null
+++ b/kokoro/linux/java_compatibility/continuous.cfg
@@ -0,0 +1,5 @@
+# Config file for running tests in Kokoro
+
+# Location of the build script in repository
+build_file: "protobuf/kokoro/linux/java_compatibility/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/linux/java_compatibility/presubmit.cfg b/kokoro/linux/java_compatibility/presubmit.cfg
new file mode 100644
index 0000000..4897f5c
--- /dev/null
+++ b/kokoro/linux/java_compatibility/presubmit.cfg
@@ -0,0 +1,5 @@
+# Config file for running tests in Kokoro
+
+# Location of the build script in repository
+build_file: "protobuf/kokoro/linux/java_compatibility/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/linux/prepare_build_linux_rc b/kokoro/linux/prepare_build_linux_rc
new file mode 100644
index 0000000..4c3f255
--- /dev/null
+++ b/kokoro/linux/prepare_build_linux_rc
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+# Source this rc script to prepare the environment for Linux builds
+
+# Set up dotnet
+sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list'
+sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 417A0893
+sudo apt-get update
+sudo apt-get install -y dotnet-dev-1.0.4
diff --git a/kokoro/linux/python_compatibility/build.sh b/kokoro/linux/python_compatibility/build.sh
new file mode 100755
index 0000000..041e65f
--- /dev/null
+++ b/kokoro/linux/python_compatibility/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/linux/prepare_build_linux_rc
+
+./tests.sh python_compatibility
diff --git a/kokoro/linux/python_compatibility/continuous.cfg b/kokoro/linux/python_compatibility/continuous.cfg
new file mode 100644
index 0000000..4cf6bb0
--- /dev/null
+++ b/kokoro/linux/python_compatibility/continuous.cfg
@@ -0,0 +1,5 @@
+# Config file for running tests in Kokoro
+
+# Location of the build script in repository
+build_file: "protobuf/kokoro/linux/python_compatibility/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/linux/python_compatibility/presubmit.cfg b/kokoro/linux/python_compatibility/presubmit.cfg
new file mode 100644
index 0000000..4cf6bb0
--- /dev/null
+++ b/kokoro/linux/python_compatibility/presubmit.cfg
@@ -0,0 +1,5 @@
+# Config file for running tests in Kokoro
+
+# Location of the build script in repository
+build_file: "protobuf/kokoro/linux/python_compatibility/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/cpp/build.sh b/kokoro/macos/cpp/build.sh
new file mode 100755
index 0000000..bae2ebb
--- /dev/null
+++ b/kokoro/macos/cpp/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/macos/prepare_build_macos_rc
+
+./tests.sh cpp
diff --git a/kokoro/macos/cpp/continuous.cfg b/kokoro/macos/cpp/continuous.cfg
new file mode 100644
index 0000000..4bea1cb
--- /dev/null
+++ b/kokoro/macos/cpp/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/cpp/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/cpp/presubmit.cfg b/kokoro/macos/cpp/presubmit.cfg
new file mode 100644
index 0000000..4bea1cb
--- /dev/null
+++ b/kokoro/macos/cpp/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/cpp/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/cpp_distcheck/build.sh b/kokoro/macos/cpp_distcheck/build.sh
new file mode 100755
index 0000000..d729b63
--- /dev/null
+++ b/kokoro/macos/cpp_distcheck/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/macos/prepare_build_macos_rc
+
+./tests.sh cpp_distcheck
diff --git a/kokoro/macos/cpp_distcheck/continuous.cfg b/kokoro/macos/cpp_distcheck/continuous.cfg
new file mode 100644
index 0000000..89441bc
--- /dev/null
+++ b/kokoro/macos/cpp_distcheck/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/cpp_distcheck/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/cpp_distcheck/presubmit.cfg b/kokoro/macos/cpp_distcheck/presubmit.cfg
new file mode 100644
index 0000000..89441bc
--- /dev/null
+++ b/kokoro/macos/cpp_distcheck/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/cpp_distcheck/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/javascript/build.sh b/kokoro/macos/javascript/build.sh
new file mode 100755
index 0000000..016832a
--- /dev/null
+++ b/kokoro/macos/javascript/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/macos/prepare_build_macos_rc
+
+./tests.sh javascript
diff --git a/kokoro/macos/javascript/continuous.cfg b/kokoro/macos/javascript/continuous.cfg
new file mode 100644
index 0000000..b478cc1
--- /dev/null
+++ b/kokoro/macos/javascript/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/javascript/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/javascript/presubmit.cfg b/kokoro/macos/javascript/presubmit.cfg
new file mode 100644
index 0000000..b478cc1
--- /dev/null
+++ b/kokoro/macos/javascript/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/javascript/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/jruby/build.sh b/kokoro/macos/jruby/build.sh
new file mode 100755
index 0000000..c82eaeb
--- /dev/null
+++ b/kokoro/macos/jruby/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/macos/prepare_build_macos_rc
+
+./tests.sh jruby
diff --git a/kokoro/macos/jruby/continuous.cfg b/kokoro/macos/jruby/continuous.cfg
new file mode 100644
index 0000000..f1310fd
--- /dev/null
+++ b/kokoro/macos/jruby/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/jruby/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/jruby/presubmit.cfg b/kokoro/macos/jruby/presubmit.cfg
new file mode 100644
index 0000000..f1310fd
--- /dev/null
+++ b/kokoro/macos/jruby/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/jruby/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/objectivec_cocoapods_integration/build.sh b/kokoro/macos/objectivec_cocoapods_integration/build.sh
new file mode 100755
index 0000000..f96d289
--- /dev/null
+++ b/kokoro/macos/objectivec_cocoapods_integration/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/macos/prepare_build_macos_rc
+
+./tests.sh objectivec_cocoapods_integration
diff --git a/kokoro/macos/objectivec_cocoapods_integration/continuous.cfg b/kokoro/macos/objectivec_cocoapods_integration/continuous.cfg
new file mode 100644
index 0000000..952874e
--- /dev/null
+++ b/kokoro/macos/objectivec_cocoapods_integration/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/objectivec_cocoapods_integration/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/objectivec_cocoapods_integration/presubmit.cfg b/kokoro/macos/objectivec_cocoapods_integration/presubmit.cfg
new file mode 100644
index 0000000..952874e
--- /dev/null
+++ b/kokoro/macos/objectivec_cocoapods_integration/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/objectivec_cocoapods_integration/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/objectivec_ios_debug/build.sh b/kokoro/macos/objectivec_ios_debug/build.sh
new file mode 100755
index 0000000..1055d72
--- /dev/null
+++ b/kokoro/macos/objectivec_ios_debug/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/macos/prepare_build_macos_rc
+
+./tests.sh objectivec_ios_debug
diff --git a/kokoro/macos/objectivec_ios_debug/continuous.cfg b/kokoro/macos/objectivec_ios_debug/continuous.cfg
new file mode 100644
index 0000000..473d545
--- /dev/null
+++ b/kokoro/macos/objectivec_ios_debug/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/objectivec_ios_debug/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/objectivec_ios_debug/presubmit.cfg b/kokoro/macos/objectivec_ios_debug/presubmit.cfg
new file mode 100644
index 0000000..473d545
--- /dev/null
+++ b/kokoro/macos/objectivec_ios_debug/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/objectivec_ios_debug/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/objectivec_ios_release/build.sh b/kokoro/macos/objectivec_ios_release/build.sh
new file mode 100755
index 0000000..76ce3ba
--- /dev/null
+++ b/kokoro/macos/objectivec_ios_release/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/macos/prepare_build_macos_rc
+
+./tests.sh objectivec_ios_release
diff --git a/kokoro/macos/objectivec_ios_release/continuous.cfg b/kokoro/macos/objectivec_ios_release/continuous.cfg
new file mode 100644
index 0000000..3cbfb68
--- /dev/null
+++ b/kokoro/macos/objectivec_ios_release/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/objectivec_ios_release/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/objectivec_ios_release/presubmit.cfg b/kokoro/macos/objectivec_ios_release/presubmit.cfg
new file mode 100644
index 0000000..3cbfb68
--- /dev/null
+++ b/kokoro/macos/objectivec_ios_release/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/objectivec_ios_release/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/objectivec_osx/build.sh b/kokoro/macos/objectivec_osx/build.sh
new file mode 100755
index 0000000..000be27
--- /dev/null
+++ b/kokoro/macos/objectivec_osx/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/macos/prepare_build_macos_rc
+
+./tests.sh objectivec_osx
diff --git a/kokoro/macos/objectivec_osx/continuous.cfg b/kokoro/macos/objectivec_osx/continuous.cfg
new file mode 100644
index 0000000..41bd46a
--- /dev/null
+++ b/kokoro/macos/objectivec_osx/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/objectivec_osx/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/objectivec_osx/presubmit.cfg b/kokoro/macos/objectivec_osx/presubmit.cfg
new file mode 100644
index 0000000..41bd46a
--- /dev/null
+++ b/kokoro/macos/objectivec_osx/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/objectivec_osx/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/php5.6_mac/build.sh b/kokoro/macos/php5.6_mac/build.sh
new file mode 100755
index 0000000..7487889
--- /dev/null
+++ b/kokoro/macos/php5.6_mac/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/macos/prepare_build_macos_rc
+
+./tests.sh php5.6_mac
diff --git a/kokoro/macos/php5.6_mac/continuous.cfg b/kokoro/macos/php5.6_mac/continuous.cfg
new file mode 100644
index 0000000..ff345e9
--- /dev/null
+++ b/kokoro/macos/php5.6_mac/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/php5.6_mac/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/php5.6_mac/presubmit.cfg b/kokoro/macos/php5.6_mac/presubmit.cfg
new file mode 100644
index 0000000..ff345e9
--- /dev/null
+++ b/kokoro/macos/php5.6_mac/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/php5.6_mac/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/php7.0_mac/build.sh b/kokoro/macos/php7.0_mac/build.sh
new file mode 100755
index 0000000..e5a37e3
--- /dev/null
+++ b/kokoro/macos/php7.0_mac/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/macos/prepare_build_macos_rc
+
+./tests.sh php7.0_mac
diff --git a/kokoro/macos/php7.0_mac/continuous.cfg b/kokoro/macos/php7.0_mac/continuous.cfg
new file mode 100644
index 0000000..c2c1811
--- /dev/null
+++ b/kokoro/macos/php7.0_mac/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/php7.0_mac/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/php7.0_mac/presubmit.cfg b/kokoro/macos/php7.0_mac/presubmit.cfg
new file mode 100644
index 0000000..c2c1811
--- /dev/null
+++ b/kokoro/macos/php7.0_mac/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/php7.0_mac/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/prepare_build_macos_rc b/kokoro/macos/prepare_build_macos_rc
new file mode 100755
index 0000000..2b9f4df
--- /dev/null
+++ b/kokoro/macos/prepare_build_macos_rc
@@ -0,0 +1,33 @@
+#!/bin/bash
+#
+# This script sets up a Kokoro MacOS worker for running Protobuf tests
+
+##
+# Select Xcode version
+
+export DEVELOPER_DIR=/Applications/Xcode_8.1.app/Contents/Developer
+
+##
+# Select C/C++ compilers
+
+export CC=gcc
+export CXX=g++
+
+##
+# Install Brew and core softwares
+
+ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
+brew tap homebrew/homebrew-php
+brew install autoconf automake ccache cmake gflags gpg gpg2 libtool maven node pcre php56 ruby wget
+
+##
+# Install Tox
+
+sudo pip install tox==2.4.1
+
+##
+# Install RVM
+
+gpg2 --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
+command curl -sSL https://rvm.io/mpapis.asc | gpg2 --import -
+curl -sSL https://get.rvm.io | bash -s stable --ruby
diff --git a/kokoro/macos/python/build.sh b/kokoro/macos/python/build.sh
new file mode 100755
index 0000000..6b17b95
--- /dev/null
+++ b/kokoro/macos/python/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/macos/prepare_build_macos_rc
+
+./tests.sh python
diff --git a/kokoro/macos/python/continuous.cfg b/kokoro/macos/python/continuous.cfg
new file mode 100644
index 0000000..0fc8b50
--- /dev/null
+++ b/kokoro/macos/python/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/python/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/python/presubmit.cfg b/kokoro/macos/python/presubmit.cfg
new file mode 100644
index 0000000..0fc8b50
--- /dev/null
+++ b/kokoro/macos/python/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/python/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/python_cpp/build.sh b/kokoro/macos/python_cpp/build.sh
new file mode 100755
index 0000000..cb53def
--- /dev/null
+++ b/kokoro/macos/python_cpp/build.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/macos/prepare_build_macos_rc
+g++ --version
+
+./tests.sh python_cpp
diff --git a/kokoro/macos/python_cpp/continuous.cfg b/kokoro/macos/python_cpp/continuous.cfg
new file mode 100644
index 0000000..22f4a0e
--- /dev/null
+++ b/kokoro/macos/python_cpp/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/python_cpp/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/python_cpp/presubmit.cfg b/kokoro/macos/python_cpp/presubmit.cfg
new file mode 100644
index 0000000..22f4a0e
--- /dev/null
+++ b/kokoro/macos/python_cpp/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/python_cpp/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/ruby21/build.sh b/kokoro/macos/ruby21/build.sh
new file mode 100755
index 0000000..748ea65
--- /dev/null
+++ b/kokoro/macos/ruby21/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/macos/prepare_build_macos_rc
+
+./tests.sh ruby21
diff --git a/kokoro/macos/ruby21/continuous.cfg b/kokoro/macos/ruby21/continuous.cfg
new file mode 100644
index 0000000..489796d
--- /dev/null
+++ b/kokoro/macos/ruby21/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/ruby21/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/ruby21/presubmit.cfg b/kokoro/macos/ruby21/presubmit.cfg
new file mode 100644
index 0000000..489796d
--- /dev/null
+++ b/kokoro/macos/ruby21/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/ruby21/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/ruby22/build.sh b/kokoro/macos/ruby22/build.sh
new file mode 100755
index 0000000..5c4de42
--- /dev/null
+++ b/kokoro/macos/ruby22/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Build file to set up and run tests
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+# Prepare worker environment to run tests
+source kokoro/macos/prepare_build_macos_rc
+
+./tests.sh ruby22
diff --git a/kokoro/macos/ruby22/continuous.cfg b/kokoro/macos/ruby22/continuous.cfg
new file mode 100644
index 0000000..d270544
--- /dev/null
+++ b/kokoro/macos/ruby22/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/ruby22/build.sh"
+timeout_mins: 1440
diff --git a/kokoro/macos/ruby22/presubmit.cfg b/kokoro/macos/ruby22/presubmit.cfg
new file mode 100644
index 0000000..d270544
--- /dev/null
+++ b/kokoro/macos/ruby22/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/ruby22/build.sh"
+timeout_mins: 1440
diff --git a/objectivec/GPBCodedInputStream.m b/objectivec/GPBCodedInputStream.m
index eef0535..22859e7 100644
--- a/objectivec/GPBCodedInputStream.m
+++ b/objectivec/GPBCodedInputStream.m
@@ -230,16 +230,16 @@
   }
 
   state->lastTag = ReadRawVarint32(state);
-  if (state->lastTag == 0) {
-    // If we actually read zero, that's not a valid tag.
-    RaiseException(GPBCodedInputStreamErrorInvalidTag,
-                   @"A zero tag on the wire is invalid.");
-  }
-  // Tags have to include a valid wireformat, check that also.
+  // Tags have to include a valid wireformat.
   if (!GPBWireFormatIsValidTag(state->lastTag)) {
     RaiseException(GPBCodedInputStreamErrorInvalidTag,
                    @"Invalid wireformat in tag.");
   }
+  // Zero is not a valid field number.
+  if (GPBWireFormatGetTagFieldNumber(state->lastTag) == 0) {
+    RaiseException(GPBCodedInputStreamErrorInvalidTag,
+                   @"A zero field number on the wire is invalid.");
+  }
   return state->lastTag;
 }
 
diff --git a/objectivec/GPBCodedOutputStream.h b/objectivec/GPBCodedOutputStream.h
index d6fff3d..23c404b 100644
--- a/objectivec/GPBCodedOutputStream.h
+++ b/objectivec/GPBCodedOutputStream.h
@@ -47,11 +47,20 @@
 NS_ASSUME_NONNULL_BEGIN
 
 /**
+ * @c GPBCodedOutputStream exception names.
+ **/
+extern NSString *const GPBCodedOutputStreamException_OutOfSpace;
+extern NSString *const GPBCodedOutputStreamException_WriteFailed;
+
+/**
  * Writes out protocol message fields.
  *
  * The common uses of protocol buffers shouldn't need to use this class.
  * GPBMessage's provide a -data method that will serialize the message for you.
  *
+ * @note Any -write* api can raise the GPBCodedOutputStreamException_*
+ *       exceptions.
+ *
  * @note Subclassing of GPBCodedOutputStream is NOT supported.
  **/
 @interface GPBCodedOutputStream : NSObject
diff --git a/objectivec/GPBCodedOutputStream.m b/objectivec/GPBCodedOutputStream.m
index 7c3ab44..c299040 100644
--- a/objectivec/GPBCodedOutputStream.m
+++ b/objectivec/GPBCodedOutputStream.m
@@ -36,6 +36,11 @@
 #import "GPBUnknownFieldSet_PackagePrivate.h"
 #import "GPBUtilities_PackagePrivate.h"
 
+// These values are the existing values so as not to break any code that might
+// have already been inspecting them when they weren't documented/exposed.
+NSString *const GPBCodedOutputStreamException_OutOfSpace = @"OutOfSpace";
+NSString *const GPBCodedOutputStreamException_WriteFailed = @"WriteFailed";
+
 // Structure for containing state of a GPBCodedInputStream. Brought out into
 // a struct so that we can inline several common functions instead of dealing
 // with overhead of ObjC dispatch.
@@ -59,13 +64,13 @@
 static void GPBRefreshBuffer(GPBOutputBufferState *state) {
   if (state->output == nil) {
     // We're writing to a single buffer.
-    [NSException raise:@"OutOfSpace" format:@""];
+    [NSException raise:GPBCodedOutputStreamException_OutOfSpace format:@""];
   }
   if (state->position != 0) {
     NSInteger written =
         [state->output write:state->bytes maxLength:state->position];
     if (written != (NSInteger)state->position) {
-      [NSException raise:@"WriteFailed" format:@""];
+      [NSException raise:GPBCodedOutputStreamException_WriteFailed format:@""];
     }
     state->position = 0;
   }
diff --git a/objectivec/GPBDescriptor_PackagePrivate.h b/objectivec/GPBDescriptor_PackagePrivate.h
index 9173e7a..452b3f8 100644
--- a/objectivec/GPBDescriptor_PackagePrivate.h
+++ b/objectivec/GPBDescriptor_PackagePrivate.h
@@ -286,10 +286,6 @@
 // would be the wire type for packed.
 uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self);
 
-GPB_INLINE BOOL GPBPreserveUnknownFields(GPBFileSyntax syntax) {
-  return syntax != GPBFileSyntaxProto3;
-}
-
 GPB_INLINE BOOL GPBHasPreservingUnknownEnumSemantics(GPBFileSyntax syntax) {
   return syntax == GPBFileSyntaxProto3;
 }
diff --git a/objectivec/GPBDictionary.m b/objectivec/GPBDictionary.m
index 1c67c68..7713376 100644
--- a/objectivec/GPBDictionary.m
+++ b/objectivec/GPBDictionary.m
@@ -329,13 +329,15 @@
 
 size_t GPBDictionaryComputeSizeInternalHelper(NSDictionary *dict, GPBFieldDescriptor *field) {
   GPBDataType mapValueType = GPBGetFieldDataType(field);
-  __block size_t result = 0;
-  [dict enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSString *key;
+  NSEnumerator *keys = [dict keyEnumerator];
+  while ((key = [keys nextObject])) {
+    id obj = dict[key];
     size_t msgSize = GPBComputeStringSize(kMapKeyFieldNumber, key);
     msgSize += ComputeDictObjectFieldSize(obj, kMapValueFieldNumber, mapValueType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * dict.count;
   return result;
@@ -347,8 +349,10 @@
   NSCAssert(field.mapKeyDataType == GPBDataTypeString, @"Unexpected key type");
   GPBDataType mapValueType = GPBGetFieldDataType(field);
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [dict enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
-    #pragma unused(stop)
+  NSString *key;
+  NSEnumerator *keys = [dict keyEnumerator];
+  while ((key = [keys nextObject])) {
+    id obj = dict[key];
     // Write the tag.
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
@@ -359,14 +363,16 @@
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     [outputStream writeString:kMapKeyFieldNumber value:key];
     WriteDictObjectField(outputStream, obj, kMapValueFieldNumber, mapValueType);
-  }];
+  }
 }
 
 BOOL GPBDictionaryIsInitializedInternalHelper(NSDictionary *dict, GPBFieldDescriptor *field) {
   NSCAssert(field.mapKeyDataType == GPBDataTypeString, @"Unexpected key type");
   NSCAssert(GPBGetFieldDataType(field) == GPBDataTypeMessage, @"Unexpected value type");
   #pragma unused(field)  // For when asserts are off in release.
-  for (GPBMessage *msg in [dict objectEnumerator]) {
+  GPBMessage *msg;
+  NSEnumerator *objects = [dict objectEnumerator];
+  while ((msg = [objects nextObject])) {
     if (!msg.initialized) {
       return NO;
     }
@@ -406,7 +412,7 @@
       valueToFill->valueInt32 = GPBCodedInputStreamReadInt32(&stream->state_);
       break;
     case GPBDataTypeInt64:
-      valueToFill->valueInt64 = GPBCodedInputStreamReadInt32(&stream->state_);
+      valueToFill->valueInt64 = GPBCodedInputStreamReadInt64(&stream->state_);
       break;
     case GPBDataTypeSInt32:
       valueToFill->valueInt32 = GPBCodedInputStreamReadSInt32(&stream->state_);
@@ -796,15 +802,20 @@
 //%- (void)enumerateKeysAndEnumsUsingBlock:
 //%    (void (^)(KEY_TYPE KisP##key, VALUE_TYPE value, BOOL *stop))block {
 //%  GPBEnumValidationFunc func = _validationFunc;
-//%  [_dictionary enumerateKeysAndObjectsUsingBlock:^(ENUM_TYPE##KHELPER(KEY_TYPE)##aKey,
-//%                                                   ENUM_TYPE##VHELPER(VALUE_TYPE)##aValue,
-//%                                                   BOOL *stop) {
+//%  BOOL stop = NO;
+//%  NSEnumerator *keys = [_dictionary keyEnumerator];
+//%  ENUM_TYPE##KHELPER(KEY_TYPE)##aKey;
+//%  while ((aKey = [keys nextObject])) {
+//%    ENUM_TYPE##VHELPER(VALUE_TYPE)##aValue = _dictionary[aKey];
 //%      VALUE_TYPE unwrapped = UNWRAP##VALUE_NAME(aValue);
 //%      if (!func(unwrapped)) {
 //%        unwrapped = kGPBUnrecognizedEnumeratorValue;
 //%      }
-//%      block(UNWRAP##KEY_NAME(aKey), unwrapped, stop);
-//%  }];
+//%    block(UNWRAP##KEY_NAME(aKey), unwrapped, &stop);
+//%    if (stop) {
+//%      break;
+//%    }
+//%  }
 //%}
 //%
 //%DICTIONARY_MUTABLE_CORE2(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, Value, Enum, value, Raw)
@@ -863,30 +874,37 @@
 //%
 //%- (void)enumerateKeysAnd##ACCESSOR_NAME##VNAME##sUsingBlock:
 //%    (void (^)(KEY_TYPE KisP##key, VALUE_TYPE VNAME_VAR, BOOL *stop))block {
-//%  [_dictionary enumerateKeysAndObjectsUsingBlock:^(ENUM_TYPE##KHELPER(KEY_TYPE)##aKey,
-//%                                                   ENUM_TYPE##VHELPER(VALUE_TYPE)##a##VNAME_VAR$u,
-//%                                                   BOOL *stop) {
-//%      block(UNWRAP##KEY_NAME(aKey), UNWRAP##VALUE_NAME(a##VNAME_VAR$u), stop);
-//%  }];
+//%  BOOL stop = NO;
+//%  NSDictionary *internal = _dictionary;
+//%  NSEnumerator *keys = [internal keyEnumerator];
+//%  ENUM_TYPE##KHELPER(KEY_TYPE)##aKey;
+//%  while ((aKey = [keys nextObject])) {
+//%    ENUM_TYPE##VHELPER(VALUE_TYPE)##a##VNAME_VAR$u = internal[aKey];
+//%    block(UNWRAP##KEY_NAME(aKey), UNWRAP##VALUE_NAME(a##VNAME_VAR$u), &stop);
+//%    if (stop) {
+//%      break;
+//%    }
+//%  }
 //%}
 //%
 //%EXTRA_METHODS_##VHELPER(KEY_NAME, VALUE_NAME)- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-//%  NSUInteger count = _dictionary.count;
+//%  NSDictionary *internal = _dictionary;
+//%  NSUInteger count = internal.count;
 //%  if (count == 0) {
 //%    return 0;
 //%  }
 //%
 //%  GPBDataType valueDataType = GPBGetFieldDataType(field);
 //%  GPBDataType keyDataType = field.mapKeyDataType;
-//%  __block size_t result = 0;
-//%  [_dictionary enumerateKeysAndObjectsUsingBlock:^(ENUM_TYPE##KHELPER(KEY_TYPE)##aKey,
-//%                                                   ENUM_TYPE##VHELPER(VALUE_TYPE)##a##VNAME_VAR$u##,
-//%                                                   BOOL *stop) {
-//%    #pragma unused(stop)
+//%  size_t result = 0;
+//%  NSEnumerator *keys = [internal keyEnumerator];
+//%  ENUM_TYPE##KHELPER(KEY_TYPE)##aKey;
+//%  while ((aKey = [keys nextObject])) {
+//%    ENUM_TYPE##VHELPER(VALUE_TYPE)##a##VNAME_VAR$u = internal[aKey];
 //%    size_t msgSize = ComputeDict##KEY_NAME##FieldSize(UNWRAP##KEY_NAME(aKey), kMapKeyFieldNumber, keyDataType);
 //%    msgSize += ComputeDict##VALUE_NAME##FieldSize(UNWRAP##VALUE_NAME(a##VNAME_VAR$u), kMapValueFieldNumber, valueDataType);
 //%    result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-//%  }];
+//%  }
 //%  size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
 //%  result += tagSize * count;
 //%  return result;
@@ -897,20 +915,22 @@
 //%  GPBDataType valueDataType = GPBGetFieldDataType(field);
 //%  GPBDataType keyDataType = field.mapKeyDataType;
 //%  uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-//%  [_dictionary enumerateKeysAndObjectsUsingBlock:^(ENUM_TYPE##KHELPER(KEY_TYPE)##aKey,
-//%                                                   ENUM_TYPE##VHELPER(VALUE_TYPE)##a##VNAME_VAR$u,
-//%                                                   BOOL *stop) {
-//%    #pragma unused(stop)
-//%    // Write the tag.
+//%  NSDictionary *internal = _dictionary;
+//%  NSEnumerator *keys = [internal keyEnumerator];
+//%  ENUM_TYPE##KHELPER(KEY_TYPE)##aKey;
+//%  while ((aKey = [keys nextObject])) {
+//%    ENUM_TYPE##VHELPER(VALUE_TYPE)##a##VNAME_VAR$u = internal[aKey];
 //%    [outputStream writeInt32NoTag:tag];
 //%    // Write the size of the message.
-//%    size_t msgSize = ComputeDict##KEY_NAME##FieldSize(UNWRAP##KEY_NAME(aKey), kMapKeyFieldNumber, keyDataType);
-//%    msgSize += ComputeDict##VALUE_NAME##FieldSize(UNWRAP##VALUE_NAME(a##VNAME_VAR$u), kMapValueFieldNumber, valueDataType);
+//%    KEY_TYPE KisP##unwrappedKey = UNWRAP##KEY_NAME(aKey);
+//%    VALUE_TYPE unwrappedValue = UNWRAP##VALUE_NAME(a##VNAME_VAR$u);
+//%    size_t msgSize = ComputeDict##KEY_NAME##FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+//%    msgSize += ComputeDict##VALUE_NAME##FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
 //%    [outputStream writeInt32NoTag:(int32_t)msgSize];
 //%    // Write the fields.
-//%    WriteDict##KEY_NAME##Field(outputStream, UNWRAP##KEY_NAME(aKey), kMapKeyFieldNumber, keyDataType);
-//%    WriteDict##VALUE_NAME##Field(outputStream, UNWRAP##VALUE_NAME(a##VNAME_VAR$u), kMapValueFieldNumber, valueDataType);
-//%  }];
+//%    WriteDict##KEY_NAME##Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+//%    WriteDict##VALUE_NAME##Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+//%  }
 //%}
 //%
 //%SERIAL_DATA_FOR_ENTRY_##VHELPER(KEY_NAME, VALUE_NAME)- (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -1366,14 +1386,15 @@
 //%- (instancetype)deepCopyWithZone:(NSZone *)zone {
 //%  GPB##KEY_NAME##VALUE_NAME##Dictionary *newDict =
 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] init];
-//%  [_dictionary enumerateKeysAndObjectsUsingBlock:^(id aKey,
-//%                                                   GPBMessage *msg,
-//%                                                   BOOL *stop) {
-//%    #pragma unused(stop)
+//%  NSEnumerator *keys = [_dictionary keyEnumerator];
+//%  id aKey;
+//%  NSMutableDictionary *internalDict = newDict->_dictionary;
+//%  while ((aKey = [keys nextObject])) {
+//%    GPBMessage *msg = _dictionary[aKey];
 //%    GPBMessage *copiedMsg = [msg copyWithZone:zone];
-//%    [newDict->_dictionary setObject:copiedMsg forKey:aKey];
+//%    [internalDict setObject:copiedMsg forKey:aKey];
 //%    [copiedMsg release];
-//%  }];
+//%  }
 //%  return newDict;
 //%}
 //%
@@ -1632,30 +1653,37 @@
 
 - (void)enumerateKeysAndUInt32sUsingBlock:
     (void (^)(uint32_t key, uint32_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey unsignedIntValue], [aValue unsignedIntValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey unsignedIntValue], [aValue unsignedIntValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictUInt32FieldSize([aValue unsignedIntValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -1666,20 +1694,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictUInt32FieldSize([aValue unsignedIntValue], kMapValueFieldNumber, valueDataType);
+    uint32_t unwrappedKey = [aKey unsignedIntValue];
+    uint32_t unwrappedValue = [aValue unsignedIntValue];
+    size_t msgSize = ComputeDictUInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictUInt32FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt32Field(outputStream, [aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictUInt32Field(outputStream, [aValue unsignedIntValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictUInt32Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -1839,30 +1869,37 @@
 
 - (void)enumerateKeysAndInt32sUsingBlock:
     (void (^)(uint32_t key, int32_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey unsignedIntValue], [aValue intValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey unsignedIntValue], [aValue intValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictInt32FieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -1873,20 +1910,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictInt32FieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
+    uint32_t unwrappedKey = [aKey unsignedIntValue];
+    int32_t unwrappedValue = [aValue intValue];
+    size_t msgSize = ComputeDictUInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictInt32FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt32Field(outputStream, [aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictInt32Field(outputStream, [aValue intValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictInt32Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -2046,30 +2085,37 @@
 
 - (void)enumerateKeysAndUInt64sUsingBlock:
     (void (^)(uint32_t key, uint64_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey unsignedIntValue], [aValue unsignedLongLongValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey unsignedIntValue], [aValue unsignedLongLongValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictUInt64FieldSize([aValue unsignedLongLongValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -2080,20 +2126,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictUInt64FieldSize([aValue unsignedLongLongValue], kMapValueFieldNumber, valueDataType);
+    uint32_t unwrappedKey = [aKey unsignedIntValue];
+    uint64_t unwrappedValue = [aValue unsignedLongLongValue];
+    size_t msgSize = ComputeDictUInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictUInt64FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt32Field(outputStream, [aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictUInt64Field(outputStream, [aValue unsignedLongLongValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictUInt64Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -2253,30 +2301,37 @@
 
 - (void)enumerateKeysAndInt64sUsingBlock:
     (void (^)(uint32_t key, int64_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey unsignedIntValue], [aValue longLongValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey unsignedIntValue], [aValue longLongValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictInt64FieldSize([aValue longLongValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -2287,20 +2342,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictInt64FieldSize([aValue longLongValue], kMapValueFieldNumber, valueDataType);
+    uint32_t unwrappedKey = [aKey unsignedIntValue];
+    int64_t unwrappedValue = [aValue longLongValue];
+    size_t msgSize = ComputeDictUInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictInt64FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt32Field(outputStream, [aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictInt64Field(outputStream, [aValue longLongValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictInt64Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -2460,30 +2517,37 @@
 
 - (void)enumerateKeysAndBoolsUsingBlock:
     (void (^)(uint32_t key, BOOL value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey unsignedIntValue], [aValue boolValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey unsignedIntValue], [aValue boolValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictBoolFieldSize([aValue boolValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -2494,20 +2558,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictBoolFieldSize([aValue boolValue], kMapValueFieldNumber, valueDataType);
+    uint32_t unwrappedKey = [aKey unsignedIntValue];
+    BOOL unwrappedValue = [aValue boolValue];
+    size_t msgSize = ComputeDictUInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictBoolFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt32Field(outputStream, [aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictBoolField(outputStream, [aValue boolValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictBoolField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -2667,30 +2733,37 @@
 
 - (void)enumerateKeysAndFloatsUsingBlock:
     (void (^)(uint32_t key, float value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey unsignedIntValue], [aValue floatValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey unsignedIntValue], [aValue floatValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictFloatFieldSize([aValue floatValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -2701,20 +2774,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictFloatFieldSize([aValue floatValue], kMapValueFieldNumber, valueDataType);
+    uint32_t unwrappedKey = [aKey unsignedIntValue];
+    float unwrappedValue = [aValue floatValue];
+    size_t msgSize = ComputeDictUInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictFloatFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt32Field(outputStream, [aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictFloatField(outputStream, [aValue floatValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictFloatField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -2874,30 +2949,37 @@
 
 - (void)enumerateKeysAndDoublesUsingBlock:
     (void (^)(uint32_t key, double value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey unsignedIntValue], [aValue doubleValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey unsignedIntValue], [aValue doubleValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictDoubleFieldSize([aValue doubleValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -2908,20 +2990,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictDoubleFieldSize([aValue doubleValue], kMapValueFieldNumber, valueDataType);
+    uint32_t unwrappedKey = [aKey unsignedIntValue];
+    double unwrappedValue = [aValue doubleValue];
+    size_t msgSize = ComputeDictUInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictDoubleFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt32Field(outputStream, [aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictDoubleField(outputStream, [aValue doubleValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictDoubleField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -3109,30 +3193,37 @@
 
 - (void)enumerateKeysAndRawValuesUsingBlock:
     (void (^)(uint32_t key, int32_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey unsignedIntValue], [aValue intValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey unsignedIntValue], [aValue intValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictEnumFieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -3143,20 +3234,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictEnumFieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
+    uint32_t unwrappedKey = [aKey unsignedIntValue];
+    int32_t unwrappedValue = [aValue intValue];
+    size_t msgSize = ComputeDictUInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictEnumFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt32Field(outputStream, [aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictEnumField(outputStream, [aValue intValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictEnumField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
@@ -3206,15 +3299,20 @@
 - (void)enumerateKeysAndEnumsUsingBlock:
     (void (^)(uint32_t key, int32_t value, BOOL *stop))block {
   GPBEnumValidationFunc func = _validationFunc;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
+  BOOL stop = NO;
+  NSEnumerator *keys = [_dictionary keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = _dictionary[aKey];
       int32_t unwrapped = [aValue intValue];
       if (!func(unwrapped)) {
         unwrapped = kGPBUnrecognizedEnumeratorValue;
       }
-      block([aKey unsignedIntValue], unwrapped, stop);
-  }];
+    block([aKey unsignedIntValue], unwrapped, &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (void)addRawEntriesFromDictionary:(GPBUInt32EnumDictionary *)otherDictionary {
@@ -3371,11 +3469,17 @@
 
 - (void)enumerateKeysAndObjectsUsingBlock:
     (void (^)(uint32_t key, id object, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   id aObject,
-                                                   BOOL *stop) {
-      block([aKey unsignedIntValue], aObject, stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    id aObject = internal[aKey];
+    block([aKey unsignedIntValue], aObject, &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (BOOL)isInitialized {
@@ -3390,34 +3494,36 @@
 - (instancetype)deepCopyWithZone:(NSZone *)zone {
   GPBUInt32ObjectDictionary *newDict =
       [[GPBUInt32ObjectDictionary alloc] init];
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(id aKey,
-                                                   GPBMessage *msg,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  NSEnumerator *keys = [_dictionary keyEnumerator];
+  id aKey;
+  NSMutableDictionary *internalDict = newDict->_dictionary;
+  while ((aKey = [keys nextObject])) {
+    GPBMessage *msg = _dictionary[aKey];
     GPBMessage *copiedMsg = [msg copyWithZone:zone];
-    [newDict->_dictionary setObject:copiedMsg forKey:aKey];
+    [internalDict setObject:copiedMsg forKey:aKey];
     [copiedMsg release];
-  }];
+  }
   return newDict;
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   id aObject,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    id aObject = internal[aKey];
     size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictObjectFieldSize(aObject, kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -3428,20 +3534,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   id aObject,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    id aObject = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt32FieldSize([aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictObjectFieldSize(aObject, kMapValueFieldNumber, valueDataType);
+    uint32_t unwrappedKey = [aKey unsignedIntValue];
+    id unwrappedValue = aObject;
+    size_t msgSize = ComputeDictUInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictObjectFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt32Field(outputStream, [aKey unsignedIntValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictObjectField(outputStream, aObject, kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictObjectField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -3605,30 +3713,37 @@
 
 - (void)enumerateKeysAndUInt32sUsingBlock:
     (void (^)(int32_t key, uint32_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey intValue], [aValue unsignedIntValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey intValue], [aValue unsignedIntValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictUInt32FieldSize([aValue unsignedIntValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -3639,20 +3754,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictUInt32FieldSize([aValue unsignedIntValue], kMapValueFieldNumber, valueDataType);
+    int32_t unwrappedKey = [aKey intValue];
+    uint32_t unwrappedValue = [aValue unsignedIntValue];
+    size_t msgSize = ComputeDictInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictUInt32FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt32Field(outputStream, [aKey intValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictUInt32Field(outputStream, [aValue unsignedIntValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictUInt32Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -3812,30 +3929,37 @@
 
 - (void)enumerateKeysAndInt32sUsingBlock:
     (void (^)(int32_t key, int32_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey intValue], [aValue intValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey intValue], [aValue intValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictInt32FieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -3846,20 +3970,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictInt32FieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
+    int32_t unwrappedKey = [aKey intValue];
+    int32_t unwrappedValue = [aValue intValue];
+    size_t msgSize = ComputeDictInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictInt32FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt32Field(outputStream, [aKey intValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictInt32Field(outputStream, [aValue intValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictInt32Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -4019,30 +4145,37 @@
 
 - (void)enumerateKeysAndUInt64sUsingBlock:
     (void (^)(int32_t key, uint64_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey intValue], [aValue unsignedLongLongValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey intValue], [aValue unsignedLongLongValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictUInt64FieldSize([aValue unsignedLongLongValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -4053,20 +4186,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictUInt64FieldSize([aValue unsignedLongLongValue], kMapValueFieldNumber, valueDataType);
+    int32_t unwrappedKey = [aKey intValue];
+    uint64_t unwrappedValue = [aValue unsignedLongLongValue];
+    size_t msgSize = ComputeDictInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictUInt64FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt32Field(outputStream, [aKey intValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictUInt64Field(outputStream, [aValue unsignedLongLongValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictUInt64Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -4226,30 +4361,37 @@
 
 - (void)enumerateKeysAndInt64sUsingBlock:
     (void (^)(int32_t key, int64_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey intValue], [aValue longLongValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey intValue], [aValue longLongValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictInt64FieldSize([aValue longLongValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -4260,20 +4402,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictInt64FieldSize([aValue longLongValue], kMapValueFieldNumber, valueDataType);
+    int32_t unwrappedKey = [aKey intValue];
+    int64_t unwrappedValue = [aValue longLongValue];
+    size_t msgSize = ComputeDictInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictInt64FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt32Field(outputStream, [aKey intValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictInt64Field(outputStream, [aValue longLongValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictInt64Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -4433,30 +4577,37 @@
 
 - (void)enumerateKeysAndBoolsUsingBlock:
     (void (^)(int32_t key, BOOL value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey intValue], [aValue boolValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey intValue], [aValue boolValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictBoolFieldSize([aValue boolValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -4467,20 +4618,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictBoolFieldSize([aValue boolValue], kMapValueFieldNumber, valueDataType);
+    int32_t unwrappedKey = [aKey intValue];
+    BOOL unwrappedValue = [aValue boolValue];
+    size_t msgSize = ComputeDictInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictBoolFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt32Field(outputStream, [aKey intValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictBoolField(outputStream, [aValue boolValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictBoolField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -4640,30 +4793,37 @@
 
 - (void)enumerateKeysAndFloatsUsingBlock:
     (void (^)(int32_t key, float value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey intValue], [aValue floatValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey intValue], [aValue floatValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictFloatFieldSize([aValue floatValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -4674,20 +4834,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictFloatFieldSize([aValue floatValue], kMapValueFieldNumber, valueDataType);
+    int32_t unwrappedKey = [aKey intValue];
+    float unwrappedValue = [aValue floatValue];
+    size_t msgSize = ComputeDictInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictFloatFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt32Field(outputStream, [aKey intValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictFloatField(outputStream, [aValue floatValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictFloatField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -4847,30 +5009,37 @@
 
 - (void)enumerateKeysAndDoublesUsingBlock:
     (void (^)(int32_t key, double value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey intValue], [aValue doubleValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey intValue], [aValue doubleValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictDoubleFieldSize([aValue doubleValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -4881,20 +5050,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictDoubleFieldSize([aValue doubleValue], kMapValueFieldNumber, valueDataType);
+    int32_t unwrappedKey = [aKey intValue];
+    double unwrappedValue = [aValue doubleValue];
+    size_t msgSize = ComputeDictInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictDoubleFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt32Field(outputStream, [aKey intValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictDoubleField(outputStream, [aValue doubleValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictDoubleField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -5082,30 +5253,37 @@
 
 - (void)enumerateKeysAndRawValuesUsingBlock:
     (void (^)(int32_t key, int32_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey intValue], [aValue intValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey intValue], [aValue intValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictEnumFieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -5116,20 +5294,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictEnumFieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
+    int32_t unwrappedKey = [aKey intValue];
+    int32_t unwrappedValue = [aValue intValue];
+    size_t msgSize = ComputeDictInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictEnumFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt32Field(outputStream, [aKey intValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictEnumField(outputStream, [aValue intValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictEnumField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
@@ -5179,15 +5359,20 @@
 - (void)enumerateKeysAndEnumsUsingBlock:
     (void (^)(int32_t key, int32_t value, BOOL *stop))block {
   GPBEnumValidationFunc func = _validationFunc;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
+  BOOL stop = NO;
+  NSEnumerator *keys = [_dictionary keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = _dictionary[aKey];
       int32_t unwrapped = [aValue intValue];
       if (!func(unwrapped)) {
         unwrapped = kGPBUnrecognizedEnumeratorValue;
       }
-      block([aKey intValue], unwrapped, stop);
-  }];
+    block([aKey intValue], unwrapped, &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (void)addRawEntriesFromDictionary:(GPBInt32EnumDictionary *)otherDictionary {
@@ -5344,11 +5529,17 @@
 
 - (void)enumerateKeysAndObjectsUsingBlock:
     (void (^)(int32_t key, id object, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   id aObject,
-                                                   BOOL *stop) {
-      block([aKey intValue], aObject, stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    id aObject = internal[aKey];
+    block([aKey intValue], aObject, &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (BOOL)isInitialized {
@@ -5363,34 +5554,36 @@
 - (instancetype)deepCopyWithZone:(NSZone *)zone {
   GPBInt32ObjectDictionary *newDict =
       [[GPBInt32ObjectDictionary alloc] init];
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(id aKey,
-                                                   GPBMessage *msg,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  NSEnumerator *keys = [_dictionary keyEnumerator];
+  id aKey;
+  NSMutableDictionary *internalDict = newDict->_dictionary;
+  while ((aKey = [keys nextObject])) {
+    GPBMessage *msg = _dictionary[aKey];
     GPBMessage *copiedMsg = [msg copyWithZone:zone];
-    [newDict->_dictionary setObject:copiedMsg forKey:aKey];
+    [internalDict setObject:copiedMsg forKey:aKey];
     [copiedMsg release];
-  }];
+  }
   return newDict;
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   id aObject,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    id aObject = internal[aKey];
     size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictObjectFieldSize(aObject, kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -5401,20 +5594,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   id aObject,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    id aObject = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt32FieldSize([aKey intValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictObjectFieldSize(aObject, kMapValueFieldNumber, valueDataType);
+    int32_t unwrappedKey = [aKey intValue];
+    id unwrappedValue = aObject;
+    size_t msgSize = ComputeDictInt32FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictObjectFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt32Field(outputStream, [aKey intValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictObjectField(outputStream, aObject, kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt32Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictObjectField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -5578,30 +5773,37 @@
 
 - (void)enumerateKeysAndUInt32sUsingBlock:
     (void (^)(uint64_t key, uint32_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey unsignedLongLongValue], [aValue unsignedIntValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey unsignedLongLongValue], [aValue unsignedIntValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictUInt32FieldSize([aValue unsignedIntValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -5612,20 +5814,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictUInt32FieldSize([aValue unsignedIntValue], kMapValueFieldNumber, valueDataType);
+    uint64_t unwrappedKey = [aKey unsignedLongLongValue];
+    uint32_t unwrappedValue = [aValue unsignedIntValue];
+    size_t msgSize = ComputeDictUInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictUInt32FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt64Field(outputStream, [aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictUInt32Field(outputStream, [aValue unsignedIntValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictUInt32Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -5785,30 +5989,37 @@
 
 - (void)enumerateKeysAndInt32sUsingBlock:
     (void (^)(uint64_t key, int32_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey unsignedLongLongValue], [aValue intValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey unsignedLongLongValue], [aValue intValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictInt32FieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -5819,20 +6030,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictInt32FieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
+    uint64_t unwrappedKey = [aKey unsignedLongLongValue];
+    int32_t unwrappedValue = [aValue intValue];
+    size_t msgSize = ComputeDictUInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictInt32FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt64Field(outputStream, [aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictInt32Field(outputStream, [aValue intValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictInt32Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -5992,30 +6205,37 @@
 
 - (void)enumerateKeysAndUInt64sUsingBlock:
     (void (^)(uint64_t key, uint64_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey unsignedLongLongValue], [aValue unsignedLongLongValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey unsignedLongLongValue], [aValue unsignedLongLongValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictUInt64FieldSize([aValue unsignedLongLongValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -6026,20 +6246,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictUInt64FieldSize([aValue unsignedLongLongValue], kMapValueFieldNumber, valueDataType);
+    uint64_t unwrappedKey = [aKey unsignedLongLongValue];
+    uint64_t unwrappedValue = [aValue unsignedLongLongValue];
+    size_t msgSize = ComputeDictUInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictUInt64FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt64Field(outputStream, [aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictUInt64Field(outputStream, [aValue unsignedLongLongValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictUInt64Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -6199,30 +6421,37 @@
 
 - (void)enumerateKeysAndInt64sUsingBlock:
     (void (^)(uint64_t key, int64_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey unsignedLongLongValue], [aValue longLongValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey unsignedLongLongValue], [aValue longLongValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictInt64FieldSize([aValue longLongValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -6233,20 +6462,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictInt64FieldSize([aValue longLongValue], kMapValueFieldNumber, valueDataType);
+    uint64_t unwrappedKey = [aKey unsignedLongLongValue];
+    int64_t unwrappedValue = [aValue longLongValue];
+    size_t msgSize = ComputeDictUInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictInt64FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt64Field(outputStream, [aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictInt64Field(outputStream, [aValue longLongValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictInt64Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -6406,30 +6637,37 @@
 
 - (void)enumerateKeysAndBoolsUsingBlock:
     (void (^)(uint64_t key, BOOL value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey unsignedLongLongValue], [aValue boolValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey unsignedLongLongValue], [aValue boolValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictBoolFieldSize([aValue boolValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -6440,20 +6678,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictBoolFieldSize([aValue boolValue], kMapValueFieldNumber, valueDataType);
+    uint64_t unwrappedKey = [aKey unsignedLongLongValue];
+    BOOL unwrappedValue = [aValue boolValue];
+    size_t msgSize = ComputeDictUInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictBoolFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt64Field(outputStream, [aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictBoolField(outputStream, [aValue boolValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictBoolField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -6613,30 +6853,37 @@
 
 - (void)enumerateKeysAndFloatsUsingBlock:
     (void (^)(uint64_t key, float value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey unsignedLongLongValue], [aValue floatValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey unsignedLongLongValue], [aValue floatValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictFloatFieldSize([aValue floatValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -6647,20 +6894,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictFloatFieldSize([aValue floatValue], kMapValueFieldNumber, valueDataType);
+    uint64_t unwrappedKey = [aKey unsignedLongLongValue];
+    float unwrappedValue = [aValue floatValue];
+    size_t msgSize = ComputeDictUInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictFloatFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt64Field(outputStream, [aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictFloatField(outputStream, [aValue floatValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictFloatField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -6820,30 +7069,37 @@
 
 - (void)enumerateKeysAndDoublesUsingBlock:
     (void (^)(uint64_t key, double value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey unsignedLongLongValue], [aValue doubleValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey unsignedLongLongValue], [aValue doubleValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictDoubleFieldSize([aValue doubleValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -6854,20 +7110,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictDoubleFieldSize([aValue doubleValue], kMapValueFieldNumber, valueDataType);
+    uint64_t unwrappedKey = [aKey unsignedLongLongValue];
+    double unwrappedValue = [aValue doubleValue];
+    size_t msgSize = ComputeDictUInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictDoubleFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt64Field(outputStream, [aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictDoubleField(outputStream, [aValue doubleValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictDoubleField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -7055,30 +7313,37 @@
 
 - (void)enumerateKeysAndRawValuesUsingBlock:
     (void (^)(uint64_t key, int32_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey unsignedLongLongValue], [aValue intValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey unsignedLongLongValue], [aValue intValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictEnumFieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -7089,20 +7354,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictEnumFieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
+    uint64_t unwrappedKey = [aKey unsignedLongLongValue];
+    int32_t unwrappedValue = [aValue intValue];
+    size_t msgSize = ComputeDictUInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictEnumFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt64Field(outputStream, [aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictEnumField(outputStream, [aValue intValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictEnumField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
@@ -7152,15 +7419,20 @@
 - (void)enumerateKeysAndEnumsUsingBlock:
     (void (^)(uint64_t key, int32_t value, BOOL *stop))block {
   GPBEnumValidationFunc func = _validationFunc;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
+  BOOL stop = NO;
+  NSEnumerator *keys = [_dictionary keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = _dictionary[aKey];
       int32_t unwrapped = [aValue intValue];
       if (!func(unwrapped)) {
         unwrapped = kGPBUnrecognizedEnumeratorValue;
       }
-      block([aKey unsignedLongLongValue], unwrapped, stop);
-  }];
+    block([aKey unsignedLongLongValue], unwrapped, &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (void)addRawEntriesFromDictionary:(GPBUInt64EnumDictionary *)otherDictionary {
@@ -7317,11 +7589,17 @@
 
 - (void)enumerateKeysAndObjectsUsingBlock:
     (void (^)(uint64_t key, id object, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   id aObject,
-                                                   BOOL *stop) {
-      block([aKey unsignedLongLongValue], aObject, stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    id aObject = internal[aKey];
+    block([aKey unsignedLongLongValue], aObject, &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (BOOL)isInitialized {
@@ -7336,34 +7614,36 @@
 - (instancetype)deepCopyWithZone:(NSZone *)zone {
   GPBUInt64ObjectDictionary *newDict =
       [[GPBUInt64ObjectDictionary alloc] init];
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(id aKey,
-                                                   GPBMessage *msg,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  NSEnumerator *keys = [_dictionary keyEnumerator];
+  id aKey;
+  NSMutableDictionary *internalDict = newDict->_dictionary;
+  while ((aKey = [keys nextObject])) {
+    GPBMessage *msg = _dictionary[aKey];
     GPBMessage *copiedMsg = [msg copyWithZone:zone];
-    [newDict->_dictionary setObject:copiedMsg forKey:aKey];
+    [internalDict setObject:copiedMsg forKey:aKey];
     [copiedMsg release];
-  }];
+  }
   return newDict;
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   id aObject,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    id aObject = internal[aKey];
     size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictObjectFieldSize(aObject, kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -7374,20 +7654,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   id aObject,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    id aObject = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictUInt64FieldSize([aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictObjectFieldSize(aObject, kMapValueFieldNumber, valueDataType);
+    uint64_t unwrappedKey = [aKey unsignedLongLongValue];
+    id unwrappedValue = aObject;
+    size_t msgSize = ComputeDictUInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictObjectFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictUInt64Field(outputStream, [aKey unsignedLongLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictObjectField(outputStream, aObject, kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictUInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictObjectField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -7551,30 +7833,37 @@
 
 - (void)enumerateKeysAndUInt32sUsingBlock:
     (void (^)(int64_t key, uint32_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey longLongValue], [aValue unsignedIntValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey longLongValue], [aValue unsignedIntValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictUInt32FieldSize([aValue unsignedIntValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -7585,20 +7874,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictUInt32FieldSize([aValue unsignedIntValue], kMapValueFieldNumber, valueDataType);
+    int64_t unwrappedKey = [aKey longLongValue];
+    uint32_t unwrappedValue = [aValue unsignedIntValue];
+    size_t msgSize = ComputeDictInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictUInt32FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt64Field(outputStream, [aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictUInt32Field(outputStream, [aValue unsignedIntValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictUInt32Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -7758,30 +8049,37 @@
 
 - (void)enumerateKeysAndInt32sUsingBlock:
     (void (^)(int64_t key, int32_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey longLongValue], [aValue intValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey longLongValue], [aValue intValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictInt32FieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -7792,20 +8090,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictInt32FieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
+    int64_t unwrappedKey = [aKey longLongValue];
+    int32_t unwrappedValue = [aValue intValue];
+    size_t msgSize = ComputeDictInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictInt32FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt64Field(outputStream, [aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictInt32Field(outputStream, [aValue intValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictInt32Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -7965,30 +8265,37 @@
 
 - (void)enumerateKeysAndUInt64sUsingBlock:
     (void (^)(int64_t key, uint64_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey longLongValue], [aValue unsignedLongLongValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey longLongValue], [aValue unsignedLongLongValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictUInt64FieldSize([aValue unsignedLongLongValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -7999,20 +8306,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictUInt64FieldSize([aValue unsignedLongLongValue], kMapValueFieldNumber, valueDataType);
+    int64_t unwrappedKey = [aKey longLongValue];
+    uint64_t unwrappedValue = [aValue unsignedLongLongValue];
+    size_t msgSize = ComputeDictInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictUInt64FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt64Field(outputStream, [aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictUInt64Field(outputStream, [aValue unsignedLongLongValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictUInt64Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -8172,30 +8481,37 @@
 
 - (void)enumerateKeysAndInt64sUsingBlock:
     (void (^)(int64_t key, int64_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey longLongValue], [aValue longLongValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey longLongValue], [aValue longLongValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictInt64FieldSize([aValue longLongValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -8206,20 +8522,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictInt64FieldSize([aValue longLongValue], kMapValueFieldNumber, valueDataType);
+    int64_t unwrappedKey = [aKey longLongValue];
+    int64_t unwrappedValue = [aValue longLongValue];
+    size_t msgSize = ComputeDictInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictInt64FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt64Field(outputStream, [aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictInt64Field(outputStream, [aValue longLongValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictInt64Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -8379,30 +8697,37 @@
 
 - (void)enumerateKeysAndBoolsUsingBlock:
     (void (^)(int64_t key, BOOL value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey longLongValue], [aValue boolValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey longLongValue], [aValue boolValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictBoolFieldSize([aValue boolValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -8413,20 +8738,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictBoolFieldSize([aValue boolValue], kMapValueFieldNumber, valueDataType);
+    int64_t unwrappedKey = [aKey longLongValue];
+    BOOL unwrappedValue = [aValue boolValue];
+    size_t msgSize = ComputeDictInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictBoolFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt64Field(outputStream, [aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictBoolField(outputStream, [aValue boolValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictBoolField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -8586,30 +8913,37 @@
 
 - (void)enumerateKeysAndFloatsUsingBlock:
     (void (^)(int64_t key, float value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey longLongValue], [aValue floatValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey longLongValue], [aValue floatValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictFloatFieldSize([aValue floatValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -8620,20 +8954,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictFloatFieldSize([aValue floatValue], kMapValueFieldNumber, valueDataType);
+    int64_t unwrappedKey = [aKey longLongValue];
+    float unwrappedValue = [aValue floatValue];
+    size_t msgSize = ComputeDictInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictFloatFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt64Field(outputStream, [aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictFloatField(outputStream, [aValue floatValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictFloatField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -8793,30 +9129,37 @@
 
 - (void)enumerateKeysAndDoublesUsingBlock:
     (void (^)(int64_t key, double value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey longLongValue], [aValue doubleValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey longLongValue], [aValue doubleValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictDoubleFieldSize([aValue doubleValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -8827,20 +9170,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictDoubleFieldSize([aValue doubleValue], kMapValueFieldNumber, valueDataType);
+    int64_t unwrappedKey = [aKey longLongValue];
+    double unwrappedValue = [aValue doubleValue];
+    size_t msgSize = ComputeDictInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictDoubleFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt64Field(outputStream, [aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictDoubleField(outputStream, [aValue doubleValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictDoubleField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -9028,30 +9373,37 @@
 
 - (void)enumerateKeysAndRawValuesUsingBlock:
     (void (^)(int64_t key, int32_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block([aKey longLongValue], [aValue intValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block([aKey longLongValue], [aValue intValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictEnumFieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -9062,20 +9414,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictEnumFieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
+    int64_t unwrappedKey = [aKey longLongValue];
+    int32_t unwrappedValue = [aValue intValue];
+    size_t msgSize = ComputeDictInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictEnumFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt64Field(outputStream, [aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictEnumField(outputStream, [aValue intValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictEnumField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
@@ -9125,15 +9479,20 @@
 - (void)enumerateKeysAndEnumsUsingBlock:
     (void (^)(int64_t key, int32_t value, BOOL *stop))block {
   GPBEnumValidationFunc func = _validationFunc;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
+  BOOL stop = NO;
+  NSEnumerator *keys = [_dictionary keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = _dictionary[aKey];
       int32_t unwrapped = [aValue intValue];
       if (!func(unwrapped)) {
         unwrapped = kGPBUnrecognizedEnumeratorValue;
       }
-      block([aKey longLongValue], unwrapped, stop);
-  }];
+    block([aKey longLongValue], unwrapped, &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (void)addRawEntriesFromDictionary:(GPBInt64EnumDictionary *)otherDictionary {
@@ -9290,11 +9649,17 @@
 
 - (void)enumerateKeysAndObjectsUsingBlock:
     (void (^)(int64_t key, id object, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   id aObject,
-                                                   BOOL *stop) {
-      block([aKey longLongValue], aObject, stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    id aObject = internal[aKey];
+    block([aKey longLongValue], aObject, &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (BOOL)isInitialized {
@@ -9309,34 +9674,36 @@
 - (instancetype)deepCopyWithZone:(NSZone *)zone {
   GPBInt64ObjectDictionary *newDict =
       [[GPBInt64ObjectDictionary alloc] init];
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(id aKey,
-                                                   GPBMessage *msg,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  NSEnumerator *keys = [_dictionary keyEnumerator];
+  id aKey;
+  NSMutableDictionary *internalDict = newDict->_dictionary;
+  while ((aKey = [keys nextObject])) {
+    GPBMessage *msg = _dictionary[aKey];
     GPBMessage *copiedMsg = [msg copyWithZone:zone];
-    [newDict->_dictionary setObject:copiedMsg forKey:aKey];
+    [internalDict setObject:copiedMsg forKey:aKey];
     [copiedMsg release];
-  }];
+  }
   return newDict;
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   id aObject,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    id aObject = internal[aKey];
     size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictObjectFieldSize(aObject, kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -9347,20 +9714,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
-                                                   id aObject,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSNumber *aKey;
+  while ((aKey = [keys nextObject])) {
+    id aObject = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictInt64FieldSize([aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictObjectFieldSize(aObject, kMapValueFieldNumber, valueDataType);
+    int64_t unwrappedKey = [aKey longLongValue];
+    id unwrappedValue = aObject;
+    size_t msgSize = ComputeDictInt64FieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictObjectFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictInt64Field(outputStream, [aKey longLongValue], kMapKeyFieldNumber, keyDataType);
-    WriteDictObjectField(outputStream, aObject, kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictInt64Field(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictObjectField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -9528,30 +9897,37 @@
 
 - (void)enumerateKeysAndUInt32sUsingBlock:
     (void (^)(NSString *key, uint32_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block(aKey, [aValue unsignedIntValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block(aKey, [aValue unsignedIntValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictStringFieldSize(aKey, kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictUInt32FieldSize([aValue unsignedIntValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -9562,20 +9938,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictStringFieldSize(aKey, kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictUInt32FieldSize([aValue unsignedIntValue], kMapValueFieldNumber, valueDataType);
+    NSString *unwrappedKey = aKey;
+    uint32_t unwrappedValue = [aValue unsignedIntValue];
+    size_t msgSize = ComputeDictStringFieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictUInt32FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictStringField(outputStream, aKey, kMapKeyFieldNumber, keyDataType);
-    WriteDictUInt32Field(outputStream, [aValue unsignedIntValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictStringField(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictUInt32Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -9743,30 +10121,37 @@
 
 - (void)enumerateKeysAndInt32sUsingBlock:
     (void (^)(NSString *key, int32_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block(aKey, [aValue intValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block(aKey, [aValue intValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictStringFieldSize(aKey, kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictInt32FieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -9777,20 +10162,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictStringFieldSize(aKey, kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictInt32FieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
+    NSString *unwrappedKey = aKey;
+    int32_t unwrappedValue = [aValue intValue];
+    size_t msgSize = ComputeDictStringFieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictInt32FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictStringField(outputStream, aKey, kMapKeyFieldNumber, keyDataType);
-    WriteDictInt32Field(outputStream, [aValue intValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictStringField(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictInt32Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -9958,30 +10345,37 @@
 
 - (void)enumerateKeysAndUInt64sUsingBlock:
     (void (^)(NSString *key, uint64_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block(aKey, [aValue unsignedLongLongValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block(aKey, [aValue unsignedLongLongValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictStringFieldSize(aKey, kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictUInt64FieldSize([aValue unsignedLongLongValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -9992,20 +10386,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictStringFieldSize(aKey, kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictUInt64FieldSize([aValue unsignedLongLongValue], kMapValueFieldNumber, valueDataType);
+    NSString *unwrappedKey = aKey;
+    uint64_t unwrappedValue = [aValue unsignedLongLongValue];
+    size_t msgSize = ComputeDictStringFieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictUInt64FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictStringField(outputStream, aKey, kMapKeyFieldNumber, keyDataType);
-    WriteDictUInt64Field(outputStream, [aValue unsignedLongLongValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictStringField(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictUInt64Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -10173,30 +10569,37 @@
 
 - (void)enumerateKeysAndInt64sUsingBlock:
     (void (^)(NSString *key, int64_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block(aKey, [aValue longLongValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block(aKey, [aValue longLongValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictStringFieldSize(aKey, kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictInt64FieldSize([aValue longLongValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -10207,20 +10610,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictStringFieldSize(aKey, kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictInt64FieldSize([aValue longLongValue], kMapValueFieldNumber, valueDataType);
+    NSString *unwrappedKey = aKey;
+    int64_t unwrappedValue = [aValue longLongValue];
+    size_t msgSize = ComputeDictStringFieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictInt64FieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictStringField(outputStream, aKey, kMapKeyFieldNumber, keyDataType);
-    WriteDictInt64Field(outputStream, [aValue longLongValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictStringField(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictInt64Field(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -10388,30 +10793,37 @@
 
 - (void)enumerateKeysAndBoolsUsingBlock:
     (void (^)(NSString *key, BOOL value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block(aKey, [aValue boolValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block(aKey, [aValue boolValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictStringFieldSize(aKey, kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictBoolFieldSize([aValue boolValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -10422,20 +10834,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictStringFieldSize(aKey, kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictBoolFieldSize([aValue boolValue], kMapValueFieldNumber, valueDataType);
+    NSString *unwrappedKey = aKey;
+    BOOL unwrappedValue = [aValue boolValue];
+    size_t msgSize = ComputeDictStringFieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictBoolFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictStringField(outputStream, aKey, kMapKeyFieldNumber, keyDataType);
-    WriteDictBoolField(outputStream, [aValue boolValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictStringField(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictBoolField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -10603,30 +11017,37 @@
 
 - (void)enumerateKeysAndFloatsUsingBlock:
     (void (^)(NSString *key, float value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block(aKey, [aValue floatValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block(aKey, [aValue floatValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictStringFieldSize(aKey, kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictFloatFieldSize([aValue floatValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -10637,20 +11058,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictStringFieldSize(aKey, kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictFloatFieldSize([aValue floatValue], kMapValueFieldNumber, valueDataType);
+    NSString *unwrappedKey = aKey;
+    float unwrappedValue = [aValue floatValue];
+    size_t msgSize = ComputeDictStringFieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictFloatFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictStringField(outputStream, aKey, kMapKeyFieldNumber, keyDataType);
-    WriteDictFloatField(outputStream, [aValue floatValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictStringField(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictFloatField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -10818,30 +11241,37 @@
 
 - (void)enumerateKeysAndDoublesUsingBlock:
     (void (^)(NSString *key, double value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block(aKey, [aValue doubleValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block(aKey, [aValue doubleValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictStringFieldSize(aKey, kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictDoubleFieldSize([aValue doubleValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -10852,20 +11282,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictStringFieldSize(aKey, kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictDoubleFieldSize([aValue doubleValue], kMapValueFieldNumber, valueDataType);
+    NSString *unwrappedKey = aKey;
+    double unwrappedValue = [aValue doubleValue];
+    size_t msgSize = ComputeDictStringFieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictDoubleFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictStringField(outputStream, aKey, kMapKeyFieldNumber, keyDataType);
-    WriteDictDoubleField(outputStream, [aValue doubleValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictStringField(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictDoubleField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (void)setGPBGenericValue:(GPBGenericValue *)value
@@ -11061,30 +11493,37 @@
 
 - (void)enumerateKeysAndRawValuesUsingBlock:
     (void (^)(NSString *key, int32_t value, BOOL *stop))block {
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-      block(aKey, [aValue intValue], stop);
-  }];
+  BOOL stop = NO;
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
+    block(aKey, [aValue intValue], &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field {
-  NSUInteger count = _dictionary.count;
+  NSDictionary *internal = _dictionary;
+  NSUInteger count = internal.count;
   if (count == 0) {
     return 0;
   }
 
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
-  __block size_t result = 0;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
+  size_t result = 0;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     size_t msgSize = ComputeDictStringFieldSize(aKey, kMapKeyFieldNumber, keyDataType);
     msgSize += ComputeDictEnumFieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
     result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
-  }];
+  }
   size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
   result += tagSize * count;
   return result;
@@ -11095,20 +11534,22 @@
   GPBDataType valueDataType = GPBGetFieldDataType(field);
   GPBDataType keyDataType = field.mapKeyDataType;
   uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
-    #pragma unused(stop)
-    // Write the tag.
+  NSDictionary *internal = _dictionary;
+  NSEnumerator *keys = [internal keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = internal[aKey];
     [outputStream writeInt32NoTag:tag];
     // Write the size of the message.
-    size_t msgSize = ComputeDictStringFieldSize(aKey, kMapKeyFieldNumber, keyDataType);
-    msgSize += ComputeDictEnumFieldSize([aValue intValue], kMapValueFieldNumber, valueDataType);
+    NSString *unwrappedKey = aKey;
+    int32_t unwrappedValue = [aValue intValue];
+    size_t msgSize = ComputeDictStringFieldSize(unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    msgSize += ComputeDictEnumFieldSize(unwrappedValue, kMapValueFieldNumber, valueDataType);
     [outputStream writeInt32NoTag:(int32_t)msgSize];
     // Write the fields.
-    WriteDictStringField(outputStream, aKey, kMapKeyFieldNumber, keyDataType);
-    WriteDictEnumField(outputStream, [aValue intValue], kMapValueFieldNumber, valueDataType);
-  }];
+    WriteDictStringField(outputStream, unwrappedKey, kMapKeyFieldNumber, keyDataType);
+    WriteDictEnumField(outputStream, unwrappedValue, kMapValueFieldNumber, valueDataType);
+  }
 }
 
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
@@ -11158,15 +11599,20 @@
 - (void)enumerateKeysAndEnumsUsingBlock:
     (void (^)(NSString *key, int32_t value, BOOL *stop))block {
   GPBEnumValidationFunc func = _validationFunc;
-  [_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
-                                                   NSNumber *aValue,
-                                                   BOOL *stop) {
+  BOOL stop = NO;
+  NSEnumerator *keys = [_dictionary keyEnumerator];
+  NSString *aKey;
+  while ((aKey = [keys nextObject])) {
+    NSNumber *aValue = _dictionary[aKey];
       int32_t unwrapped = [aValue intValue];
       if (!func(unwrapped)) {
         unwrapped = kGPBUnrecognizedEnumeratorValue;
       }
-      block(aKey, unwrapped, stop);
-  }];
+    block(aKey, unwrapped, &stop);
+    if (stop) {
+      break;
+    }
+  }
 }
 
 - (void)addRawEntriesFromDictionary:(GPBStringEnumDictionary *)otherDictionary {
diff --git a/objectivec/GPBExtensionRegistry.m b/objectivec/GPBExtensionRegistry.m
index 65534b6..b056a52 100644
--- a/objectivec/GPBExtensionRegistry.m
+++ b/objectivec/GPBExtensionRegistry.m
@@ -57,14 +57,16 @@
 
 - (instancetype)copyWithZone:(NSZone *)zone {
   GPBExtensionRegistry *result = [[[self class] allocWithZone:zone] init];
-  if (result && mutableClassMap_.count) {
-    [result->mutableClassMap_ addEntriesFromDictionary:mutableClassMap_];
-  }
+  [result addExtensions:self];
   return result;
 }
 
-- (CFMutableDictionaryRef)extensionMapForContainingMessageClass:
-        (Class)containingMessageClass {
+- (void)addExtension:(GPBExtensionDescriptor *)extension {
+  if (extension == nil) {
+    return;
+  }
+
+  Class containingMessageClass = extension.containingMessageClass;
   CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
       [mutableClassMap_ objectForKey:containingMessageClass];
   if (extensionMap == nil) {
@@ -74,18 +76,9 @@
                                              &kCFTypeDictionaryValueCallBacks);
     [mutableClassMap_ setObject:(id)extensionMap
                          forKey:(id<NSCopying>)containingMessageClass];
-  }
-  return extensionMap;
-}
-
-- (void)addExtension:(GPBExtensionDescriptor *)extension {
-  if (extension == nil) {
-    return;
+    CFRelease(extensionMap);
   }
 
-  Class containingMessageClass = extension.containingMessageClass;
-  CFMutableDictionaryRef extensionMap =
-      [self extensionMapForContainingMessageClass:containingMessageClass];
   ssize_t key = extension.fieldNumber;
   CFDictionarySetValue(extensionMap, (const void *)key, extension);
 }
@@ -119,10 +112,16 @@
     Class containingMessageClass = key;
     CFMutableDictionaryRef otherExtensionMap = (CFMutableDictionaryRef)value;
 
-    CFMutableDictionaryRef extensionMap =
-        [self extensionMapForContainingMessageClass:containingMessageClass];
-
-    CFDictionaryApplyFunction(otherExtensionMap, CopyKeyValue, extensionMap);
+    CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
+        [mutableClassMap_ objectForKey:containingMessageClass];
+    if (extensionMap == nil) {
+      extensionMap = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, otherExtensionMap);
+      [mutableClassMap_ setObject:(id)extensionMap
+                           forKey:(id<NSCopying>)containingMessageClass];
+      CFRelease(extensionMap);
+    } else {
+      CFDictionaryApplyFunction(otherExtensionMap, CopyKeyValue, extensionMap);
+    }
   }];
 }
 
diff --git a/objectivec/GPBMessage.h b/objectivec/GPBMessage.h
index 2c325ba..276740d 100644
--- a/objectivec/GPBMessage.h
+++ b/objectivec/GPBMessage.h
@@ -292,6 +292,9 @@
  * Writes out the message to the given coded output stream.
  *
  * @param output The coded output stream into which to write the message.
+ *
+ * @note This can raise the GPBCodedOutputStreamException_* exceptions.
+ *
  **/
 - (void)writeToCodedOutputStream:(GPBCodedOutputStream *)output;
 
@@ -299,6 +302,8 @@
  * Writes out the message to the given output stream.
  *
  * @param output The output stream into which to write the message.
+ *
+ * @note This can raise the GPBCodedOutputStreamException_* exceptions.
  **/
 - (void)writeToOutputStream:(NSOutputStream *)output;
 
@@ -307,6 +312,8 @@
  * the given output stream.
  *
  * @param output The coded output stream into which to write the message.
+ *
+ * @note This can raise the GPBCodedOutputStreamException_* exceptions.
  **/
 - (void)writeDelimitedToCodedOutputStream:(GPBCodedOutputStream *)output;
 
@@ -315,6 +322,8 @@
  * the given output stream.
  *
  * @param output The output stream into which to write the message.
+ *
+ * @note This can raise the GPBCodedOutputStreamException_* exceptions.
  **/
 - (void)writeDelimitedToOutputStream:(NSOutputStream *)output;
 
diff --git a/objectivec/GPBMessage.m b/objectivec/GPBMessage.m
index 627a396..37cff6c 100644
--- a/objectivec/GPBMessage.m
+++ b/objectivec/GPBMessage.m
@@ -2372,17 +2372,11 @@
         // zero signals EOF / limit reached
         return;
       } else {
-        if (GPBPreserveUnknownFields(syntax)) {
-          if (![self parseUnknownField:input
-                     extensionRegistry:extensionRegistry
-                                   tag:tag]) {
-            // it's an endgroup tag
-            return;
-          }
-        } else {
-          if (![input skipField:tag]) {
-            return;
-          }
+        if (![self parseUnknownField:input
+                   extensionRegistry:extensionRegistry
+                                 tag:tag]) {
+          // it's an endgroup tag
+          return;
         }
       }
     }  // if(!merged)
@@ -3083,7 +3077,7 @@
 + (BOOL)resolveInstanceMethod:(SEL)sel {
   const GPBDescriptor *descriptor = [self descriptor];
   if (!descriptor) {
-    return NO;
+    return [super resolveInstanceMethod:sel];
   }
 
   // NOTE: hasOrCountSel_/setHasSel_ will be NULL if the field for the given
diff --git a/objectivec/GPBUnknownField.h b/objectivec/GPBUnknownField.h
index a135cc2..5b96023 100644
--- a/objectivec/GPBUnknownField.h
+++ b/objectivec/GPBUnknownField.h
@@ -42,6 +42,9 @@
  **/
 @interface GPBUnknownField : NSObject<NSCopying>
 
+/** Initialize a field with the given number. */
+- (instancetype)initWithNumber:(int32_t)number;
+
 /** The field number the data is stored under. */
 @property(nonatomic, readonly, assign) int32_t number;
 
diff --git a/objectivec/GPBUnknownField_PackagePrivate.h b/objectivec/GPBUnknownField_PackagePrivate.h
index 1fbce0f..2b4c789 100644
--- a/objectivec/GPBUnknownField_PackagePrivate.h
+++ b/objectivec/GPBUnknownField_PackagePrivate.h
@@ -36,8 +36,6 @@
 
 @interface GPBUnknownField ()
 
-- (instancetype)initWithNumber:(int32_t)number;
-
 - (void)writeToOutput:(GPBCodedOutputStream *)output;
 - (size_t)serializedSize;
 
diff --git a/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
index 919d007..cd7fcc9 100644
--- a/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
+++ b/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
@@ -52,6 +52,7 @@
 		F4487C751AADF7F500531423 /* GPBMessageTests+Runtime.m in Sources */ = {isa = PBXBuildFile; fileRef = F4487C741AADF7F500531423 /* GPBMessageTests+Runtime.m */; };
 		F4487C7F1AAF62CD00531423 /* GPBMessageTests+Serialization.m in Sources */ = {isa = PBXBuildFile; fileRef = F4487C7E1AAF62CD00531423 /* GPBMessageTests+Serialization.m */; };
 		F4487C831AAF6AB300531423 /* GPBMessageTests+Merge.m in Sources */ = {isa = PBXBuildFile; fileRef = F4487C821AAF6AB300531423 /* GPBMessageTests+Merge.m */; };
+		F4584D821ECCB52A00803AB6 /* GPBExtensionRegistryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = F4584D7E1ECCB38900803AB6 /* GPBExtensionRegistryTest.m */; };
 		F45C69CC16DFD08D0081955B /* GPBExtensionInternals.m in Sources */ = {isa = PBXBuildFile; fileRef = F45C69CB16DFD08D0081955B /* GPBExtensionInternals.m */; };
 		F45E57C71AE6DC6A000B7D99 /* text_format_map_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F45E57C61AE6DC6A000B7D99 /* text_format_map_unittest_data.txt */; };
 		F47476E51D21A524007C7B1A /* Duration.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248D41A92826400BC1EC6 /* Duration.pbobjc.m */; };
@@ -180,6 +181,7 @@
 		F4487C821AAF6AB300531423 /* GPBMessageTests+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBMessageTests+Merge.m"; sourceTree = "<group>"; };
 		F44929001C866B1900C2548A /* GPBCodedOutputStream_PackagePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBCodedOutputStream_PackagePrivate.h; sourceTree = "<group>"; };
 		F451D3F51A8AAE8700B8A22C /* GPBProtocolBuffers_RuntimeSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBProtocolBuffers_RuntimeSupport.h; sourceTree = "<group>"; };
+		F4584D7E1ECCB38900803AB6 /* GPBExtensionRegistryTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBExtensionRegistryTest.m; sourceTree = "<group>"; };
 		F45C69CB16DFD08D0081955B /* GPBExtensionInternals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBExtensionInternals.m; sourceTree = "<group>"; };
 		F45E57C61AE6DC6A000B7D99 /* text_format_map_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_map_unittest_data.txt; sourceTree = "<group>"; };
 		F4AC9E1D1A8BEB3500BD6E83 /* unittest_cycle.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = unittest_cycle.proto; sourceTree = "<group>"; };
@@ -403,6 +405,7 @@
 				F4353D301AC06F10005A6198 /* GPBDictionaryTests+String.m */,
 				F4353D311AC06F10005A6198 /* GPBDictionaryTests+UInt32.m */,
 				F4353D321AC06F10005A6198 /* GPBDictionaryTests+UInt64.m */,
+				F4584D7E1ECCB38900803AB6 /* GPBExtensionRegistryTest.m */,
 				7461B6A30F94FDF800A0C422 /* GPBMessageTests.m */,
 				F4487C821AAF6AB300531423 /* GPBMessageTests+Merge.m */,
 				F4487C741AADF7F500531423 /* GPBMessageTests+Runtime.m */,
@@ -418,8 +421,8 @@
 				7461B6BA0F94FDF900A0C422 /* GPBUtilitiesTests.m */,
 				8B4248DB1A92933A00BC1EC6 /* GPBWellKnownTypesTest.m */,
 				7461B6BC0F94FDF900A0C422 /* GPBWireFormatTests.m */,
-				F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */,
 				F45E57C61AE6DC6A000B7D99 /* text_format_map_unittest_data.txt */,
+				F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */,
 				8B7E6A7414893DBA00F8884A /* unittest_custom_options.proto */,
 				F4AC9E1D1A8BEB3500BD6E83 /* unittest_cycle.proto */,
 				8B7E6A7514893DBA00F8884A /* unittest_embed_optimize_for.proto */,
@@ -429,8 +432,8 @@
 				8BBD9DB016DD1DC8008E1EC1 /* unittest_lite.proto */,
 				8B7E6A7B14893DBC00F8884A /* unittest_mset.proto */,
 				8B7E6A7C14893DBC00F8884A /* unittest_no_generic_services.proto */,
-				8B09AAF614B663A7007B4184 /* unittest_objc.proto */,
 				F4CF31701B162ED800BD9B06 /* unittest_objc_startup.proto */,
+				8B09AAF614B663A7007B4184 /* unittest_objc.proto */,
 				8B7E6A7D14893DBC00F8884A /* unittest_optimize_for.proto */,
 				F4487C781AADFB3100531423 /* unittest_runtime_proto2.proto */,
 				F4487C791AADFB3200531423 /* unittest_runtime_proto3.proto */,
@@ -669,6 +672,7 @@
 				F4F8D8831D789FD9002CE128 /* GPBUnittestProtos2.m in Sources */,
 				F4353D1D1AB8822D005A6198 /* GPBDescriptorTests.m in Sources */,
 				8B4248BB1A8C256A00BC1EC6 /* GPBSwiftTests.swift in Sources */,
+				F4584D821ECCB52A00803AB6 /* GPBExtensionRegistryTest.m in Sources */,
 				5102DABC1891A073002037B6 /* GPBConcurrencyTests.m in Sources */,
 				F4487C751AADF7F500531423 /* GPBMessageTests+Runtime.m in Sources */,
 				F4353D351AC06F10005A6198 /* GPBDictionaryTests+Int32.m in Sources */,
diff --git a/objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme b/objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme
index 2f61813..2883109 100644
--- a/objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme
+++ b/objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme
@@ -51,6 +51,12 @@
                   Identifier = "DescriptorTests">
                </Test>
                <Test
+                  Identifier = "GPBAutocreatedArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBAutocreatedDictionaryTests">
+               </Test>
+               <Test
                   Identifier = "GPBBoolArrayTests">
                </Test>
                <Test
@@ -90,6 +96,9 @@
                   Identifier = "GPBEnumArrayTests">
                </Test>
                <Test
+                  Identifier = "GPBExtensionRegistryTest">
+               </Test>
+               <Test
                   Identifier = "GPBFloatArrayTests">
                </Test>
                <Test
diff --git a/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
index 64fc45c..2211cb3 100644
--- a/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
+++ b/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
@@ -60,6 +60,7 @@
 		F4487C771AADF84900531423 /* GPBMessageTests+Runtime.m in Sources */ = {isa = PBXBuildFile; fileRef = F4487C761AADF84900531423 /* GPBMessageTests+Runtime.m */; };
 		F4487C811AAF62FC00531423 /* GPBMessageTests+Serialization.m in Sources */ = {isa = PBXBuildFile; fileRef = F4487C801AAF62FC00531423 /* GPBMessageTests+Serialization.m */; };
 		F4487C851AAF6AC500531423 /* GPBMessageTests+Merge.m in Sources */ = {isa = PBXBuildFile; fileRef = F4487C841AAF6AC500531423 /* GPBMessageTests+Merge.m */; };
+		F4584D831ECCB53600803AB6 /* GPBExtensionRegistryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = F4584D801ECCB39E00803AB6 /* GPBExtensionRegistryTest.m */; };
 		F45C69CC16DFD08D0081955B /* GPBExtensionInternals.m in Sources */ = {isa = PBXBuildFile; fileRef = F45C69CB16DFD08D0081955B /* GPBExtensionInternals.m */; };
 		F45E57C91AE6DC98000B7D99 /* text_format_map_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F45E57C81AE6DC98000B7D99 /* text_format_map_unittest_data.txt */; };
 		F47476E91D21A537007C7B1A /* Duration.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248DE1A929C7D00BC1EC6 /* Duration.pbobjc.m */; };
@@ -202,6 +203,7 @@
 		F4487C841AAF6AC500531423 /* GPBMessageTests+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBMessageTests+Merge.m"; sourceTree = "<group>"; };
 		F44929021C866B3B00C2548A /* GPBCodedOutputStream_PackagePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBCodedOutputStream_PackagePrivate.h; sourceTree = "<group>"; };
 		F451D3F61A8AAEA600B8A22C /* GPBProtocolBuffers_RuntimeSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBProtocolBuffers_RuntimeSupport.h; sourceTree = "<group>"; };
+		F4584D801ECCB39E00803AB6 /* GPBExtensionRegistryTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPBExtensionRegistryTest.m; path = Tests/GPBExtensionRegistryTest.m; sourceTree = SOURCE_ROOT; };
 		F45C69CB16DFD08D0081955B /* GPBExtensionInternals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBExtensionInternals.m; sourceTree = "<group>"; };
 		F45E57C81AE6DC98000B7D99 /* text_format_map_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_map_unittest_data.txt; sourceTree = "<group>"; };
 		F4AC9E1C1A8BEB1000BD6E83 /* unittest_cycle.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = unittest_cycle.proto; sourceTree = "<group>"; };
@@ -441,6 +443,7 @@
 				F4353D3E1AC06F31005A6198 /* GPBDictionaryTests+String.m */,
 				F4353D3F1AC06F31005A6198 /* GPBDictionaryTests+UInt32.m */,
 				F4353D401AC06F31005A6198 /* GPBDictionaryTests+UInt64.m */,
+				F4584D801ECCB39E00803AB6 /* GPBExtensionRegistryTest.m */,
 				7461B6A30F94FDF800A0C422 /* GPBMessageTests.m */,
 				F4487C841AAF6AC500531423 /* GPBMessageTests+Merge.m */,
 				F4487C761AADF84900531423 /* GPBMessageTests+Runtime.m */,
@@ -456,8 +459,8 @@
 				7461B6BA0F94FDF900A0C422 /* GPBUtilitiesTests.m */,
 				8B4248E51A929C9900BC1EC6 /* GPBWellKnownTypesTest.m */,
 				7461B6BC0F94FDF900A0C422 /* GPBWireFormatTests.m */,
-				F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */,
 				F45E57C81AE6DC98000B7D99 /* text_format_map_unittest_data.txt */,
+				F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */,
 				8B7E6A7414893DBA00F8884A /* unittest_custom_options.proto */,
 				F4AC9E1C1A8BEB1000BD6E83 /* unittest_cycle.proto */,
 				8B7E6A7514893DBA00F8884A /* unittest_embed_optimize_for.proto */,
@@ -467,8 +470,8 @@
 				8BBD9DB016DD1DC8008E1EC1 /* unittest_lite.proto */,
 				8B7E6A7B14893DBC00F8884A /* unittest_mset.proto */,
 				8B7E6A7C14893DBC00F8884A /* unittest_no_generic_services.proto */,
-				8B09AAF614B663A7007B4184 /* unittest_objc.proto */,
 				F4CF31711B162EF500BD9B06 /* unittest_objc_startup.proto */,
+				8B09AAF614B663A7007B4184 /* unittest_objc.proto */,
 				8B7E6A7D14893DBC00F8884A /* unittest_optimize_for.proto */,
 				F4487C7A1AADFB5500531423 /* unittest_runtime_proto2.proto */,
 				F4487C7B1AADFB5500531423 /* unittest_runtime_proto3.proto */,
@@ -765,6 +768,7 @@
 				F4F8D8861D78A193002CE128 /* GPBUnittestProtos2.m in Sources */,
 				F4B51B1C1BBC5C7100744318 /* GPBObjectiveCPlusPlusTest.mm in Sources */,
 				8B4248B41A8BD96E00BC1EC6 /* GPBSwiftTests.swift in Sources */,
+				F4584D831ECCB53600803AB6 /* GPBExtensionRegistryTest.m in Sources */,
 				5102DABC1891A073002037B6 /* GPBConcurrencyTests.m in Sources */,
 				F4487C771AADF84900531423 /* GPBMessageTests+Runtime.m in Sources */,
 				F4353D431AC06F31005A6198 /* GPBDictionaryTests+Int32.m in Sources */,
diff --git a/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme b/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme
index be31c30..1ba3a32 100644
--- a/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme
+++ b/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme
@@ -51,6 +51,12 @@
                   Identifier = "DescriptorTests">
                </Test>
                <Test
+                  Identifier = "GPBAutocreatedArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBAutocreatedDictionaryTests">
+               </Test>
+               <Test
                   Identifier = "GPBBoolArrayTests">
                </Test>
                <Test
@@ -90,6 +96,9 @@
                   Identifier = "GPBEnumArrayTests">
                </Test>
                <Test
+                  Identifier = "GPBExtensionRegistryTest">
+               </Test>
+               <Test
                   Identifier = "GPBFloatArrayTests">
                </Test>
                <Test
diff --git a/objectivec/Tests/GPBExtensionRegistryTest.m b/objectivec/Tests/GPBExtensionRegistryTest.m
new file mode 100644
index 0000000..b116882
--- /dev/null
+++ b/objectivec/Tests/GPBExtensionRegistryTest.m
@@ -0,0 +1,138 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2017 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#import "GPBTestUtilities.h"
+
+#import "GPBExtensionRegistry.h"
+#import "google/protobuf/Unittest.pbobjc.h"
+
+@interface GPBExtensionRegistryTest : GPBTestCase
+@end
+
+@implementation GPBExtensionRegistryTest
+
+- (void)testBasics {
+  GPBExtensionRegistry *reg = [[[GPBExtensionRegistry alloc] init] autorelease];
+  XCTAssertNotNil(reg);
+
+  XCTAssertNil([reg extensionForDescriptor:[TestAllExtensions descriptor]
+                               fieldNumber:1]);
+  XCTAssertNil([reg extensionForDescriptor:[TestAllTypes descriptor]
+                               fieldNumber:1]);
+
+  [reg addExtension:[UnittestRoot optionalInt32Extension]];
+  [reg addExtension:[UnittestRoot packedInt64Extension]];
+
+  XCTAssertTrue([reg extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:1] ==
+                [UnittestRoot optionalInt32Extension]); // ptr equality
+  XCTAssertNil([reg extensionForDescriptor:[TestAllTypes descriptor]
+                               fieldNumber:1]);
+  XCTAssertTrue([reg extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:91] ==
+                [UnittestRoot packedInt64Extension]); // ptr equality
+}
+
+- (void)testCopy {
+  GPBExtensionRegistry *reg1 = [[[GPBExtensionRegistry alloc] init] autorelease];
+  [reg1 addExtension:[UnittestRoot optionalInt32Extension]];
+
+  GPBExtensionRegistry *reg2 = [[reg1 copy] autorelease];
+  XCTAssertNotNil(reg2);
+
+  XCTAssertTrue([reg1 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:1] ==
+                [UnittestRoot optionalInt32Extension]); // ptr equality
+  XCTAssertTrue([reg2 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:1] ==
+                [UnittestRoot optionalInt32Extension]); // ptr equality
+
+  // Message class that had registered extension(s) at the -copy time.
+
+  [reg1 addExtension:[UnittestRoot optionalBoolExtension]];
+  [reg2 addExtension:[UnittestRoot optionalStringExtension]];
+
+  XCTAssertTrue([reg1 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:13] ==
+                [UnittestRoot optionalBoolExtension]); // ptr equality
+  XCTAssertNil([reg1 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:14]);
+  XCTAssertNil([reg2 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:13]);
+  XCTAssertTrue([reg2 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:14] ==
+                [UnittestRoot optionalStringExtension]); // ptr equality
+
+  // Message class that did not have any registered extensions at the -copy time.
+
+  [reg1 addExtension:[UnittestRoot packedInt64Extension]];
+  [reg2 addExtension:[UnittestRoot packedSint32Extension]];
+
+  XCTAssertTrue([reg1 extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:91] ==
+                [UnittestRoot packedInt64Extension]); // ptr equality
+  XCTAssertNil([reg1 extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:94]);
+  XCTAssertNil([reg2 extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:91]);
+  XCTAssertTrue([reg2 extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:94] ==
+                [UnittestRoot packedSint32Extension]); // ptr equality
+
+}
+
+- (void)testAddExtensions {
+  GPBExtensionRegistry *reg1 = [[[GPBExtensionRegistry alloc] init] autorelease];
+  [reg1 addExtension:[UnittestRoot optionalInt32Extension]];
+
+  GPBExtensionRegistry *reg2 = [[[GPBExtensionRegistry alloc] init] autorelease];
+
+  XCTAssertNil([reg2 extensionForDescriptor:[TestAllExtensions descriptor]
+                                fieldNumber:1]);
+
+  [reg2 addExtensions:reg1];
+
+  XCTAssertTrue([reg2 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:1] ==
+                [UnittestRoot optionalInt32Extension]); // ptr equality
+
+  // Confirm adding to the first doesn't add to the second.
+
+  [reg1 addExtension:[UnittestRoot optionalBoolExtension]];
+  [reg1 addExtension:[UnittestRoot packedInt64Extension]];
+
+  XCTAssertTrue([reg1 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:13] ==
+                [UnittestRoot optionalBoolExtension]); // ptr equality
+  XCTAssertTrue([reg1 extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:91] ==
+                [UnittestRoot packedInt64Extension]); // ptr equality
+  XCTAssertNil([reg2 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:13]);
+  XCTAssertNil([reg2 extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:91]);
+
+  // Confirm adding to the second doesn't add to the first.
+
+  [reg2 addExtension:[UnittestRoot optionalStringExtension]];
+  [reg2 addExtension:[UnittestRoot packedSint32Extension]];
+
+  XCTAssertNil([reg1 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:14]);
+  XCTAssertNil([reg1 extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:94]);
+  XCTAssertTrue([reg2 extensionForDescriptor:[TestAllExtensions descriptor] fieldNumber:14] ==
+                [UnittestRoot optionalStringExtension]); // ptr equality
+  XCTAssertTrue([reg2 extensionForDescriptor:[TestPackedExtensions descriptor] fieldNumber:94] ==
+                [UnittestRoot packedSint32Extension]); // ptr equality
+}
+
+@end
diff --git a/objectivec/Tests/GPBMessageTests+Serialization.m b/objectivec/Tests/GPBMessageTests+Serialization.m
index 3c861fe..4a4c544 100644
--- a/objectivec/Tests/GPBMessageTests+Serialization.m
+++ b/objectivec/Tests/GPBMessageTests+Serialization.m
@@ -113,35 +113,6 @@
   [msg release];
 }
 
-- (void)testProto3DroppingUnknownFields {
-  DropUnknownsFooWithExtraFields *fooWithExtras =
-      [[DropUnknownsFooWithExtraFields alloc] init];
-
-  fooWithExtras.int32Value = 1;
-  fooWithExtras.enumValue = DropUnknownsFooWithExtraFields_NestedEnum_Baz;
-  fooWithExtras.extraInt32Value = 2;
-
-  NSData *data = [fooWithExtras data];
-  XCTAssertNotNil(data);
-  DropUnknownsFoo *foo = [DropUnknownsFoo parseFromData:data error:NULL];
-
-  XCTAssertEqual(foo.int32Value, 1);
-  XCTAssertEqual(foo.enumValue, DropUnknownsFoo_NestedEnum_Baz);
-  // Nothing should end up in the unknowns.
-  XCTAssertEqual([foo.unknownFields countOfFields], 0U);
-
-  [fooWithExtras release];
-  data = [foo data];
-  fooWithExtras =
-      [DropUnknownsFooWithExtraFields parseFromData:data error:NULL];
-  XCTAssertEqual(fooWithExtras.int32Value, 1);
-  XCTAssertEqual(fooWithExtras.enumValue,
-                 DropUnknownsFooWithExtraFields_NestedEnum_Baz);
-  // And the extra value is gone (back to the default).
-  XCTAssertEqual(fooWithExtras.extraInt32Value, 0);
-  XCTAssertEqual([foo.unknownFields countOfFields], 0U);
-}
-
 - (void)testProto2UnknownEnumToUnknownField {
   Message3 *orig = [[Message3 alloc] init];
 
@@ -946,6 +917,41 @@
   XCTAssertEqual(error.code, GPBCodedInputStreamErrorInvalidTag);
 }
 
+- (void)testZeroFieldNum {
+  // These are ConformanceTestSuite::TestIllegalTags.
+
+  const char *tests[] = {
+    "\1DEADBEEF",
+    "\2\1\1",
+    "\3\4",
+    "\5DEAD"
+  };
+
+  for (size_t i = 0; i < GPBARRAYSIZE(tests); ++i) {
+    NSData *data = DataFromCStr(tests[i]);
+
+    {
+      // Message from proto2 syntax file
+      NSError *error = nil;
+      Message2 *msg = [Message2 parseFromData:data error:&error];
+      XCTAssertNil(msg, @"i = %zd", i);
+      XCTAssertNotNil(error, @"i = %zd", i);
+      XCTAssertEqualObjects(error.domain, GPBCodedInputStreamErrorDomain, @"i = %zd", i);
+      XCTAssertEqual(error.code, GPBCodedInputStreamErrorInvalidTag, @"i = %zd", i);
+    }
+
+    {
+      // Message from proto3 syntax file
+      NSError *error = nil;
+      Message3 *msg = [Message3 parseFromData:data error:&error];
+      XCTAssertNil(msg, @"i = %zd", i);
+      XCTAssertNotNil(error, @"i = %zd", i);
+      XCTAssertEqualObjects(error.domain, GPBCodedInputStreamErrorDomain, @"i = %zd", i);
+      XCTAssertEqual(error.code, GPBCodedInputStreamErrorInvalidTag, @"i = %zd", i);
+    }
+  }
+}
+
 - (void)testErrorRecursionDepthReached {
   NSData *data = DataFromCStr(
       "\x0A\xF2\x01\x0A\xEF\x01\x0A\xEC\x01\x0A\xE9\x01\x0A\xE6\x01"
@@ -1149,22 +1155,27 @@
   [msg.mapInt32Int32 setInt32:101 forKey:2001];
   [msg.mapInt64Int64 setInt64:1002 forKey:202];
   [msg.mapInt64Int64 setInt64:103 forKey:2003];
+  [msg.mapInt64Int64 setInt64:4294967296 forKey:4294967297];
   [msg.mapUint32Uint32 setUInt32:1004 forKey:204];
   [msg.mapUint32Uint32 setUInt32:105 forKey:2005];
   [msg.mapUint64Uint64 setUInt64:1006 forKey:206];
   [msg.mapUint64Uint64 setUInt64:107 forKey:2007];
+  [msg.mapUint64Uint64 setUInt64:4294967298 forKey:4294967299];
   [msg.mapSint32Sint32 setInt32:1008 forKey:208];
   [msg.mapSint32Sint32 setInt32:109 forKey:2009];
   [msg.mapSint64Sint64 setInt64:1010 forKey:210];
   [msg.mapSint64Sint64 setInt64:111 forKey:2011];
+  [msg.mapSint64Sint64 setInt64:4294967300 forKey:4294967301];
   [msg.mapFixed32Fixed32 setUInt32:1012 forKey:212];
   [msg.mapFixed32Fixed32 setUInt32:113 forKey:2013];
   [msg.mapFixed64Fixed64 setUInt64:1014 forKey:214];
   [msg.mapFixed64Fixed64 setUInt64:115 forKey:2015];
+  [msg.mapFixed64Fixed64 setUInt64:4294967302 forKey:4294967303];
   [msg.mapSfixed32Sfixed32 setInt32:1016 forKey:216];
   [msg.mapSfixed32Sfixed32 setInt32:117 forKey:2017];
   [msg.mapSfixed64Sfixed64 setInt64:1018 forKey:218];
   [msg.mapSfixed64Sfixed64 setInt64:119 forKey:2019];
+  [msg.mapSfixed64Sfixed64 setInt64:4294967304 forKey:4294967305];
   [msg.mapInt32Float setFloat:1020.f forKey:220];
   [msg.mapInt32Float setFloat:121.f forKey:2021];
   [msg.mapInt32Double setDouble:1022. forKey:222];
diff --git a/objectivec/Tests/GPBPerfTests.m b/objectivec/Tests/GPBPerfTests.m
index 1259d14..8dd0ffc 100644
--- a/objectivec/Tests/GPBPerfTests.m
+++ b/objectivec/Tests/GPBPerfTests.m
@@ -64,6 +64,112 @@
   }];
 }
 
+- (void)testMessageSerialParsingPerformance {
+  // This and the next test are meant to monitor that the parsing functionality of protos does not
+  // lock across threads when parsing different instances. The Serial version of the test should run
+  // around ~2 times slower than the Parallel version since it's parsing the protos in the same
+  // thread.
+  TestAllTypes *allTypesMessage = [TestAllTypes message];
+  [self setAllFields:allTypesMessage repeatedCount:2];
+  NSData *allTypesData = allTypesMessage.data;
+
+  [self measureBlock:^{
+    for (int i = 0; i < 500; ++i) {
+      [TestAllTypes parseFromData:allTypesData error:NULL];
+      [TestAllTypes parseFromData:allTypesData error:NULL];
+    }
+  }];
+}
+
+- (void)testMessageParallelParsingPerformance {
+  // This and the previous test are meant to monitor that the parsing functionality of protos does
+  // not lock across threads when parsing different instances. The Serial version of the test should
+  // run around ~2 times slower than the Parallel version since it's parsing the protos in the same
+  // thread.
+  TestAllTypes *allTypesMessage = [TestAllTypes message];
+  [self setAllFields:allTypesMessage repeatedCount:2];
+  NSData *allTypesData = allTypesMessage.data;
+
+  dispatch_queue_t concurrentQueue = dispatch_queue_create("perfQueue", DISPATCH_QUEUE_CONCURRENT);
+
+  [self measureBlock:^{
+    for (int i = 0; i < 500; ++i) {
+      dispatch_group_t group = dispatch_group_create();
+
+      dispatch_group_async(group, concurrentQueue, ^{
+        [TestAllTypes parseFromData:allTypesData error:NULL];
+      });
+
+      dispatch_group_async(group, concurrentQueue, ^{
+        [TestAllTypes parseFromData:allTypesData error:NULL];
+      });
+
+      dispatch_group_notify(group, concurrentQueue, ^{});
+
+      dispatch_release(group);
+    }
+  }];
+
+  dispatch_release(concurrentQueue);
+}
+
+- (void)testMessageSerialExtensionsParsingPerformance {
+  // This and the next test are meant to monitor that the parsing functionality of protos does not
+  // lock across threads when parsing different instances when using extensions. The Serial version
+  // of the test should run around ~2 times slower than the Parallel version since it's parsing the
+  // protos in the same thread.
+  TestAllExtensions *allExtensionsMessage = [TestAllExtensions message];
+  [self setAllExtensions:allExtensionsMessage repeatedCount:2];
+  NSData *allExtensionsData = allExtensionsMessage.data;
+
+  [self measureBlock:^{
+    for (int i = 0; i < 500; ++i) {
+      [TestAllExtensions parseFromData:allExtensionsData
+                     extensionRegistry:[self extensionRegistry]
+                                 error:NULL];
+      [TestAllExtensions parseFromData:allExtensionsData
+                     extensionRegistry:[self extensionRegistry]
+                                 error:NULL];
+    }
+  }];
+}
+
+- (void)testMessageParallelExtensionsParsingPerformance {
+  // This and the previous test are meant to monitor that the parsing functionality of protos does
+  // not lock across threads when parsing different instances when using extensions. The Serial
+  // version of the test should run around ~2 times slower than the Parallel version since it's
+  // parsing the protos in the same thread.
+  TestAllExtensions *allExtensionsMessage = [TestAllExtensions message];
+  [self setAllExtensions:allExtensionsMessage repeatedCount:2];
+  NSData *allExtensionsData = allExtensionsMessage.data;
+
+  dispatch_queue_t concurrentQueue = dispatch_queue_create("perfQueue", DISPATCH_QUEUE_CONCURRENT);
+
+  [self measureBlock:^{
+    for (int i = 0; i < 500; ++i) {
+      dispatch_group_t group = dispatch_group_create();
+
+      dispatch_group_async(group, concurrentQueue, ^{
+        [TestAllExtensions parseFromData:allExtensionsData
+                       extensionRegistry:[UnittestRoot extensionRegistry]
+                                   error:NULL];
+      });
+
+      dispatch_group_async(group, concurrentQueue, ^{
+        [TestAllExtensions parseFromData:allExtensionsData
+                       extensionRegistry:[UnittestRoot extensionRegistry]
+                                   error:NULL];
+      });
+
+      dispatch_group_notify(group, concurrentQueue, ^{});
+
+      dispatch_release(group);
+    }
+  }];
+
+  dispatch_release(concurrentQueue);
+}
+
 - (void)testExtensionsPerformance {
   [self measureBlock:^{
     for (int i = 0; i < 200; ++i) {
diff --git a/php/composer.json b/php/composer.json
index 32b0f44..724a45d 100644
--- a/php/composer.json
+++ b/php/composer.json
@@ -20,9 +20,6 @@
       "GPBMetadata\\": "tests/generated/GPBMetadata",
       "GPBMetadata\\Google\\Protobuf\\Internal\\": "src/GPBMetadata/Google/Protobuf/Internal",
       "": "tests/generated"
-    },
-    "files": [
-      "src/Google/Protobuf/descriptor.php"
-    ]
+    }
   }
 }
diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c
index 8e563a6..332616b 100644
--- a/php/ext/google/protobuf/def.c
+++ b/php/ext/google/protobuf/def.c
@@ -30,8 +30,8 @@
 
 #include "protobuf.h"
 
-const char* const kReservedNames[] = {"Empty"};
-const int kReservedNamesSize = 1;
+const char* const kReservedNames[] = {"Empty", "ECHO", "ARRAY"};
+const int kReservedNamesSize = 3;
 
 // Forward declare.
 static void descriptor_init_c_instance(Descriptor* intern TSRMLS_DC);
@@ -405,23 +405,34 @@
 }
 
 static void convert_to_class_name_inplace(const char *package,
+                                          const char *namespace_given,
                                           const char *prefix, char *classname) {
-  size_t package_len = package == NULL ? 0 : strlen(package);
   size_t prefix_len = prefix == NULL ? 0 : strlen(prefix);
   size_t classname_len = strlen(classname);
   int i = 0, j;
   bool first_char = true;
 
-  int offset = package_len != 0 ? 2 : 0;
+  size_t package_len = package == NULL ? 0 : strlen(package);
+  size_t namespace_given_len =
+      namespace_given == NULL ? 0 : strlen(namespace_given);
+  bool use_namespace_given = namespace_given != NULL;
+  size_t namespace_len =
+      use_namespace_given ? namespace_given_len : package_len;
+
+  int offset = namespace_len != 0 ? 2 : 0;
 
   for (j = 0; j < classname_len; j++) {
-    classname[package_len + prefix_len + classname_len + offset - 1 - j] =
+    classname[namespace_len + prefix_len + classname_len + offset - 1 - j] =
         classname[classname_len - j - 1];
   }
 
-  if (package_len != 0) {
+  if (namespace_len != 0) {
     classname[i++] = '\\';
-    for (j = 0; j < package_len; j++) {
+    for (j = 0; j < namespace_len; j++) {
+      if (use_namespace_given) {
+        classname[i++] = namespace_given[j];
+        continue;
+      }
       // php packages are divided by '\'.
       if (package[j] == '.') {
         classname[i++] = '\\';
@@ -490,16 +501,20 @@
      * bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if    \
      * given message is google.protobuf.Empty.*/                               \
     const char *fullname = upb_##def_type_lower##_fullname(def_type_lower);    \
+    const char *php_namespace = upb_filedef_phpnamespace(files[0]);            \
     const char *prefix_given = upb_filedef_phpprefix(files[0]);                \
     size_t classname_len = strlen(fullname) + 5;                               \
     if (prefix_given != NULL) {                                                \
       classname_len += strlen(prefix_given);                                   \
     }                                                                          \
+    if (php_namespace != NULL) {                                               \
+      classname_len += strlen(php_namespace);                                  \
+    }                                                                          \
     char *classname = ecalloc(sizeof(char), classname_len);                    \
     const char *package = upb_filedef_package(files[0]);                       \
     classname_no_prefix(fullname, package, classname);                         \
     const char *prefix = classname_prefix(classname, prefix_given, package);   \
-    convert_to_class_name_inplace(package, prefix, classname);                 \
+    convert_to_class_name_inplace(package, php_namespace, prefix, classname);  \
     PHP_PROTO_CE_DECLARE pce;                                                  \
     if (php_proto_zend_lookup_class(classname, strlen(classname), &pce) ==     \
         FAILURE) {                                                             \
diff --git a/php/ext/google/protobuf/encode_decode.c b/php/ext/google/protobuf/encode_decode.c
index 28bf18f..ef3d4cf 100644
--- a/php/ext/google/protobuf/encode_decode.c
+++ b/php/ext/google/protobuf/encode_decode.c
@@ -164,18 +164,21 @@
   int property_ofs;        // properties table cache
   uint32_t oneof_case_num; // oneof-case number to place in oneof_case field
   const upb_msgdef *md;    // msgdef, for oneof submessage handler
+  const upb_msgdef *parent_md;  // msgdef, for parent submessage
 } oneof_handlerdata_t;
 
 static const void *newoneofhandlerdata(upb_handlers *h,
                                        uint32_t ofs,
                                        uint32_t case_ofs,
                                        int property_ofs,
+                                       const upb_msgdef *m,
                                        const upb_fielddef *f) {
   oneof_handlerdata_t* hd =
       (oneof_handlerdata_t*)malloc(sizeof(oneof_handlerdata_t));
   hd->ofs = ofs;
   hd->case_ofs = case_ofs;
   hd->property_ofs = property_ofs;
+  hd->parent_md = m;
   // We reuse the field tag number as a oneof union discriminant tag. Note that
   // we don't expose these numbers to the user, so the only requirement is that
   // we have some unique ID for each union case/possibility. The field tag
@@ -284,10 +287,19 @@
 #if PHP_MAJOR_VERSION < 7
 static void *empty_php_string(zval** value_ptr) {
   SEPARATE_ZVAL_IF_NOT_REF(value_ptr);
+  if (Z_TYPE_PP(value_ptr) == IS_STRING &&
+      !IS_INTERNED(Z_STRVAL_PP(value_ptr))) {
+    FREE(Z_STRVAL_PP(value_ptr));
+  }
+  ZVAL_EMPTY_STRING(*value_ptr);
   return (void*)(*value_ptr);
 }
 #else
 static void *empty_php_string(zval* value_ptr) {
+  if (Z_TYPE_P(value_ptr) == IS_STRING) {
+    zend_string_release(Z_STR_P(value_ptr));
+  }
+  ZVAL_EMPTY_STRING(value_ptr);
   return value_ptr;
 }
 #endif
@@ -654,6 +666,44 @@
 
 #undef DEFINE_ONEOF_HANDLER
 
+static void oneof_cleanup(MessageHeader* msg,
+                          const oneof_handlerdata_t* oneofdata) {
+  uint32_t old_case_num =
+      DEREF(message_data(msg), oneofdata->case_ofs, uint32_t);
+  if (old_case_num == 0) {
+    return;
+  }
+
+  const upb_fielddef* old_field =
+      upb_msgdef_itof(oneofdata->parent_md, old_case_num);
+  bool need_clean = false;
+
+  switch (upb_fielddef_type(old_field)) {
+    case UPB_TYPE_STRING:
+    case UPB_TYPE_BYTES:
+      need_clean = true;
+      break;
+    case UPB_TYPE_MESSAGE:
+      if (oneofdata->oneof_case_num != old_case_num) {
+        need_clean = true;
+      }
+      break;
+    default:
+      break;
+  }
+
+  if (need_clean) {
+#if PHP_MAJOR_VERSION < 7
+    SEPARATE_ZVAL_IF_NOT_REF(
+        DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*));
+    php_proto_zval_ptr_dtor(
+        *DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*));
+    MAKE_STD_ZVAL(*DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*));
+    ZVAL_NULL(*DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*));
+#endif
+  }
+}
+
 // Handlers for string/bytes in a oneof.
 static void *oneofbytes_handler(void *closure,
                                 const void *hd,
@@ -661,6 +711,8 @@
   MessageHeader* msg = closure;
   const oneof_handlerdata_t *oneofdata = hd;
 
+  oneof_cleanup(msg, oneofdata);
+
   DEREF(message_data(msg), oneofdata->case_ofs, uint32_t) =
       oneofdata->oneof_case_num;
   DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*) =
@@ -691,22 +743,11 @@
   MessageHeader* submsg;
 
   if (oldcase != oneofdata->oneof_case_num) {
-    // Ideally, we should clean up the old data. However, we don't even know the
-    // type of the old data. So, we will defer the desctruction of the old data
-    // to the time that containing message's destroyed or the same oneof field
-    // is accessed again and find that the old data hasn't been cleaned.
-    DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*) =
-        &(msg->std.properties_table)[oneofdata->property_ofs];
-
-    // Old data was't cleaned when the oneof was accessed from another field.
-    if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(DEREF(
-        message_data(msg), oneofdata->ofs, CACHED_VALUE*))) != IS_NULL) {
-          php_proto_zval_ptr_dtor(
-              CACHED_PTR_TO_ZVAL_PTR(
-                  DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*)));
-    }
+    oneof_cleanup(msg, oneofdata);
 
     // Create new message.
+    DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*) =
+        &(msg->std.properties_table)[oneofdata->property_ofs];
     ZVAL_OBJ(CACHED_PTR_TO_ZVAL_PTR(
         DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*)),
         subklass->create_object(subklass TSRMLS_CC));
@@ -856,6 +897,7 @@
 
 // Set up handlers for a oneof field.
 static void add_handlers_for_oneof_field(upb_handlers *h,
+                                         const upb_msgdef *m,
                                          const upb_fielddef *f,
                                          size_t offset,
                                          size_t oneof_case_offset,
@@ -864,7 +906,7 @@
   upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
   upb_handlerattr_sethandlerdata(
       &attr, newoneofhandlerdata(h, offset, oneof_case_offset,
-                                 property_cache_offset, f));
+                                 property_cache_offset, m, f));
 
   switch (upb_fielddef_type(f)) {
 
@@ -936,8 +978,8 @@
           desc->layout->fields[upb_fielddef_index(f)].case_offset;
       int property_cache_index =
           desc->layout->fields[upb_fielddef_index(f)].cache_index;
-      add_handlers_for_oneof_field(h, f, offset, oneof_case_offset,
-                                   property_cache_index);
+      add_handlers_for_oneof_field(h, desc->msgdef, f, offset,
+                                   oneof_case_offset, property_cache_index);
     } else if (is_map_field(f)) {
       add_handlers_for_mapfield(h, f, offset, desc);
     } else if (upb_fielddef_isseq(f)) {
@@ -1167,6 +1209,7 @@
        upb_msg_field_next(&i)) {
     upb_fielddef* f = upb_msg_iter_field(&i);
     uint32_t offset = desc->layout->fields[upb_fielddef_index(f)].offset;
+    bool containing_oneof = false;
 
     if (upb_fielddef_containingoneof(f)) {
       uint32_t oneof_case_offset =
@@ -1179,6 +1222,7 @@
       }
       // Otherwise, fall through to the appropriate singular-field handler
       // below.
+      containing_oneof = true;
     }
 
     if (is_map_field(f)) {
@@ -1196,7 +1240,7 @@
     } else if (upb_fielddef_isstring(f)) {
       zval* str = CACHED_PTR_TO_ZVAL_PTR(
           DEREF(message_data(msg), offset, CACHED_VALUE*));
-      if (Z_STRLEN_P(str) > 0) {
+      if (containing_oneof || Z_STRLEN_P(str) > 0) {
         putstr(str, f, sink);
       }
     } else if (upb_fielddef_issubmsg(f)) {
@@ -1209,7 +1253,7 @@
 #define T(upbtypeconst, upbtype, ctype, default_value)     \
   case upbtypeconst: {                                     \
     ctype value = DEREF(message_data(msg), offset, ctype); \
-    if (value != default_value) {                          \
+    if (containing_oneof || value != default_value) {      \
       upb_sink_put##upbtype(sink, sel, value);             \
     }                                                      \
   } break;
@@ -1219,10 +1263,10 @@
         T(UPB_TYPE_DOUBLE, double, double, 0.0)
         T(UPB_TYPE_BOOL, bool, uint8_t, 0)
         case UPB_TYPE_ENUM:
-          T(UPB_TYPE_INT32, int32, int32_t, 0)
-          T(UPB_TYPE_UINT32, uint32, uint32_t, 0)
-          T(UPB_TYPE_INT64, int64, int64_t, 0)
-          T(UPB_TYPE_UINT64, uint64, uint64_t, 0)
+        T(UPB_TYPE_INT32, int32, int32_t, 0)
+        T(UPB_TYPE_UINT32, uint32, uint32_t, 0)
+        T(UPB_TYPE_INT64, int64, int64_t, 0)
+        T(UPB_TYPE_UINT64, uint64, uint64_t, 0)
 
         case UPB_TYPE_STRING:
         case UPB_TYPE_BYTES:
@@ -1244,18 +1288,23 @@
 
   assert(Z_TYPE_P(str) == IS_STRING);
 
-  // Ensure that the string has the correct encoding. We also check at field-set
-  // time, but the user may have mutated the string object since then.
-  if (upb_fielddef_type(f) == UPB_TYPE_STRING &&
-      !is_structurally_valid_utf8(Z_STRVAL_P(str), Z_STRLEN_P(str))) {
-    zend_error(E_USER_ERROR, "Given string is not UTF8 encoded.");
-    return;
-  }
-
   upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), Z_STRLEN_P(str),
                     &subsink);
-  upb_sink_putstring(&subsink, getsel(f, UPB_HANDLER_STRING), Z_STRVAL_P(str),
-                     Z_STRLEN_P(str), NULL);
+
+  // For oneof string field, we may get here with string length is zero.
+  if (Z_STRLEN_P(str) > 0) {
+    // Ensure that the string has the correct encoding. We also check at
+    // field-set time, but the user may have mutated the string object since
+    // then.
+    if (upb_fielddef_type(f) == UPB_TYPE_STRING &&
+        !is_structurally_valid_utf8(Z_STRVAL_P(str), Z_STRLEN_P(str))) {
+      zend_error(E_USER_ERROR, "Given string is not UTF8 encoded.");
+      return;
+    }
+    upb_sink_putstring(&subsink, getsel(f, UPB_HANDLER_STRING), Z_STRVAL_P(str),
+                       Z_STRLEN_P(str), NULL);
+  }
+
   upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR));
 }
 
@@ -1450,7 +1499,7 @@
   }
 }
 
-PHP_METHOD(Message, jsonEncode) {
+PHP_METHOD(Message, serializeToJsonString) {
   Descriptor* desc =
       UNBOX_HASHTABLE_VALUE(Descriptor, get_ce_obj(Z_OBJCE_P(getThis())));
 
@@ -1481,13 +1530,14 @@
   }
 }
 
-PHP_METHOD(Message, jsonDecode) {
+PHP_METHOD(Message, mergeFromJsonString) {
   Descriptor* desc =
       UNBOX_HASHTABLE_VALUE(Descriptor, get_ce_obj(Z_OBJCE_P(getThis())));
   MessageHeader* msg = UNBOX(MessageHeader, getThis());
 
   char *data = NULL;
-  int data_len;
+  PHP_PROTO_SIZE data_len;
+
   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) ==
       FAILURE) {
     return;
diff --git a/php/ext/google/protobuf/map.c b/php/ext/google/protobuf/map.c
index a5d4844..4a52486 100644
--- a/php/ext/google/protobuf/map.c
+++ b/php/ext/google/protobuf/map.c
@@ -143,6 +143,7 @@
   PHP_ME(MapField, offsetSet,    arginfo_offsetSet, ZEND_ACC_PUBLIC)
   PHP_ME(MapField, offsetUnset,  arginfo_offsetGet, ZEND_ACC_PUBLIC)
   PHP_ME(MapField, count,        arginfo_void,      ZEND_ACC_PUBLIC)
+  PHP_ME(MapField, getIterator,  arginfo_void,      ZEND_ACC_PUBLIC)
   ZEND_FE_END
 };
 
@@ -156,7 +157,10 @@
 // -----------------------------------------------------------------------------
 
 zend_class_entry* map_field_type;
+zend_class_entry* map_field_iter_type;
+
 zend_object_handlers* map_field_handlers;
+zend_object_handlers* map_field_iter_handlers;
 
 static void map_begin_internal(Map *map, MapIter *iter) {
   iter->self = map;
@@ -231,8 +235,8 @@
 // Init class entry.
 PHP_PROTO_INIT_CLASS_START("Google\\Protobuf\\Internal\\MapField", Map,
                            map_field)
-zend_class_implements(map_field_type TSRMLS_CC, 2, spl_ce_ArrayAccess,
-                      spl_ce_Countable);
+zend_class_implements(map_field_type TSRMLS_CC, 3, spl_ce_ArrayAccess,
+                      zend_ce_aggregate, spl_ce_Countable);
 map_field_handlers->write_dimension = map_field_write_dimension;
 map_field_handlers->get_gc = map_field_get_gc;
 PHP_PROTO_INIT_CLASS_END
@@ -444,6 +448,15 @@
   RETURN_LONG(upb_strtable_count(&intern->table));
 }
 
+PHP_METHOD(MapField, getIterator) {
+  CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(return_value,
+                                   map_field_iter_type);
+
+  Map *intern = UNBOX(Map, getThis());
+  MapIter *iter = UNBOX(MapIter, return_value);
+  map_begin(getThis(), iter TSRMLS_CC);
+}
+
 // -----------------------------------------------------------------------------
 // Map Iterator
 // -----------------------------------------------------------------------------
@@ -470,3 +483,79 @@
   *len = native_slot_size(iter->self->value_type);
   return upb_strtable_iter_value(&iter->it);
 }
+
+// -----------------------------------------------------------------------------
+// MapFieldIter methods
+// -----------------------------------------------------------------------------
+static zend_function_entry map_field_iter_methods[] = {
+  PHP_ME(MapFieldIter, rewind,      arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(MapFieldIter, current,     arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(MapFieldIter, key,         arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(MapFieldIter, next,        arginfo_void, ZEND_ACC_PUBLIC)
+  PHP_ME(MapFieldIter, valid,       arginfo_void, ZEND_ACC_PUBLIC)
+  ZEND_FE_END
+};
+
+// -----------------------------------------------------------------------------
+// MapFieldIter creation/desctruction
+// -----------------------------------------------------------------------------
+
+// Define object free method.
+PHP_PROTO_OBJECT_FREE_START(MapIter, map_field_iter)
+PHP_PROTO_OBJECT_FREE_END
+
+PHP_PROTO_OBJECT_DTOR_START(MapIter, map_field_iter)
+PHP_PROTO_OBJECT_DTOR_END
+
+// Define object create method.
+PHP_PROTO_OBJECT_CREATE_START(MapIter, map_field_iter)
+intern->self = NULL;
+PHP_PROTO_OBJECT_CREATE_END(MapIter, map_field_iter)
+
+// Init class entry.
+PHP_PROTO_INIT_CLASS_START("Google\\Protobuf\\Internal\\MapFieldIter",
+                           MapIter, map_field_iter)
+zend_class_implements(map_field_iter_type TSRMLS_CC, 1, zend_ce_iterator);
+PHP_PROTO_INIT_CLASS_END
+
+// -----------------------------------------------------------------------------
+// PHP MapFieldIter Methods
+// -----------------------------------------------------------------------------
+
+PHP_METHOD(MapFieldIter, rewind) {
+  MapIter *intern = UNBOX(MapIter, getThis());
+  map_begin_internal(intern->self, intern);
+}
+
+PHP_METHOD(MapFieldIter, current) {
+  MapIter *intern = UNBOX(MapIter, getThis());
+  Map *map_field = intern->self;
+
+  int value_length = 0;
+  upb_value value = map_iter_value(intern, &value_length);
+
+  void* mem = upb_value_memory(&value);
+  native_slot_get_by_array(map_field->value_type, mem,
+                           ZVAL_PTR_TO_CACHED_PTR(return_value) TSRMLS_CC);
+}
+
+PHP_METHOD(MapFieldIter, key) {
+  MapIter *intern = UNBOX(MapIter, getThis());
+  Map *map_field = intern->self;
+
+  int key_length = 0;
+  const char* key = map_iter_key(intern, &key_length);
+
+  native_slot_get_by_map_key(map_field->key_type, key, key_length,
+                             ZVAL_PTR_TO_CACHED_PTR(return_value) TSRMLS_CC);
+}
+
+PHP_METHOD(MapFieldIter, next) {
+  MapIter *intern = UNBOX(MapIter, getThis());
+  map_next(intern);
+}
+
+PHP_METHOD(MapFieldIter, valid) {
+  MapIter *intern = UNBOX(MapIter, getThis());
+  RETURN_BOOL(!map_done(intern));
+}
diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c
index cabc398..b8ef9fc 100644
--- a/php/ext/google/protobuf/message.c
+++ b/php/ext/google/protobuf/message.c
@@ -30,7 +30,6 @@
 
 #include <php.h>
 #include <stdlib.h>
-#include <ext/json/php_json.h>
 
 #include "protobuf.h"
 
@@ -41,8 +40,8 @@
   PHP_ME(Message, clear, NULL, ZEND_ACC_PUBLIC)
   PHP_ME(Message, serializeToString, NULL, ZEND_ACC_PUBLIC)
   PHP_ME(Message, mergeFromString, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Message, jsonEncode, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Message, jsonDecode, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(Message, serializeToJsonString, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(Message, mergeFromJsonString, NULL, ZEND_ACC_PUBLIC)
   PHP_ME(Message, mergeFrom, NULL, ZEND_ACC_PUBLIC)
   PHP_ME(Message, readOneof, NULL, ZEND_ACC_PROTECTED)
   PHP_ME(Message, writeOneof, NULL, ZEND_ACC_PROTECTED)
diff --git a/php/ext/google/protobuf/protobuf.c b/php/ext/google/protobuf/protobuf.c
index 6a848b2..5de9cfe 100644
--- a/php/ext/google/protobuf/protobuf.c
+++ b/php/ext/google/protobuf/protobuf.c
@@ -189,6 +189,7 @@
 
 static PHP_MINIT_FUNCTION(protobuf) {
   map_field_init(TSRMLS_C);
+  map_field_iter_init(TSRMLS_C);
   repeated_field_init(TSRMLS_C);
   repeated_field_iter_init(TSRMLS_C);
   gpb_type_init(TSRMLS_C);
@@ -206,6 +207,7 @@
   PEFREE(repeated_field_handlers);
   PEFREE(repeated_field_iter_handlers);
   PEFREE(map_field_handlers);
+  PEFREE(map_field_iter_handlers);
 
   return 0;
 }
diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h
index e6d42eb..eecae13 100644
--- a/php/ext/google/protobuf/protobuf.h
+++ b/php/ext/google/protobuf/protobuf.h
@@ -373,6 +373,7 @@
 struct RepeatedField;
 struct RepeatedFieldIter;
 struct Map;
+struct MapIter;
 struct Oneof;
 
 typedef struct DescriptorPool DescriptorPool;
@@ -385,6 +386,7 @@
 typedef struct RepeatedField RepeatedField;
 typedef struct RepeatedFieldIter RepeatedFieldIter;
 typedef struct Map Map;
+typedef struct MapIter MapIter;
 typedef struct Oneof Oneof;
 
 // -----------------------------------------------------------------------------
@@ -400,6 +402,7 @@
 void descriptor_pool_init(TSRMLS_D);
 void gpb_type_init(TSRMLS_D);
 void map_field_init(TSRMLS_D);
+void map_field_iter_init(TSRMLS_D);
 void repeated_field_init(TSRMLS_D);
 void repeated_field_iter_init(TSRMLS_D);
 void util_init(TSRMLS_D);
@@ -593,8 +596,8 @@
 
 PHP_METHOD(Message, serializeToString);
 PHP_METHOD(Message, mergeFromString);
-PHP_METHOD(Message, jsonEncode);
-PHP_METHOD(Message, jsonDecode);
+PHP_METHOD(Message, serializeToJsonString);
+PHP_METHOD(Message, mergeFromJsonString);
 
 // -----------------------------------------------------------------------------
 // Type check / conversion.
@@ -637,7 +640,7 @@
 bool native_slot_set_by_array(upb_fieldtype_t type,
                               const zend_class_entry* klass, void* memory,
                               zval* value TSRMLS_DC);
-void native_slot_init(upb_fieldtype_t type, void* memory, void* cache);
+void native_slot_init(upb_fieldtype_t type, void* memory, CACHED_VALUE* cache);
 // For each property, in order to avoid conversion between the zval object and
 // the actual data type during parsing/serialization, the containing message
 // object use the custom memory layout to store the actual data type for each
@@ -659,6 +662,7 @@
 // -----------------------------------------------------------------------------
 
 extern zend_object_handlers* map_field_handlers;
+extern zend_object_handlers* map_field_iter_handlers;
 
 PHP_PROTO_WRAP_OBJECT_START(Map)
   upb_fieldtype_t key_type;
@@ -667,10 +671,10 @@
   upb_strtable table;
 PHP_PROTO_WRAP_OBJECT_END
 
-typedef struct {
+PHP_PROTO_WRAP_OBJECT_START(MapIter)
   Map* self;
   upb_strtable_iter it;
-} MapIter;
+PHP_PROTO_WRAP_OBJECT_END
 
 void map_begin(zval* self, MapIter* iter TSRMLS_DC);
 void map_next(MapIter* iter);
@@ -709,6 +713,13 @@
 PHP_METHOD(MapField, offsetSet);
 PHP_METHOD(MapField, offsetUnset);
 PHP_METHOD(MapField, count);
+PHP_METHOD(MapField, getIterator);
+
+PHP_METHOD(MapFieldIter, rewind);
+PHP_METHOD(MapFieldIter, current);
+PHP_METHOD(MapFieldIter, key);
+PHP_METHOD(MapFieldIter, next);
+PHP_METHOD(MapFieldIter, valid);
 
 // -----------------------------------------------------------------------------
 // Repeated Field.
diff --git a/php/ext/google/protobuf/storage.c b/php/ext/google/protobuf/storage.c
index 6318f88..6c789bc 100644
--- a/php/ext/google/protobuf/storage.c
+++ b/php/ext/google/protobuf/storage.c
@@ -210,7 +210,7 @@
   return true;
 }
 
-void native_slot_init(upb_fieldtype_t type, void* memory, void* cache) {
+void native_slot_init(upb_fieldtype_t type, void* memory, CACHED_VALUE* cache) {
   zval* tmp = NULL;
   switch (type) {
     case UPB_TYPE_FLOAT:
@@ -224,6 +224,9 @@
       break;
     case UPB_TYPE_STRING:
     case UPB_TYPE_BYTES:
+      DEREF(memory, CACHED_VALUE*) = cache;
+      ZVAL_EMPTY_STRING(CACHED_PTR_TO_ZVAL_PTR(cache));
+      break;
     case UPB_TYPE_MESSAGE:
       DEREF(memory, CACHED_VALUE*) = cache;
       break;
@@ -355,6 +358,19 @@
   }
 }
 
+void native_slot_get_by_map_key(upb_fieldtype_t type, const void* memory,
+                                int length, CACHED_VALUE* cache TSRMLS_DC) {
+  switch (type) {
+    case UPB_TYPE_STRING:
+    case UPB_TYPE_BYTES: {
+      PHP_PROTO_ZVAL_STRINGL(CACHED_PTR_TO_ZVAL_PTR(cache), memory, length, 1);
+      return;
+    }
+    default:
+      native_slot_get(type, memory, cache TSRMLS_CC);
+  }
+}
+
 void native_slot_get_default(upb_fieldtype_t type,
                              CACHED_VALUE* cache TSRMLS_DC) {
   switch (type) {
@@ -608,6 +624,21 @@
     int cache_index = slot_property_cache(layout, storage, field);
     CACHED_VALUE* property_ptr = &properties_table[cache_index];
 
+    // Clean up initial value by generated code. In the generated code of
+    // previous versions, each php field is given an initial value. However, the
+    // order to initialize these fields may not be consistent with the order of
+    // upb fields.
+    if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(property_ptr)) == IS_STRING) {
+#if PHP_MAJOR_VERSION < 7
+      if (!IS_INTERNED(Z_STRVAL_PP(property_ptr))) {
+        FREE(Z_STRVAL_PP(property_ptr));
+      }
+#else
+      zend_string_release(Z_STR_P(property_ptr));
+#endif
+    }
+    ZVAL_NULL(CACHED_PTR_TO_ZVAL_PTR(property_ptr));
+
     if (upb_fielddef_containingoneof(field)) {
       memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
       *oneof_case = ONEOF_CASE_NONE;
@@ -731,7 +762,7 @@
   }
 }
 
-static native_slot_merge(const upb_fielddef* field, const void* from_memory,
+static void native_slot_merge(const upb_fielddef* field, const void* from_memory,
                          void* to_memory PHP_PROTO_TSRMLS_DC) {
   upb_fieldtype_t type = upb_fielddef_type(field);
   zend_class_entry* ce = NULL;
@@ -788,7 +819,7 @@
   }
 }
 
-static native_slot_merge_by_array(const upb_fielddef* field, const void* from_memory,
+static void native_slot_merge_by_array(const upb_fielddef* field, const void* from_memory,
                          void* to_memory PHP_PROTO_TSRMLS_DC) {
   upb_fieldtype_t type = upb_fielddef_type(field);
   switch (type) {
diff --git a/php/ext/google/protobuf/upb.c b/php/ext/google/protobuf/upb.c
index 7098301..d701dcb 100644
--- a/php/ext/google/protobuf/upb.c
+++ b/php/ext/google/protobuf/upb.c
@@ -1859,6 +1859,7 @@
   upb_gfree((void*)f->name);
   upb_gfree((void*)f->package);
   upb_gfree((void*)f->phpprefix);
+  upb_gfree((void*)f->phpnamespace);
   upb_gfree(f);
 }
 
@@ -1874,6 +1875,7 @@
   f->package = NULL;
   f->name = NULL;
   f->phpprefix = NULL;
+  f->phpnamespace = NULL;
   f->syntax = UPB_SYNTAX_PROTO2;
 
   if (!upb_refcounted_init(upb_filedef_upcast_mutable(f), &upb_filedef_vtbl,
@@ -1912,6 +1914,10 @@
   return f->phpprefix;
 }
 
+const char *upb_filedef_phpnamespace(const upb_filedef *f) {
+  return f->phpnamespace;
+}
+
 upb_syntax_t upb_filedef_syntax(const upb_filedef *f) {
   return f->syntax;
 }
@@ -1980,6 +1986,18 @@
   return true;
 }
 
+bool upb_filedef_setphpnamespace(upb_filedef *f, const char *phpnamespace,
+                                 upb_status *s) {
+  phpnamespace = upb_gstrdup(phpnamespace);
+  if (!phpnamespace) {
+    upb_upberr_setoom(s);
+    return false;
+  }
+  upb_gfree((void*)f->phpnamespace);
+  f->phpnamespace = phpnamespace;
+  return true;
+}
+
 bool upb_filedef_setsyntax(upb_filedef *f, upb_syntax_t syntax,
                            upb_status *s) {
   UPB_UNUSED(s);
@@ -2290,6 +2308,9 @@
   bool ret;
 
   n = upb_filedef_defcount(file);
+  if (n == 0) {
+    return true;
+  }
   defs = upb_gmalloc(sizeof(*defs) * n);
 
   if (defs == NULL) {
@@ -6419,14 +6440,14 @@
 
 
 static const upb_msgdef msgs[22];
-static const upb_fielddef fields[106];
+static const upb_fielddef fields[107];
 static const upb_enumdef enums[5];
 static const upb_tabent strentries[236];
 static const upb_tabent intentries[18];
-static const upb_tabval arrays[186];
+static const upb_tabval arrays[187];
 
 #ifdef UPB_DEBUG_REFS
-static upb_inttable reftables[266];
+static upb_inttable reftables[268];
 #endif
 
 static const upb_msgdef msgs[22] = {
@@ -6441,20 +6462,20 @@
   UPB_MSGDEF_INIT("google.protobuf.FieldOptions", 12, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[4], &arrays[42], 11, 6), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[56]), false, UPB_SYNTAX_PROTO2, &reftables[16], &reftables[17]),
   UPB_MSGDEF_INIT("google.protobuf.FileDescriptorProto", 42, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[53], 13, 12), UPB_STRTABLE_INIT(12, 15, UPB_CTYPE_PTR, 4, &strentries[72]), false, UPB_SYNTAX_PROTO2, &reftables[18], &reftables[19]),
   UPB_MSGDEF_INIT("google.protobuf.FileDescriptorSet", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[66], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[88]), false, UPB_SYNTAX_PROTO2, &reftables[20], &reftables[21]),
-  UPB_MSGDEF_INIT("google.protobuf.FileOptions", 34, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[68], 41, 16), UPB_STRTABLE_INIT(17, 31, UPB_CTYPE_PTR, 5, &strentries[92]), false, UPB_SYNTAX_PROTO2, &reftables[22], &reftables[23]),
-  UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 10, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[109], 8, 4), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[124]), false, UPB_SYNTAX_PROTO2, &reftables[24], &reftables[25]),
-  UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 15, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[117], 7, 6), UPB_STRTABLE_INIT(6, 7, UPB_CTYPE_PTR, 3, &strentries[132]), false, UPB_SYNTAX_PROTO2, &reftables[26], &reftables[27]),
-  UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[10], &arrays[124], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[140]), false, UPB_SYNTAX_PROTO2, &reftables[28], &reftables[29]),
-  UPB_MSGDEF_INIT("google.protobuf.OneofDescriptorProto", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[125], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[144]), false, UPB_SYNTAX_PROTO2, &reftables[30], &reftables[31]),
-  UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[127], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[148]), false, UPB_SYNTAX_PROTO2, &reftables[32], &reftables[33]),
-  UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[14], &arrays[131], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[152]), false, UPB_SYNTAX_PROTO2, &reftables[34], &reftables[35]),
-  UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[132], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[156]), false, UPB_SYNTAX_PROTO2, &reftables[36], &reftables[37]),
-  UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 19, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[134], 7, 5), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[160]), false, UPB_SYNTAX_PROTO2, &reftables[38], &reftables[39]),
-  UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 18, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[141], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[168]), false, UPB_SYNTAX_PROTO2, &reftables[40], &reftables[41]),
-  UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[150], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[184]), false, UPB_SYNTAX_PROTO2, &reftables[42], &reftables[43]),
+  UPB_MSGDEF_INIT("google.protobuf.FileOptions", 37, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[68], 42, 17), UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_PTR, 5, &strentries[92]), false, UPB_SYNTAX_PROTO2, &reftables[22], &reftables[23]),
+  UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 10, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[110], 8, 4), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[124]), false, UPB_SYNTAX_PROTO2, &reftables[24], &reftables[25]),
+  UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 15, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[118], 7, 6), UPB_STRTABLE_INIT(6, 7, UPB_CTYPE_PTR, 3, &strentries[132]), false, UPB_SYNTAX_PROTO2, &reftables[26], &reftables[27]),
+  UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[10], &arrays[125], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[140]), false, UPB_SYNTAX_PROTO2, &reftables[28], &reftables[29]),
+  UPB_MSGDEF_INIT("google.protobuf.OneofDescriptorProto", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[126], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[144]), false, UPB_SYNTAX_PROTO2, &reftables[30], &reftables[31]),
+  UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[128], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[148]), false, UPB_SYNTAX_PROTO2, &reftables[32], &reftables[33]),
+  UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[14], &arrays[132], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[152]), false, UPB_SYNTAX_PROTO2, &reftables[34], &reftables[35]),
+  UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[133], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[156]), false, UPB_SYNTAX_PROTO2, &reftables[36], &reftables[37]),
+  UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 19, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[135], 7, 5), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[160]), false, UPB_SYNTAX_PROTO2, &reftables[38], &reftables[39]),
+  UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 18, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[142], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[168]), false, UPB_SYNTAX_PROTO2, &reftables[40], &reftables[41]),
+  UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[151], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[184]), false, UPB_SYNTAX_PROTO2, &reftables[42], &reftables[43]),
 };
 
-static const upb_fielddef fields[106] = {
+static const upb_fielddef fields[107] = {
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "aggregate_value", 8, &msgs[20], NULL, 15, 6, {0},&reftables[44], &reftables[45]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "allow_alias", 2, &msgs[4], NULL, 6, 1, {0},&reftables[46], &reftables[47]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_enable_arenas", 31, &msgs[11], NULL, 23, 12, {0},&reftables[48], &reftables[49]),
@@ -6505,77 +6526,78 @@
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "message_type", 4, &msgs[9], (const upb_def*)(&msgs[0]), 10, 0, {0},&reftables[138], &reftables[139]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "method", 2, &msgs[16], (const upb_def*)(&msgs[13]), 6, 0, {0},&reftables[140], &reftables[141]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "name", 2, &msgs[20], (const upb_def*)(&msgs[21]), 5, 0, {0},&reftables[142], &reftables[143]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[0], NULL, 32, 8, {0},&reftables[144], &reftables[145]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[5], NULL, 4, 1, {0},&reftables[146], &reftables[147]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[13], NULL, 4, 1, {0},&reftables[148], &reftables[149]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[5], NULL, 4, 1, {0},&reftables[144], &reftables[145]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[9], NULL, 22, 6, {0},&reftables[146], &reftables[147]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[3], NULL, 8, 2, {0},&reftables[148], &reftables[149]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[16], NULL, 8, 2, {0},&reftables[150], &reftables[151]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[3], NULL, 8, 2, {0},&reftables[152], &reftables[153]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[15], NULL, 2, 0, {0},&reftables[154], &reftables[155]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[15], NULL, 2, 0, {0},&reftables[152], &reftables[153]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[13], NULL, 4, 1, {0},&reftables[154], &reftables[155]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[7], NULL, 4, 1, {0},&reftables[156], &reftables[157]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[9], NULL, 22, 6, {0},&reftables[158], &reftables[159]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[0], NULL, 32, 8, {0},&reftables[158], &reftables[159]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_STRING, 0, false, false, false, false, "name_part", 1, &msgs[21], NULL, 2, 0, {0},&reftables[160], &reftables[161]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, false, "negative_int_value", 5, &msgs[20], NULL, 10, 3, {0},&reftables[162], &reftables[163]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "nested_type", 3, &msgs[0], (const upb_def*)(&msgs[0]), 15, 1, {0},&reftables[164], &reftables[165]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "no_standard_descriptor_accessor", 2, &msgs[12], NULL, 7, 2, {0},&reftables[166], &reftables[167]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 2, &msgs[5], NULL, 7, 2, {0},&reftables[168], &reftables[169]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 3, &msgs[7], NULL, 10, 3, {0},&reftables[170], &reftables[171]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 3, &msgs[7], NULL, 10, 3, {0},&reftables[168], &reftables[169]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 2, &msgs[5], NULL, 7, 2, {0},&reftables[170], &reftables[171]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "objc_class_prefix", 36, &msgs[11], NULL, 24, 13, {0},&reftables[172], &reftables[173]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "oneof_decl", 8, &msgs[0], (const upb_def*)(&msgs[15]), 28, 6, {0},&reftables[174], &reftables[175]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "oneof_index", 9, &msgs[7], NULL, 19, 8, {0},&reftables[176], &reftables[177]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "optimize_for", 9, &msgs[11], (const upb_def*)(&enums[4]), 12, 3, {0},&reftables[178], &reftables[179]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[9], (const upb_def*)(&msgs[11]), 20, 4, {0},&reftables[180], &reftables[181]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 7, &msgs[0], (const upb_def*)(&msgs[12]), 25, 5, {0},&reftables[182], &reftables[183]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 4, &msgs[13], (const upb_def*)(&msgs[14]), 3, 0, {0},&reftables[184], &reftables[185]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[7], (const upb_def*)(&msgs[8]), 3, 0, {0},&reftables[186], &reftables[187]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[5], (const upb_def*)(&msgs[6]), 3, 0, {0},&reftables[188], &reftables[189]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[16], (const upb_def*)(&msgs[17]), 7, 1, {0},&reftables[190], &reftables[191]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[3], (const upb_def*)(&msgs[4]), 7, 1, {0},&reftables[192], &reftables[193]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 7, &msgs[0], (const upb_def*)(&msgs[12]), 25, 5, {0},&reftables[180], &reftables[181]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[9], (const upb_def*)(&msgs[11]), 20, 4, {0},&reftables[182], &reftables[183]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[7], (const upb_def*)(&msgs[8]), 3, 0, {0},&reftables[184], &reftables[185]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 4, &msgs[13], (const upb_def*)(&msgs[14]), 3, 0, {0},&reftables[186], &reftables[187]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[16], (const upb_def*)(&msgs[17]), 7, 1, {0},&reftables[188], &reftables[189]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[3], (const upb_def*)(&msgs[4]), 7, 1, {0},&reftables[190], &reftables[191]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[5], (const upb_def*)(&msgs[6]), 3, 0, {0},&reftables[192], &reftables[193]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "output_type", 3, &msgs[13], NULL, 10, 3, {0},&reftables[194], &reftables[195]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "package", 2, &msgs[9], NULL, 25, 7, {0},&reftables[196], &reftables[197]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "packed", 2, &msgs[8], NULL, 7, 2, {0},&reftables[198], &reftables[199]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "path", 1, &msgs[19], NULL, 4, 0, {0},&reftables[200], &reftables[201]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_class_prefix", 40, &msgs[11], NULL, 31, 16, {0},&reftables[202], &reftables[203]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, false, "positive_int_value", 4, &msgs[20], NULL, 9, 2, {0},&reftables[204], &reftables[205]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "public_dependency", 10, &msgs[9], NULL, 35, 9, {0},&reftables[206], &reftables[207]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "py_generic_services", 18, &msgs[11], NULL, 19, 8, {0},&reftables[208], &reftables[209]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "reserved_name", 10, &msgs[0], NULL, 37, 9, {0},&reftables[210], &reftables[211]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "reserved_range", 9, &msgs[0], (const upb_def*)(&msgs[2]), 31, 7, {0},&reftables[212], &reftables[213]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "server_streaming", 6, &msgs[13], NULL, 14, 5, {0},&reftables[214], &reftables[215]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "service", 6, &msgs[9], (const upb_def*)(&msgs[16]), 16, 2, {0},&reftables[216], &reftables[217]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "source_code_info", 9, &msgs[9], (const upb_def*)(&msgs[18]), 21, 5, {0},&reftables[218], &reftables[219]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "span", 2, &msgs[19], NULL, 7, 1, {0},&reftables[220], &reftables[221]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[2], NULL, 2, 0, {0},&reftables[222], &reftables[223]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[1], NULL, 2, 0, {0},&reftables[224], &reftables[225]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, false, "string_value", 7, &msgs[20], NULL, 12, 5, {0},&reftables[226], &reftables[227]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "syntax", 12, &msgs[9], NULL, 39, 11, {0},&reftables[228], &reftables[229]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "trailing_comments", 4, &msgs[19], NULL, 11, 3, {0},&reftables[230], &reftables[231]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "type", 5, &msgs[7], (const upb_def*)(&enums[1]), 12, 5, {0},&reftables[232], &reftables[233]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "type_name", 6, &msgs[7], NULL, 13, 6, {0},&reftables[234], &reftables[235]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[14], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[236], &reftables[237]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_namespace", 41, &msgs[11], NULL, 34, 17, {0},&reftables[204], &reftables[205]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, false, "positive_int_value", 4, &msgs[20], NULL, 9, 2, {0},&reftables[206], &reftables[207]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "public_dependency", 10, &msgs[9], NULL, 35, 9, {0},&reftables[208], &reftables[209]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "py_generic_services", 18, &msgs[11], NULL, 19, 8, {0},&reftables[210], &reftables[211]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "reserved_name", 10, &msgs[0], NULL, 37, 9, {0},&reftables[212], &reftables[213]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "reserved_range", 9, &msgs[0], (const upb_def*)(&msgs[2]), 31, 7, {0},&reftables[214], &reftables[215]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "server_streaming", 6, &msgs[13], NULL, 14, 5, {0},&reftables[216], &reftables[217]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "service", 6, &msgs[9], (const upb_def*)(&msgs[16]), 16, 2, {0},&reftables[218], &reftables[219]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "source_code_info", 9, &msgs[9], (const upb_def*)(&msgs[18]), 21, 5, {0},&reftables[220], &reftables[221]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "span", 2, &msgs[19], NULL, 7, 1, {0},&reftables[222], &reftables[223]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[2], NULL, 2, 0, {0},&reftables[224], &reftables[225]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[1], NULL, 2, 0, {0},&reftables[226], &reftables[227]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, false, "string_value", 7, &msgs[20], NULL, 12, 5, {0},&reftables[228], &reftables[229]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "syntax", 12, &msgs[9], NULL, 39, 11, {0},&reftables[230], &reftables[231]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "trailing_comments", 4, &msgs[19], NULL, 11, 3, {0},&reftables[232], &reftables[233]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "type", 5, &msgs[7], (const upb_def*)(&enums[1]), 12, 5, {0},&reftables[234], &reftables[235]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "type_name", 6, &msgs[7], NULL, 13, 6, {0},&reftables[236], &reftables[237]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[12], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[238], &reftables[239]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[17], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[240], &reftables[241]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[8], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[242], &reftables[243]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[11], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[244], &reftables[245]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[6], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[246], &reftables[247]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[4], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[248], &reftables[249]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "value", 2, &msgs[3], (const upb_def*)(&msgs[5]), 6, 0, {0},&reftables[250], &reftables[251]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "weak", 10, &msgs[8], NULL, 11, 6, {0},&reftables[252], &reftables[253]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "weak_dependency", 11, &msgs[9], NULL, 38, 10, {0},&reftables[254], &reftables[255]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[11], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[242], &reftables[243]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[14], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[244], &reftables[245]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[8], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[246], &reftables[247]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[6], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[248], &reftables[249]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[4], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[250], &reftables[251]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "value", 2, &msgs[3], (const upb_def*)(&msgs[5]), 6, 0, {0},&reftables[252], &reftables[253]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "weak", 10, &msgs[8], NULL, 11, 6, {0},&reftables[254], &reftables[255]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "weak_dependency", 11, &msgs[9], NULL, 38, 10, {0},&reftables[256], &reftables[257]),
 };
 
 static const upb_enumdef enums[5] = {
-  UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Label", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[188]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[153], 4, 3), 0, &reftables[256], &reftables[257]),
-  UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Type", UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_INT32, 5, &strentries[192]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[157], 19, 18), 0, &reftables[258], &reftables[259]),
-  UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.CType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[224]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[176], 3, 3), 0, &reftables[260], &reftables[261]),
-  UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.JSType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[228]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[179], 3, 3), 0, &reftables[262], &reftables[263]),
-  UPB_ENUMDEF_INIT("google.protobuf.FileOptions.OptimizeMode", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[232]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[182], 4, 3), 0, &reftables[264], &reftables[265]),
+  UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Label", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[188]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[154], 4, 3), 0, &reftables[258], &reftables[259]),
+  UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Type", UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_INT32, 5, &strentries[192]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[158], 19, 18), 0, &reftables[260], &reftables[261]),
+  UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.CType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[224]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[177], 3, 3), 0, &reftables[262], &reftables[263]),
+  UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.JSType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[228]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[180], 3, 3), 0, &reftables[264], &reftables[265]),
+  UPB_ENUMDEF_INIT("google.protobuf.FileOptions.OptimizeMode", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[232]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[183], 4, 3), 0, &reftables[266], &reftables[267]),
 };
 
 static const upb_tabent strentries[236] = {
   {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[22]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "reserved_name"), UPB_TABVALUE_PTR_INIT(&fields[83]), NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[50]), NULL},
+  {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "reserved_name"), UPB_TABVALUE_PTR_INIT(&fields[84]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[57]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
@@ -6584,31 +6606,31 @@
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "nested_type"), UPB_TABVALUE_PTR_INIT(&fields[60]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "reserved_range"), UPB_TABVALUE_PTR_INIT(&fields[84]), NULL},
-  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[69]), NULL},
+  {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "reserved_range"), UPB_TABVALUE_PTR_INIT(&fields[85]), NULL},
+  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[68]), NULL},
   {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "oneof_decl"), UPB_TABVALUE_PTR_INIT(&fields[65]), NULL},
   {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[20]), &strentries[13]},
-  {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[90]), NULL},
+  {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[91]), NULL},
   {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "end"), UPB_TABVALUE_PTR_INIT(&fields[18]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[89]), NULL},
+  {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[90]), NULL},
   {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "end"), UPB_TABVALUE_PTR_INIT(&fields[17]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[103]), NULL},
-  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[74]), NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[54]), &strentries[26]},
-  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[102]), NULL},
+  {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[104]), NULL},
+  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[73]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[52]), &strentries[26]},
+  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[103]), NULL},
   {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[14]), NULL},
   {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "allow_alias"), UPB_TABVALUE_PTR_INIT(&fields[1]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[62]), NULL},
+  {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[63]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[72]), NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[51]), &strentries[34]},
-  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL},
+  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[74]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[50]), &strentries[34]},
+  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[102]), NULL},
   {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[13]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
@@ -6620,17 +6642,17 @@
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[63]), &strentries[53]},
+  {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[62]), &strentries[53]},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\010", "\000", "\000", "\000", "extendee"), UPB_TABVALUE_PTR_INIT(&fields[21]), NULL},
-  {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "type_name"), UPB_TABVALUE_PTR_INIT(&fields[95]), NULL},
+  {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "type_name"), UPB_TABVALUE_PTR_INIT(&fields[96]), NULL},
   {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "json_name"), UPB_TABVALUE_PTR_INIT(&fields[38]), NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "type"), UPB_TABVALUE_PTR_INIT(&fields[94]), &strentries[50]},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "type"), UPB_TABVALUE_PTR_INIT(&fields[95]), &strentries[50]},
   {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "default_value"), UPB_TABVALUE_PTR_INIT(&fields[7]), NULL},
-  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[71]), NULL},
-  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[99]), NULL},
+  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[70]), NULL},
+  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "weak"), UPB_TABVALUE_PTR_INIT(&fields[104]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "weak"), UPB_TABVALUE_PTR_INIT(&fields[105]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
@@ -6645,21 +6667,21 @@
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[23]), NULL},
-  {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "weak_dependency"), UPB_TABVALUE_PTR_INIT(&fields[105]), NULL},
+  {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "weak_dependency"), UPB_TABVALUE_PTR_INIT(&fields[106]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[57]), NULL},
-  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "service"), UPB_TABVALUE_PTR_INIT(&fields[86]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[51]), NULL},
+  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "service"), UPB_TABVALUE_PTR_INIT(&fields[87]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "source_code_info"), UPB_TABVALUE_PTR_INIT(&fields[87]), NULL},
+  {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "source_code_info"), UPB_TABVALUE_PTR_INIT(&fields[88]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "syntax"), UPB_TABVALUE_PTR_INIT(&fields[92]), NULL},
+  {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "syntax"), UPB_TABVALUE_PTR_INIT(&fields[93]), NULL},
   {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "dependency"), UPB_TABVALUE_PTR_INIT(&fields[8]), NULL},
   {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "message_type"), UPB_TABVALUE_PTR_INIT(&fields[47]), NULL},
   {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "package"), UPB_TABVALUE_PTR_INIT(&fields[76]), NULL},
-  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[68]), &strentries[86]},
+  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[69]), &strentries[86]},
   {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[19]), NULL},
-  {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "public_dependency"), UPB_TABVALUE_PTR_INIT(&fields[81]), &strentries[85]},
+  {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "public_dependency"), UPB_TABVALUE_PTR_INIT(&fields[82]), &strentries[85]},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "file"), UPB_TABVALUE_PTR_INIT(&fields[26]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
@@ -6680,17 +6702,17 @@
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "java_outer_classname"), UPB_TABVALUE_PTR_INIT(&fields[34]), NULL},
-  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL},
+  {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "php_namespace"), UPB_TABVALUE_PTR_INIT(&fields[80]), &strentries[113]},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "java_multiple_files"), UPB_TABVALUE_PTR_INIT(&fields[33]), &strentries[117]},
-  {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[99]), NULL},
   {UPB_TABKEY_STR("\025", "\000", "\000", "\000", "java_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[32]), &strentries[118]},
   {UPB_TABKEY_STR("\035", "\000", "\000", "\000", "java_generate_equals_and_hash"), UPB_TABVALUE_PTR_INIT(&fields[31]), NULL},
   {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "php_class_prefix"), UPB_TABVALUE_PTR_INIT(&fields[79]), NULL},
   {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "javanano_use_deprecated_package"), UPB_TABVALUE_PTR_INIT(&fields[37]), &strentries[123]},
-  {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "py_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[82]), NULL},
+  {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "py_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[83]), NULL},
   {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "optimize_for"), UPB_TABVALUE_PTR_INIT(&fields[67]), NULL},
   {UPB_TABKEY_STR("\026", "\000", "\000", "\000", "java_string_check_utf8"), UPB_TABVALUE_PTR_INIT(&fields[36]), NULL},
   {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[12]), &strentries[119]},
@@ -6706,22 +6728,22 @@
   {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "no_standard_descriptor_accessor"), UPB_TABVALUE_PTR_INIT(&fields[61]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "client_streaming"), UPB_TABVALUE_PTR_INIT(&fields[4]), NULL},
-  {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "server_streaming"), UPB_TABVALUE_PTR_INIT(&fields[85]), NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[52]), NULL},
+  {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "server_streaming"), UPB_TABVALUE_PTR_INIT(&fields[86]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[55]), NULL},
   {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "input_type"), UPB_TABVALUE_PTR_INIT(&fields[29]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "output_type"), UPB_TABVALUE_PTR_INIT(&fields[75]), NULL},
-  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[70]), NULL},
-  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[96]), NULL},
+  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[71]), NULL},
+  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL},
   {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[55]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[54]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[73]), &strentries[150]},
+  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[72]), &strentries[150]},
   {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "method"), UPB_TABVALUE_PTR_INIT(&fields[48]), NULL},
   {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[53]), &strentries[149]},
   {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL},
@@ -6735,9 +6757,9 @@
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "span"), UPB_TABVALUE_PTR_INIT(&fields[88]), &strentries[167]},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "span"), UPB_TABVALUE_PTR_INIT(&fields[89]), &strentries[167]},
   {UPB_TABKEY_STR("\031", "\000", "\000", "\000", "leading_detached_comments"), UPB_TABVALUE_PTR_INIT(&fields[43]), &strentries[165]},
-  {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "trailing_comments"), UPB_TABVALUE_PTR_INIT(&fields[93]), NULL},
+  {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "trailing_comments"), UPB_TABVALUE_PTR_INIT(&fields[94]), NULL},
   {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "leading_comments"), UPB_TABVALUE_PTR_INIT(&fields[42]), &strentries[164]},
   {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "path"), UPB_TABVALUE_PTR_INIT(&fields[78]), NULL},
   {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "double_value"), UPB_TABVALUE_PTR_INIT(&fields[16]), NULL},
@@ -6753,9 +6775,9 @@
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "positive_int_value"), UPB_TABVALUE_PTR_INIT(&fields[80]), NULL},
+  {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "positive_int_value"), UPB_TABVALUE_PTR_INIT(&fields[81]), NULL},
   {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "identifier_value"), UPB_TABVALUE_PTR_INIT(&fields[28]), NULL},
-  {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "string_value"), UPB_TABVALUE_PTR_INIT(&fields[91]), &strentries[182]},
+  {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "string_value"), UPB_TABVALUE_PTR_INIT(&fields[92]), &strentries[182]},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "is_extension"), UPB_TABVALUE_PTR_INIT(&fields[30]), NULL},
@@ -6812,66 +6834,66 @@
 
 static const upb_tabent intentries[18] = {
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+  {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[103]), NULL},
+  {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[102]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[99]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL},
-  {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[96]), NULL},
+  {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[15]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL},
 };
 
-static const upb_tabval arrays[186] = {
+static const upb_tabval arrays[187] = {
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[50]),
+  UPB_TABVALUE_PTR_INIT(&fields[57]),
   UPB_TABVALUE_PTR_INIT(&fields[25]),
   UPB_TABVALUE_PTR_INIT(&fields[60]),
   UPB_TABVALUE_PTR_INIT(&fields[20]),
   UPB_TABVALUE_PTR_INIT(&fields[24]),
   UPB_TABVALUE_PTR_INIT(&fields[22]),
-  UPB_TABVALUE_PTR_INIT(&fields[69]),
+  UPB_TABVALUE_PTR_INIT(&fields[68]),
   UPB_TABVALUE_PTR_INIT(&fields[65]),
+  UPB_TABVALUE_PTR_INIT(&fields[85]),
   UPB_TABVALUE_PTR_INIT(&fields[84]),
-  UPB_TABVALUE_PTR_INIT(&fields[83]),
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[90]),
+  UPB_TABVALUE_PTR_INIT(&fields[91]),
   UPB_TABVALUE_PTR_INIT(&fields[18]),
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[89]),
+  UPB_TABVALUE_PTR_INIT(&fields[90]),
   UPB_TABVALUE_PTR_INIT(&fields[17]),
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[54]),
-  UPB_TABVALUE_PTR_INIT(&fields[103]),
-  UPB_TABVALUE_PTR_INIT(&fields[74]),
+  UPB_TABVALUE_PTR_INIT(&fields[52]),
+  UPB_TABVALUE_PTR_INIT(&fields[104]),
+  UPB_TABVALUE_PTR_INIT(&fields[73]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[1]),
   UPB_TABVALUE_PTR_INIT(&fields[14]),
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[51]),
-  UPB_TABVALUE_PTR_INIT(&fields[62]),
-  UPB_TABVALUE_PTR_INIT(&fields[72]),
+  UPB_TABVALUE_PTR_INIT(&fields[50]),
+  UPB_TABVALUE_PTR_INIT(&fields[63]),
+  UPB_TABVALUE_PTR_INIT(&fields[74]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[13]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[56]),
   UPB_TABVALUE_PTR_INIT(&fields[21]),
-  UPB_TABVALUE_PTR_INIT(&fields[63]),
+  UPB_TABVALUE_PTR_INIT(&fields[62]),
   UPB_TABVALUE_PTR_INIT(&fields[40]),
-  UPB_TABVALUE_PTR_INIT(&fields[94]),
   UPB_TABVALUE_PTR_INIT(&fields[95]),
+  UPB_TABVALUE_PTR_INIT(&fields[96]),
   UPB_TABVALUE_PTR_INIT(&fields[7]),
-  UPB_TABVALUE_PTR_INIT(&fields[71]),
+  UPB_TABVALUE_PTR_INIT(&fields[70]),
   UPB_TABVALUE_PTR_INIT(&fields[66]),
   UPB_TABVALUE_PTR_INIT(&fields[38]),
   UPB_TABVALUE_EMPTY_INIT,
@@ -6884,20 +6906,20 @@
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[104]),
+  UPB_TABVALUE_PTR_INIT(&fields[105]),
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[57]),
+  UPB_TABVALUE_PTR_INIT(&fields[51]),
   UPB_TABVALUE_PTR_INIT(&fields[76]),
   UPB_TABVALUE_PTR_INIT(&fields[8]),
   UPB_TABVALUE_PTR_INIT(&fields[47]),
   UPB_TABVALUE_PTR_INIT(&fields[19]),
-  UPB_TABVALUE_PTR_INIT(&fields[86]),
-  UPB_TABVALUE_PTR_INIT(&fields[23]),
-  UPB_TABVALUE_PTR_INIT(&fields[68]),
   UPB_TABVALUE_PTR_INIT(&fields[87]),
-  UPB_TABVALUE_PTR_INIT(&fields[81]),
-  UPB_TABVALUE_PTR_INIT(&fields[105]),
-  UPB_TABVALUE_PTR_INIT(&fields[92]),
+  UPB_TABVALUE_PTR_INIT(&fields[23]),
+  UPB_TABVALUE_PTR_INIT(&fields[69]),
+  UPB_TABVALUE_PTR_INIT(&fields[88]),
+  UPB_TABVALUE_PTR_INIT(&fields[82]),
+  UPB_TABVALUE_PTR_INIT(&fields[106]),
+  UPB_TABVALUE_PTR_INIT(&fields[93]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[26]),
   UPB_TABVALUE_EMPTY_INIT,
@@ -6918,7 +6940,7 @@
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[3]),
   UPB_TABVALUE_PTR_INIT(&fields[32]),
-  UPB_TABVALUE_PTR_INIT(&fields[82]),
+  UPB_TABVALUE_PTR_INIT(&fields[83]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[31]),
   UPB_TABVALUE_EMPTY_INIT,
@@ -6941,6 +6963,7 @@
   UPB_TABVALUE_PTR_INIT(&fields[37]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[79]),
+  UPB_TABVALUE_PTR_INIT(&fields[80]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[46]),
   UPB_TABVALUE_PTR_INIT(&fields[61]),
@@ -6950,37 +6973,37 @@
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[45]),
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[52]),
+  UPB_TABVALUE_PTR_INIT(&fields[55]),
   UPB_TABVALUE_PTR_INIT(&fields[29]),
   UPB_TABVALUE_PTR_INIT(&fields[75]),
-  UPB_TABVALUE_PTR_INIT(&fields[70]),
+  UPB_TABVALUE_PTR_INIT(&fields[71]),
   UPB_TABVALUE_PTR_INIT(&fields[4]),
-  UPB_TABVALUE_PTR_INIT(&fields[85]),
+  UPB_TABVALUE_PTR_INIT(&fields[86]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[55]),
+  UPB_TABVALUE_PTR_INIT(&fields[54]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[53]),
   UPB_TABVALUE_PTR_INIT(&fields[48]),
-  UPB_TABVALUE_PTR_INIT(&fields[73]),
+  UPB_TABVALUE_PTR_INIT(&fields[72]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[44]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[78]),
-  UPB_TABVALUE_PTR_INIT(&fields[88]),
+  UPB_TABVALUE_PTR_INIT(&fields[89]),
   UPB_TABVALUE_PTR_INIT(&fields[42]),
-  UPB_TABVALUE_PTR_INIT(&fields[93]),
+  UPB_TABVALUE_PTR_INIT(&fields[94]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[43]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[49]),
   UPB_TABVALUE_PTR_INIT(&fields[28]),
-  UPB_TABVALUE_PTR_INIT(&fields[80]),
+  UPB_TABVALUE_PTR_INIT(&fields[81]),
   UPB_TABVALUE_PTR_INIT(&fields[59]),
   UPB_TABVALUE_PTR_INIT(&fields[16]),
-  UPB_TABVALUE_PTR_INIT(&fields[91]),
+  UPB_TABVALUE_PTR_INIT(&fields[92]),
   UPB_TABVALUE_PTR_INIT(&fields[0]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[58]),
@@ -7021,7 +7044,9 @@
 };
 
 #ifdef UPB_DEBUG_REFS
-static upb_inttable reftables[266] = {
+static upb_inttable reftables[268] = {
+  UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+  UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
   UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
   UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
   UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
@@ -7565,6 +7590,34 @@
   return n;
 }
 
+static void *file_startphpnamespace(void *closure, const void *hd,
+                                    size_t size_hint) {
+  upb_descreader *r = closure;
+  bool ok;
+  UPB_UNUSED(hd);
+  UPB_UNUSED(size_hint);
+
+  ok = upb_filedef_setphpnamespace(r->file, "", NULL);
+  UPB_ASSERT(ok);
+  return closure;
+}
+
+static size_t file_onphpnamespace(void *closure, const void *hd,
+                                  const char *buf, size_t n,
+                                  const upb_bufhandle *handle) {
+  upb_descreader *r = closure;
+  char *php_namespace;
+  bool ok;
+  UPB_UNUSED(hd);
+  UPB_UNUSED(handle);
+
+  php_namespace = upb_gstrndup(buf, n);
+  ok = upb_filedef_setphpnamespace(r->file, php_namespace, NULL);
+  upb_gfree(php_namespace);
+  UPB_ASSERT(ok);
+  return n;
+}
+
 static size_t file_onphpprefix(void *closure, const void *hd, const char *buf,
                              size_t n, const upb_bufhandle *handle) {
   upb_descreader *r = closure;
@@ -8109,6 +8162,10 @@
   } else if (upbdefs_google_protobuf_FileOptions_is(m)) {
     upb_handlers_setstring(h, F(FileOptions, php_class_prefix),
                            &file_onphpprefix, NULL);
+    upb_handlers_setstartstr(h, F(FileOptions, php_namespace),
+                             &file_startphpnamespace, NULL);
+    upb_handlers_setstring(h, F(FileOptions, php_namespace),
+                           &file_onphpnamespace, NULL);
   }
 
   UPB_ASSERT(upb_ok(upb_handlers_status(h)));
@@ -11271,57 +11328,6 @@
   return r;
 }
 
-/* Given an encoded varint v, returns an integer with a single bit set that
- * indicates the end of the varint.  Subtracting one from this value will
- * yield a mask that leaves only bits that are part of the varint.  Returns
- * 0 if the varint is unterminated. */
-static uint64_t upb_get_vstopbit(uint64_t v) {
-  uint64_t cbits = v | 0x7f7f7f7f7f7f7f7fULL;
-  return ~cbits & (cbits+1);
-}
-
-/* A branchless decoder.  Credit to Pascal Massimino for the bit-twiddling. */
-upb_decoderet upb_vdecode_max8_massimino(upb_decoderet r) {
-  uint64_t b;
-  uint64_t stop_bit;
-  upb_decoderet my_r;
-  memcpy(&b, r.p, sizeof(b));
-  stop_bit = upb_get_vstopbit(b);
-  b =  (b & 0x7f7f7f7f7f7f7f7fULL) & (stop_bit - 1);
-  b +=       b & 0x007f007f007f007fULL;
-  b +=  3 * (b & 0x0000ffff0000ffffULL);
-  b += 15 * (b & 0x00000000ffffffffULL);
-  if (stop_bit == 0) {
-    /* Error: unterminated varint. */
-    upb_decoderet err_r = {(void*)0, 0};
-    return err_r;
-  }
-  my_r = upb_decoderet_make(r.p + ((__builtin_ctzll(stop_bit) + 1) / 8),
-                            r.val | (b << 7));
-  return my_r;
-}
-
-/* A branchless decoder.  Credit to Daniel Wright for the bit-twiddling. */
-upb_decoderet upb_vdecode_max8_wright(upb_decoderet r) {
-  uint64_t b;
-  uint64_t stop_bit;
-  upb_decoderet my_r;
-  memcpy(&b, r.p, sizeof(b));
-  stop_bit = upb_get_vstopbit(b);
-  b &= (stop_bit - 1);
-  b = ((b & 0x7f007f007f007f00ULL) >> 1) | (b & 0x007f007f007f007fULL);
-  b = ((b & 0xffff0000ffff0000ULL) >> 2) | (b & 0x0000ffff0000ffffULL);
-  b = ((b & 0xffffffff00000000ULL) >> 4) | (b & 0x00000000ffffffffULL);
-  if (stop_bit == 0) {
-    /* Error: unterminated varint. */
-    upb_decoderet err_r = {(void*)0, 0};
-    return err_r;
-  }
-  my_r = upb_decoderet_make(r.p + ((__builtin_ctzll(stop_bit) + 1) / 8),
-                            r.val | (b << 14));
-  return my_r;
-}
-
 #line 1 "upb/json/parser.rl"
 /*
 ** upb::json::Parser (upb_json_parser)
diff --git a/php/ext/google/protobuf/upb.h b/php/ext/google/protobuf/upb.h
index 78f255f..4b51275 100644
--- a/php/ext/google/protobuf/upb.h
+++ b/php/ext/google/protobuf/upb.h
@@ -2973,10 +2973,16 @@
   bool set_package(const char* package, Status* s);
 
   /* Sets the php class prefix which is prepended to all php generated classes
-   / from this .proto. Default is empty. */
+   * from this .proto. Default is empty. */
   const char* phpprefix() const;
   bool set_phpprefix(const char* phpprefix, Status* s);
 
+  /* Use this option to change the namespace of php generated classes. Default
+   * is empty. When this option is empty, the package name will be used for
+   * determining the namespace. */
+  const char* phpnamespace() const;
+  bool set_phpnamespace(const char* phpnamespace, Status* s);
+
   /* Syntax for the file.  Defaults to proto2. */
   upb_syntax_t syntax() const;
   void set_syntax(upb_syntax_t syntax);
@@ -3031,6 +3037,7 @@
 const char *upb_filedef_name(const upb_filedef *f);
 const char *upb_filedef_package(const upb_filedef *f);
 const char *upb_filedef_phpprefix(const upb_filedef *f);
+const char *upb_filedef_phpnamespace(const upb_filedef *f);
 upb_syntax_t upb_filedef_syntax(const upb_filedef *f);
 size_t upb_filedef_defcount(const upb_filedef *f);
 size_t upb_filedef_depcount(const upb_filedef *f);
@@ -3042,6 +3049,8 @@
 bool upb_filedef_setpackage(upb_filedef *f, const char *package, upb_status *s);
 bool upb_filedef_setphpprefix(upb_filedef *f, const char *phpprefix,
                               upb_status *s);
+bool upb_filedef_setphpnamespace(upb_filedef *f, const char *phpnamespace,
+                                 upb_status *s);
 bool upb_filedef_setsyntax(upb_filedef *f, upb_syntax_t syntax, upb_status *s);
 
 bool upb_filedef_adddef(upb_filedef *f, upb_def *def, const void *ref_donor,
@@ -3806,6 +3815,12 @@
 inline bool FileDef::set_phpprefix(const char* phpprefix, Status* s) {
   return upb_filedef_setphpprefix(this, phpprefix, s);
 }
+inline const char* FileDef::phpnamespace() const {
+  return upb_filedef_phpnamespace(this);
+}
+inline bool FileDef::set_phpnamespace(const char* phpnamespace, Status* s) {
+  return upb_filedef_setphpnamespace(this, phpnamespace, s);
+}
 inline int FileDef::def_count() const {
   return upb_filedef_defcount(this);
 }
@@ -4021,6 +4036,7 @@
   const char *name;
   const char *package;
   const char *phpprefix;
+  const char *phpnamespace;
   upb_syntax_t syntax;
 
   upb_inttable defs;
@@ -7228,6 +7244,7 @@
 UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_objc_class_prefix(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 36); }
 UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_optimize_for(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 9); }
 UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_php_class_prefix(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 40); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_php_namespace(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 41); }
 UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_py_generic_services(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 18); }
 UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_uninterpreted_option(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 999); }
 UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_f_deprecated(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_MessageOptions_is(m)); return upb_msgdef_itof(m, 3); }
@@ -8326,16 +8343,8 @@
   return ret;
 }
 
-/* Four functions for decoding a varint of at most eight bytes.  They are all
- * functionally identical, but are implemented in different ways and likely have
- * different performance profiles.  We keep them around for performance testing.
- *
- * Note that these functions may not read byte-by-byte, so they must not be used
- * unless there are at least eight bytes left in the buffer! */
 upb_decoderet upb_vdecode_max8_branch32(upb_decoderet r);
 upb_decoderet upb_vdecode_max8_branch64(upb_decoderet r);
-upb_decoderet upb_vdecode_max8_wright(upb_decoderet r);
-upb_decoderet upb_vdecode_max8_massimino(upb_decoderet r);
 
 /* Template for a function that checks the first two bytes with branching
  * and dispatches 2-10 bytes with a separate function.  Note that this may read
@@ -8360,8 +8369,6 @@
 
 UPB_VARINT_DECODER_CHECK2(branch32, upb_vdecode_max8_branch32)
 UPB_VARINT_DECODER_CHECK2(branch64, upb_vdecode_max8_branch64)
-UPB_VARINT_DECODER_CHECK2(wright, upb_vdecode_max8_wright)
-UPB_VARINT_DECODER_CHECK2(massimino, upb_vdecode_max8_massimino)
 #undef UPB_VARINT_DECODER_CHECK2
 
 /* Our canonical functions for decoding varints, based on the currently
@@ -8373,10 +8380,6 @@
     return upb_vdecode_check2_branch32(p);
 }
 
-UPB_INLINE upb_decoderet upb_vdecode_max8_fast(upb_decoderet r) {
-  return upb_vdecode_max8_massimino(r);
-}
-
 
 /* Encoding *******************************************************************/
 
diff --git a/php/phpunit.xml b/php/phpunit.xml
index 0191a60..637467b 100644
--- a/php/phpunit.xml
+++ b/php/phpunit.xml
@@ -7,8 +7,10 @@
       <file>tests/array_test.php</file>
       <file>tests/encode_decode_test.php</file>
       <file>tests/generated_class_test.php</file>
+      <file>tests/generated_phpdoc_test.php</file>
       <file>tests/map_field_test.php</file>
       <file>tests/well_known_test.php</file>
+      <file>tests/generated_service_test.php</file>
     </testsuite>
   </testsuites>
 </phpunit>
diff --git a/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php b/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php
index 0b7698e..60722d0 100644
--- a/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php
+++ b/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php
@@ -144,12 +144,14 @@
             ->optional('cc_generic_services', \Google\Protobuf\Internal\GPBType::BOOL, 16)
             ->optional('java_generic_services', \Google\Protobuf\Internal\GPBType::BOOL, 17)
             ->optional('py_generic_services', \Google\Protobuf\Internal\GPBType::BOOL, 18)
+            ->optional('php_generic_services', \Google\Protobuf\Internal\GPBType::BOOL, 19)
             ->optional('deprecated', \Google\Protobuf\Internal\GPBType::BOOL, 23)
             ->optional('cc_enable_arenas', \Google\Protobuf\Internal\GPBType::BOOL, 31)
             ->optional('objc_class_prefix', \Google\Protobuf\Internal\GPBType::STRING, 36)
             ->optional('csharp_namespace', \Google\Protobuf\Internal\GPBType::STRING, 37)
             ->optional('swift_prefix', \Google\Protobuf\Internal\GPBType::STRING, 39)
             ->optional('php_class_prefix', \Google\Protobuf\Internal\GPBType::STRING, 40)
+            ->optional('php_namespace', \Google\Protobuf\Internal\GPBType::STRING, 41)
             ->repeated('uninterpreted_option', \Google\Protobuf\Internal\GPBType::MESSAGE, 999, 'google.protobuf.internal.UninterpretedOption')
             ->finalizeToPool();
 
diff --git a/php/src/Google/Protobuf/Internal/InputStream.php b/php/src/Google/Protobuf/Internal/CodedInputStream.php
similarity index 95%
rename from php/src/Google/Protobuf/Internal/InputStream.php
rename to php/src/Google/Protobuf/Internal/CodedInputStream.php
index 8012a22..6131d5d 100644
--- a/php/src/Google/Protobuf/Internal/InputStream.php
+++ b/php/src/Google/Protobuf/Internal/CodedInputStream.php
@@ -34,28 +34,7 @@
 
 use Google\Protobuf\Internal\Uint64;
 
-function combineInt32ToInt64($high, $low)
-{
-    $isNeg = $high < 0;
-    if ($isNeg) {
-        $high = ~$high;
-        $low = ~$low;
-        $low++;
-        if (!$low) {
-            $high++;
-        }
-    }
-    $result = bcadd(bcmul($high, 4294967296), $low);
-    if ($low < 0) {
-        $result = bcadd($result, 4294967296);
-    }
-    if ($isNeg) {
-      $result = bcsub(0, $result);
-    }
-    return $result;
-}
-
-class InputStream
+class CodedInputStream
 {
 
     private $buffer;
@@ -94,7 +73,7 @@
         $this->current += $amount;
     }
 
-    private function bufferSize()
+    public function bufferSize()
     {
         return $this->buffer_end - $this->current;
     }
@@ -192,7 +171,10 @@
                 $count += 1;
             } while ($b & 0x80);
 
-            $var = combineInt32ToInt64($high, $low);
+            $var = GPBUtil::combineInt32ToInt64($high, $low);
+            if (bccomp($var, 0) < 0) {
+                $var = bcadd($var, "18446744073709551616");
+            }
         } else {
             $result = 0;
             $shift = 0;
@@ -265,7 +247,7 @@
         }
         $high = unpack('V', $data)[1];
         if (PHP_INT_SIZE == 4) {
-            $var = combineInt32ToInt64($high, $low);
+            $var = GPBUtil::combineInt32ToInt64($high, $low);
         } else {
             $var = ($high << 32) | $low;
         }
diff --git a/php/src/Google/Protobuf/Internal/OutputStream.php b/php/src/Google/Protobuf/Internal/CodedOutputStream.php
similarity index 92%
rename from php/src/Google/Protobuf/Internal/OutputStream.php
rename to php/src/Google/Protobuf/Internal/CodedOutputStream.php
index 8c6d9b6..4525d8d 100644
--- a/php/src/Google/Protobuf/Internal/OutputStream.php
+++ b/php/src/Google/Protobuf/Internal/CodedOutputStream.php
@@ -32,7 +32,7 @@
 
 namespace Google\Protobuf\Internal;
 
-class OutputStream
+class CodedOutputStream
 {
 
     private $buffer;
@@ -53,10 +53,10 @@
         return $this->buffer;
     }
 
-    public function writeVarint32($value)
+    public function writeVarint32($value, $trim)
     {
         $bytes = str_repeat(chr(0), self::MAX_VARINT64_BYTES);
-        $size = self::writeVarintToArray($value, $bytes);
+        $size = self::writeVarintToArray($value, $bytes, $trim);
         return $this->writeRaw($bytes, $size);
     }
 
@@ -83,7 +83,7 @@
 
     public function writeTag($tag)
     {
-        return $this->writeVarint32($tag);
+        return $this->writeVarint32($tag, true);
     }
 
     public function writeRaw($data, $size)
@@ -101,19 +101,19 @@
         return true;
     }
 
-    private static function writeVarintToArray($value, &$buffer)
+    private static function writeVarintToArray($value, &$buffer, $trim = false)
     {
         $current = 0;
 
         $high = 0;
         $low = 0;
         if (PHP_INT_SIZE == 4) {
-            GPBUtil::divideInt64ToInt32($value, $high, $low);
+            GPBUtil::divideInt64ToInt32($value, $high, $low, $trim);
         } else {
             $low = $value;
         }
 
-        while ($low >= 0x80 || $low < 0) {
+        while (($low >= 0x80 || $low < 0) || $high != 0) {
             $buffer[$current] = chr($low | 0x80);
             $value = ($value >> 7) & ~(0x7F << ((PHP_INT_SIZE << 3) - 7));
             $carry = ($high & 0x7F) << ((PHP_INT_SIZE << 3) - 7);
diff --git a/php/src/Google/Protobuf/Internal/Descriptor.php b/php/src/Google/Protobuf/Internal/Descriptor.php
new file mode 100644
index 0000000..44225ad
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/Descriptor.php
@@ -0,0 +1,189 @@
+<?php
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+namespace Google\Protobuf\Internal;
+
+class Descriptor
+{
+
+    private $full_name;
+    private $field = [];
+    private $json_to_field = [];
+    private $name_to_field = [];
+    private $nested_type = [];
+    private $enum_type = [];
+    private $klass;
+    private $options;
+    private $oneof_decl = [];
+
+    public function addOneofDecl($oneof)
+    {
+        $this->oneof_decl[] = $oneof;
+    }
+
+    public function getOneofDecl()
+    {
+        return $this->oneof_decl;
+    }
+
+    public function setFullName($full_name)
+    {
+        $this->full_name = $full_name;
+    }
+
+    public function getFullName()
+    {
+        return $this->full_name;
+    }
+
+    public function addField($field)
+    {
+        $this->field[$field->getNumber()] = $field;
+        $this->json_to_field[$field->getJsonName()] = $field;
+        $this->name_to_field[$field->getName()] = $field;
+    }
+
+    public function getField()
+    {
+        return $this->field;
+    }
+
+    public function addNestedType($desc)
+    {
+        $this->nested_type[] = $desc;
+    }
+
+    public function getNestedType()
+    {
+        return $this->nested_type;
+    }
+
+    public function addEnumType($desc)
+    {
+        $this->enum_type[] = $desc;
+    }
+
+    public function getEnumType()
+    {
+        return $this->enum_type;
+    }
+
+    public function getFieldByNumber($number)
+    {
+        if (!isset($this->field[$number])) {
+          return NULL;
+        } else {
+          return $this->field[$number];
+        }
+    }
+
+    public function getFieldByJsonName($json_name)
+    {
+        if (!isset($this->json_to_field[$json_name])) {
+          return NULL;
+        } else {
+          return $this->json_to_field[$json_name];
+        }
+    }
+
+    public function getFieldByName($name)
+    {
+        if (!isset($this->name_to_field[$name])) {
+          return NULL;
+        } else {
+          return $this->name_to_field[$name];
+        }
+    }
+
+    public function setClass($klass)
+    {
+        $this->klass = $klass;
+    }
+
+    public function getClass()
+    {
+        return $this->klass;
+    }
+
+    public function setOptions($options)
+    {
+        $this->options = $options;
+    }
+
+    public function getOptions()
+    {
+        return $this->options;
+    }
+
+    public static function buildFromProto($proto, $file_proto, $containing)
+    {
+        $desc = new Descriptor();
+
+        $message_name_without_package  = "";
+        $classname = "";
+        $fullname = "";
+        GPBUtil::getFullClassName(
+            $proto,
+            $containing,
+            $file_proto,
+            $message_name_without_package,
+            $classname,
+            $fullname);
+        $desc->setFullName($fullname);
+        $desc->setClass($classname);
+        $desc->setOptions($proto->getOptions());
+
+        foreach ($proto->getField() as $field_proto) {
+            $desc->addField(FieldDescriptor::buildFromProto($field_proto));
+        }
+
+        // Handle nested types.
+        foreach ($proto->getNestedType() as $nested_proto) {
+            $desc->addNestedType(Descriptor::buildFromProto(
+              $nested_proto, $file_proto, $message_name_without_package));
+        }
+
+        // Handle nested enum.
+        foreach ($proto->getEnumType() as $enum_proto) {
+            $desc->addEnumType(EnumDescriptor::buildFromProto(
+              $enum_proto, $file_proto, $message_name_without_package));
+        }
+
+        // Handle oneof fields.
+        foreach ($proto->getOneofDecl() as $oneof_proto) {
+            $desc->addOneofDecl(
+                OneofDescriptor::buildFromProto($oneof_proto, $desc));
+        }
+
+        return $desc;
+    }
+}
diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto.php b/php/src/Google/Protobuf/Internal/DescriptorProto.php
index 948c587..1d6959b 100644
--- a/php/src/Google/Protobuf/Internal/DescriptorProto.php
+++ b/php/src/Google/Protobuf/Internal/DescriptorProto.php
@@ -8,70 +8,65 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * <pre>
  * Describes a message type.
- * </pre>
  *
- * Protobuf type <code>google.protobuf.DescriptorProto</code>
+ * Generated from protobuf message <code>google.protobuf.DescriptorProto</code>
  */
 class DescriptorProto extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
      */
     private $name = '';
     private $has_name = false;
     /**
-     * <code>repeated .google.protobuf.FieldDescriptorProto field = 2;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.FieldDescriptorProto field = 2;</code>
      */
     private $field;
     private $has_field = false;
     /**
-     * <code>repeated .google.protobuf.FieldDescriptorProto extension = 6;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.FieldDescriptorProto extension = 6;</code>
      */
     private $extension;
     private $has_extension = false;
     /**
-     * <code>repeated .google.protobuf.DescriptorProto nested_type = 3;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto nested_type = 3;</code>
      */
     private $nested_type;
     private $has_nested_type = false;
     /**
-     * <code>repeated .google.protobuf.EnumDescriptorProto enum_type = 4;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.EnumDescriptorProto enum_type = 4;</code>
      */
     private $enum_type;
     private $has_enum_type = false;
     /**
-     * <code>repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;</code>
      */
     private $extension_range;
     private $has_extension_range = false;
     /**
-     * <code>repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;</code>
      */
     private $oneof_decl;
     private $has_oneof_decl = false;
     /**
-     * <code>optional .google.protobuf.MessageOptions options = 7;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.MessageOptions options = 7;</code>
      */
     private $options = null;
     private $has_options = false;
     /**
-     * <code>repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;</code>
      */
     private $reserved_range;
     private $has_reserved_range = false;
     /**
-     * <pre>
      * Reserved field names, which may not be used by fields in the same message.
      * A given name may only be reserved once.
-     * </pre>
      *
-     * <code>repeated string reserved_name = 10;</code>
+     * Generated from protobuf field <code>repeated string reserved_name = 10;</code>
      */
     private $reserved_name;
     private $has_reserved_name = false;
@@ -82,7 +77,8 @@
     }
 
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
+     * @return string
      */
     public function getName()
     {
@@ -90,13 +86,17 @@
     }
 
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
+     * @param string $var
+     * @return $this
      */
     public function setName($var)
     {
         GPBUtil::checkString($var, True);
         $this->name = $var;
         $this->has_name = true;
+
+        return $this;
     }
 
     public function hasName()
@@ -105,7 +105,8 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.FieldDescriptorProto field = 2;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.FieldDescriptorProto field = 2;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getField()
     {
@@ -113,13 +114,17 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.FieldDescriptorProto field = 2;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.FieldDescriptorProto field = 2;</code>
+     * @param \Google\Protobuf\Internal\FieldDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setField(&$var)
+    public function setField($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class);
         $this->field = $arr;
         $this->has_field = true;
+
+        return $this;
     }
 
     public function hasField()
@@ -128,7 +133,8 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.FieldDescriptorProto extension = 6;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.FieldDescriptorProto extension = 6;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getExtension()
     {
@@ -136,13 +142,17 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.FieldDescriptorProto extension = 6;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.FieldDescriptorProto extension = 6;</code>
+     * @param \Google\Protobuf\Internal\FieldDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setExtension(&$var)
+    public function setExtension($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class);
         $this->extension = $arr;
         $this->has_extension = true;
+
+        return $this;
     }
 
     public function hasExtension()
@@ -151,7 +161,8 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.DescriptorProto nested_type = 3;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto nested_type = 3;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getNestedType()
     {
@@ -159,13 +170,17 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.DescriptorProto nested_type = 3;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto nested_type = 3;</code>
+     * @param \Google\Protobuf\Internal\DescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setNestedType(&$var)
+    public function setNestedType($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto::class);
         $this->nested_type = $arr;
         $this->has_nested_type = true;
+
+        return $this;
     }
 
     public function hasNestedType()
@@ -174,7 +189,8 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.EnumDescriptorProto enum_type = 4;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.EnumDescriptorProto enum_type = 4;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getEnumType()
     {
@@ -182,13 +198,17 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.EnumDescriptorProto enum_type = 4;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.EnumDescriptorProto enum_type = 4;</code>
+     * @param \Google\Protobuf\Internal\EnumDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setEnumType(&$var)
+    public function setEnumType($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto::class);
         $this->enum_type = $arr;
         $this->has_enum_type = true;
+
+        return $this;
     }
 
     public function hasEnumType()
@@ -197,7 +217,8 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getExtensionRange()
     {
@@ -205,13 +226,17 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;</code>
+     * @param \Google\Protobuf\Internal\DescriptorProto_ExtensionRange[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setExtensionRange(&$var)
+    public function setExtensionRange($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto_ExtensionRange::class);
         $this->extension_range = $arr;
         $this->has_extension_range = true;
+
+        return $this;
     }
 
     public function hasExtensionRange()
@@ -220,7 +245,8 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getOneofDecl()
     {
@@ -228,13 +254,17 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;</code>
+     * @param \Google\Protobuf\Internal\OneofDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setOneofDecl(&$var)
+    public function setOneofDecl($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\OneofDescriptorProto::class);
         $this->oneof_decl = $arr;
         $this->has_oneof_decl = true;
+
+        return $this;
     }
 
     public function hasOneofDecl()
@@ -243,7 +273,8 @@
     }
 
     /**
-     * <code>optional .google.protobuf.MessageOptions options = 7;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.MessageOptions options = 7;</code>
+     * @return \Google\Protobuf\Internal\MessageOptions
      */
     public function getOptions()
     {
@@ -251,13 +282,17 @@
     }
 
     /**
-     * <code>optional .google.protobuf.MessageOptions options = 7;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.MessageOptions options = 7;</code>
+     * @param \Google\Protobuf\Internal\MessageOptions $var
+     * @return $this
      */
-    public function setOptions(&$var)
+    public function setOptions($var)
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\MessageOptions::class);
         $this->options = $var;
         $this->has_options = true;
+
+        return $this;
     }
 
     public function hasOptions()
@@ -266,7 +301,8 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getReservedRange()
     {
@@ -274,13 +310,17 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;</code>
+     * @param \Google\Protobuf\Internal\DescriptorProto_ReservedRange[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setReservedRange(&$var)
+    public function setReservedRange($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto_ReservedRange::class);
         $this->reserved_range = $arr;
         $this->has_reserved_range = true;
+
+        return $this;
     }
 
     public function hasReservedRange()
@@ -289,12 +329,11 @@
     }
 
     /**
-     * <pre>
      * Reserved field names, which may not be used by fields in the same message.
      * A given name may only be reserved once.
-     * </pre>
      *
-     * <code>repeated string reserved_name = 10;</code>
+     * Generated from protobuf field <code>repeated string reserved_name = 10;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getReservedName()
     {
@@ -302,18 +341,20 @@
     }
 
     /**
-     * <pre>
      * Reserved field names, which may not be used by fields in the same message.
      * A given name may only be reserved once.
-     * </pre>
      *
-     * <code>repeated string reserved_name = 10;</code>
+     * Generated from protobuf field <code>repeated string reserved_name = 10;</code>
+     * @param string[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setReservedName(&$var)
+    public function setReservedName($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING);
         $this->reserved_name = $arr;
         $this->has_reserved_name = true;
+
+        return $this;
     }
 
     public function hasReservedName()
diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php b/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php
index b68ded5..1d45599 100644
--- a/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php
+++ b/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php
@@ -8,26 +8,25 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * Protobuf type <code>google.protobuf.DescriptorProto.ExtensionRange</code>
+ * Generated from protobuf message <code>google.protobuf.DescriptorProto.ExtensionRange</code>
  */
 class DescriptorProto_ExtensionRange extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <code>optional int32 start = 1;</code>
+     * Generated from protobuf field <code>optional int32 start = 1;</code>
      */
     private $start = 0;
     private $has_start = false;
     /**
-     * <code>optional int32 end = 2;</code>
+     * Generated from protobuf field <code>optional int32 end = 2;</code>
      */
     private $end = 0;
     private $has_end = false;
     /**
-     * <code>optional .google.protobuf.ExtensionRangeOptions options = 3;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.ExtensionRangeOptions options = 3;</code>
      */
     private $options = null;
     private $has_options = false;
@@ -38,7 +37,8 @@
     }
 
     /**
-     * <code>optional int32 start = 1;</code>
+     * Generated from protobuf field <code>optional int32 start = 1;</code>
+     * @return int
      */
     public function getStart()
     {
@@ -46,13 +46,17 @@
     }
 
     /**
-     * <code>optional int32 start = 1;</code>
+     * Generated from protobuf field <code>optional int32 start = 1;</code>
+     * @param int $var
+     * @return $this
      */
     public function setStart($var)
     {
         GPBUtil::checkInt32($var);
         $this->start = $var;
         $this->has_start = true;
+
+        return $this;
     }
 
     public function hasStart()
@@ -61,7 +65,8 @@
     }
 
     /**
-     * <code>optional int32 end = 2;</code>
+     * Generated from protobuf field <code>optional int32 end = 2;</code>
+     * @return int
      */
     public function getEnd()
     {
@@ -69,13 +74,17 @@
     }
 
     /**
-     * <code>optional int32 end = 2;</code>
+     * Generated from protobuf field <code>optional int32 end = 2;</code>
+     * @param int $var
+     * @return $this
      */
     public function setEnd($var)
     {
         GPBUtil::checkInt32($var);
         $this->end = $var;
         $this->has_end = true;
+
+        return $this;
     }
 
     public function hasEnd()
@@ -84,7 +93,8 @@
     }
 
     /**
-     * <code>optional .google.protobuf.ExtensionRangeOptions options = 3;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.ExtensionRangeOptions options = 3;</code>
+     * @return \Google\Protobuf\Internal\ExtensionRangeOptions
      */
     public function getOptions()
     {
@@ -92,13 +102,17 @@
     }
 
     /**
-     * <code>optional .google.protobuf.ExtensionRangeOptions options = 3;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.ExtensionRangeOptions options = 3;</code>
+     * @param \Google\Protobuf\Internal\ExtensionRangeOptions $var
+     * @return $this
      */
-    public function setOptions(&$var)
+    public function setOptions($var)
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\ExtensionRangeOptions::class);
         $this->options = $var;
         $this->has_options = true;
+
+        return $this;
     }
 
     public function hasOptions()
diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php b/php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php
index be36b8a..b1022d6 100644
--- a/php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php
+++ b/php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php
@@ -8,35 +8,28 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * <pre>
  * Range of reserved tag numbers. Reserved tag numbers may not be used by
  * fields or extension ranges in the same message. Reserved ranges may
  * not overlap.
- * </pre>
  *
- * Protobuf type <code>google.protobuf.DescriptorProto.ReservedRange</code>
+ * Generated from protobuf message <code>google.protobuf.DescriptorProto.ReservedRange</code>
  */
 class DescriptorProto_ReservedRange extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <pre>
      * Inclusive.
-     * </pre>
      *
-     * <code>optional int32 start = 1;</code>
+     * Generated from protobuf field <code>optional int32 start = 1;</code>
      */
     private $start = 0;
     private $has_start = false;
     /**
-     * <pre>
      * Exclusive.
-     * </pre>
      *
-     * <code>optional int32 end = 2;</code>
+     * Generated from protobuf field <code>optional int32 end = 2;</code>
      */
     private $end = 0;
     private $has_end = false;
@@ -47,11 +40,10 @@
     }
 
     /**
-     * <pre>
      * Inclusive.
-     * </pre>
      *
-     * <code>optional int32 start = 1;</code>
+     * Generated from protobuf field <code>optional int32 start = 1;</code>
+     * @return int
      */
     public function getStart()
     {
@@ -59,17 +51,19 @@
     }
 
     /**
-     * <pre>
      * Inclusive.
-     * </pre>
      *
-     * <code>optional int32 start = 1;</code>
+     * Generated from protobuf field <code>optional int32 start = 1;</code>
+     * @param int $var
+     * @return $this
      */
     public function setStart($var)
     {
         GPBUtil::checkInt32($var);
         $this->start = $var;
         $this->has_start = true;
+
+        return $this;
     }
 
     public function hasStart()
@@ -78,11 +72,10 @@
     }
 
     /**
-     * <pre>
      * Exclusive.
-     * </pre>
      *
-     * <code>optional int32 end = 2;</code>
+     * Generated from protobuf field <code>optional int32 end = 2;</code>
+     * @return int
      */
     public function getEnd()
     {
@@ -90,17 +83,19 @@
     }
 
     /**
-     * <pre>
      * Exclusive.
-     * </pre>
      *
-     * <code>optional int32 end = 2;</code>
+     * Generated from protobuf field <code>optional int32 end = 2;</code>
+     * @param int $var
+     * @return $this
      */
     public function setEnd($var)
     {
         GPBUtil::checkInt32($var);
         $this->end = $var;
         $this->has_end = true;
+
+        return $this;
     }
 
     public function hasEnd()
diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptor.php b/php/src/Google/Protobuf/Internal/EnumDescriptor.php
new file mode 100644
index 0000000..33a55a4
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/EnumDescriptor.php
@@ -0,0 +1,72 @@
+<?php
+
+namespace Google\Protobuf\Internal;
+
+class EnumDescriptor
+{
+
+    private $klass;
+    private $full_name;
+    private $value;
+    private $name_to_value;
+
+    public function setFullName($full_name)
+    {
+        $this->full_name = $full_name;
+    }
+
+    public function getFullName()
+    {
+        return $this->full_name;
+    }
+
+    public function addValue($number, $value)
+    {
+        $this->value[$number] = $value;
+        $this->name_to_value[$value->getName()] = $value;
+    }
+
+    public function getValueByNumber($number)
+    {
+        return $this->value[$number];
+    }
+
+    public function getValueByName($name)
+    {
+        return $this->name_to_value[$name];
+    }
+
+    public function setClass($klass)
+    {
+        $this->klass = $klass;
+    }
+
+    public function getClass()
+    {
+        return $this->klass;
+    }
+
+    public static function buildFromProto($proto, $file_proto, $containing)
+    {
+        $desc = new EnumDescriptor();
+
+        $enum_name_without_package  = "";
+        $classname = "";
+        $fullname = "";
+        GPBUtil::getFullClassName(
+            $proto,
+            $containing,
+            $file_proto,
+            $enum_name_without_package,
+            $classname,
+            $fullname);
+        $desc->setFullName($fullname);
+        $desc->setClass($classname);
+        $values = $proto->getValue();
+        foreach ($values as $value) {
+            $desc->addValue($value->getNumber(), $value);
+        }
+
+        return $desc;
+    }
+}
diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php b/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php
index 73f6edb..816fbae 100644
--- a/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php
+++ b/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php
@@ -8,30 +8,27 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * <pre>
  * Describes an enum type.
- * </pre>
  *
- * Protobuf type <code>google.protobuf.EnumDescriptorProto</code>
+ * Generated from protobuf message <code>google.protobuf.EnumDescriptorProto</code>
  */
 class EnumDescriptorProto extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
      */
     private $name = '';
     private $has_name = false;
     /**
-     * <code>repeated .google.protobuf.EnumValueDescriptorProto value = 2;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.EnumValueDescriptorProto value = 2;</code>
      */
     private $value;
     private $has_value = false;
     /**
-     * <code>optional .google.protobuf.EnumOptions options = 3;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.EnumOptions options = 3;</code>
      */
     private $options = null;
     private $has_options = false;
@@ -42,7 +39,8 @@
     }
 
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
+     * @return string
      */
     public function getName()
     {
@@ -50,13 +48,17 @@
     }
 
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
+     * @param string $var
+     * @return $this
      */
     public function setName($var)
     {
         GPBUtil::checkString($var, True);
         $this->name = $var;
         $this->has_name = true;
+
+        return $this;
     }
 
     public function hasName()
@@ -65,7 +67,8 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.EnumValueDescriptorProto value = 2;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.EnumValueDescriptorProto value = 2;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getValue()
     {
@@ -73,13 +76,17 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.EnumValueDescriptorProto value = 2;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.EnumValueDescriptorProto value = 2;</code>
+     * @param \Google\Protobuf\Internal\EnumValueDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setValue(&$var)
+    public function setValue($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumValueDescriptorProto::class);
         $this->value = $arr;
         $this->has_value = true;
+
+        return $this;
     }
 
     public function hasValue()
@@ -88,7 +95,8 @@
     }
 
     /**
-     * <code>optional .google.protobuf.EnumOptions options = 3;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.EnumOptions options = 3;</code>
+     * @return \Google\Protobuf\Internal\EnumOptions
      */
     public function getOptions()
     {
@@ -96,13 +104,17 @@
     }
 
     /**
-     * <code>optional .google.protobuf.EnumOptions options = 3;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.EnumOptions options = 3;</code>
+     * @param \Google\Protobuf\Internal\EnumOptions $var
+     * @return $this
      */
-    public function setOptions(&$var)
+    public function setOptions($var)
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\EnumOptions::class);
         $this->options = $var;
         $this->has_options = true;
+
+        return $this;
     }
 
     public function hasOptions()
diff --git a/php/src/Google/Protobuf/Internal/EnumOptions.php b/php/src/Google/Protobuf/Internal/EnumOptions.php
index 4fa0bce..3f598a4 100644
--- a/php/src/Google/Protobuf/Internal/EnumOptions.php
+++ b/php/src/Google/Protobuf/Internal/EnumOptions.php
@@ -8,42 +8,35 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * Protobuf type <code>google.protobuf.EnumOptions</code>
+ * Generated from protobuf message <code>google.protobuf.EnumOptions</code>
  */
 class EnumOptions extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <pre>
      * Set this option to true to allow mapping different tag names to the same
      * value.
-     * </pre>
      *
-     * <code>optional bool allow_alias = 2;</code>
+     * Generated from protobuf field <code>optional bool allow_alias = 2;</code>
      */
     private $allow_alias = false;
     private $has_allow_alias = false;
     /**
-     * <pre>
      * Is this enum deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for the enum, or it will be completely ignored; in the very least, this
      * is a formalization for deprecating enums.
-     * </pre>
      *
-     * <code>optional bool deprecated = 3 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 3 [default = false];</code>
      */
     private $deprecated = false;
     private $has_deprecated = false;
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
      */
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
@@ -54,12 +47,11 @@
     }
 
     /**
-     * <pre>
      * Set this option to true to allow mapping different tag names to the same
      * value.
-     * </pre>
      *
-     * <code>optional bool allow_alias = 2;</code>
+     * Generated from protobuf field <code>optional bool allow_alias = 2;</code>
+     * @return bool
      */
     public function getAllowAlias()
     {
@@ -67,18 +59,20 @@
     }
 
     /**
-     * <pre>
      * Set this option to true to allow mapping different tag names to the same
      * value.
-     * </pre>
      *
-     * <code>optional bool allow_alias = 2;</code>
+     * Generated from protobuf field <code>optional bool allow_alias = 2;</code>
+     * @param bool $var
+     * @return $this
      */
     public function setAllowAlias($var)
     {
         GPBUtil::checkBool($var);
         $this->allow_alias = $var;
         $this->has_allow_alias = true;
+
+        return $this;
     }
 
     public function hasAllowAlias()
@@ -87,14 +81,13 @@
     }
 
     /**
-     * <pre>
      * Is this enum deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for the enum, or it will be completely ignored; in the very least, this
      * is a formalization for deprecating enums.
-     * </pre>
      *
-     * <code>optional bool deprecated = 3 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 3 [default = false];</code>
+     * @return bool
      */
     public function getDeprecated()
     {
@@ -102,20 +95,22 @@
     }
 
     /**
-     * <pre>
      * Is this enum deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for the enum, or it will be completely ignored; in the very least, this
      * is a formalization for deprecating enums.
-     * </pre>
      *
-     * <code>optional bool deprecated = 3 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 3 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setDeprecated($var)
     {
         GPBUtil::checkBool($var);
         $this->deprecated = $var;
         $this->has_deprecated = true;
+
+        return $this;
     }
 
     public function hasDeprecated()
@@ -124,11 +119,10 @@
     }
 
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getUninterpretedOption()
     {
@@ -136,17 +130,19 @@
     }
 
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * @param \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setUninterpretedOption(&$var)
+    public function setUninterpretedOption($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class);
         $this->uninterpreted_option = $arr;
         $this->has_uninterpreted_option = true;
+
+        return $this;
     }
 
     public function hasUninterpretedOption()
diff --git a/php/src/Google/Protobuf/Internal/EnumValueDescriptor.php b/php/src/Google/Protobuf/Internal/EnumValueDescriptor.php
new file mode 100644
index 0000000..549766e
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/EnumValueDescriptor.php
@@ -0,0 +1,59 @@
+<?php
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+namespace Google\Protobuf\Internal;
+
+class EnumValueDescriptor
+{
+    private $name;
+    private $number;
+
+    public function setName($name)
+    {
+        $this->name = $name;
+    }
+
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    public function setNumber($number)
+    {
+        $this->number = $number;
+    }
+
+    public function getNumber()
+    {
+        return $this->number;
+    }
+}
diff --git a/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php b/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php
index 94dc36e..e363220 100644
--- a/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php
+++ b/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php
@@ -8,30 +8,27 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * <pre>
  * Describes a value within an enum.
- * </pre>
  *
- * Protobuf type <code>google.protobuf.EnumValueDescriptorProto</code>
+ * Generated from protobuf message <code>google.protobuf.EnumValueDescriptorProto</code>
  */
 class EnumValueDescriptorProto extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
      */
     private $name = '';
     private $has_name = false;
     /**
-     * <code>optional int32 number = 2;</code>
+     * Generated from protobuf field <code>optional int32 number = 2;</code>
      */
     private $number = 0;
     private $has_number = false;
     /**
-     * <code>optional .google.protobuf.EnumValueOptions options = 3;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.EnumValueOptions options = 3;</code>
      */
     private $options = null;
     private $has_options = false;
@@ -42,7 +39,8 @@
     }
 
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
+     * @return string
      */
     public function getName()
     {
@@ -50,13 +48,17 @@
     }
 
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
+     * @param string $var
+     * @return $this
      */
     public function setName($var)
     {
         GPBUtil::checkString($var, True);
         $this->name = $var;
         $this->has_name = true;
+
+        return $this;
     }
 
     public function hasName()
@@ -65,7 +67,8 @@
     }
 
     /**
-     * <code>optional int32 number = 2;</code>
+     * Generated from protobuf field <code>optional int32 number = 2;</code>
+     * @return int
      */
     public function getNumber()
     {
@@ -73,13 +76,17 @@
     }
 
     /**
-     * <code>optional int32 number = 2;</code>
+     * Generated from protobuf field <code>optional int32 number = 2;</code>
+     * @param int $var
+     * @return $this
      */
     public function setNumber($var)
     {
         GPBUtil::checkInt32($var);
         $this->number = $var;
         $this->has_number = true;
+
+        return $this;
     }
 
     public function hasNumber()
@@ -88,7 +95,8 @@
     }
 
     /**
-     * <code>optional .google.protobuf.EnumValueOptions options = 3;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.EnumValueOptions options = 3;</code>
+     * @return \Google\Protobuf\Internal\EnumValueOptions
      */
     public function getOptions()
     {
@@ -96,13 +104,17 @@
     }
 
     /**
-     * <code>optional .google.protobuf.EnumValueOptions options = 3;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.EnumValueOptions options = 3;</code>
+     * @param \Google\Protobuf\Internal\EnumValueOptions $var
+     * @return $this
      */
-    public function setOptions(&$var)
+    public function setOptions($var)
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\EnumValueOptions::class);
         $this->options = $var;
         $this->has_options = true;
+
+        return $this;
     }
 
     public function hasOptions()
diff --git a/php/src/Google/Protobuf/Internal/EnumValueOptions.php b/php/src/Google/Protobuf/Internal/EnumValueOptions.php
index 232a673..db8de17 100644
--- a/php/src/Google/Protobuf/Internal/EnumValueOptions.php
+++ b/php/src/Google/Protobuf/Internal/EnumValueOptions.php
@@ -8,32 +8,27 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * Protobuf type <code>google.protobuf.EnumValueOptions</code>
+ * Generated from protobuf message <code>google.protobuf.EnumValueOptions</code>
  */
 class EnumValueOptions extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <pre>
      * Is this enum value deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for the enum value, or it will be completely ignored; in the very least,
      * this is a formalization for deprecating enum values.
-     * </pre>
      *
-     * <code>optional bool deprecated = 1 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 1 [default = false];</code>
      */
     private $deprecated = false;
     private $has_deprecated = false;
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
      */
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
@@ -44,14 +39,13 @@
     }
 
     /**
-     * <pre>
      * Is this enum value deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for the enum value, or it will be completely ignored; in the very least,
      * this is a formalization for deprecating enum values.
-     * </pre>
      *
-     * <code>optional bool deprecated = 1 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 1 [default = false];</code>
+     * @return bool
      */
     public function getDeprecated()
     {
@@ -59,20 +53,22 @@
     }
 
     /**
-     * <pre>
      * Is this enum value deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for the enum value, or it will be completely ignored; in the very least,
      * this is a formalization for deprecating enum values.
-     * </pre>
      *
-     * <code>optional bool deprecated = 1 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 1 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setDeprecated($var)
     {
         GPBUtil::checkBool($var);
         $this->deprecated = $var;
         $this->has_deprecated = true;
+
+        return $this;
     }
 
     public function hasDeprecated()
@@ -81,11 +77,10 @@
     }
 
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getUninterpretedOption()
     {
@@ -93,17 +88,19 @@
     }
 
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * @param \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setUninterpretedOption(&$var)
+    public function setUninterpretedOption($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class);
         $this->uninterpreted_option = $arr;
         $this->has_uninterpreted_option = true;
+
+        return $this;
     }
 
     public function hasUninterpretedOption()
diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptor.php b/php/src/Google/Protobuf/Internal/FieldDescriptor.php
new file mode 100644
index 0000000..f18bf81
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/FieldDescriptor.php
@@ -0,0 +1,253 @@
+<?php
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+namespace Google\Protobuf\Internal;
+
+class FieldDescriptor
+{
+
+    private $name;
+    private $json_name;
+    private $setter;
+    private $getter;
+    private $number;
+    private $label;
+    private $type;
+    private $message_type;
+    private $enum_type;
+    private $packed;
+    private $is_map;
+    private $oneof_index = -1;
+
+    public function setOneofIndex($index)
+    {
+        $this->oneof_index = $index;
+    }
+
+    public function getOneofIndex()
+    {
+        return $this->oneof_index;
+    }
+
+    public function setName($name)
+    {
+        $this->name = $name;
+    }
+
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    public function setJsonName($json_name)
+    {
+        $this->json_name = $json_name;
+    }
+
+    public function getJsonName()
+    {
+        return $this->json_name;
+    }
+
+    public function setSetter($setter)
+    {
+        $this->setter = $setter;
+    }
+
+    public function getSetter()
+    {
+        return $this->setter;
+    }
+
+    public function setGetter($getter)
+    {
+        $this->getter = $getter;
+    }
+
+    public function getGetter()
+    {
+        return $this->getter;
+    }
+
+    public function setNumber($number)
+    {
+        $this->number = $number;
+    }
+
+    public function getNumber()
+    {
+        return $this->number;
+    }
+
+    public function setLabel($label)
+    {
+        $this->label = $label;
+    }
+
+    public function getLabel()
+    {
+        return $this->label;
+    }
+
+    public function isRepeated()
+    {
+        return $this->label === GPBLabel::REPEATED;
+    }
+
+    public function setType($type)
+    {
+        $this->type = $type;
+    }
+
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    public function setMessageType($message_type)
+    {
+        $this->message_type = $message_type;
+    }
+
+    public function getMessageType()
+    {
+        return $this->message_type;
+    }
+
+    public function setEnumType($enum_type)
+    {
+        $this->enum_type = $enum_type;
+    }
+
+    public function getEnumType()
+    {
+        return $this->enum_type;
+    }
+
+    public function setPacked($packed)
+    {
+        $this->packed = $packed;
+    }
+
+    public function getPacked()
+    {
+        return $this->packed;
+    }
+
+    public function isPackable()
+    {
+        return $this->isRepeated() && self::isTypePackable($this->type);
+    }
+
+    public function isMap()
+    {
+        return $this->getType() == GPBType::MESSAGE &&
+               !is_null($this->getMessageType()->getOptions()) &&
+               $this->getMessageType()->getOptions()->getMapEntry();
+    }
+
+    private static function isTypePackable($field_type)
+    {
+        return ($field_type !== GPBType::STRING  &&
+            $field_type !== GPBType::GROUP   &&
+            $field_type !== GPBType::MESSAGE &&
+            $field_type !== GPBType::BYTES);
+    }
+
+    public static function getFieldDescriptor($proto)
+    {
+        $type_name = null;
+        $type = $proto->getType();
+        switch ($type) {
+            case GPBType::MESSAGE:
+            case GPBType::GROUP:
+            case GPBType::ENUM:
+                $type_name = $proto->getTypeName();
+                break;
+            default:
+                break;
+        }
+
+        $oneof_index = $proto->hasOneofIndex() ? $proto->getOneofIndex() : -1;
+        $packed = false;
+        $options = $proto->getOptions();
+        if ($options !== null) {
+            $packed = $options->getPacked();
+        }
+
+        $field = new FieldDescriptor();
+        $field->setName($proto->getName());
+
+        $json_name = $proto->hasJsonName() ? $proto->getJsonName() :
+            lcfirst(implode('', array_map('ucwords', explode('_', $proto->getName()))));
+        if ($proto->hasJsonName()) {
+            $json_name = $proto->getJsonName();
+        } else {
+            $proto_name = $proto->getName();
+            $json_name = implode('', array_map('ucwords', explode('_', $proto_name)));
+            if ($proto_name[0] !== "_" && !ctype_upper($proto_name[0])) {
+                $json_name = lcfirst($json_name);
+            }
+        }
+        $field->setJsonName($json_name);
+
+        $camel_name = implode('', array_map('ucwords', explode('_', $proto->getName())));
+        $field->setGetter('get' . $camel_name);
+        $field->setSetter('set' . $camel_name);
+        $field->setType($proto->getType());
+        $field->setNumber($proto->getNumber());
+        $field->setLabel($proto->getLabel());
+        $field->setPacked($packed);
+        $field->setOneofIndex($oneof_index);
+
+        // At this time, the message/enum type may have not been added to pool.
+        // So we use the type name as place holder and will replace it with the
+        // actual descriptor in cross building.
+        switch ($type) {
+            case GPBType::MESSAGE:
+                $field->setMessageType($type_name);
+                break;
+            case GPBType::ENUM:
+                $field->setEnumType($type_name);
+                break;
+            default:
+                break;
+        }
+
+        return $field;
+    }
+
+    public static function buildFromProto($proto)
+    {
+        return FieldDescriptor::getFieldDescriptor($proto);
+    }
+}
diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php
index 6ae2cd4..10c2759 100644
--- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php
+++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php
@@ -8,103 +8,88 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * <pre>
  * Describes a field within a message.
- * </pre>
  *
- * Protobuf type <code>google.protobuf.FieldDescriptorProto</code>
+ * Generated from protobuf message <code>google.protobuf.FieldDescriptorProto</code>
  */
 class FieldDescriptorProto extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
      */
     private $name = '';
     private $has_name = false;
     /**
-     * <code>optional int32 number = 3;</code>
+     * Generated from protobuf field <code>optional int32 number = 3;</code>
      */
     private $number = 0;
     private $has_number = false;
     /**
-     * <code>optional .google.protobuf.FieldDescriptorProto.Label label = 4;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FieldDescriptorProto.Label label = 4;</code>
      */
     private $label = 0;
     private $has_label = false;
     /**
-     * <pre>
      * If type_name is set, this need not be set.  If both this and type_name
      * are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
-     * </pre>
      *
-     * <code>optional .google.protobuf.FieldDescriptorProto.Type type = 5;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FieldDescriptorProto.Type type = 5;</code>
      */
     private $type = 0;
     private $has_type = false;
     /**
-     * <pre>
      * For message and enum types, this is the name of the type.  If the name
      * starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping
      * rules are used to find the type (i.e. first the nested types within this
      * message are searched, then within the parent, on up to the root
      * namespace).
-     * </pre>
      *
-     * <code>optional string type_name = 6;</code>
+     * Generated from protobuf field <code>optional string type_name = 6;</code>
      */
     private $type_name = '';
     private $has_type_name = false;
     /**
-     * <pre>
      * For extensions, this is the name of the type being extended.  It is
      * resolved in the same manner as type_name.
-     * </pre>
      *
-     * <code>optional string extendee = 2;</code>
+     * Generated from protobuf field <code>optional string extendee = 2;</code>
      */
     private $extendee = '';
     private $has_extendee = false;
     /**
-     * <pre>
      * For numeric types, contains the original text representation of the value.
      * For booleans, "true" or "false".
      * For strings, contains the default text contents (not escaped in any way).
-     * For bytes, contains the C escaped value.  All bytes &gt;= 128 are escaped.
+     * For bytes, contains the C escaped value.  All bytes >= 128 are escaped.
      * TODO(kenton):  Base-64 encode?
-     * </pre>
      *
-     * <code>optional string default_value = 7;</code>
+     * Generated from protobuf field <code>optional string default_value = 7;</code>
      */
     private $default_value = '';
     private $has_default_value = false;
     /**
-     * <pre>
      * If set, gives the index of a oneof in the containing type's oneof_decl
      * list.  This field is a member of that oneof.
-     * </pre>
      *
-     * <code>optional int32 oneof_index = 9;</code>
+     * Generated from protobuf field <code>optional int32 oneof_index = 9;</code>
      */
     private $oneof_index = 0;
     private $has_oneof_index = false;
     /**
-     * <pre>
      * JSON name of this field. The value is set by protocol compiler. If the
      * user has set a "json_name" option on this field, that option's value
      * will be used. Otherwise, it's deduced from the field's name by converting
      * it to camelCase.
-     * </pre>
      *
-     * <code>optional string json_name = 10;</code>
+     * Generated from protobuf field <code>optional string json_name = 10;</code>
      */
     private $json_name = '';
     private $has_json_name = false;
     /**
-     * <code>optional .google.protobuf.FieldOptions options = 8;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions options = 8;</code>
      */
     private $options = null;
     private $has_options = false;
@@ -115,7 +100,8 @@
     }
 
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
+     * @return string
      */
     public function getName()
     {
@@ -123,13 +109,17 @@
     }
 
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
+     * @param string $var
+     * @return $this
      */
     public function setName($var)
     {
         GPBUtil::checkString($var, True);
         $this->name = $var;
         $this->has_name = true;
+
+        return $this;
     }
 
     public function hasName()
@@ -138,7 +128,8 @@
     }
 
     /**
-     * <code>optional int32 number = 3;</code>
+     * Generated from protobuf field <code>optional int32 number = 3;</code>
+     * @return int
      */
     public function getNumber()
     {
@@ -146,13 +137,17 @@
     }
 
     /**
-     * <code>optional int32 number = 3;</code>
+     * Generated from protobuf field <code>optional int32 number = 3;</code>
+     * @param int $var
+     * @return $this
      */
     public function setNumber($var)
     {
         GPBUtil::checkInt32($var);
         $this->number = $var;
         $this->has_number = true;
+
+        return $this;
     }
 
     public function hasNumber()
@@ -161,7 +156,8 @@
     }
 
     /**
-     * <code>optional .google.protobuf.FieldDescriptorProto.Label label = 4;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FieldDescriptorProto.Label label = 4;</code>
+     * @return int
      */
     public function getLabel()
     {
@@ -169,13 +165,17 @@
     }
 
     /**
-     * <code>optional .google.protobuf.FieldDescriptorProto.Label label = 4;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FieldDescriptorProto.Label label = 4;</code>
+     * @param int $var
+     * @return $this
      */
     public function setLabel($var)
     {
         GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldDescriptorProto_Label::class);
         $this->label = $var;
         $this->has_label = true;
+
+        return $this;
     }
 
     public function hasLabel()
@@ -184,12 +184,11 @@
     }
 
     /**
-     * <pre>
      * If type_name is set, this need not be set.  If both this and type_name
      * are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
-     * </pre>
      *
-     * <code>optional .google.protobuf.FieldDescriptorProto.Type type = 5;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FieldDescriptorProto.Type type = 5;</code>
+     * @return int
      */
     public function getType()
     {
@@ -197,18 +196,20 @@
     }
 
     /**
-     * <pre>
      * If type_name is set, this need not be set.  If both this and type_name
      * are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
-     * </pre>
      *
-     * <code>optional .google.protobuf.FieldDescriptorProto.Type type = 5;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FieldDescriptorProto.Type type = 5;</code>
+     * @param int $var
+     * @return $this
      */
     public function setType($var)
     {
         GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldDescriptorProto_Type::class);
         $this->type = $var;
         $this->has_type = true;
+
+        return $this;
     }
 
     public function hasType()
@@ -217,15 +218,14 @@
     }
 
     /**
-     * <pre>
      * For message and enum types, this is the name of the type.  If the name
      * starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping
      * rules are used to find the type (i.e. first the nested types within this
      * message are searched, then within the parent, on up to the root
      * namespace).
-     * </pre>
      *
-     * <code>optional string type_name = 6;</code>
+     * Generated from protobuf field <code>optional string type_name = 6;</code>
+     * @return string
      */
     public function getTypeName()
     {
@@ -233,21 +233,23 @@
     }
 
     /**
-     * <pre>
      * For message and enum types, this is the name of the type.  If the name
      * starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping
      * rules are used to find the type (i.e. first the nested types within this
      * message are searched, then within the parent, on up to the root
      * namespace).
-     * </pre>
      *
-     * <code>optional string type_name = 6;</code>
+     * Generated from protobuf field <code>optional string type_name = 6;</code>
+     * @param string $var
+     * @return $this
      */
     public function setTypeName($var)
     {
         GPBUtil::checkString($var, True);
         $this->type_name = $var;
         $this->has_type_name = true;
+
+        return $this;
     }
 
     public function hasTypeName()
@@ -256,12 +258,11 @@
     }
 
     /**
-     * <pre>
      * For extensions, this is the name of the type being extended.  It is
      * resolved in the same manner as type_name.
-     * </pre>
      *
-     * <code>optional string extendee = 2;</code>
+     * Generated from protobuf field <code>optional string extendee = 2;</code>
+     * @return string
      */
     public function getExtendee()
     {
@@ -269,18 +270,20 @@
     }
 
     /**
-     * <pre>
      * For extensions, this is the name of the type being extended.  It is
      * resolved in the same manner as type_name.
-     * </pre>
      *
-     * <code>optional string extendee = 2;</code>
+     * Generated from protobuf field <code>optional string extendee = 2;</code>
+     * @param string $var
+     * @return $this
      */
     public function setExtendee($var)
     {
         GPBUtil::checkString($var, True);
         $this->extendee = $var;
         $this->has_extendee = true;
+
+        return $this;
     }
 
     public function hasExtendee()
@@ -289,15 +292,14 @@
     }
 
     /**
-     * <pre>
      * For numeric types, contains the original text representation of the value.
      * For booleans, "true" or "false".
      * For strings, contains the default text contents (not escaped in any way).
-     * For bytes, contains the C escaped value.  All bytes &gt;= 128 are escaped.
+     * For bytes, contains the C escaped value.  All bytes >= 128 are escaped.
      * TODO(kenton):  Base-64 encode?
-     * </pre>
      *
-     * <code>optional string default_value = 7;</code>
+     * Generated from protobuf field <code>optional string default_value = 7;</code>
+     * @return string
      */
     public function getDefaultValue()
     {
@@ -305,21 +307,23 @@
     }
 
     /**
-     * <pre>
      * For numeric types, contains the original text representation of the value.
      * For booleans, "true" or "false".
      * For strings, contains the default text contents (not escaped in any way).
-     * For bytes, contains the C escaped value.  All bytes &gt;= 128 are escaped.
+     * For bytes, contains the C escaped value.  All bytes >= 128 are escaped.
      * TODO(kenton):  Base-64 encode?
-     * </pre>
      *
-     * <code>optional string default_value = 7;</code>
+     * Generated from protobuf field <code>optional string default_value = 7;</code>
+     * @param string $var
+     * @return $this
      */
     public function setDefaultValue($var)
     {
         GPBUtil::checkString($var, True);
         $this->default_value = $var;
         $this->has_default_value = true;
+
+        return $this;
     }
 
     public function hasDefaultValue()
@@ -328,12 +332,11 @@
     }
 
     /**
-     * <pre>
      * If set, gives the index of a oneof in the containing type's oneof_decl
      * list.  This field is a member of that oneof.
-     * </pre>
      *
-     * <code>optional int32 oneof_index = 9;</code>
+     * Generated from protobuf field <code>optional int32 oneof_index = 9;</code>
+     * @return int
      */
     public function getOneofIndex()
     {
@@ -341,18 +344,20 @@
     }
 
     /**
-     * <pre>
      * If set, gives the index of a oneof in the containing type's oneof_decl
      * list.  This field is a member of that oneof.
-     * </pre>
      *
-     * <code>optional int32 oneof_index = 9;</code>
+     * Generated from protobuf field <code>optional int32 oneof_index = 9;</code>
+     * @param int $var
+     * @return $this
      */
     public function setOneofIndex($var)
     {
         GPBUtil::checkInt32($var);
         $this->oneof_index = $var;
         $this->has_oneof_index = true;
+
+        return $this;
     }
 
     public function hasOneofIndex()
@@ -361,14 +366,13 @@
     }
 
     /**
-     * <pre>
      * JSON name of this field. The value is set by protocol compiler. If the
      * user has set a "json_name" option on this field, that option's value
      * will be used. Otherwise, it's deduced from the field's name by converting
      * it to camelCase.
-     * </pre>
      *
-     * <code>optional string json_name = 10;</code>
+     * Generated from protobuf field <code>optional string json_name = 10;</code>
+     * @return string
      */
     public function getJsonName()
     {
@@ -376,20 +380,22 @@
     }
 
     /**
-     * <pre>
      * JSON name of this field. The value is set by protocol compiler. If the
      * user has set a "json_name" option on this field, that option's value
      * will be used. Otherwise, it's deduced from the field's name by converting
      * it to camelCase.
-     * </pre>
      *
-     * <code>optional string json_name = 10;</code>
+     * Generated from protobuf field <code>optional string json_name = 10;</code>
+     * @param string $var
+     * @return $this
      */
     public function setJsonName($var)
     {
         GPBUtil::checkString($var, True);
         $this->json_name = $var;
         $this->has_json_name = true;
+
+        return $this;
     }
 
     public function hasJsonName()
@@ -398,7 +404,8 @@
     }
 
     /**
-     * <code>optional .google.protobuf.FieldOptions options = 8;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions options = 8;</code>
+     * @return \Google\Protobuf\Internal\FieldOptions
      */
     public function getOptions()
     {
@@ -406,13 +413,17 @@
     }
 
     /**
-     * <code>optional .google.protobuf.FieldOptions options = 8;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions options = 8;</code>
+     * @param \Google\Protobuf\Internal\FieldOptions $var
+     * @return $this
      */
-    public function setOptions(&$var)
+    public function setOptions($var)
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FieldOptions::class);
         $this->options = $var;
         $this->has_options = true;
+
+        return $this;
     }
 
     public function hasOptions()
diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php
index a3cd8ef..f2a32fd 100644
--- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php
+++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php
@@ -5,24 +5,22 @@
 namespace Google\Protobuf\Internal;
 
 /**
- * Protobuf enum <code>google.protobuf.FieldDescriptorProto.Label</code>
+ * Protobuf enum <code>Google\Protobuf\Internal</code>
  */
 class FieldDescriptorProto_Label
 {
     /**
-     * <pre>
      * 0 is reserved for errors
-     * </pre>
      *
-     * <code>LABEL_OPTIONAL = 1;</code>
+     * Generated from protobuf enum <code>LABEL_OPTIONAL = 1;</code>
      */
     const LABEL_OPTIONAL = 1;
     /**
-     * <code>LABEL_REQUIRED = 2;</code>
+     * Generated from protobuf enum <code>LABEL_REQUIRED = 2;</code>
      */
     const LABEL_REQUIRED = 2;
     /**
-     * <code>LABEL_REPEATED = 3;</code>
+     * Generated from protobuf enum <code>LABEL_REPEATED = 3;</code>
      */
     const LABEL_REPEATED = 3;
 }
diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php
index 8335f9b..1b022de 100644
--- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php
+++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php
@@ -5,118 +5,102 @@
 namespace Google\Protobuf\Internal;
 
 /**
- * Protobuf enum <code>google.protobuf.FieldDescriptorProto.Type</code>
+ * Protobuf enum <code>Google\Protobuf\Internal</code>
  */
 class FieldDescriptorProto_Type
 {
     /**
-     * <pre>
      * 0 is reserved for errors.
      * Order is weird for historical reasons.
-     * </pre>
      *
-     * <code>TYPE_DOUBLE = 1;</code>
+     * Generated from protobuf enum <code>TYPE_DOUBLE = 1;</code>
      */
     const TYPE_DOUBLE = 1;
     /**
-     * <code>TYPE_FLOAT = 2;</code>
+     * Generated from protobuf enum <code>TYPE_FLOAT = 2;</code>
      */
     const TYPE_FLOAT = 2;
     /**
-     * <pre>
      * Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT64 if
      * negative values are likely.
-     * </pre>
      *
-     * <code>TYPE_INT64 = 3;</code>
+     * Generated from protobuf enum <code>TYPE_INT64 = 3;</code>
      */
     const TYPE_INT64 = 3;
     /**
-     * <code>TYPE_UINT64 = 4;</code>
+     * Generated from protobuf enum <code>TYPE_UINT64 = 4;</code>
      */
     const TYPE_UINT64 = 4;
     /**
-     * <pre>
      * Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT32 if
      * negative values are likely.
-     * </pre>
      *
-     * <code>TYPE_INT32 = 5;</code>
+     * Generated from protobuf enum <code>TYPE_INT32 = 5;</code>
      */
     const TYPE_INT32 = 5;
     /**
-     * <code>TYPE_FIXED64 = 6;</code>
+     * Generated from protobuf enum <code>TYPE_FIXED64 = 6;</code>
      */
     const TYPE_FIXED64 = 6;
     /**
-     * <code>TYPE_FIXED32 = 7;</code>
+     * Generated from protobuf enum <code>TYPE_FIXED32 = 7;</code>
      */
     const TYPE_FIXED32 = 7;
     /**
-     * <code>TYPE_BOOL = 8;</code>
+     * Generated from protobuf enum <code>TYPE_BOOL = 8;</code>
      */
     const TYPE_BOOL = 8;
     /**
-     * <code>TYPE_STRING = 9;</code>
+     * Generated from protobuf enum <code>TYPE_STRING = 9;</code>
      */
     const TYPE_STRING = 9;
     /**
-     * <pre>
      * Tag-delimited aggregate.
      * Group type is deprecated and not supported in proto3. However, Proto3
      * implementations should still be able to parse the group wire format and
      * treat group fields as unknown fields.
-     * </pre>
      *
-     * <code>TYPE_GROUP = 10;</code>
+     * Generated from protobuf enum <code>TYPE_GROUP = 10;</code>
      */
     const TYPE_GROUP = 10;
     /**
-     * <pre>
      * Length-delimited aggregate.
-     * </pre>
      *
-     * <code>TYPE_MESSAGE = 11;</code>
+     * Generated from protobuf enum <code>TYPE_MESSAGE = 11;</code>
      */
     const TYPE_MESSAGE = 11;
     /**
-     * <pre>
      * New in version 2.
-     * </pre>
      *
-     * <code>TYPE_BYTES = 12;</code>
+     * Generated from protobuf enum <code>TYPE_BYTES = 12;</code>
      */
     const TYPE_BYTES = 12;
     /**
-     * <code>TYPE_UINT32 = 13;</code>
+     * Generated from protobuf enum <code>TYPE_UINT32 = 13;</code>
      */
     const TYPE_UINT32 = 13;
     /**
-     * <code>TYPE_ENUM = 14;</code>
+     * Generated from protobuf enum <code>TYPE_ENUM = 14;</code>
      */
     const TYPE_ENUM = 14;
     /**
-     * <code>TYPE_SFIXED32 = 15;</code>
+     * Generated from protobuf enum <code>TYPE_SFIXED32 = 15;</code>
      */
     const TYPE_SFIXED32 = 15;
     /**
-     * <code>TYPE_SFIXED64 = 16;</code>
+     * Generated from protobuf enum <code>TYPE_SFIXED64 = 16;</code>
      */
     const TYPE_SFIXED64 = 16;
     /**
-     * <pre>
      * Uses ZigZag encoding.
-     * </pre>
      *
-     * <code>TYPE_SINT32 = 17;</code>
+     * Generated from protobuf enum <code>TYPE_SINT32 = 17;</code>
      */
     const TYPE_SINT32 = 17;
     /**
-     * <pre>
      * Uses ZigZag encoding.
-     * </pre>
      *
-     * <code>TYPE_SINT64 = 18;</code>
+     * Generated from protobuf enum <code>TYPE_SINT64 = 18;</code>
      */
     const TYPE_SINT64 = 18;
 }
diff --git a/php/src/Google/Protobuf/Internal/FieldOptions.php b/php/src/Google/Protobuf/Internal/FieldOptions.php
index 94c4418..169f860 100644
--- a/php/src/Google/Protobuf/Internal/FieldOptions.php
+++ b/php/src/Google/Protobuf/Internal/FieldOptions.php
@@ -8,41 +8,35 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * Protobuf type <code>google.protobuf.FieldOptions</code>
+ * Generated from protobuf message <code>google.protobuf.FieldOptions</code>
  */
 class FieldOptions extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <pre>
      * The ctype option instructs the C++ code generator to use a different
      * representation of the field than it normally would.  See the specific
      * options below.  This option is not yet implemented in the open source
      * release -- sorry, we'll try to include it in a future version!
-     * </pre>
      *
-     * <code>optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];</code>
      */
     private $ctype = 0;
     private $has_ctype = false;
     /**
-     * <pre>
      * The packed option can be enabled for repeated primitive fields to enable
      * a more efficient representation on the wire. Rather than repeatedly
      * writing the tag and type for each element, the entire array is encoded as
      * a single length-delimited blob. In proto3, only explicit setting it to
      * false will avoid using packed encoding.
-     * </pre>
      *
-     * <code>optional bool packed = 2;</code>
+     * Generated from protobuf field <code>optional bool packed = 2;</code>
      */
     private $packed = false;
     private $has_packed = false;
     /**
-     * <pre>
      * The jstype option determines the JavaScript type used for values of the
      * field.  The option is permitted only for 64 bit integral and fixed types
      * (int64, uint64, sint64, fixed64, sfixed64).  A field with jstype JS_STRING
@@ -53,14 +47,12 @@
      * JS_NORMAL is implementation dependent.
      * This option is an enum to permit additional types to be added, e.g.
      * goog.math.Integer.
-     * </pre>
      *
-     * <code>optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];</code>
      */
     private $jstype = 0;
     private $has_jstype = false;
     /**
-     * <pre>
      * Should this field be parsed lazily?  Lazy applies only to message-type
      * fields.  It means that when the outer message is initially parsed, the
      * inner message's contents will not be parsed but instead stored in encoded
@@ -85,39 +77,32 @@
      * implementation must either *always* check its required fields, or *never*
      * check its required fields, regardless of whether or not the message has
      * been parsed.
-     * </pre>
      *
-     * <code>optional bool lazy = 5 [default = false];</code>
+     * Generated from protobuf field <code>optional bool lazy = 5 [default = false];</code>
      */
     private $lazy = false;
     private $has_lazy = false;
     /**
-     * <pre>
      * Is this field deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for accessors, or it will be completely ignored; in the very least, this
      * is a formalization for deprecating fields.
-     * </pre>
      *
-     * <code>optional bool deprecated = 3 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 3 [default = false];</code>
      */
     private $deprecated = false;
     private $has_deprecated = false;
     /**
-     * <pre>
      * For Google-internal migration only. Do not use.
-     * </pre>
      *
-     * <code>optional bool weak = 10 [default = false];</code>
+     * Generated from protobuf field <code>optional bool weak = 10 [default = false];</code>
      */
     private $weak = false;
     private $has_weak = false;
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
      */
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
@@ -128,14 +113,13 @@
     }
 
     /**
-     * <pre>
      * The ctype option instructs the C++ code generator to use a different
      * representation of the field than it normally would.  See the specific
      * options below.  This option is not yet implemented in the open source
      * release -- sorry, we'll try to include it in a future version!
-     * </pre>
      *
-     * <code>optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];</code>
+     * @return int
      */
     public function getCtype()
     {
@@ -143,20 +127,22 @@
     }
 
     /**
-     * <pre>
      * The ctype option instructs the C++ code generator to use a different
      * representation of the field than it normally would.  See the specific
      * options below.  This option is not yet implemented in the open source
      * release -- sorry, we'll try to include it in a future version!
-     * </pre>
      *
-     * <code>optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];</code>
+     * @param int $var
+     * @return $this
      */
     public function setCtype($var)
     {
         GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldOptions_CType::class);
         $this->ctype = $var;
         $this->has_ctype = true;
+
+        return $this;
     }
 
     public function hasCtype()
@@ -165,15 +151,14 @@
     }
 
     /**
-     * <pre>
      * The packed option can be enabled for repeated primitive fields to enable
      * a more efficient representation on the wire. Rather than repeatedly
      * writing the tag and type for each element, the entire array is encoded as
      * a single length-delimited blob. In proto3, only explicit setting it to
      * false will avoid using packed encoding.
-     * </pre>
      *
-     * <code>optional bool packed = 2;</code>
+     * Generated from protobuf field <code>optional bool packed = 2;</code>
+     * @return bool
      */
     public function getPacked()
     {
@@ -181,21 +166,23 @@
     }
 
     /**
-     * <pre>
      * The packed option can be enabled for repeated primitive fields to enable
      * a more efficient representation on the wire. Rather than repeatedly
      * writing the tag and type for each element, the entire array is encoded as
      * a single length-delimited blob. In proto3, only explicit setting it to
      * false will avoid using packed encoding.
-     * </pre>
      *
-     * <code>optional bool packed = 2;</code>
+     * Generated from protobuf field <code>optional bool packed = 2;</code>
+     * @param bool $var
+     * @return $this
      */
     public function setPacked($var)
     {
         GPBUtil::checkBool($var);
         $this->packed = $var;
         $this->has_packed = true;
+
+        return $this;
     }
 
     public function hasPacked()
@@ -204,7 +191,6 @@
     }
 
     /**
-     * <pre>
      * The jstype option determines the JavaScript type used for values of the
      * field.  The option is permitted only for 64 bit integral and fixed types
      * (int64, uint64, sint64, fixed64, sfixed64).  A field with jstype JS_STRING
@@ -215,9 +201,9 @@
      * JS_NORMAL is implementation dependent.
      * This option is an enum to permit additional types to be added, e.g.
      * goog.math.Integer.
-     * </pre>
      *
-     * <code>optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];</code>
+     * @return int
      */
     public function getJstype()
     {
@@ -225,7 +211,6 @@
     }
 
     /**
-     * <pre>
      * The jstype option determines the JavaScript type used for values of the
      * field.  The option is permitted only for 64 bit integral and fixed types
      * (int64, uint64, sint64, fixed64, sfixed64).  A field with jstype JS_STRING
@@ -236,15 +221,18 @@
      * JS_NORMAL is implementation dependent.
      * This option is an enum to permit additional types to be added, e.g.
      * goog.math.Integer.
-     * </pre>
      *
-     * <code>optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];</code>
+     * @param int $var
+     * @return $this
      */
     public function setJstype($var)
     {
         GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldOptions_JSType::class);
         $this->jstype = $var;
         $this->has_jstype = true;
+
+        return $this;
     }
 
     public function hasJstype()
@@ -253,7 +241,6 @@
     }
 
     /**
-     * <pre>
      * Should this field be parsed lazily?  Lazy applies only to message-type
      * fields.  It means that when the outer message is initially parsed, the
      * inner message's contents will not be parsed but instead stored in encoded
@@ -278,9 +265,9 @@
      * implementation must either *always* check its required fields, or *never*
      * check its required fields, regardless of whether or not the message has
      * been parsed.
-     * </pre>
      *
-     * <code>optional bool lazy = 5 [default = false];</code>
+     * Generated from protobuf field <code>optional bool lazy = 5 [default = false];</code>
+     * @return bool
      */
     public function getLazy()
     {
@@ -288,7 +275,6 @@
     }
 
     /**
-     * <pre>
      * Should this field be parsed lazily?  Lazy applies only to message-type
      * fields.  It means that when the outer message is initially parsed, the
      * inner message's contents will not be parsed but instead stored in encoded
@@ -313,15 +299,18 @@
      * implementation must either *always* check its required fields, or *never*
      * check its required fields, regardless of whether or not the message has
      * been parsed.
-     * </pre>
      *
-     * <code>optional bool lazy = 5 [default = false];</code>
+     * Generated from protobuf field <code>optional bool lazy = 5 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setLazy($var)
     {
         GPBUtil::checkBool($var);
         $this->lazy = $var;
         $this->has_lazy = true;
+
+        return $this;
     }
 
     public function hasLazy()
@@ -330,14 +319,13 @@
     }
 
     /**
-     * <pre>
      * Is this field deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for accessors, or it will be completely ignored; in the very least, this
      * is a formalization for deprecating fields.
-     * </pre>
      *
-     * <code>optional bool deprecated = 3 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 3 [default = false];</code>
+     * @return bool
      */
     public function getDeprecated()
     {
@@ -345,20 +333,22 @@
     }
 
     /**
-     * <pre>
      * Is this field deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for accessors, or it will be completely ignored; in the very least, this
      * is a formalization for deprecating fields.
-     * </pre>
      *
-     * <code>optional bool deprecated = 3 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 3 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setDeprecated($var)
     {
         GPBUtil::checkBool($var);
         $this->deprecated = $var;
         $this->has_deprecated = true;
+
+        return $this;
     }
 
     public function hasDeprecated()
@@ -367,11 +357,10 @@
     }
 
     /**
-     * <pre>
      * For Google-internal migration only. Do not use.
-     * </pre>
      *
-     * <code>optional bool weak = 10 [default = false];</code>
+     * Generated from protobuf field <code>optional bool weak = 10 [default = false];</code>
+     * @return bool
      */
     public function getWeak()
     {
@@ -379,17 +368,19 @@
     }
 
     /**
-     * <pre>
      * For Google-internal migration only. Do not use.
-     * </pre>
      *
-     * <code>optional bool weak = 10 [default = false];</code>
+     * Generated from protobuf field <code>optional bool weak = 10 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setWeak($var)
     {
         GPBUtil::checkBool($var);
         $this->weak = $var;
         $this->has_weak = true;
+
+        return $this;
     }
 
     public function hasWeak()
@@ -398,11 +389,10 @@
     }
 
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getUninterpretedOption()
     {
@@ -410,17 +400,19 @@
     }
 
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * @param \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setUninterpretedOption(&$var)
+    public function setUninterpretedOption($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class);
         $this->uninterpreted_option = $arr;
         $this->has_uninterpreted_option = true;
+
+        return $this;
     }
 
     public function hasUninterpretedOption()
diff --git a/php/src/Google/Protobuf/Internal/FieldOptions_CType.php b/php/src/Google/Protobuf/Internal/FieldOptions_CType.php
index f59f20b..0f33072 100644
--- a/php/src/Google/Protobuf/Internal/FieldOptions_CType.php
+++ b/php/src/Google/Protobuf/Internal/FieldOptions_CType.php
@@ -5,24 +5,22 @@
 namespace Google\Protobuf\Internal;
 
 /**
- * Protobuf enum <code>google.protobuf.FieldOptions.CType</code>
+ * Protobuf enum <code>Google\Protobuf\Internal</code>
  */
 class FieldOptions_CType
 {
     /**
-     * <pre>
      * Default mode.
-     * </pre>
      *
-     * <code>STRING = 0;</code>
+     * Generated from protobuf enum <code>STRING = 0;</code>
      */
     const STRING = 0;
     /**
-     * <code>CORD = 1;</code>
+     * Generated from protobuf enum <code>CORD = 1;</code>
      */
     const CORD = 1;
     /**
-     * <code>STRING_PIECE = 2;</code>
+     * Generated from protobuf enum <code>STRING_PIECE = 2;</code>
      */
     const STRING_PIECE = 2;
 }
diff --git a/php/src/Google/Protobuf/Internal/FieldOptions_JSType.php b/php/src/Google/Protobuf/Internal/FieldOptions_JSType.php
index 0c6995b..73bdf3f 100644
--- a/php/src/Google/Protobuf/Internal/FieldOptions_JSType.php
+++ b/php/src/Google/Protobuf/Internal/FieldOptions_JSType.php
@@ -5,32 +5,26 @@
 namespace Google\Protobuf\Internal;
 
 /**
- * Protobuf enum <code>google.protobuf.FieldOptions.JSType</code>
+ * Protobuf enum <code>Google\Protobuf\Internal</code>
  */
 class FieldOptions_JSType
 {
     /**
-     * <pre>
      * Use the default type.
-     * </pre>
      *
-     * <code>JS_NORMAL = 0;</code>
+     * Generated from protobuf enum <code>JS_NORMAL = 0;</code>
      */
     const JS_NORMAL = 0;
     /**
-     * <pre>
      * Use JavaScript strings.
-     * </pre>
      *
-     * <code>JS_STRING = 1;</code>
+     * Generated from protobuf enum <code>JS_STRING = 1;</code>
      */
     const JS_STRING = 1;
     /**
-     * <pre>
      * Use JavaScript numbers.
-     * </pre>
      *
-     * <code>JS_NUMBER = 2;</code>
+     * Generated from protobuf enum <code>JS_NUMBER = 2;</code>
      */
     const JS_NUMBER = 2;
 }
diff --git a/php/src/Google/Protobuf/Internal/FileDescriptor.php b/php/src/Google/Protobuf/Internal/FileDescriptor.php
new file mode 100644
index 0000000..038da38
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/FileDescriptor.php
@@ -0,0 +1,89 @@
+<?php
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+namespace Google\Protobuf\Internal;
+
+class FileDescriptor
+{
+
+    private $package;
+    private $message_type = [];
+    private $enum_type = [];
+
+    public function setPackage($package)
+    {
+        $this->package = $package;
+    }
+
+    public function getPackage()
+    {
+        return $this->package;
+    }
+
+    public function getMessageType()
+    {
+        return $this->message_type;
+    }
+
+    public function addMessageType($desc)
+    {
+        $this->message_type[] = $desc;
+    }
+
+    public function getEnumType()
+    {
+        return $this->enum_type;
+    }
+
+    public function addEnumType($desc)
+    {
+        $this->enum_type[]= $desc;
+    }
+
+    public static function buildFromProto($proto)
+    {
+        $file = new FileDescriptor();
+        $file->setPackage($proto->getPackage());
+        foreach ($proto->getMessageType() as $message_proto) {
+            $file->addMessageType(Descriptor::buildFromProto(
+                $message_proto, $proto, ""));
+        }
+        foreach ($proto->getEnumType() as $enum_proto) {
+            $file->addEnumType(
+                EnumDescriptor::buildFromProto(
+                    $enum_proto,
+                    $proto,
+                    ""));
+        }
+        return $file;
+    }
+}
diff --git a/php/src/Google/Protobuf/Internal/FileDescriptorProto.php b/php/src/Google/Protobuf/Internal/FileDescriptorProto.php
index 0363d9e..9ee222d 100644
--- a/php/src/Google/Protobuf/Internal/FileDescriptorProto.php
+++ b/php/src/Google/Protobuf/Internal/FileDescriptorProto.php
@@ -8,112 +8,93 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * <pre>
  * Describes a complete .proto file.
- * </pre>
  *
- * Protobuf type <code>google.protobuf.FileDescriptorProto</code>
+ * Generated from protobuf message <code>google.protobuf.FileDescriptorProto</code>
  */
 class FileDescriptorProto extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <pre>
      * file name, relative to root of source tree
-     * </pre>
      *
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
      */
     private $name = '';
     private $has_name = false;
     /**
-     * <pre>
      * e.g. "foo", "foo.bar", etc.
-     * </pre>
      *
-     * <code>optional string package = 2;</code>
+     * Generated from protobuf field <code>optional string package = 2;</code>
      */
     private $package = '';
     private $has_package = false;
     /**
-     * <pre>
      * Names of files imported by this file.
-     * </pre>
      *
-     * <code>repeated string dependency = 3;</code>
+     * Generated from protobuf field <code>repeated string dependency = 3;</code>
      */
     private $dependency;
     private $has_dependency = false;
     /**
-     * <pre>
      * Indexes of the public imported files in the dependency list above.
-     * </pre>
      *
-     * <code>repeated int32 public_dependency = 10;</code>
+     * Generated from protobuf field <code>repeated int32 public_dependency = 10;</code>
      */
     private $public_dependency;
     private $has_public_dependency = false;
     /**
-     * <pre>
      * Indexes of the weak imported files in the dependency list.
      * For Google-internal migration only. Do not use.
-     * </pre>
      *
-     * <code>repeated int32 weak_dependency = 11;</code>
+     * Generated from protobuf field <code>repeated int32 weak_dependency = 11;</code>
      */
     private $weak_dependency;
     private $has_weak_dependency = false;
     /**
-     * <pre>
      * All top-level definitions in this file.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.DescriptorProto message_type = 4;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto message_type = 4;</code>
      */
     private $message_type;
     private $has_message_type = false;
     /**
-     * <code>repeated .google.protobuf.EnumDescriptorProto enum_type = 5;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.EnumDescriptorProto enum_type = 5;</code>
      */
     private $enum_type;
     private $has_enum_type = false;
     /**
-     * <code>repeated .google.protobuf.ServiceDescriptorProto service = 6;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.ServiceDescriptorProto service = 6;</code>
      */
     private $service;
     private $has_service = false;
     /**
-     * <code>repeated .google.protobuf.FieldDescriptorProto extension = 7;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.FieldDescriptorProto extension = 7;</code>
      */
     private $extension;
     private $has_extension = false;
     /**
-     * <code>optional .google.protobuf.FileOptions options = 8;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FileOptions options = 8;</code>
      */
     private $options = null;
     private $has_options = false;
     /**
-     * <pre>
      * This field contains optional information about the original source code.
      * You may safely remove this entire field without harming runtime
      * functionality of the descriptors -- the information is needed only by
      * development tools.
-     * </pre>
      *
-     * <code>optional .google.protobuf.SourceCodeInfo source_code_info = 9;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.SourceCodeInfo source_code_info = 9;</code>
      */
     private $source_code_info = null;
     private $has_source_code_info = false;
     /**
-     * <pre>
      * The syntax of the proto file.
      * The supported values are "proto2" and "proto3".
-     * </pre>
      *
-     * <code>optional string syntax = 12;</code>
+     * Generated from protobuf field <code>optional string syntax = 12;</code>
      */
     private $syntax = '';
     private $has_syntax = false;
@@ -124,11 +105,10 @@
     }
 
     /**
-     * <pre>
      * file name, relative to root of source tree
-     * </pre>
      *
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
+     * @return string
      */
     public function getName()
     {
@@ -136,17 +116,19 @@
     }
 
     /**
-     * <pre>
      * file name, relative to root of source tree
-     * </pre>
      *
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
+     * @param string $var
+     * @return $this
      */
     public function setName($var)
     {
         GPBUtil::checkString($var, True);
         $this->name = $var;
         $this->has_name = true;
+
+        return $this;
     }
 
     public function hasName()
@@ -155,11 +137,10 @@
     }
 
     /**
-     * <pre>
      * e.g. "foo", "foo.bar", etc.
-     * </pre>
      *
-     * <code>optional string package = 2;</code>
+     * Generated from protobuf field <code>optional string package = 2;</code>
+     * @return string
      */
     public function getPackage()
     {
@@ -167,17 +148,19 @@
     }
 
     /**
-     * <pre>
      * e.g. "foo", "foo.bar", etc.
-     * </pre>
      *
-     * <code>optional string package = 2;</code>
+     * Generated from protobuf field <code>optional string package = 2;</code>
+     * @param string $var
+     * @return $this
      */
     public function setPackage($var)
     {
         GPBUtil::checkString($var, True);
         $this->package = $var;
         $this->has_package = true;
+
+        return $this;
     }
 
     public function hasPackage()
@@ -186,11 +169,10 @@
     }
 
     /**
-     * <pre>
      * Names of files imported by this file.
-     * </pre>
      *
-     * <code>repeated string dependency = 3;</code>
+     * Generated from protobuf field <code>repeated string dependency = 3;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getDependency()
     {
@@ -198,17 +180,19 @@
     }
 
     /**
-     * <pre>
      * Names of files imported by this file.
-     * </pre>
      *
-     * <code>repeated string dependency = 3;</code>
+     * Generated from protobuf field <code>repeated string dependency = 3;</code>
+     * @param string[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setDependency(&$var)
+    public function setDependency($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING);
         $this->dependency = $arr;
         $this->has_dependency = true;
+
+        return $this;
     }
 
     public function hasDependency()
@@ -217,11 +201,10 @@
     }
 
     /**
-     * <pre>
      * Indexes of the public imported files in the dependency list above.
-     * </pre>
      *
-     * <code>repeated int32 public_dependency = 10;</code>
+     * Generated from protobuf field <code>repeated int32 public_dependency = 10;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getPublicDependency()
     {
@@ -229,17 +212,19 @@
     }
 
     /**
-     * <pre>
      * Indexes of the public imported files in the dependency list above.
-     * </pre>
      *
-     * <code>repeated int32 public_dependency = 10;</code>
+     * Generated from protobuf field <code>repeated int32 public_dependency = 10;</code>
+     * @param int[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setPublicDependency(&$var)
+    public function setPublicDependency($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
         $this->public_dependency = $arr;
         $this->has_public_dependency = true;
+
+        return $this;
     }
 
     public function hasPublicDependency()
@@ -248,12 +233,11 @@
     }
 
     /**
-     * <pre>
      * Indexes of the weak imported files in the dependency list.
      * For Google-internal migration only. Do not use.
-     * </pre>
      *
-     * <code>repeated int32 weak_dependency = 11;</code>
+     * Generated from protobuf field <code>repeated int32 weak_dependency = 11;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getWeakDependency()
     {
@@ -261,18 +245,20 @@
     }
 
     /**
-     * <pre>
      * Indexes of the weak imported files in the dependency list.
      * For Google-internal migration only. Do not use.
-     * </pre>
      *
-     * <code>repeated int32 weak_dependency = 11;</code>
+     * Generated from protobuf field <code>repeated int32 weak_dependency = 11;</code>
+     * @param int[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setWeakDependency(&$var)
+    public function setWeakDependency($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
         $this->weak_dependency = $arr;
         $this->has_weak_dependency = true;
+
+        return $this;
     }
 
     public function hasWeakDependency()
@@ -281,11 +267,10 @@
     }
 
     /**
-     * <pre>
      * All top-level definitions in this file.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.DescriptorProto message_type = 4;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto message_type = 4;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getMessageType()
     {
@@ -293,17 +278,19 @@
     }
 
     /**
-     * <pre>
      * All top-level definitions in this file.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.DescriptorProto message_type = 4;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto message_type = 4;</code>
+     * @param \Google\Protobuf\Internal\DescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setMessageType(&$var)
+    public function setMessageType($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto::class);
         $this->message_type = $arr;
         $this->has_message_type = true;
+
+        return $this;
     }
 
     public function hasMessageType()
@@ -312,7 +299,8 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.EnumDescriptorProto enum_type = 5;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.EnumDescriptorProto enum_type = 5;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getEnumType()
     {
@@ -320,13 +308,17 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.EnumDescriptorProto enum_type = 5;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.EnumDescriptorProto enum_type = 5;</code>
+     * @param \Google\Protobuf\Internal\EnumDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setEnumType(&$var)
+    public function setEnumType($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto::class);
         $this->enum_type = $arr;
         $this->has_enum_type = true;
+
+        return $this;
     }
 
     public function hasEnumType()
@@ -335,7 +327,8 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.ServiceDescriptorProto service = 6;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.ServiceDescriptorProto service = 6;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getService()
     {
@@ -343,13 +336,17 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.ServiceDescriptorProto service = 6;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.ServiceDescriptorProto service = 6;</code>
+     * @param \Google\Protobuf\Internal\ServiceDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setService(&$var)
+    public function setService($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\ServiceDescriptorProto::class);
         $this->service = $arr;
         $this->has_service = true;
+
+        return $this;
     }
 
     public function hasService()
@@ -358,7 +355,8 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.FieldDescriptorProto extension = 7;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.FieldDescriptorProto extension = 7;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getExtension()
     {
@@ -366,13 +364,17 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.FieldDescriptorProto extension = 7;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.FieldDescriptorProto extension = 7;</code>
+     * @param \Google\Protobuf\Internal\FieldDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setExtension(&$var)
+    public function setExtension($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class);
         $this->extension = $arr;
         $this->has_extension = true;
+
+        return $this;
     }
 
     public function hasExtension()
@@ -381,7 +383,8 @@
     }
 
     /**
-     * <code>optional .google.protobuf.FileOptions options = 8;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FileOptions options = 8;</code>
+     * @return \Google\Protobuf\Internal\FileOptions
      */
     public function getOptions()
     {
@@ -389,13 +392,17 @@
     }
 
     /**
-     * <code>optional .google.protobuf.FileOptions options = 8;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FileOptions options = 8;</code>
+     * @param \Google\Protobuf\Internal\FileOptions $var
+     * @return $this
      */
-    public function setOptions(&$var)
+    public function setOptions($var)
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FileOptions::class);
         $this->options = $var;
         $this->has_options = true;
+
+        return $this;
     }
 
     public function hasOptions()
@@ -404,14 +411,13 @@
     }
 
     /**
-     * <pre>
      * This field contains optional information about the original source code.
      * You may safely remove this entire field without harming runtime
      * functionality of the descriptors -- the information is needed only by
      * development tools.
-     * </pre>
      *
-     * <code>optional .google.protobuf.SourceCodeInfo source_code_info = 9;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.SourceCodeInfo source_code_info = 9;</code>
+     * @return \Google\Protobuf\Internal\SourceCodeInfo
      */
     public function getSourceCodeInfo()
     {
@@ -419,20 +425,22 @@
     }
 
     /**
-     * <pre>
      * This field contains optional information about the original source code.
      * You may safely remove this entire field without harming runtime
      * functionality of the descriptors -- the information is needed only by
      * development tools.
-     * </pre>
      *
-     * <code>optional .google.protobuf.SourceCodeInfo source_code_info = 9;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.SourceCodeInfo source_code_info = 9;</code>
+     * @param \Google\Protobuf\Internal\SourceCodeInfo $var
+     * @return $this
      */
-    public function setSourceCodeInfo(&$var)
+    public function setSourceCodeInfo($var)
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\SourceCodeInfo::class);
         $this->source_code_info = $var;
         $this->has_source_code_info = true;
+
+        return $this;
     }
 
     public function hasSourceCodeInfo()
@@ -441,12 +449,11 @@
     }
 
     /**
-     * <pre>
      * The syntax of the proto file.
      * The supported values are "proto2" and "proto3".
-     * </pre>
      *
-     * <code>optional string syntax = 12;</code>
+     * Generated from protobuf field <code>optional string syntax = 12;</code>
+     * @return string
      */
     public function getSyntax()
     {
@@ -454,18 +461,20 @@
     }
 
     /**
-     * <pre>
      * The syntax of the proto file.
      * The supported values are "proto2" and "proto3".
-     * </pre>
      *
-     * <code>optional string syntax = 12;</code>
+     * Generated from protobuf field <code>optional string syntax = 12;</code>
+     * @param string $var
+     * @return $this
      */
     public function setSyntax($var)
     {
         GPBUtil::checkString($var, True);
         $this->syntax = $var;
         $this->has_syntax = true;
+
+        return $this;
     }
 
     public function hasSyntax()
diff --git a/php/src/Google/Protobuf/Internal/FileDescriptorSet.php b/php/src/Google/Protobuf/Internal/FileDescriptorSet.php
index 0bcc805..0b2cf95 100644
--- a/php/src/Google/Protobuf/Internal/FileDescriptorSet.php
+++ b/php/src/Google/Protobuf/Internal/FileDescriptorSet.php
@@ -8,21 +8,18 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * <pre>
  * The protocol compiler can output a FileDescriptorSet containing the .proto
  * files it parses.
- * </pre>
  *
- * Protobuf type <code>google.protobuf.FileDescriptorSet</code>
+ * Generated from protobuf message <code>google.protobuf.FileDescriptorSet</code>
  */
 class FileDescriptorSet extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <code>repeated .google.protobuf.FileDescriptorProto file = 1;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.FileDescriptorProto file = 1;</code>
      */
     private $file;
     private $has_file = false;
@@ -33,7 +30,8 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.FileDescriptorProto file = 1;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.FileDescriptorProto file = 1;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getFile()
     {
@@ -41,13 +39,17 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.FileDescriptorProto file = 1;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.FileDescriptorProto file = 1;</code>
+     * @param \Google\Protobuf\Internal\FileDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setFile(&$var)
+    public function setFile($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FileDescriptorProto::class);
         $this->file = $arr;
         $this->has_file = true;
+
+        return $this;
     }
 
     public function hasFile()
diff --git a/php/src/Google/Protobuf/Internal/FileOptions.php b/php/src/Google/Protobuf/Internal/FileOptions.php
index 22653a4..c2dd5e0 100644
--- a/php/src/Google/Protobuf/Internal/FileOptions.php
+++ b/php/src/Google/Protobuf/Internal/FileOptions.php
@@ -8,96 +8,82 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * Protobuf type <code>google.protobuf.FileOptions</code>
+ * Generated from protobuf message <code>google.protobuf.FileOptions</code>
  */
 class FileOptions extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <pre>
      * Sets the Java package where classes generated from this .proto will be
      * placed.  By default, the proto package is used, but this is often
      * inappropriate because proto packages do not normally start with backwards
      * domain names.
-     * </pre>
      *
-     * <code>optional string java_package = 1;</code>
+     * Generated from protobuf field <code>optional string java_package = 1;</code>
      */
     private $java_package = '';
     private $has_java_package = false;
     /**
-     * <pre>
      * If set, all the classes from the .proto file are wrapped in a single
      * outer class with the given name.  This applies to both Proto1
      * (equivalent to the old "--one_java_file" option) and Proto2 (where
      * a .proto always translates to a single class, but you may want to
      * explicitly choose the class name).
-     * </pre>
      *
-     * <code>optional string java_outer_classname = 8;</code>
+     * Generated from protobuf field <code>optional string java_outer_classname = 8;</code>
      */
     private $java_outer_classname = '';
     private $has_java_outer_classname = false;
     /**
-     * <pre>
      * If set true, then the Java code generator will generate a separate .java
      * file for each top-level message, enum, and service defined in the .proto
      * file.  Thus, these types will *not* be nested inside the outer class
      * named by java_outer_classname.  However, the outer class will still be
      * generated to contain the file's getDescriptor() method as well as any
      * top-level extensions defined in the file.
-     * </pre>
      *
-     * <code>optional bool java_multiple_files = 10 [default = false];</code>
+     * Generated from protobuf field <code>optional bool java_multiple_files = 10 [default = false];</code>
      */
     private $java_multiple_files = false;
     private $has_java_multiple_files = false;
     /**
-     * <pre>
      * This option does nothing.
-     * </pre>
      *
-     * <code>optional bool java_generate_equals_and_hash = 20 [deprecated = true];</code>
+     * Generated from protobuf field <code>optional bool java_generate_equals_and_hash = 20 [deprecated = true];</code>
      */
     private $java_generate_equals_and_hash = false;
     private $has_java_generate_equals_and_hash = false;
     /**
-     * <pre>
      * If set true, then the Java2 code generator will generate code that
      * throws an exception whenever an attempt is made to assign a non-UTF-8
      * byte sequence to a string field.
      * Message reflection will do the same.
      * However, an extension field still accepts non-UTF-8 byte sequences.
      * This option has no effect on when used with the lite runtime.
-     * </pre>
      *
-     * <code>optional bool java_string_check_utf8 = 27 [default = false];</code>
+     * Generated from protobuf field <code>optional bool java_string_check_utf8 = 27 [default = false];</code>
      */
     private $java_string_check_utf8 = false;
     private $has_java_string_check_utf8 = false;
     /**
-     * <code>optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];</code>
      */
     private $optimize_for = 0;
     private $has_optimize_for = false;
     /**
-     * <pre>
      * Sets the Go package where structs generated from this .proto will be
      * placed. If omitted, the Go package will be derived from the following:
      *   - The basename of the package import path, if provided.
      *   - Otherwise, the package statement in the .proto file, if present.
      *   - Otherwise, the basename of the .proto file, without extension.
-     * </pre>
      *
-     * <code>optional string go_package = 11;</code>
+     * Generated from protobuf field <code>optional string go_package = 11;</code>
      */
     private $go_package = '';
     private $has_go_package = false;
     /**
-     * <pre>
      * Should generic services be generated in each language?  "Generic" services
      * are not specific to any particular RPC system.  They are generated by the
      * main code generators in each language (without additional plugins).
@@ -107,91 +93,90 @@
      * that generate code specific to your particular RPC system.  Therefore,
      * these default to false.  Old code which depends on generic services should
      * explicitly set them to true.
-     * </pre>
      *
-     * <code>optional bool cc_generic_services = 16 [default = false];</code>
+     * Generated from protobuf field <code>optional bool cc_generic_services = 16 [default = false];</code>
      */
     private $cc_generic_services = false;
     private $has_cc_generic_services = false;
     /**
-     * <code>optional bool java_generic_services = 17 [default = false];</code>
+     * Generated from protobuf field <code>optional bool java_generic_services = 17 [default = false];</code>
      */
     private $java_generic_services = false;
     private $has_java_generic_services = false;
     /**
-     * <code>optional bool py_generic_services = 18 [default = false];</code>
+     * Generated from protobuf field <code>optional bool py_generic_services = 18 [default = false];</code>
      */
     private $py_generic_services = false;
     private $has_py_generic_services = false;
     /**
-     * <pre>
+     * Generated from protobuf field <code>optional bool php_generic_services = 19 [default = false];</code>
+     */
+    private $php_generic_services = false;
+    private $has_php_generic_services = false;
+    /**
      * Is this file deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for everything in the file, or it will be completely ignored; in the very
      * least, this is a formalization for deprecating files.
-     * </pre>
      *
-     * <code>optional bool deprecated = 23 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 23 [default = false];</code>
      */
     private $deprecated = false;
     private $has_deprecated = false;
     /**
-     * <pre>
      * Enables the use of arenas for the proto messages in this file. This applies
      * only to generated classes for C++.
-     * </pre>
      *
-     * <code>optional bool cc_enable_arenas = 31 [default = false];</code>
+     * Generated from protobuf field <code>optional bool cc_enable_arenas = 31 [default = false];</code>
      */
     private $cc_enable_arenas = false;
     private $has_cc_enable_arenas = false;
     /**
-     * <pre>
      * Sets the objective c class prefix which is prepended to all objective c
      * generated classes from this .proto. There is no default.
-     * </pre>
      *
-     * <code>optional string objc_class_prefix = 36;</code>
+     * Generated from protobuf field <code>optional string objc_class_prefix = 36;</code>
      */
     private $objc_class_prefix = '';
     private $has_objc_class_prefix = false;
     /**
-     * <pre>
      * Namespace for generated classes; defaults to the package.
-     * </pre>
      *
-     * <code>optional string csharp_namespace = 37;</code>
+     * Generated from protobuf field <code>optional string csharp_namespace = 37;</code>
      */
     private $csharp_namespace = '';
     private $has_csharp_namespace = false;
     /**
-     * <pre>
      * By default Swift generators will take the proto package and CamelCase it
      * replacing '.' with underscore and use that to prefix the types/symbols
      * defined. When this options is provided, they will use this value instead
      * to prefix the types/symbols defined.
-     * </pre>
      *
-     * <code>optional string swift_prefix = 39;</code>
+     * Generated from protobuf field <code>optional string swift_prefix = 39;</code>
      */
     private $swift_prefix = '';
     private $has_swift_prefix = false;
     /**
-     * <pre>
      * Sets the php class prefix which is prepended to all php generated classes
      * from this .proto. Default is empty.
-     * </pre>
      *
-     * <code>optional string php_class_prefix = 40;</code>
+     * Generated from protobuf field <code>optional string php_class_prefix = 40;</code>
      */
     private $php_class_prefix = '';
     private $has_php_class_prefix = false;
     /**
-     * <pre>
-     * The parser stores options it doesn't recognize here. See above.
-     * </pre>
+     * Use this option to change the namespace of php generated classes. Default
+     * is empty. When this option is empty, the package name will be used for
+     * determining the namespace.
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>optional string php_namespace = 41;</code>
+     */
+    private $php_namespace = '';
+    private $has_php_namespace = false;
+    /**
+     * The parser stores options it doesn't recognize here. See above.
+     *
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
      */
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
@@ -202,14 +187,13 @@
     }
 
     /**
-     * <pre>
      * Sets the Java package where classes generated from this .proto will be
      * placed.  By default, the proto package is used, but this is often
      * inappropriate because proto packages do not normally start with backwards
      * domain names.
-     * </pre>
      *
-     * <code>optional string java_package = 1;</code>
+     * Generated from protobuf field <code>optional string java_package = 1;</code>
+     * @return string
      */
     public function getJavaPackage()
     {
@@ -217,20 +201,22 @@
     }
 
     /**
-     * <pre>
      * Sets the Java package where classes generated from this .proto will be
      * placed.  By default, the proto package is used, but this is often
      * inappropriate because proto packages do not normally start with backwards
      * domain names.
-     * </pre>
      *
-     * <code>optional string java_package = 1;</code>
+     * Generated from protobuf field <code>optional string java_package = 1;</code>
+     * @param string $var
+     * @return $this
      */
     public function setJavaPackage($var)
     {
         GPBUtil::checkString($var, True);
         $this->java_package = $var;
         $this->has_java_package = true;
+
+        return $this;
     }
 
     public function hasJavaPackage()
@@ -239,15 +225,14 @@
     }
 
     /**
-     * <pre>
      * If set, all the classes from the .proto file are wrapped in a single
      * outer class with the given name.  This applies to both Proto1
      * (equivalent to the old "--one_java_file" option) and Proto2 (where
      * a .proto always translates to a single class, but you may want to
      * explicitly choose the class name).
-     * </pre>
      *
-     * <code>optional string java_outer_classname = 8;</code>
+     * Generated from protobuf field <code>optional string java_outer_classname = 8;</code>
+     * @return string
      */
     public function getJavaOuterClassname()
     {
@@ -255,21 +240,23 @@
     }
 
     /**
-     * <pre>
      * If set, all the classes from the .proto file are wrapped in a single
      * outer class with the given name.  This applies to both Proto1
      * (equivalent to the old "--one_java_file" option) and Proto2 (where
      * a .proto always translates to a single class, but you may want to
      * explicitly choose the class name).
-     * </pre>
      *
-     * <code>optional string java_outer_classname = 8;</code>
+     * Generated from protobuf field <code>optional string java_outer_classname = 8;</code>
+     * @param string $var
+     * @return $this
      */
     public function setJavaOuterClassname($var)
     {
         GPBUtil::checkString($var, True);
         $this->java_outer_classname = $var;
         $this->has_java_outer_classname = true;
+
+        return $this;
     }
 
     public function hasJavaOuterClassname()
@@ -278,16 +265,15 @@
     }
 
     /**
-     * <pre>
      * If set true, then the Java code generator will generate a separate .java
      * file for each top-level message, enum, and service defined in the .proto
      * file.  Thus, these types will *not* be nested inside the outer class
      * named by java_outer_classname.  However, the outer class will still be
      * generated to contain the file's getDescriptor() method as well as any
      * top-level extensions defined in the file.
-     * </pre>
      *
-     * <code>optional bool java_multiple_files = 10 [default = false];</code>
+     * Generated from protobuf field <code>optional bool java_multiple_files = 10 [default = false];</code>
+     * @return bool
      */
     public function getJavaMultipleFiles()
     {
@@ -295,22 +281,24 @@
     }
 
     /**
-     * <pre>
      * If set true, then the Java code generator will generate a separate .java
      * file for each top-level message, enum, and service defined in the .proto
      * file.  Thus, these types will *not* be nested inside the outer class
      * named by java_outer_classname.  However, the outer class will still be
      * generated to contain the file's getDescriptor() method as well as any
      * top-level extensions defined in the file.
-     * </pre>
      *
-     * <code>optional bool java_multiple_files = 10 [default = false];</code>
+     * Generated from protobuf field <code>optional bool java_multiple_files = 10 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setJavaMultipleFiles($var)
     {
         GPBUtil::checkBool($var);
         $this->java_multiple_files = $var;
         $this->has_java_multiple_files = true;
+
+        return $this;
     }
 
     public function hasJavaMultipleFiles()
@@ -319,11 +307,10 @@
     }
 
     /**
-     * <pre>
      * This option does nothing.
-     * </pre>
      *
-     * <code>optional bool java_generate_equals_and_hash = 20 [deprecated = true];</code>
+     * Generated from protobuf field <code>optional bool java_generate_equals_and_hash = 20 [deprecated = true];</code>
+     * @return bool
      */
     public function getJavaGenerateEqualsAndHash()
     {
@@ -331,17 +318,19 @@
     }
 
     /**
-     * <pre>
      * This option does nothing.
-     * </pre>
      *
-     * <code>optional bool java_generate_equals_and_hash = 20 [deprecated = true];</code>
+     * Generated from protobuf field <code>optional bool java_generate_equals_and_hash = 20 [deprecated = true];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setJavaGenerateEqualsAndHash($var)
     {
         GPBUtil::checkBool($var);
         $this->java_generate_equals_and_hash = $var;
         $this->has_java_generate_equals_and_hash = true;
+
+        return $this;
     }
 
     public function hasJavaGenerateEqualsAndHash()
@@ -350,16 +339,15 @@
     }
 
     /**
-     * <pre>
      * If set true, then the Java2 code generator will generate code that
      * throws an exception whenever an attempt is made to assign a non-UTF-8
      * byte sequence to a string field.
      * Message reflection will do the same.
      * However, an extension field still accepts non-UTF-8 byte sequences.
      * This option has no effect on when used with the lite runtime.
-     * </pre>
      *
-     * <code>optional bool java_string_check_utf8 = 27 [default = false];</code>
+     * Generated from protobuf field <code>optional bool java_string_check_utf8 = 27 [default = false];</code>
+     * @return bool
      */
     public function getJavaStringCheckUtf8()
     {
@@ -367,22 +355,24 @@
     }
 
     /**
-     * <pre>
      * If set true, then the Java2 code generator will generate code that
      * throws an exception whenever an attempt is made to assign a non-UTF-8
      * byte sequence to a string field.
      * Message reflection will do the same.
      * However, an extension field still accepts non-UTF-8 byte sequences.
      * This option has no effect on when used with the lite runtime.
-     * </pre>
      *
-     * <code>optional bool java_string_check_utf8 = 27 [default = false];</code>
+     * Generated from protobuf field <code>optional bool java_string_check_utf8 = 27 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setJavaStringCheckUtf8($var)
     {
         GPBUtil::checkBool($var);
         $this->java_string_check_utf8 = $var;
         $this->has_java_string_check_utf8 = true;
+
+        return $this;
     }
 
     public function hasJavaStringCheckUtf8()
@@ -391,7 +381,8 @@
     }
 
     /**
-     * <code>optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];</code>
+     * @return int
      */
     public function getOptimizeFor()
     {
@@ -399,13 +390,17 @@
     }
 
     /**
-     * <code>optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];</code>
+     * Generated from protobuf field <code>optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];</code>
+     * @param int $var
+     * @return $this
      */
     public function setOptimizeFor($var)
     {
         GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FileOptions_OptimizeMode::class);
         $this->optimize_for = $var;
         $this->has_optimize_for = true;
+
+        return $this;
     }
 
     public function hasOptimizeFor()
@@ -414,15 +409,14 @@
     }
 
     /**
-     * <pre>
      * Sets the Go package where structs generated from this .proto will be
      * placed. If omitted, the Go package will be derived from the following:
      *   - The basename of the package import path, if provided.
      *   - Otherwise, the package statement in the .proto file, if present.
      *   - Otherwise, the basename of the .proto file, without extension.
-     * </pre>
      *
-     * <code>optional string go_package = 11;</code>
+     * Generated from protobuf field <code>optional string go_package = 11;</code>
+     * @return string
      */
     public function getGoPackage()
     {
@@ -430,21 +424,23 @@
     }
 
     /**
-     * <pre>
      * Sets the Go package where structs generated from this .proto will be
      * placed. If omitted, the Go package will be derived from the following:
      *   - The basename of the package import path, if provided.
      *   - Otherwise, the package statement in the .proto file, if present.
      *   - Otherwise, the basename of the .proto file, without extension.
-     * </pre>
      *
-     * <code>optional string go_package = 11;</code>
+     * Generated from protobuf field <code>optional string go_package = 11;</code>
+     * @param string $var
+     * @return $this
      */
     public function setGoPackage($var)
     {
         GPBUtil::checkString($var, True);
         $this->go_package = $var;
         $this->has_go_package = true;
+
+        return $this;
     }
 
     public function hasGoPackage()
@@ -453,7 +449,6 @@
     }
 
     /**
-     * <pre>
      * Should generic services be generated in each language?  "Generic" services
      * are not specific to any particular RPC system.  They are generated by the
      * main code generators in each language (without additional plugins).
@@ -463,9 +458,9 @@
      * that generate code specific to your particular RPC system.  Therefore,
      * these default to false.  Old code which depends on generic services should
      * explicitly set them to true.
-     * </pre>
      *
-     * <code>optional bool cc_generic_services = 16 [default = false];</code>
+     * Generated from protobuf field <code>optional bool cc_generic_services = 16 [default = false];</code>
+     * @return bool
      */
     public function getCcGenericServices()
     {
@@ -473,7 +468,6 @@
     }
 
     /**
-     * <pre>
      * Should generic services be generated in each language?  "Generic" services
      * are not specific to any particular RPC system.  They are generated by the
      * main code generators in each language (without additional plugins).
@@ -483,15 +477,18 @@
      * that generate code specific to your particular RPC system.  Therefore,
      * these default to false.  Old code which depends on generic services should
      * explicitly set them to true.
-     * </pre>
      *
-     * <code>optional bool cc_generic_services = 16 [default = false];</code>
+     * Generated from protobuf field <code>optional bool cc_generic_services = 16 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setCcGenericServices($var)
     {
         GPBUtil::checkBool($var);
         $this->cc_generic_services = $var;
         $this->has_cc_generic_services = true;
+
+        return $this;
     }
 
     public function hasCcGenericServices()
@@ -500,7 +497,8 @@
     }
 
     /**
-     * <code>optional bool java_generic_services = 17 [default = false];</code>
+     * Generated from protobuf field <code>optional bool java_generic_services = 17 [default = false];</code>
+     * @return bool
      */
     public function getJavaGenericServices()
     {
@@ -508,13 +506,17 @@
     }
 
     /**
-     * <code>optional bool java_generic_services = 17 [default = false];</code>
+     * Generated from protobuf field <code>optional bool java_generic_services = 17 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setJavaGenericServices($var)
     {
         GPBUtil::checkBool($var);
         $this->java_generic_services = $var;
         $this->has_java_generic_services = true;
+
+        return $this;
     }
 
     public function hasJavaGenericServices()
@@ -523,7 +525,8 @@
     }
 
     /**
-     * <code>optional bool py_generic_services = 18 [default = false];</code>
+     * Generated from protobuf field <code>optional bool py_generic_services = 18 [default = false];</code>
+     * @return bool
      */
     public function getPyGenericServices()
     {
@@ -531,13 +534,17 @@
     }
 
     /**
-     * <code>optional bool py_generic_services = 18 [default = false];</code>
+     * Generated from protobuf field <code>optional bool py_generic_services = 18 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setPyGenericServices($var)
     {
         GPBUtil::checkBool($var);
         $this->py_generic_services = $var;
         $this->has_py_generic_services = true;
+
+        return $this;
     }
 
     public function hasPyGenericServices()
@@ -546,14 +553,41 @@
     }
 
     /**
-     * <pre>
+     * Generated from protobuf field <code>optional bool php_generic_services = 19 [default = false];</code>
+     * @return bool
+     */
+    public function getPhpGenericServices()
+    {
+        return $this->php_generic_services;
+    }
+
+    /**
+     * Generated from protobuf field <code>optional bool php_generic_services = 19 [default = false];</code>
+     * @param bool $var
+     * @return $this
+     */
+    public function setPhpGenericServices($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->php_generic_services = $var;
+        $this->has_php_generic_services = true;
+
+        return $this;
+    }
+
+    public function hasPhpGenericServices()
+    {
+        return $this->has_php_generic_services;
+    }
+
+    /**
      * Is this file deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for everything in the file, or it will be completely ignored; in the very
      * least, this is a formalization for deprecating files.
-     * </pre>
      *
-     * <code>optional bool deprecated = 23 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 23 [default = false];</code>
+     * @return bool
      */
     public function getDeprecated()
     {
@@ -561,20 +595,22 @@
     }
 
     /**
-     * <pre>
      * Is this file deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for everything in the file, or it will be completely ignored; in the very
      * least, this is a formalization for deprecating files.
-     * </pre>
      *
-     * <code>optional bool deprecated = 23 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 23 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setDeprecated($var)
     {
         GPBUtil::checkBool($var);
         $this->deprecated = $var;
         $this->has_deprecated = true;
+
+        return $this;
     }
 
     public function hasDeprecated()
@@ -583,12 +619,11 @@
     }
 
     /**
-     * <pre>
      * Enables the use of arenas for the proto messages in this file. This applies
      * only to generated classes for C++.
-     * </pre>
      *
-     * <code>optional bool cc_enable_arenas = 31 [default = false];</code>
+     * Generated from protobuf field <code>optional bool cc_enable_arenas = 31 [default = false];</code>
+     * @return bool
      */
     public function getCcEnableArenas()
     {
@@ -596,18 +631,20 @@
     }
 
     /**
-     * <pre>
      * Enables the use of arenas for the proto messages in this file. This applies
      * only to generated classes for C++.
-     * </pre>
      *
-     * <code>optional bool cc_enable_arenas = 31 [default = false];</code>
+     * Generated from protobuf field <code>optional bool cc_enable_arenas = 31 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setCcEnableArenas($var)
     {
         GPBUtil::checkBool($var);
         $this->cc_enable_arenas = $var;
         $this->has_cc_enable_arenas = true;
+
+        return $this;
     }
 
     public function hasCcEnableArenas()
@@ -616,12 +653,11 @@
     }
 
     /**
-     * <pre>
      * Sets the objective c class prefix which is prepended to all objective c
      * generated classes from this .proto. There is no default.
-     * </pre>
      *
-     * <code>optional string objc_class_prefix = 36;</code>
+     * Generated from protobuf field <code>optional string objc_class_prefix = 36;</code>
+     * @return string
      */
     public function getObjcClassPrefix()
     {
@@ -629,18 +665,20 @@
     }
 
     /**
-     * <pre>
      * Sets the objective c class prefix which is prepended to all objective c
      * generated classes from this .proto. There is no default.
-     * </pre>
      *
-     * <code>optional string objc_class_prefix = 36;</code>
+     * Generated from protobuf field <code>optional string objc_class_prefix = 36;</code>
+     * @param string $var
+     * @return $this
      */
     public function setObjcClassPrefix($var)
     {
         GPBUtil::checkString($var, True);
         $this->objc_class_prefix = $var;
         $this->has_objc_class_prefix = true;
+
+        return $this;
     }
 
     public function hasObjcClassPrefix()
@@ -649,11 +687,10 @@
     }
 
     /**
-     * <pre>
      * Namespace for generated classes; defaults to the package.
-     * </pre>
      *
-     * <code>optional string csharp_namespace = 37;</code>
+     * Generated from protobuf field <code>optional string csharp_namespace = 37;</code>
+     * @return string
      */
     public function getCsharpNamespace()
     {
@@ -661,17 +698,19 @@
     }
 
     /**
-     * <pre>
      * Namespace for generated classes; defaults to the package.
-     * </pre>
      *
-     * <code>optional string csharp_namespace = 37;</code>
+     * Generated from protobuf field <code>optional string csharp_namespace = 37;</code>
+     * @param string $var
+     * @return $this
      */
     public function setCsharpNamespace($var)
     {
         GPBUtil::checkString($var, True);
         $this->csharp_namespace = $var;
         $this->has_csharp_namespace = true;
+
+        return $this;
     }
 
     public function hasCsharpNamespace()
@@ -680,14 +719,13 @@
     }
 
     /**
-     * <pre>
      * By default Swift generators will take the proto package and CamelCase it
      * replacing '.' with underscore and use that to prefix the types/symbols
      * defined. When this options is provided, they will use this value instead
      * to prefix the types/symbols defined.
-     * </pre>
      *
-     * <code>optional string swift_prefix = 39;</code>
+     * Generated from protobuf field <code>optional string swift_prefix = 39;</code>
+     * @return string
      */
     public function getSwiftPrefix()
     {
@@ -695,20 +733,22 @@
     }
 
     /**
-     * <pre>
      * By default Swift generators will take the proto package and CamelCase it
      * replacing '.' with underscore and use that to prefix the types/symbols
      * defined. When this options is provided, they will use this value instead
      * to prefix the types/symbols defined.
-     * </pre>
      *
-     * <code>optional string swift_prefix = 39;</code>
+     * Generated from protobuf field <code>optional string swift_prefix = 39;</code>
+     * @param string $var
+     * @return $this
      */
     public function setSwiftPrefix($var)
     {
         GPBUtil::checkString($var, True);
         $this->swift_prefix = $var;
         $this->has_swift_prefix = true;
+
+        return $this;
     }
 
     public function hasSwiftPrefix()
@@ -717,12 +757,11 @@
     }
 
     /**
-     * <pre>
      * Sets the php class prefix which is prepended to all php generated classes
      * from this .proto. Default is empty.
-     * </pre>
      *
-     * <code>optional string php_class_prefix = 40;</code>
+     * Generated from protobuf field <code>optional string php_class_prefix = 40;</code>
+     * @return string
      */
     public function getPhpClassPrefix()
     {
@@ -730,18 +769,20 @@
     }
 
     /**
-     * <pre>
      * Sets the php class prefix which is prepended to all php generated classes
      * from this .proto. Default is empty.
-     * </pre>
      *
-     * <code>optional string php_class_prefix = 40;</code>
+     * Generated from protobuf field <code>optional string php_class_prefix = 40;</code>
+     * @param string $var
+     * @return $this
      */
     public function setPhpClassPrefix($var)
     {
         GPBUtil::checkString($var, True);
         $this->php_class_prefix = $var;
         $this->has_php_class_prefix = true;
+
+        return $this;
     }
 
     public function hasPhpClassPrefix()
@@ -750,11 +791,46 @@
     }
 
     /**
-     * <pre>
-     * The parser stores options it doesn't recognize here. See above.
-     * </pre>
+     * Use this option to change the namespace of php generated classes. Default
+     * is empty. When this option is empty, the package name will be used for
+     * determining the namespace.
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>optional string php_namespace = 41;</code>
+     * @return string
+     */
+    public function getPhpNamespace()
+    {
+        return $this->php_namespace;
+    }
+
+    /**
+     * Use this option to change the namespace of php generated classes. Default
+     * is empty. When this option is empty, the package name will be used for
+     * determining the namespace.
+     *
+     * Generated from protobuf field <code>optional string php_namespace = 41;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setPhpNamespace($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->php_namespace = $var;
+        $this->has_php_namespace = true;
+
+        return $this;
+    }
+
+    public function hasPhpNamespace()
+    {
+        return $this->has_php_namespace;
+    }
+
+    /**
+     * The parser stores options it doesn't recognize here. See above.
+     *
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getUninterpretedOption()
     {
@@ -762,17 +838,19 @@
     }
 
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * @param \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setUninterpretedOption(&$var)
+    public function setUninterpretedOption($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class);
         $this->uninterpreted_option = $arr;
         $this->has_uninterpreted_option = true;
+
+        return $this;
     }
 
     public function hasUninterpretedOption()
diff --git a/php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php b/php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php
index b550e7f..4dd56ef 100644
--- a/php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php
+++ b/php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php
@@ -5,36 +5,28 @@
 namespace Google\Protobuf\Internal;
 
 /**
- * <pre>
  * Generated classes can be optimized for speed or code size.
- * </pre>
  *
- * Protobuf enum <code>google.protobuf.FileOptions.OptimizeMode</code>
+ * Protobuf enum <code>Google\Protobuf\Internal</code>
  */
 class FileOptions_OptimizeMode
 {
     /**
-     * <pre>
      * Generate complete code for parsing, serialization,
-     * </pre>
      *
-     * <code>SPEED = 1;</code>
+     * Generated from protobuf enum <code>SPEED = 1;</code>
      */
     const SPEED = 1;
     /**
-     * <pre>
      * etc.
-     * </pre>
      *
-     * <code>CODE_SIZE = 2;</code>
+     * Generated from protobuf enum <code>CODE_SIZE = 2;</code>
      */
     const CODE_SIZE = 2;
     /**
-     * <pre>
      * Generate code using MessageLite and the lite runtime.
-     * </pre>
      *
-     * <code>LITE_RUNTIME = 3;</code>
+     * Generated from protobuf enum <code>LITE_RUNTIME = 3;</code>
      */
     const LITE_RUNTIME = 3;
 }
diff --git a/php/src/Google/Protobuf/Internal/GPBJsonWire.php b/php/src/Google/Protobuf/Internal/GPBJsonWire.php
new file mode 100644
index 0000000..9778935
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/GPBJsonWire.php
@@ -0,0 +1,285 @@
+<?php
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+namespace Google\Protobuf\Internal;
+
+class GPBJsonWire
+{
+
+    public static function serializeFieldToStream(
+        $value,
+        $field,
+        &$output)
+    {
+        $output->writeRaw("\"", 1);
+        $field_name = GPBJsonWire::formatFieldName($field);
+        $output->writeRaw($field_name, strlen($field_name));
+        $output->writeRaw("\":", 2);
+        return static::serializeFieldValueToStream($value, $field, $output);
+    }
+
+    private static function serializeFieldValueToStream(
+        $values,
+        $field,
+        &$output)
+    {
+        if ($field->isMap()) {
+            $output->writeRaw("{", 1);
+            $first = true;
+            $map_entry = $field->getMessageType();
+            $key_field = $map_entry->getFieldByNumber(1);
+            $value_field = $map_entry->getFieldByNumber(2);
+
+            switch ($key_field->getType()) {
+            case GPBType::STRING:
+            case GPBType::SFIXED64:
+            case GPBType::INT64:
+            case GPBType::SINT64:
+            case GPBType::FIXED64:
+            case GPBType::UINT64:
+                $additional_quote = false;
+                break;
+            default:
+                $additional_quote = true;
+            }
+
+            foreach ($values as $key => $value) {
+                if ($first) {
+                    $first = false;
+                } else {
+                    $output->writeRaw(",", 1);
+                }
+                if ($additional_quote) {
+                    $output->writeRaw("\"", 1);
+                }
+                if (!static::serializeSingularFieldValueToStream(
+                    $key,
+                    $key_field,
+                    $output)) {
+                    return false;
+                }
+                if ($additional_quote) {
+                    $output->writeRaw("\"", 1);
+                }
+                $output->writeRaw(":", 1);
+                if (!static::serializeSingularFieldValueToStream(
+                    $value,
+                    $value_field,
+                    $output)) {
+                    return false;
+                }
+            }
+            $output->writeRaw("}", 1);
+            return true;
+        } elseif ($field->isRepeated()) {
+            $output->writeRaw("[", 1);
+            $first = true;
+            foreach ($values as $value) {
+                if ($first) {
+                    $first = false;
+                } else {
+                    $output->writeRaw(",", 1);
+                }
+                if (!static::serializeSingularFieldValueToStream(
+                    $value,
+                    $field,
+                    $output)) {
+                    return false;
+                }
+            }
+            $output->writeRaw("]", 1);
+            return true;
+        } else {
+            return static::serializeSingularFieldValueToStream(
+                $values,
+                $field,
+                $output);
+        }
+    }
+
+    private static function serializeSingularFieldValueToStream(
+        $value,
+        $field,
+        &$output)
+    {
+        switch ($field->getType()) {
+            case GPBType::SFIXED32:
+            case GPBType::SINT32:
+            case GPBType::INT32:
+                $str_value = strval($value);
+                $output->writeRaw($str_value, strlen($str_value));
+                break;
+            case GPBType::FIXED32:
+            case GPBType::UINT32:
+                if ($value < 0) {
+                    $value = bcadd($value, "4294967296");
+                }
+                $str_value = strval($value);
+                $output->writeRaw($str_value, strlen($str_value));
+                break;
+            case GPBType::FIXED64:
+            case GPBType::UINT64:
+                if ($value < 0) {
+                    $value = bcadd($value, "18446744073709551616");
+                }
+                // Intentional fall through.
+            case GPBType::SFIXED64:
+            case GPBType::INT64:
+            case GPBType::SINT64:
+                $output->writeRaw("\"", 1);
+                $str_value = strval($value);
+                $output->writeRaw($str_value, strlen($str_value));
+                $output->writeRaw("\"", 1);
+                break;
+            case GPBType::FLOAT:
+                if (is_nan($value)) {
+                    $str_value = "\"NaN\"";
+                } elseif ($value === INF) {
+                    $str_value = "\"Infinity\"";
+                } elseif ($value === -INF) {
+                    $str_value = "\"-Infinity\"";
+                } else {
+                    $str_value = sprintf("%.8g", $value);
+                }
+                $output->writeRaw($str_value, strlen($str_value));
+                break;
+            case GPBType::DOUBLE:
+                if (is_nan($value)) {
+                    $str_value = "\"NaN\"";
+                } elseif ($value === INF) {
+                    $str_value = "\"Infinity\"";
+                } elseif ($value === -INF) {
+                    $str_value = "\"-Infinity\"";
+                } else {
+                    $str_value = sprintf("%.17g", $value);
+                }
+                $output->writeRaw($str_value, strlen($str_value));
+                break;
+            case GPBType::ENUM:
+                $enum_desc = $field->getEnumType();
+                $enum_value_desc = $enum_desc->getValueByNumber($value);
+                if (!is_null($enum_value_desc)) {
+                    $str_value = $enum_value_desc->getName();
+                    $output->writeRaw("\"", 1);
+                    $output->writeRaw($str_value, strlen($str_value));
+                    $output->writeRaw("\"", 1);
+                } else {
+                    $str_value = strval($value);
+                    $output->writeRaw($str_value, strlen($str_value));
+                }
+                break;
+            case GPBType::BOOL:
+                if ($value) {
+                    $output->writeRaw("true", 4);
+                } else {
+                    $output->writeRaw("false", 5);
+                }
+                break;
+            case GPBType::BYTES:
+                $value = base64_encode($value);
+            case GPBType::STRING:
+                $value = json_encode($value);
+                $output->writeRaw($value, strlen($value));
+                break;
+            //    case GPBType::GROUP:
+            //      echo "GROUP\xA";
+            //      trigger_error("Not implemented.", E_ERROR);
+            //      break;
+            case GPBType::MESSAGE:
+                $value->serializeToJsonStream($output);
+                break;
+            default:
+                user_error("Unsupported type.");
+                return false;
+        }
+        return true;
+    }
+
+    private static function formatFieldName($field)
+    {
+        return $field->getJsonName();
+    }
+
+    // Used for escaping control chars in strings.
+    private static $k_control_char_limit = 0x20;
+
+    private static function jsonNiceEscape($c)
+    {
+      switch ($c) {
+          case '"':  return "\\\"";
+          case '\\': return "\\\\";
+          case '/': return "\\/";
+          case '\b': return "\\b";
+          case '\f': return "\\f";
+          case '\n': return "\\n";
+          case '\r': return "\\r";
+          case '\t': return "\\t";
+          default:   return NULL;
+      }
+    }
+
+    private static function isJsonEscaped($c)
+    {
+        // See RFC 4627.
+        return $c < chr($k_control_char_limit) || $c === "\"" || $c === "\\";
+    }
+
+    public static function escapedJson($value)
+    {
+        $escaped_value = "";
+        $unescaped_run = "";
+        for ($i = 0; $i < strlen($value); $i++) {
+            $c = $value[$i];
+            // Handle escaping.
+            if (static::isJsonEscaped($c)) {
+                // Use a "nice" escape, like \n, if one exists for this
+                // character.
+                $escape = static::jsonNiceEscape($c);
+                if (is_null($escape)) {
+                    $escape = "\\u00" . bin2hex($c);
+                }
+                if ($unescaped_run !== "") {
+                    $escaped_value .= $unescaped_run;
+                    $unescaped_run = "";
+                }
+                $escaped_value .= $escape;
+            } else {
+              if ($unescaped_run === "") {
+                $unescaped_run .= $c;
+              }
+            }
+        }
+        $escaped_value .= $unescaped_run;
+        return $escaped_value;
+    }
+
+}
diff --git a/php/src/Google/Protobuf/Internal/GPBUtil.php b/php/src/Google/Protobuf/Internal/GPBUtil.php
index 0e66ae6..22ad27f 100644
--- a/php/src/Google/Protobuf/Internal/GPBUtil.php
+++ b/php/src/Google/Protobuf/Internal/GPBUtil.php
@@ -45,8 +45,13 @@
             $value = bcsub(0, $value);
         }
 
-        $high = (int) bcdiv(bcadd($value, 1), 4294967296);
+        $high = bcdiv($value, 4294967296);
         $low = bcmod($value, 4294967296);
+        if (bccomp($high, 2147483647) > 0) {
+            $high = (int) bcsub($high, 4294967296);
+        } else {
+            $high = (int) $high;
+        }
         if (bccomp($low, 2147483647) > 0) {
             $low = (int) bcsub($low, 4294967296);
         } else {
@@ -58,7 +63,7 @@
             $low = ~$low;
             $low++;
             if (!$low) {
-                $high++;
+                $high = (int)($high + 1);
             }
         }
 
@@ -67,19 +72,16 @@
         }
     }
 
-
     public static function checkString(&$var, $check_utf8)
     {
         if (is_array($var) || is_object($var)) {
-            trigger_error("Expect string.", E_USER_ERROR);
-            return;
+            throw new \InvalidArgumentException("Expect string.");
         }
         if (!is_string($var)) {
             $var = strval($var);
         }
         if ($check_utf8 && !preg_match('//u', $var)) {
-            trigger_error("Expect utf-8 encoding.", E_USER_ERROR);
-            return;
+            throw new \Exception("Expect utf-8 encoding.");
         }
     }
 
@@ -93,7 +95,7 @@
         if (is_numeric($var)) {
             $var = intval($var);
         } else {
-            trigger_error("Expect integer.", E_USER_ERROR);
+            throw new \Exception("Expect integer.");
         }
     }
 
@@ -110,7 +112,7 @@
                 $var = (int) $var;
             }
         } else {
-            trigger_error("Expect integer.", E_USER_ERROR);
+            throw new \Exception("Expect integer.");
         }
     }
 
@@ -120,10 +122,15 @@
             if (PHP_INT_SIZE == 8) {
                 $var = intval($var);
             } else {
-                $var = bcdiv($var, 1, 0);
+                if (is_float($var) ||
+                    is_integer($var) ||
+                    (is_string($var) &&
+                         bccomp($var, "9223372036854774784") < 0)) {
+                    $var = number_format($var, 0, ".", "");
+                }
             }
         } else {
-            trigger_error("Expect integer.", E_USER_ERROR);
+            throw new \Exception("Expect integer.");
         }
     }
 
@@ -133,10 +140,10 @@
             if (PHP_INT_SIZE == 8) {
                 $var = intval($var);
             } else {
-                $var = bcdiv($var, 1, 0);
+                $var = number_format($var, 0, ".", "");
             }
         } else {
-            trigger_error("Expect integer.", E_USER_ERROR);
+            throw new \Exception("Expect integer.");
         }
     }
 
@@ -145,7 +152,7 @@
         if (is_float($var) || is_numeric($var)) {
             $var = floatval($var);
         } else {
-            trigger_error("Expect float.", E_USER_ERROR);
+            throw new \Exception("Expect float.");
         }
     }
 
@@ -154,15 +161,14 @@
         if (is_float($var) || is_numeric($var)) {
             $var = floatval($var);
         } else {
-            trigger_error("Expect float.", E_USER_ERROR);
+            throw new \Exception("Expect float.");
         }
     }
 
     public static function checkBool(&$var)
     {
         if (is_array($var) || is_object($var)) {
-            trigger_error("Expect boolean.", E_USER_ERROR);
-            return;
+            throw new \Exception("Expect boolean.");
         }
         $var = boolval($var);
     }
@@ -170,14 +176,14 @@
     public static function checkMessage(&$var, $klass)
     {
         if (!$var instanceof $klass && !is_null($var)) {
-            trigger_error("Expect message.", E_USER_ERROR);
+            throw new \Exception("Expect message.");
         }
     }
 
     public static function checkRepeatedField(&$var, $type, $klass = null)
     {
         if (!$var instanceof RepeatedField && !is_array($var)) {
-            trigger_error("Expect array.", E_USER_ERROR);
+            throw new \Exception("Expect array.");
         }
         if (is_array($var)) {
             $tmp = new RepeatedField($type, $klass);
@@ -187,15 +193,13 @@
             return $tmp;
         } else {
             if ($var->getType() != $type) {
-                trigger_error(
-                    "Expect repeated field of different type.",
-                    E_USER_ERROR);
+                throw new \Exception(
+                    "Expect repeated field of different type.");
             }
             if ($var->getType() === GPBType::MESSAGE &&
                 $var->getClass() !== $klass) {
-                trigger_error(
-                    "Expect repeated field of different message.",
-                    E_USER_ERROR);
+                throw new \Exception(
+                    "Expect repeated field of different message.");
             }
             return $var;
         }
@@ -204,7 +208,7 @@
     public static function checkMapField(&$var, $key_type, $value_type, $klass = null)
     {
         if (!$var instanceof MapField && !is_array($var)) {
-            trigger_error("Expect dict.", E_USER_ERROR);
+            throw new \Exception("Expect dict.");
         }
         if (is_array($var)) {
             $tmp = new MapField($key_type, $value_type, $klass);
@@ -214,20 +218,15 @@
             return $tmp;
         } else {
             if ($var->getKeyType() != $key_type) {
-                trigger_error(
-                    "Expect map field of key type.",
-                    E_USER_ERROR);
+                throw new \Exception("Expect map field of key type.");
             }
             if ($var->getValueType() != $value_type) {
-                trigger_error(
-                    "Expect map field of value type.",
-                    E_USER_ERROR);
+                throw new \Exception("Expect map field of value type.");
             }
             if ($var->getValueType() === GPBType::MESSAGE &&
                 $var->getValueClass() !== $klass) {
-                trigger_error(
-                    "Expect map field of different value message.",
-                    E_USER_ERROR);
+                throw new \Exception(
+                    "Expect map field of different value message.");
             }
             return $var;
         }
@@ -242,4 +241,103 @@
     {
         return new Uint64($value);
     }
+
+    public static function getClassNamePrefix(
+        $classname,
+        $file_proto)
+    {
+        $option = $file_proto->getOptions();
+        $prefix = is_null($option) ? "" : $option->getPhpClassPrefix();
+        if ($prefix !== "") {
+            return $prefix;
+        }
+
+        $reserved_words = array("Empty", "ECHO", "ARRAY");
+        foreach ($reserved_words as $reserved_word) {
+            if ($classname === $reserved_word) {
+                if ($file_proto->getPackage() === "google.protobuf") {
+                    return "GPB";
+                } else {
+                    return "PB";
+                }
+            }
+        }
+
+        return "";
+    }
+
+    public static function getClassNameWithoutPackage(
+        $name,
+        $file_proto)
+    {
+        $classname = implode('_', array_map('ucwords', explode('.', $name)));
+        return static::getClassNamePrefix($classname, $file_proto) . $classname;
+    }
+
+    public static function getFullClassName(
+        $proto,
+        $containing,
+        $file_proto,
+        &$message_name_without_package,
+        &$classname,
+        &$fullname)
+    {
+        // Full name needs to start with '.'.
+        $message_name_without_package = $proto->getName();
+        if ($containing !== "") {
+            $message_name_without_package =
+                $containing . "." . $message_name_without_package;
+        }
+
+        $package = $file_proto->getPackage();
+        if ($package === "") {
+            $fullname = "." . $message_name_without_package;
+        } else {
+            $fullname = "." . $package . "." . $message_name_without_package;
+        }
+
+        $class_name_without_package =
+            static::getClassNameWithoutPackage($message_name_without_package, $file_proto);
+
+        $option = $file_proto->getOptions();
+        if (!is_null($option) && $option->hasPhpNamespace()) {
+            $namespace = $option->getPhpNamespace();
+            if ($namespace !== "") {
+                $classname = $namespace . "\\" . $class_name_without_package;
+                return;
+            } else {
+                $classname = $class_name_without_package;
+                return;
+            }
+        }
+
+        if ($package === "") {
+            $classname = $class_name_without_package;
+        } else {
+            $classname =
+                implode('\\', array_map('ucwords', explode('.', $package))).
+                "\\".$class_name_without_package;
+        }
+    }
+
+    public static function combineInt32ToInt64($high, $low)
+    {
+        $isNeg = $high < 0;
+        if ($isNeg) {
+            $high = ~$high;
+            $low = ~$low;
+            $low++;
+            if (!$low) {
+                $high = (int) ($high + 1);
+            }
+        }
+        $result = bcadd(bcmul($high, 4294967296), $low);
+        if ($low < 0) {
+            $result = bcadd($result, 4294967296);
+        }
+        if ($isNeg) {
+          $result = bcsub(0, $result);
+        }
+        return $result;
+    }
 }
diff --git a/php/src/Google/Protobuf/Internal/GPBWire.php b/php/src/Google/Protobuf/Internal/GPBWire.php
index 67eb1be..e7eec55 100644
--- a/php/src/Google/Protobuf/Internal/GPBWire.php
+++ b/php/src/Google/Protobuf/Internal/GPBWire.php
@@ -117,19 +117,12 @@
   //        << decode <<
   public static function zigZagEncode32($int32)
   {
-      // Fill high 32 bits.
-      if (PHP_INT_SIZE === 8) {
-          $int32 |= ((($int32 << 32) >> 31) & (0xFFFFFFFF << 32));
+      if (PHP_INT_SIZE == 8) {
+          $trim_int32 = $int32 & 0xFFFFFFFF;
+          return (($trim_int32 << 1) ^ ($int32 << 32 >> 63)) & 0xFFFFFFFF;
+      } else {
+          return ($int32 << 1) ^ ($int32 >> 31);
       }
-
-      $uint32 = ($int32 << 1) ^ ($int32 >> 31);
-
-      // Fill high 32 bits.
-      if (PHP_INT_SIZE === 8) {
-          $uint32 |= ((($uint32 << 32) >> 31) & (0xFFFFFFFF << 32));
-      }
-
-      return $uint32;
   }
 
     public static function zigZagDecode32($uint32)
@@ -177,7 +170,11 @@
 
     public static function readInt64(&$input, &$value)
     {
-        return $input->readVarint64($value);
+        $success = $input->readVarint64($value);
+        if (PHP_INT_SIZE == 4 && bccomp($value, "9223372036854775807") > 0) {
+            $value = bcsub($value, "18446744073709551616");
+        }
+        return $success;
     }
 
     public static function readUint32(&$input, &$value)
@@ -231,7 +228,11 @@
 
     public static function readSfixed64(&$input, &$value)
     {
-        return $input->readLittleEndian64($value);
+        $success = $input->readLittleEndian64($value);
+        if (PHP_INT_SIZE == 4 && bccomp($value, "9223372036854775807") > 0) {
+            $value = bcsub($value, "18446744073709551616");
+        }
+        return $success;
     }
 
     public static function readFloat(&$input, &$value)
@@ -298,7 +299,7 @@
 
     public static function writeInt32(&$output, $value)
     {
-        return $output->writeVarint32($value);
+        return $output->writeVarint32($value, false);
     }
 
     public static function writeInt64(&$output, $value)
@@ -308,7 +309,7 @@
 
     public static function writeUint32(&$output, $value)
     {
-        return $output->writeVarint32($value);
+        return $output->writeVarint32($value, true);
     }
 
     public static function writeUint64(&$output, $value)
@@ -319,7 +320,7 @@
     public static function writeSint32(&$output, $value)
     {
         $value = GPBWire::zigZagEncode32($value);
-        return $output->writeVarint64($value);
+        return $output->writeVarint32($value, true);
     }
 
     public static function writeSint64(&$output, $value)
@@ -351,9 +352,9 @@
     public static function writeBool(&$output, $value)
     {
         if ($value) {
-            return $output->writeVarint32(1);
+            return $output->writeVarint32(1, true);
         } else {
-            return $output->writeVarint32(0);
+            return $output->writeVarint32(0, true);
         }
     }
 
@@ -377,7 +378,7 @@
     public static function writeBytes(&$output, $value)
     {
         $size = strlen($value);
-        if (!$output->writeVarint32($size)) {
+        if (!$output->writeVarint32($size, true)) {
             return false;
         }
         return $output->writeRaw($value, $size);
@@ -386,7 +387,7 @@
     public static function writeMessage(&$output, $value)
     {
         $size = $value->byteSize();
-        if (!$output->writeVarint32($size)) {
+        if (!$output->writeVarint32($size, true)) {
             return false;
         }
         return $value->serializeToStream($output);
@@ -442,7 +443,8 @@
     public static function varint64Size($value)
     {
         if (PHP_INT_SIZE == 4) {
-            if (bccomp($value, 0) < 0) {
+            if (bccomp($value, 0) < 0 ||
+                bccomp($value, "9223372036854775807") > 0) {
                 return 10;
             }    
             if (bccomp($value, 1 << 7) < 0) {
@@ -578,6 +580,9 @@
                 }
                 break;
             case GPBType::UINT32:
+                if (PHP_INT_SIZE === 8 && $value < 0) {
+                    $value += 4294967296;
+                }
                 if (!GPBWire::writeUint32($output, $value)) {
                     return false;
                 }
diff --git a/php/src/Google/Protobuf/Internal/GPBWireType.php b/php/src/Google/Protobuf/Internal/GPBWireType.php
new file mode 100644
index 0000000..c1ad370
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/GPBWireType.php
@@ -0,0 +1,43 @@
+<?php
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+namespace Google\Protobuf\Internal;
+
+class GPBWireType
+{
+    const VARINT           = 0;
+    const FIXED64          = 1;
+    const LENGTH_DELIMITED = 2;
+    const START_GROUP      = 3;
+    const END_GROUP        = 4;
+    const FIXED32          = 5;
+}
diff --git a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php
index 450854f..ae2ad74 100644
--- a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php
+++ b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php
@@ -8,27 +8,22 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * <pre>
  * Describes the relationship between generated code and its original source
  * file. A GeneratedCodeInfo message is associated with only one generated
  * source file, but may contain references to different source .proto files.
- * </pre>
  *
- * Protobuf type <code>google.protobuf.GeneratedCodeInfo</code>
+ * Generated from protobuf message <code>google.protobuf.GeneratedCodeInfo</code>
  */
 class GeneratedCodeInfo extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <pre>
      * An Annotation connects some span of text in generated code to an element
      * of its generating .proto file.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;</code>
      */
     private $annotation;
     private $has_annotation = false;
@@ -39,12 +34,11 @@
     }
 
     /**
-     * <pre>
      * An Annotation connects some span of text in generated code to an element
      * of its generating .proto file.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getAnnotation()
     {
@@ -52,18 +46,20 @@
     }
 
     /**
-     * <pre>
      * An Annotation connects some span of text in generated code to an element
      * of its generating .proto file.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;</code>
+     * @param \Google\Protobuf\Internal\GeneratedCodeInfo_Annotation[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setAnnotation(&$var)
+    public function setAnnotation($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\GeneratedCodeInfo_Annotation::class);
         $this->annotation = $arr;
         $this->has_annotation = true;
+
+        return $this;
     }
 
     public function hasAnnotation()
diff --git a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php
index ed22cc3..22ac233 100644
--- a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php
+++ b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php
@@ -8,51 +8,42 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * Protobuf type <code>google.protobuf.GeneratedCodeInfo.Annotation</code>
+ * Generated from protobuf message <code>google.protobuf.GeneratedCodeInfo.Annotation</code>
  */
 class GeneratedCodeInfo_Annotation extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <pre>
      * Identifies the element in the original source .proto file. This field
      * is formatted the same as SourceCodeInfo.Location.path.
-     * </pre>
      *
-     * <code>repeated int32 path = 1 [packed = true];</code>
+     * Generated from protobuf field <code>repeated int32 path = 1 [packed = true];</code>
      */
     private $path;
     private $has_path = false;
     /**
-     * <pre>
      * Identifies the filesystem path to the original source .proto.
-     * </pre>
      *
-     * <code>optional string source_file = 2;</code>
+     * Generated from protobuf field <code>optional string source_file = 2;</code>
      */
     private $source_file = '';
     private $has_source_file = false;
     /**
-     * <pre>
      * Identifies the starting offset in bytes in the generated code
      * that relates to the identified object.
-     * </pre>
      *
-     * <code>optional int32 begin = 3;</code>
+     * Generated from protobuf field <code>optional int32 begin = 3;</code>
      */
     private $begin = 0;
     private $has_begin = false;
     /**
-     * <pre>
      * Identifies the ending offset in bytes in the generated code that
      * relates to the identified offset. The end offset should be one past
      * the last relevant byte (so the length of the text = end - begin).
-     * </pre>
      *
-     * <code>optional int32 end = 4;</code>
+     * Generated from protobuf field <code>optional int32 end = 4;</code>
      */
     private $end = 0;
     private $has_end = false;
@@ -63,12 +54,11 @@
     }
 
     /**
-     * <pre>
      * Identifies the element in the original source .proto file. This field
      * is formatted the same as SourceCodeInfo.Location.path.
-     * </pre>
      *
-     * <code>repeated int32 path = 1 [packed = true];</code>
+     * Generated from protobuf field <code>repeated int32 path = 1 [packed = true];</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getPath()
     {
@@ -76,18 +66,20 @@
     }
 
     /**
-     * <pre>
      * Identifies the element in the original source .proto file. This field
      * is formatted the same as SourceCodeInfo.Location.path.
-     * </pre>
      *
-     * <code>repeated int32 path = 1 [packed = true];</code>
+     * Generated from protobuf field <code>repeated int32 path = 1 [packed = true];</code>
+     * @param int[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setPath(&$var)
+    public function setPath($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
         $this->path = $arr;
         $this->has_path = true;
+
+        return $this;
     }
 
     public function hasPath()
@@ -96,11 +88,10 @@
     }
 
     /**
-     * <pre>
      * Identifies the filesystem path to the original source .proto.
-     * </pre>
      *
-     * <code>optional string source_file = 2;</code>
+     * Generated from protobuf field <code>optional string source_file = 2;</code>
+     * @return string
      */
     public function getSourceFile()
     {
@@ -108,17 +99,19 @@
     }
 
     /**
-     * <pre>
      * Identifies the filesystem path to the original source .proto.
-     * </pre>
      *
-     * <code>optional string source_file = 2;</code>
+     * Generated from protobuf field <code>optional string source_file = 2;</code>
+     * @param string $var
+     * @return $this
      */
     public function setSourceFile($var)
     {
         GPBUtil::checkString($var, True);
         $this->source_file = $var;
         $this->has_source_file = true;
+
+        return $this;
     }
 
     public function hasSourceFile()
@@ -127,12 +120,11 @@
     }
 
     /**
-     * <pre>
      * Identifies the starting offset in bytes in the generated code
      * that relates to the identified object.
-     * </pre>
      *
-     * <code>optional int32 begin = 3;</code>
+     * Generated from protobuf field <code>optional int32 begin = 3;</code>
+     * @return int
      */
     public function getBegin()
     {
@@ -140,18 +132,20 @@
     }
 
     /**
-     * <pre>
      * Identifies the starting offset in bytes in the generated code
      * that relates to the identified object.
-     * </pre>
      *
-     * <code>optional int32 begin = 3;</code>
+     * Generated from protobuf field <code>optional int32 begin = 3;</code>
+     * @param int $var
+     * @return $this
      */
     public function setBegin($var)
     {
         GPBUtil::checkInt32($var);
         $this->begin = $var;
         $this->has_begin = true;
+
+        return $this;
     }
 
     public function hasBegin()
@@ -160,13 +154,12 @@
     }
 
     /**
-     * <pre>
      * Identifies the ending offset in bytes in the generated code that
      * relates to the identified offset. The end offset should be one past
      * the last relevant byte (so the length of the text = end - begin).
-     * </pre>
      *
-     * <code>optional int32 end = 4;</code>
+     * Generated from protobuf field <code>optional int32 end = 4;</code>
+     * @return int
      */
     public function getEnd()
     {
@@ -174,19 +167,21 @@
     }
 
     /**
-     * <pre>
      * Identifies the ending offset in bytes in the generated code that
      * relates to the identified offset. The end offset should be one past
      * the last relevant byte (so the length of the text = end - begin).
-     * </pre>
      *
-     * <code>optional int32 end = 4;</code>
+     * Generated from protobuf field <code>optional int32 end = 4;</code>
+     * @param int $var
+     * @return $this
      */
     public function setEnd($var)
     {
         GPBUtil::checkInt32($var);
         $this->end = $var;
         $this->has_end = true;
+
+        return $this;
     }
 
     public function hasEnd()
diff --git a/php/src/Google/Protobuf/Internal/MapField.php b/php/src/Google/Protobuf/Internal/MapField.php
index 55cc12c..38736da 100644
--- a/php/src/Google/Protobuf/Internal/MapField.php
+++ b/php/src/Google/Protobuf/Internal/MapField.php
@@ -38,131 +38,6 @@
 namespace Google\Protobuf\Internal;
 
 /**
- * MapFieldIter is used to iterate MapField. It is also need for the foreach
- * syntax.
- */
-class MapFieldIter implements \Iterator
-{
-
-    /**
-     * @ignore
-     */
-    private $container;
-
-    /**
-     * Create iterator instance for MapField.
-     *
-     * @param MapField The MapField instance for which this iterator is
-     * created.
-     * @ignore
-     */
-    public function __construct($container)
-    {
-        $this->container = $container;
-    }
-
-    /**
-     * Reset the status of the iterator
-     *
-     * @return void
-     */
-    public function rewind()
-    {
-        return reset($this->container);
-    }
-
-    /**
-     * Return the element at the current position.
-     *
-     * @return object The element at the current position.
-     */
-    public function current()
-    {
-        return current($this->container);
-    }
-
-    /**
-     * Return the current key.
-     *
-     * @return object The current key.
-     */
-    public function key()
-    {
-        return key($this->container);
-    }
-
-    /**
-     * Move to the next position.
-     *
-     * @return void
-     */
-    public function next()
-    {
-        return next($this->container);
-    }
-
-    /**
-     * Check whether there are more elements to iterate.
-     *
-     * @return bool True if there are more elements to iterate.
-     */
-    public function valid()
-    {
-        return key($this->container) !== null;
-    }
-}
-
-/**
- * @ignore
- */
-function checkKey($key_type, &$key)
-{
-    switch ($key_type) {
-        case GPBType::INT32:
-            GPBUtil::checkInt32($key);
-            break;
-        case GPBType::UINT32:
-            GPBUtil::checkUint32($key);
-            break;
-        case GPBType::INT64:
-            GPBUtil::checkInt64($key);
-            break;
-        case GPBType::UINT64:
-            GPBUtil::checkUint64($key);
-            break;
-        case GPBType::FIXED64:
-            GPBUtil::checkUint64($key);
-            break;
-        case GPBType::FIXED32:
-            GPBUtil::checkUint32($key);
-            break;
-        case GPBType::SFIXED64:
-            GPBUtil::checkInt64($key);
-            break;
-        case GPBType::SFIXED32:
-            GPBUtil::checkInt32($key);
-            break;
-        case GPBType::SINT64:
-            GPBUtil::checkInt64($key);
-            break;
-        case GPBType::SINT32:
-            GPBUtil::checkInt32($key);
-            break;
-        case GPBType::BOOL:
-            GPBUtil::checkBool($key);
-            break;
-        case GPBType::STRING:
-            GPBUtil::checkString($key, true);
-            break;
-        default:
-            trigger_error(
-                "Given type cannot be map key.",
-                E_USER_ERROR);
-            break;
-    }
-}
-
-/**
  * MapField is used by generated protocol message classes to manipulate map
  * fields. It can be used like native PHP array.
  */
@@ -255,7 +130,7 @@
      */
     public function offsetSet($key, $value)
     {
-        checkKey($this->key_type, $key);
+        $this->checkKey($this->key_type, $key);
 
         switch ($this->value_type) {
             case GPBType::INT32:
@@ -306,7 +181,7 @@
      */
     public function offsetUnset($key)
     {
-        checkKey($this->key_type, $key);
+        $this->checkKey($this->key_type, $key);
         unset($this->container[$key]);
     }
 
@@ -321,7 +196,7 @@
      */
     public function offsetExists($key)
     {
-        checkKey($this->key_type, $key);
+        $this->checkKey($this->key_type, $key);
         return isset($this->container[$key]);
     }
 
@@ -330,7 +205,7 @@
      */
     public function getIterator()
     {
-        return new MapFieldIter($this->container);
+        return new MapFieldIter($this->container, $this->key_type);
     }
 
     /**
@@ -344,4 +219,54 @@
     {
         return count($this->container);
     }
+
+    /**
+     * @ignore
+     */
+    private function checkKey($key_type, &$key)
+    {
+        switch ($key_type) {
+            case GPBType::INT32:
+                GPBUtil::checkInt32($key);
+                break;
+            case GPBType::UINT32:
+                GPBUtil::checkUint32($key);
+                break;
+            case GPBType::INT64:
+                GPBUtil::checkInt64($key);
+                break;
+            case GPBType::UINT64:
+                GPBUtil::checkUint64($key);
+                break;
+            case GPBType::FIXED64:
+                GPBUtil::checkUint64($key);
+                break;
+            case GPBType::FIXED32:
+                GPBUtil::checkUint32($key);
+                break;
+            case GPBType::SFIXED64:
+                GPBUtil::checkInt64($key);
+                break;
+            case GPBType::SFIXED32:
+                GPBUtil::checkInt32($key);
+                break;
+            case GPBType::SINT64:
+                GPBUtil::checkInt64($key);
+                break;
+            case GPBType::SINT32:
+                GPBUtil::checkInt32($key);
+                break;
+            case GPBType::BOOL:
+                GPBUtil::checkBool($key);
+                break;
+            case GPBType::STRING:
+                GPBUtil::checkString($key, true);
+                break;
+            default:
+                trigger_error(
+                    "Given type cannot be map key.",
+                    E_USER_ERROR);
+                break;
+        }
+    }
 }
diff --git a/php/src/Google/Protobuf/Internal/MapFieldIter.php b/php/src/Google/Protobuf/Internal/MapFieldIter.php
new file mode 100644
index 0000000..88e6c8b
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/MapFieldIter.php
@@ -0,0 +1,124 @@
+<?php
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * MapField and MapFieldIter are used by generated protocol message classes to
+ * manipulate map fields.
+ */
+
+namespace Google\Protobuf\Internal;
+
+/**
+ * MapFieldIter is used to iterate MapField. It is also need for the foreach
+ * syntax.
+ */
+class MapFieldIter implements \Iterator
+{
+
+    /**
+     * @ignore
+     */
+    private $container;
+
+    /**
+     * Create iterator instance for MapField.
+     *
+     * @param MapField The MapField instance for which this iterator is
+     * created.
+     * @param GPBType Map key type.
+     * @ignore
+     */
+    public function __construct($container, $key_type)
+    {
+        $this->container = $container;
+        $this->key_type = $key_type;
+    }
+
+    /**
+     * Reset the status of the iterator
+     *
+     * @return void
+     */
+    public function rewind()
+    {
+        return reset($this->container);
+    }
+
+    /**
+     * Return the element at the current position.
+     *
+     * @return object The element at the current position.
+     */
+    public function current()
+    {
+        return current($this->container);
+    }
+
+    /**
+     * Return the current key.
+     *
+     * @return object The current key.
+     */
+    public function key()
+    {
+        $key = key($this->container);
+        if ($this->key_type === GPBType::BOOL) {
+            // PHP associative array stores bool as integer for key.
+            return boolval($key);
+        } elseif ($this->key_type === GPBType::STRING) {
+            // PHP associative array stores int string as int for key.
+            return strval($key);
+        } else {
+            return $key;
+        }
+    }
+
+    /**
+     * Move to the next position.
+     *
+     * @return void
+     */
+    public function next()
+    {
+        return next($this->container);
+    }
+
+    /**
+     * Check whether there are more elements to iterate.
+     *
+     * @return bool True if there are more elements to iterate.
+     */
+    public function valid()
+    {
+        return key($this->container) !== null;
+    }
+}
diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php
index cd15e0f..1ecd4fa 100644
--- a/php/src/Google/Protobuf/Internal/Message.php
+++ b/php/src/Google/Protobuf/Internal/Message.php
@@ -36,8 +36,8 @@
 
 namespace Google\Protobuf\Internal;
 
-use Google\Protobuf\Internal\InputStream;
-use Google\Protobuf\Internal\OutputStream;
+use Google\Protobuf\Internal\CodedInputStream;
+use Google\Protobuf\Internal\CodedOutputStream;
 use Google\Protobuf\Internal\DescriptorPool;
 use Google\Protobuf\Internal\GPBLabel;
 use Google\Protobuf\Internal\GPBType;
@@ -68,6 +68,10 @@
         // specific descriptor from the descriptor pool.
         if (get_class($this) === 'Google\Protobuf\Internal\MapEntry') {
             $this->desc = $desc;
+            foreach ($desc->getField() as $field) {
+                $setter = $field->getSetter();
+                $this->$setter($this->defaultValue($field));
+            }
             return;
         }
         $pool = DescriptorPool::getGeneratedPool();
@@ -219,6 +223,58 @@
     /**
      * @ignore
      */
+    private static function skipField($input, $tag)
+    {
+        $number = GPBWire::getTagFieldNumber($tag);
+        if ($number === 0) {
+            throw new GPBDecodeException("Illegal field number zero.");
+        }
+
+        switch (GPBWire::getTagWireType($tag)) {
+            case GPBWireType::VARINT:
+                $uint64 = 0;
+                if (!$input->readVarint64($uint64)) {
+                    throw new GPBDecodeException(
+                        "Unexpected EOF inside varint.");
+                }
+                return;
+            case GPBWireType::FIXED64:
+                $uint64 = 0;
+                if (!$input->readLittleEndian64($uint64)) {
+                    throw new GPBDecodeException(
+                        "Unexpected EOF inside fixed64.");
+                }
+                return;
+            case GPBWireType::FIXED32:
+                $uint32 = 0;
+                if (!$input->readLittleEndian32($uint32)) {
+                    throw new GPBDecodeException(
+                        "Unexpected EOF inside fixed32.");
+                }
+                return;
+            case GPBWireType::LENGTH_DELIMITED:
+                $length = 0;
+                if (!$input->readVarint32($length)) {
+                    throw new GPBDecodeException(
+                        "Unexpected EOF inside length.");
+                }
+                $data = NULL;
+                if (!$input->readRaw($length, $data)) {
+                    throw new GPBDecodeException(
+                        "Unexpected EOF inside length delimited data.");
+                }
+                return;
+            case GPBWireType::START_GROUP:
+            case GPBWireType::END_GROUP:
+                throw new GPBDecodeException("Unexpected wire type.");
+            default:
+                throw new GPBDecodeException("Unexpected wire type.");
+        }
+    }
+
+    /**
+     * @ignore
+     */
     private static function parseFieldFromStreamNoTag($input, $field, &$value)
     {
         switch ($field->getType()) {
@@ -278,7 +334,6 @@
                 }
                 break;
             case GPBType::GROUP:
-                echo "GROUP\xA";
                 trigger_error("Not implemented.", E_ERROR);
                 break;
             case GPBType::MESSAGE:
@@ -349,19 +404,25 @@
     private function parseFieldFromStream($tag, $input, $field)
     {
         $value = null;
-        $field_type = $field->getType();
 
-        $value_format = GPBWire::UNKNOWN;
-        if (GPBWire::getTagWireType($tag) ===
-            GPBWire::getWireType($field_type)) {
+        if (is_null($field)) {
+            $value_format = GPBWire::UNKNOWN;
+        } elseif (GPBWire::getTagWireType($tag) ===
+            GPBWire::getWireType($field->getType())) {
             $value_format = GPBWire::NORMAL_FORMAT;
         } elseif ($field->isPackable() &&
             GPBWire::getTagWireType($tag) ===
             GPBWire::WIRETYPE_LENGTH_DELIMITED) {
             $value_format = GPBWire::PACKED_FORMAT;
+        } else {
+            // the wire type doesn't match. Put it in our unknown field set.
+            $value_format = GPBWire::UNKNOWN;
         }
 
-        if ($value_format === GPBWire::NORMAL_FORMAT) {
+        if ($value_format === GPBWire::UNKNOWN) {
+            self::skipField($input, $tag);
+            return;
+        } elseif ($value_format === GPBWire::NORMAL_FORMAT) {
             self::parseFieldFromStreamNoTag($input, $field, $value);
         } elseif ($value_format === GPBWire::PACKED_FORMAT) {
             $length = 0;
@@ -373,20 +434,18 @@
             $getter = $field->getGetter();
             while ($input->bytesUntilLimit() > 0) {
                 self::parseFieldFromStreamNoTag($input, $field, $value);
-                $this->$getter()[] = $value;
+                $this->appendHelper($field, $value);
             }
             $input->popLimit($limit);
             return;
         } else {
-            return false;
+            return;
         }
 
         if ($field->isMap()) {
-            $getter = $field->getGetter();
-            $this->$getter()[$value->getKey()] = $value->getValue();
+            $this->kvUpdateHelper($field, $value->getKey(), $value->getValue());
         } else if ($field->isRepeated()) {
-            $getter = $field->getGetter();
-            $this->$getter()[] = $value;
+            $this->appendHelper($field, $value);
         } else {
             $setter = $field->getSetter();
             $this->$setter($value);
@@ -533,9 +592,10 @@
                           $klass = $value_field->getMessageType()->getClass();
                           $copy = new $klass;
                           $copy->mergeFrom($value);
-                          $this->$getter()[$key] = $copy;
+
+                          $this->kvUpdateHelper($field, $key, $copy);
                       } else {
-                          $this->$getter()[$key] = $value;
+                          $this->kvUpdateHelper($field, $key, $value);
                       }
                   }
               }
@@ -546,9 +606,9 @@
                           $klass = $field->getMessageType()->getClass();
                           $copy = new $klass;
                           $copy->mergeFrom($tmp);
-                          $this->$getter()[] = $copy;
+                          $this->appendHelper($field, $copy);
                       } else {
-                          $this->$getter()[] = $tmp;
+                          $this->appendHelper($field, $tmp);
                       }
                   }
               }
@@ -584,11 +644,29 @@
      */
     public function mergeFromString($data)
     {
-        $input = new InputStream($data);
+        $input = new CodedInputStream($data);
         $this->parseFromStream($input);
     }
 
     /**
+     * Parses a json string to protobuf message.
+     *
+     * This function takes a string in the json wire format, matching the
+     * encoding output by serializeToJsonString().
+     * See mergeFrom() for merging behavior, if the field is already set in the
+     * specified message.
+     *
+     * @param string $data Json protobuf data.
+     * @return null.
+     * @throws Exception Invalid data.
+     */
+    public function mergeFromJsonString($data)
+    {
+        $input = new RawInputStream($data);
+        $this->parseFromJsonStream($input);
+    }
+
+    /**
      * @ignore
      */
     public function parseFromStream($input)
@@ -603,15 +681,236 @@
             $number = GPBWire::getTagFieldNumber($tag);
             $field = $this->desc->getFieldByNumber($number);
 
-            // Check whether we retrieved a known field
-            if ($field === NULL) {
-              continue;
-            }
-
             $this->parseFieldFromStream($tag, $input, $field);
         }
     }
 
+    private function convertJsonValueToProtoValue(
+        $value,
+        $field,
+        $is_map_key = false)
+    {
+        if (is_null($value)) {
+            return $this->defaultValue($field);
+        }
+        switch ($field->getType()) {
+            case GPBType::MESSAGE:
+                $klass = $field->getMessageType()->getClass();
+                if (!is_object($value) && !is_array($value)) {
+                    throw new \Exception("Expect message.");
+                }
+                $submsg = new $klass;
+                if (!is_null($value) &&
+                    $klass !== "Google\Protobuf\Any") {
+                    $submsg->mergeFromJsonArray($value);
+                }
+                return $submsg;
+            case GPBType::ENUM:
+                if (is_integer($value)) {
+                    return $value;
+                } else {
+                    $enum_value =
+                        $field->getEnumType()->getValueByName($value);
+                }
+                if (!is_null($enum_value)) {
+                    return $enum_value->getNumber();
+                }
+            case GPBType::STRING:
+                if (!is_string($value)) {
+                    throw new GPBDecodeException("Expect string");
+                }
+                return $value;
+            case GPBType::BYTES:
+                if (!is_string($value)) {
+                    throw new GPBDecodeException("Expect string");
+                }
+                $proto_value = base64_decode($value, true);
+                if ($proto_value === false) {
+                    throw new GPBDecodeException(
+                        "Invalid base64 characters");
+                }
+                return $proto_value;
+            case GPBType::BOOL:
+                if ($is_map_key) {
+                    if ($value === "true") {
+                        return true;
+                    }
+                    if ($value === "false") {
+                        return false;
+                    }
+                    throw new GPBDecodeException(
+                        "Bool field only accept bool value");
+                }
+                if (!is_bool($value)) {
+                    throw new GPBDecodeException(
+                        "Bool field only accept bool value");
+                }
+                return $value;
+            case GPBType::FLOAT:
+                if ($value === "Infinity") {
+                    return INF;
+                }
+                if ($value === "-Infinity") {
+                    return -INF;
+                }
+                if ($value === "NaN") {
+                    return NAN;
+                }
+                return $value;
+            case GPBType::DOUBLE:
+                if ($value === "Infinity") {
+                    return INF;
+                }
+                if ($value === "-Infinity") {
+                    return -INF;
+                }
+                if ($value === "NaN") {
+                    return NAN;
+                }
+                return $value;
+            case GPBType::INT32:
+                if (!is_numeric($value)) {
+                   throw new GPBDecodeException(
+                       "Invalid data type for int32 field");
+                }
+                if (bccomp($value, "2147483647") > 0) {
+                   throw new GPBDecodeException(
+                       "Int32 too large");
+                }
+                if (bccomp($value, "-2147483648") < 0) {
+                   throw new GPBDecodeException(
+                       "Int32 too small");
+                }
+                return $value;
+            case GPBType::UINT32:
+                if (!is_numeric($value)) {
+                   throw new GPBDecodeException(
+                       "Invalid data type for uint32 field");
+                }
+                if (bccomp($value, 4294967295) > 0) {
+                    throw new GPBDecodeException(
+                        "Uint32 too large");
+                }
+                return $value;
+            case GPBType::INT64:
+                if (!is_numeric($value)) {
+                   throw new GPBDecodeException(
+                       "Invalid data type for int64 field");
+                }
+                if (bccomp($value, "9223372036854775807") > 0) {
+                    throw new GPBDecodeException(
+                        "Int64 too large");
+                }
+                if (bccomp($value, "-9223372036854775808") < 0) {
+                    throw new GPBDecodeException(
+                        "Int64 too small");
+                }
+                return $value;
+            case GPBType::UINT64:
+                if (!is_numeric($value)) {
+                   throw new GPBDecodeException(
+                       "Invalid data type for int64 field");
+                }
+                if (bccomp($value, "18446744073709551615") > 0) {
+                    throw new GPBDecodeException(
+                        "Uint64 too large");
+                }
+                if (bccomp($value, "9223372036854775807") > 0) {
+                    $value = bcsub($value, "18446744073709551616");
+                }
+                return $value;
+            case GPBType::FIXED64:
+                return $value;
+            default:
+                return $value;
+        }
+    }
+
+    private function mergeFromJsonArray($array)
+    {
+        foreach ($array as $key => $value) {
+            $field = $this->desc->getFieldByJsonName($key);
+            if (is_null($field)) {
+                $field = $this->desc->getFieldByName($key);
+                if (is_null($field)) {
+                    continue;
+                }
+            }
+            $setter = $field->getSetter();
+            if ($field->isMap()) {
+                if (is_null($value)) {
+                    continue;
+                }
+                $getter = $field->getGetter();
+                $key_field = $field->getMessageType()->getFieldByNumber(1);
+                $value_field = $field->getMessageType()->getFieldByNumber(2);
+                foreach ($value as $tmp_key => $tmp_value) {
+                    if (is_null($tmp_value)) {
+                        throw new \Exception(
+                            "Map value field element cannot be null.");
+                    }
+                    $proto_key =
+                        $this->convertJsonValueToProtoValue(
+                            $tmp_key,
+                            $key_field,
+                            true);
+                    $proto_value =
+                        $this->convertJsonValueToProtoValue(
+                            $tmp_value,
+                            $value_field);
+                    $this->$getter()[$proto_key] = $proto_value;
+                }
+            } else if ($field->isRepeated()) {
+                if (is_null($value)) {
+                    continue;
+                }
+                $getter = $field->getGetter();
+                foreach ($value as $tmp) {
+                    if (is_null($tmp)) {
+                        throw new \Exception(
+                            "Repeated field elements cannot be null.");
+                    }
+                    $proto_value =
+                        $this->convertJsonValueToProtoValue($tmp, $field);
+                    $this->$getter()[] = $proto_value;
+                }
+            } else {
+                $setter = $field->getSetter();
+                $proto_value =
+                    $this->convertJsonValueToProtoValue($value, $field);
+                if ($field->getType() === GPBType::MESSAGE) {
+                    if (is_null($proto_value)) {
+                        continue;
+                    }
+                    $getter = $field->getGetter();
+                    $submsg = $this->$getter();
+                    if (!is_null($submsg)) {
+                        $submsg->mergeFrom($proto_value);
+                        continue;
+                    }
+                }
+                $this->$setter($proto_value);
+            }
+        }
+    }
+
+    /**
+     * @ignore
+     */
+    public function parseFromJsonStream($input)
+    {
+        $array = json_decode($input->getData(), JSON_BIGINT_AS_STRING);
+        if (is_null($array)) {
+            throw new GPBDecodeException(
+                "Cannot decode json string.");
+        }
+        try {
+            $this->mergeFromJsonArray($array);
+        } catch (Exception $e) {
+            throw new GPBDecodeException($e->getMessage());
+        }
+    }
+
     /**
      * @ignore
      */
@@ -651,7 +950,7 @@
             foreach ($values as $value) {
                 $size += $this->fieldDataOnlyByteSize($field, $value);
             }
-            if (!$output->writeVarint32($size)) {
+            if (!$output->writeVarint32($size, true)) {
                 return false;
             }
         }
@@ -712,6 +1011,16 @@
     /**
      * @ignore
      */
+    private function serializeFieldToJsonStream(&$output, $field)
+    {
+        $getter = $field->getGetter();
+        $values = $this->$getter();
+        return GPBJsonWire::serializeFieldToStream($values, $field, $output);
+    }
+
+    /**
+     * @ignore
+     */
     public function serializeToStream(&$output)
     {
         $fields = $this->desc->getField();
@@ -724,24 +1033,72 @@
     }
 
     /**
+     * @ignore
+     */
+    public function serializeToJsonStream(&$output)
+    {
+        $output->writeRaw("{", 1);
+        $fields = $this->desc->getField();
+        $first = true;
+        foreach ($fields as $field) {
+            if ($this->existField($field)) {
+                if ($first) {
+                    $first = false;
+                } else {
+                    $output->writeRaw(",", 1);
+                }
+                if (!$this->serializeFieldToJsonStream($output, $field)) {
+                    return false;
+                }
+            }
+        }
+        $output->writeRaw("}", 1);
+        return true;
+    }
+
+    /**
      * Serialize the message to string.
      * @return string Serialized binary protobuf data.
      */
     public function serializeToString()
     {
-        $output = new OutputStream($this->byteSize());
+        $output = new CodedOutputStream($this->byteSize());
         $this->serializeToStream($output);
         return $output->getData();
     }
 
     /**
+     * Serialize the message to json string.
+     * @return string Serialized json protobuf data.
+     */
+    public function serializeToJsonString()
+    {
+        $output = new CodedOutputStream($this->jsonByteSize());
+        $this->serializeToJsonStream($output);
+        return $output->getData();
+    }
+
+    /**
      * @ignore
      */
     private function existField($field)
     {
+        $oneof_index = $field->getOneofIndex();
+        if ($oneof_index !== -1) {
+            $oneof = $this->desc->getOneofDecl()[$oneof_index];
+            $oneof_name = $oneof->getName();
+            return $this->$oneof_name->getNumber() === $field->getNumber();
+        }
+
         $getter = $field->getGetter();
-        $value = $this->$getter();
-        return $value !== $this->defaultValue($field);
+        $values = $this->$getter();
+        if ($field->isMap()) {
+            return count($values) !== 0;
+        } elseif ($field->isRepeated()) {
+            return count($values) !== 0;
+        } else {
+            return $values !== $this->defaultValue($field);
+        }
     }
 
     /**
@@ -824,6 +1181,101 @@
     /**
      * @ignore
      */
+    private function fieldDataOnlyJsonByteSize($field, $value)
+    {
+        $size = 0;
+
+        switch ($field->getType()) {
+            case GPBType::SFIXED32:
+            case GPBType::SINT32:
+            case GPBType::INT32:
+                $size += strlen(strval($value));
+                break;
+            case GPBType::FIXED32:
+            case GPBType::UINT32:
+                if ($value < 0) {
+                    $value = bcadd($value, "4294967296");
+                }
+                $size += strlen(strval($value));
+                break;
+            case GPBType::FIXED64:
+            case GPBType::UINT64:
+                if ($value < 0) {
+                    $value = bcadd($value, "18446744073709551616");
+                }
+                // Intentional fall through.
+            case GPBType::SFIXED64:
+            case GPBType::INT64:
+            case GPBType::SINT64:
+                $size += 2;  // size for ""
+                $size += strlen(strval($value));
+                break;
+            case GPBType::FLOAT:
+                if (is_nan($value)) {
+                    $size += strlen("NaN") + 2;
+                } elseif ($value === INF) {
+                    $size += strlen("Infinity") + 2;
+                } elseif ($value === -INF) {
+                    $size += strlen("-Infinity") + 2;
+                } else {
+                    $size += strlen(sprintf("%.8g", $value));
+                }
+                break;
+            case GPBType::DOUBLE:
+                if (is_nan($value)) {
+                    $size += strlen("NaN") + 2;
+                } elseif ($value === INF) {
+                    $size += strlen("Infinity") + 2;
+                } elseif ($value === -INF) {
+                    $size += strlen("-Infinity") + 2;
+                } else {
+                    $size += strlen(sprintf("%.17g", $value));
+                }
+                break;
+            case GPBType::ENUM:
+                $enum_desc = $field->getEnumType();
+                $enum_value_desc = $enum_desc->getValueByNumber($value);
+                if (!is_null($enum_value_desc)) {
+                    $size += 2;  // size for ""
+                    $size += strlen($enum_value_desc->getName());
+                } else {
+                    $str_value = strval($value);
+                    $size += strlen($str_value);
+                }
+                break;
+            case GPBType::BOOL:
+                if ($value) {
+                    $size += 4;
+                } else {
+                    $size += 5;
+                }
+                break;
+            case GPBType::STRING:
+                $value = json_encode($value);
+                $size += strlen($value);
+                break;
+            case GPBType::BYTES:
+                $size += strlen(base64_encode($value));
+                $size += 2;  // size for \"\"
+                break;
+            case GPBType::MESSAGE:
+                $size += $value->jsonByteSize();
+                break;
+#             case GPBType::GROUP:
+#                 // TODO(teboring): Add support.
+#                 user_error("Unsupported type.");
+#                 break;
+            default:
+                user_error("Unsupported type " . $field->getType());
+                return 0;
+        }
+
+        return $size;
+    }
+
+    /**
+     * @ignore
+     */
     private function fieldByteSize($field)
     {
         $size = 0;
@@ -838,12 +1290,18 @@
                 $value_field = $message_type->getFieldByNumber(2);
                 foreach ($values as $key => $value) {
                     $data_size = 0;
-                    $data_size += $this->fieldDataOnlyByteSize($key_field, $key);
-                    $data_size += $this->fieldDataOnlyByteSize(
-                        $value_field,
-                        $value);
-                    $data_size += GPBWire::tagSize($key_field);
-                    $data_size += GPBWire::tagSize($value_field);
+                    if ($key != $this->defaultValue($key_field)) {
+                        $data_size += $this->fieldDataOnlyByteSize(
+                            $key_field,
+                            $key);
+                        $data_size += GPBWire::tagSize($key_field);
+                    }
+                    if ($value != $this->defaultValue($value_field)) {
+                        $data_size += $this->fieldDataOnlyByteSize(
+                            $value_field,
+                            $value);
+                        $data_size += GPBWire::tagSize($value_field);
+                    }
                     $size += GPBWire::varint32Size($data_size) + $data_size;
                 }
             }
@@ -879,6 +1337,68 @@
     /**
      * @ignore
      */
+    private function fieldJsonByteSize($field)
+    {
+        $size = 0;
+        if ($field->isMap()) {
+            $getter = $field->getGetter();
+            $values = $this->$getter();
+            $count = count($values);
+            if ($count !== 0) {
+                $size += 5;                              // size for "\"\":{}".
+                $size += strlen($field->getJsonName());  // size for field name
+                $size += $count - 1;                     // size for commas
+                $getter = $field->getGetter();
+                $map_entry = $field->getMessageType();
+                $key_field = $map_entry->getFieldByNumber(1);
+                $value_field = $map_entry->getFieldByNumber(2);
+                switch ($key_field->getType()) {
+                case GPBType::STRING:
+                case GPBType::SFIXED64:
+                case GPBType::INT64:
+                case GPBType::SINT64:
+                case GPBType::FIXED64:
+                case GPBType::UINT64:
+                    $additional_quote = false;
+                    break;
+                default:
+                    $additional_quote = true;
+                }
+                foreach ($values as $key => $value) {
+                    if ($additional_quote) {
+                        $size += 2;  // size for ""
+                    }
+                    $size += $this->fieldDataOnlyJsonByteSize($key_field, $key);
+                    $size += $this->fieldDataOnlyJsonByteSize($value_field, $value);
+                    $size += 1;  // size for :
+                }
+            }
+        } elseif ($field->isRepeated()) {
+            $getter = $field->getGetter();
+            $values = $this->$getter();
+            $count = count($values);
+            if ($count !== 0) {
+                $size += 5;                              // size for "\"\":[]".
+                $size += strlen($field->getJsonName());  // size for field name
+                $size += $count - 1;                     // size for commas
+                $getter = $field->getGetter();
+                foreach ($values as $value) {
+                    $size += $this->fieldDataOnlyJsonByteSize($field, $value);
+                }
+            }
+        } elseif ($this->existField($field)) {
+            $size += 3;                              // size for "\"\":".
+            $size += strlen($field->getJsonName());  // size for field name
+            $getter = $field->getGetter();
+            $value = $this->$getter();
+            $size += $this->fieldDataOnlyJsonByteSize($field, $value);
+        }
+        return $size;
+    }
+
+    /**
+     * @ignore
+     */
     public function byteSize()
     {
         $size = 0;
@@ -889,4 +1409,54 @@
         }
         return $size;
     }
+
+    private function appendHelper($field, $append_value)
+    {
+        $getter = $field->getGetter();
+        $setter = $field->getSetter();
+
+        $field_arr_value = $this->$getter();
+        $field_arr_value[] = $append_value;
+
+        if (!is_object($field_arr_value)) {
+            $this->$setter($field_arr_value);
+        }
+    }
+
+    private function kvUpdateHelper($field, $update_key, $update_value)
+    {
+        $getter = $field->getGetter();
+        $setter = $field->getSetter();
+
+        $field_arr_value = $this->$getter();
+        $field_arr_value[$update_key] = $update_value;
+
+        if (!is_object($field_arr_value)) {
+            $this->$setter($field_arr_value);
+        }
+    }
+
+    /**
+     * @ignore
+     */
+    public function jsonByteSize()
+    {
+        $size = 0;
+
+        // Size for "{}".
+        $size += 2;
+
+        $fields = $this->desc->getField();
+        $count = 0;
+        foreach ($fields as $field) {
+            $field_size = $this->fieldJsonByteSize($field);
+            $size += $field_size;
+            if ($field_size != 0) {
+              $count++;
+            }
+        }
+        // size for comma
+        $size += $count > 0 ? ($count - 1) : 0;
+        return $size;
+    }
 }
diff --git a/php/src/Google/Protobuf/Internal/MessageOptions.php b/php/src/Google/Protobuf/Internal/MessageOptions.php
index 747f329..99ff3d0 100644
--- a/php/src/Google/Protobuf/Internal/MessageOptions.php
+++ b/php/src/Google/Protobuf/Internal/MessageOptions.php
@@ -8,16 +8,14 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * Protobuf type <code>google.protobuf.MessageOptions</code>
+ * Generated from protobuf message <code>google.protobuf.MessageOptions</code>
  */
 class MessageOptions extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <pre>
      * Set true to use the old proto1 MessageSet wire format for extensions.
      * This is provided for backwards-compatibility with the MessageSet wire
      * format.  You should not use this for any other reason:  It's less
@@ -33,41 +31,35 @@
      * be int32s, enums, or repeated messages.
      * Because this is an option, the above two restrictions are not enforced by
      * the protocol compiler.
-     * </pre>
      *
-     * <code>optional bool message_set_wire_format = 1 [default = false];</code>
+     * Generated from protobuf field <code>optional bool message_set_wire_format = 1 [default = false];</code>
      */
     private $message_set_wire_format = false;
     private $has_message_set_wire_format = false;
     /**
-     * <pre>
      * Disables the generation of the standard "descriptor()" accessor, which can
      * conflict with a field of the same name.  This is meant to make migration
      * from proto1 easier; new code should avoid fields named "descriptor".
-     * </pre>
      *
-     * <code>optional bool no_standard_descriptor_accessor = 2 [default = false];</code>
+     * Generated from protobuf field <code>optional bool no_standard_descriptor_accessor = 2 [default = false];</code>
      */
     private $no_standard_descriptor_accessor = false;
     private $has_no_standard_descriptor_accessor = false;
     /**
-     * <pre>
      * Is this message deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for the message, or it will be completely ignored; in the very least,
      * this is a formalization for deprecating messages.
-     * </pre>
      *
-     * <code>optional bool deprecated = 3 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 3 [default = false];</code>
      */
     private $deprecated = false;
     private $has_deprecated = false;
     /**
-     * <pre>
      * Whether the message is an automatically generated map entry type for the
      * maps field.
      * For maps fields:
-     *     map&lt;KeyType, ValueType&gt; map_field = 1;
+     *     map<KeyType, ValueType> map_field = 1;
      * The parsed descriptor looks like:
      *     message MapFieldEntry {
      *         option map_entry = true;
@@ -82,18 +74,15 @@
      * NOTE: Do not set the option in .proto files. Always use the maps syntax
      * instead. The option should only be implicitly set by the proto compiler
      * parser.
-     * </pre>
      *
-     * <code>optional bool map_entry = 7;</code>
+     * Generated from protobuf field <code>optional bool map_entry = 7;</code>
      */
     private $map_entry = false;
     private $has_map_entry = false;
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
      */
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
@@ -104,7 +93,6 @@
     }
 
     /**
-     * <pre>
      * Set true to use the old proto1 MessageSet wire format for extensions.
      * This is provided for backwards-compatibility with the MessageSet wire
      * format.  You should not use this for any other reason:  It's less
@@ -120,9 +108,9 @@
      * be int32s, enums, or repeated messages.
      * Because this is an option, the above two restrictions are not enforced by
      * the protocol compiler.
-     * </pre>
      *
-     * <code>optional bool message_set_wire_format = 1 [default = false];</code>
+     * Generated from protobuf field <code>optional bool message_set_wire_format = 1 [default = false];</code>
+     * @return bool
      */
     public function getMessageSetWireFormat()
     {
@@ -130,7 +118,6 @@
     }
 
     /**
-     * <pre>
      * Set true to use the old proto1 MessageSet wire format for extensions.
      * This is provided for backwards-compatibility with the MessageSet wire
      * format.  You should not use this for any other reason:  It's less
@@ -146,15 +133,18 @@
      * be int32s, enums, or repeated messages.
      * Because this is an option, the above two restrictions are not enforced by
      * the protocol compiler.
-     * </pre>
      *
-     * <code>optional bool message_set_wire_format = 1 [default = false];</code>
+     * Generated from protobuf field <code>optional bool message_set_wire_format = 1 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setMessageSetWireFormat($var)
     {
         GPBUtil::checkBool($var);
         $this->message_set_wire_format = $var;
         $this->has_message_set_wire_format = true;
+
+        return $this;
     }
 
     public function hasMessageSetWireFormat()
@@ -163,13 +153,12 @@
     }
 
     /**
-     * <pre>
      * Disables the generation of the standard "descriptor()" accessor, which can
      * conflict with a field of the same name.  This is meant to make migration
      * from proto1 easier; new code should avoid fields named "descriptor".
-     * </pre>
      *
-     * <code>optional bool no_standard_descriptor_accessor = 2 [default = false];</code>
+     * Generated from protobuf field <code>optional bool no_standard_descriptor_accessor = 2 [default = false];</code>
+     * @return bool
      */
     public function getNoStandardDescriptorAccessor()
     {
@@ -177,19 +166,21 @@
     }
 
     /**
-     * <pre>
      * Disables the generation of the standard "descriptor()" accessor, which can
      * conflict with a field of the same name.  This is meant to make migration
      * from proto1 easier; new code should avoid fields named "descriptor".
-     * </pre>
      *
-     * <code>optional bool no_standard_descriptor_accessor = 2 [default = false];</code>
+     * Generated from protobuf field <code>optional bool no_standard_descriptor_accessor = 2 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setNoStandardDescriptorAccessor($var)
     {
         GPBUtil::checkBool($var);
         $this->no_standard_descriptor_accessor = $var;
         $this->has_no_standard_descriptor_accessor = true;
+
+        return $this;
     }
 
     public function hasNoStandardDescriptorAccessor()
@@ -198,14 +189,13 @@
     }
 
     /**
-     * <pre>
      * Is this message deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for the message, or it will be completely ignored; in the very least,
      * this is a formalization for deprecating messages.
-     * </pre>
      *
-     * <code>optional bool deprecated = 3 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 3 [default = false];</code>
+     * @return bool
      */
     public function getDeprecated()
     {
@@ -213,20 +203,22 @@
     }
 
     /**
-     * <pre>
      * Is this message deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for the message, or it will be completely ignored; in the very least,
      * this is a formalization for deprecating messages.
-     * </pre>
      *
-     * <code>optional bool deprecated = 3 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 3 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setDeprecated($var)
     {
         GPBUtil::checkBool($var);
         $this->deprecated = $var;
         $this->has_deprecated = true;
+
+        return $this;
     }
 
     public function hasDeprecated()
@@ -235,11 +227,10 @@
     }
 
     /**
-     * <pre>
      * Whether the message is an automatically generated map entry type for the
      * maps field.
      * For maps fields:
-     *     map&lt;KeyType, ValueType&gt; map_field = 1;
+     *     map<KeyType, ValueType> map_field = 1;
      * The parsed descriptor looks like:
      *     message MapFieldEntry {
      *         option map_entry = true;
@@ -254,9 +245,9 @@
      * NOTE: Do not set the option in .proto files. Always use the maps syntax
      * instead. The option should only be implicitly set by the proto compiler
      * parser.
-     * </pre>
      *
-     * <code>optional bool map_entry = 7;</code>
+     * Generated from protobuf field <code>optional bool map_entry = 7;</code>
+     * @return bool
      */
     public function getMapEntry()
     {
@@ -264,11 +255,10 @@
     }
 
     /**
-     * <pre>
      * Whether the message is an automatically generated map entry type for the
      * maps field.
      * For maps fields:
-     *     map&lt;KeyType, ValueType&gt; map_field = 1;
+     *     map<KeyType, ValueType> map_field = 1;
      * The parsed descriptor looks like:
      *     message MapFieldEntry {
      *         option map_entry = true;
@@ -283,15 +273,18 @@
      * NOTE: Do not set the option in .proto files. Always use the maps syntax
      * instead. The option should only be implicitly set by the proto compiler
      * parser.
-     * </pre>
      *
-     * <code>optional bool map_entry = 7;</code>
+     * Generated from protobuf field <code>optional bool map_entry = 7;</code>
+     * @param bool $var
+     * @return $this
      */
     public function setMapEntry($var)
     {
         GPBUtil::checkBool($var);
         $this->map_entry = $var;
         $this->has_map_entry = true;
+
+        return $this;
     }
 
     public function hasMapEntry()
@@ -300,11 +293,10 @@
     }
 
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getUninterpretedOption()
     {
@@ -312,17 +304,19 @@
     }
 
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * @param \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setUninterpretedOption(&$var)
+    public function setUninterpretedOption($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class);
         $this->uninterpreted_option = $arr;
         $this->has_uninterpreted_option = true;
+
+        return $this;
     }
 
     public function hasUninterpretedOption()
diff --git a/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php b/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php
index 3d8df7a..ccfce2d 100644
--- a/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php
+++ b/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php
@@ -8,58 +8,49 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * <pre>
  * Describes a method of a service.
- * </pre>
  *
- * Protobuf type <code>google.protobuf.MethodDescriptorProto</code>
+ * Generated from protobuf message <code>google.protobuf.MethodDescriptorProto</code>
  */
 class MethodDescriptorProto extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
      */
     private $name = '';
     private $has_name = false;
     /**
-     * <pre>
      * Input and output type names.  These are resolved in the same way as
      * FieldDescriptorProto.type_name, but must refer to a message type.
-     * </pre>
      *
-     * <code>optional string input_type = 2;</code>
+     * Generated from protobuf field <code>optional string input_type = 2;</code>
      */
     private $input_type = '';
     private $has_input_type = false;
     /**
-     * <code>optional string output_type = 3;</code>
+     * Generated from protobuf field <code>optional string output_type = 3;</code>
      */
     private $output_type = '';
     private $has_output_type = false;
     /**
-     * <code>optional .google.protobuf.MethodOptions options = 4;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.MethodOptions options = 4;</code>
      */
     private $options = null;
     private $has_options = false;
     /**
-     * <pre>
      * Identifies if client streams multiple client messages
-     * </pre>
      *
-     * <code>optional bool client_streaming = 5 [default = false];</code>
+     * Generated from protobuf field <code>optional bool client_streaming = 5 [default = false];</code>
      */
     private $client_streaming = false;
     private $has_client_streaming = false;
     /**
-     * <pre>
      * Identifies if server streams multiple server messages
-     * </pre>
      *
-     * <code>optional bool server_streaming = 6 [default = false];</code>
+     * Generated from protobuf field <code>optional bool server_streaming = 6 [default = false];</code>
      */
     private $server_streaming = false;
     private $has_server_streaming = false;
@@ -70,7 +61,8 @@
     }
 
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
+     * @return string
      */
     public function getName()
     {
@@ -78,13 +70,17 @@
     }
 
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
+     * @param string $var
+     * @return $this
      */
     public function setName($var)
     {
         GPBUtil::checkString($var, True);
         $this->name = $var;
         $this->has_name = true;
+
+        return $this;
     }
 
     public function hasName()
@@ -93,12 +89,11 @@
     }
 
     /**
-     * <pre>
      * Input and output type names.  These are resolved in the same way as
      * FieldDescriptorProto.type_name, but must refer to a message type.
-     * </pre>
      *
-     * <code>optional string input_type = 2;</code>
+     * Generated from protobuf field <code>optional string input_type = 2;</code>
+     * @return string
      */
     public function getInputType()
     {
@@ -106,18 +101,20 @@
     }
 
     /**
-     * <pre>
      * Input and output type names.  These are resolved in the same way as
      * FieldDescriptorProto.type_name, but must refer to a message type.
-     * </pre>
      *
-     * <code>optional string input_type = 2;</code>
+     * Generated from protobuf field <code>optional string input_type = 2;</code>
+     * @param string $var
+     * @return $this
      */
     public function setInputType($var)
     {
         GPBUtil::checkString($var, True);
         $this->input_type = $var;
         $this->has_input_type = true;
+
+        return $this;
     }
 
     public function hasInputType()
@@ -126,7 +123,8 @@
     }
 
     /**
-     * <code>optional string output_type = 3;</code>
+     * Generated from protobuf field <code>optional string output_type = 3;</code>
+     * @return string
      */
     public function getOutputType()
     {
@@ -134,13 +132,17 @@
     }
 
     /**
-     * <code>optional string output_type = 3;</code>
+     * Generated from protobuf field <code>optional string output_type = 3;</code>
+     * @param string $var
+     * @return $this
      */
     public function setOutputType($var)
     {
         GPBUtil::checkString($var, True);
         $this->output_type = $var;
         $this->has_output_type = true;
+
+        return $this;
     }
 
     public function hasOutputType()
@@ -149,7 +151,8 @@
     }
 
     /**
-     * <code>optional .google.protobuf.MethodOptions options = 4;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.MethodOptions options = 4;</code>
+     * @return \Google\Protobuf\Internal\MethodOptions
      */
     public function getOptions()
     {
@@ -157,13 +160,17 @@
     }
 
     /**
-     * <code>optional .google.protobuf.MethodOptions options = 4;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.MethodOptions options = 4;</code>
+     * @param \Google\Protobuf\Internal\MethodOptions $var
+     * @return $this
      */
-    public function setOptions(&$var)
+    public function setOptions($var)
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\MethodOptions::class);
         $this->options = $var;
         $this->has_options = true;
+
+        return $this;
     }
 
     public function hasOptions()
@@ -172,11 +179,10 @@
     }
 
     /**
-     * <pre>
      * Identifies if client streams multiple client messages
-     * </pre>
      *
-     * <code>optional bool client_streaming = 5 [default = false];</code>
+     * Generated from protobuf field <code>optional bool client_streaming = 5 [default = false];</code>
+     * @return bool
      */
     public function getClientStreaming()
     {
@@ -184,17 +190,19 @@
     }
 
     /**
-     * <pre>
      * Identifies if client streams multiple client messages
-     * </pre>
      *
-     * <code>optional bool client_streaming = 5 [default = false];</code>
+     * Generated from protobuf field <code>optional bool client_streaming = 5 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setClientStreaming($var)
     {
         GPBUtil::checkBool($var);
         $this->client_streaming = $var;
         $this->has_client_streaming = true;
+
+        return $this;
     }
 
     public function hasClientStreaming()
@@ -203,11 +211,10 @@
     }
 
     /**
-     * <pre>
      * Identifies if server streams multiple server messages
-     * </pre>
      *
-     * <code>optional bool server_streaming = 6 [default = false];</code>
+     * Generated from protobuf field <code>optional bool server_streaming = 6 [default = false];</code>
+     * @return bool
      */
     public function getServerStreaming()
     {
@@ -215,17 +222,19 @@
     }
 
     /**
-     * <pre>
      * Identifies if server streams multiple server messages
-     * </pre>
      *
-     * <code>optional bool server_streaming = 6 [default = false];</code>
+     * Generated from protobuf field <code>optional bool server_streaming = 6 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setServerStreaming($var)
     {
         GPBUtil::checkBool($var);
         $this->server_streaming = $var;
         $this->has_server_streaming = true;
+
+        return $this;
     }
 
     public function hasServerStreaming()
diff --git a/php/src/Google/Protobuf/Internal/MethodOptions.php b/php/src/Google/Protobuf/Internal/MethodOptions.php
index 6dca585..baa806b 100644
--- a/php/src/Google/Protobuf/Internal/MethodOptions.php
+++ b/php/src/Google/Protobuf/Internal/MethodOptions.php
@@ -8,37 +8,32 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * Protobuf type <code>google.protobuf.MethodOptions</code>
+ * Generated from protobuf message <code>google.protobuf.MethodOptions</code>
  */
 class MethodOptions extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <pre>
      * Is this method deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for the method, or it will be completely ignored; in the very least,
      * this is a formalization for deprecating methods.
-     * </pre>
      *
-     * <code>optional bool deprecated = 33 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 33 [default = false];</code>
      */
     private $deprecated = false;
     private $has_deprecated = false;
     /**
-     * <code>optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];</code>
+     * Generated from protobuf field <code>optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];</code>
      */
     private $idempotency_level = 0;
     private $has_idempotency_level = false;
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
      */
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
@@ -49,14 +44,13 @@
     }
 
     /**
-     * <pre>
      * Is this method deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for the method, or it will be completely ignored; in the very least,
      * this is a formalization for deprecating methods.
-     * </pre>
      *
-     * <code>optional bool deprecated = 33 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 33 [default = false];</code>
+     * @return bool
      */
     public function getDeprecated()
     {
@@ -64,20 +58,22 @@
     }
 
     /**
-     * <pre>
      * Is this method deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for the method, or it will be completely ignored; in the very least,
      * this is a formalization for deprecating methods.
-     * </pre>
      *
-     * <code>optional bool deprecated = 33 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 33 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setDeprecated($var)
     {
         GPBUtil::checkBool($var);
         $this->deprecated = $var;
         $this->has_deprecated = true;
+
+        return $this;
     }
 
     public function hasDeprecated()
@@ -86,7 +82,8 @@
     }
 
     /**
-     * <code>optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];</code>
+     * Generated from protobuf field <code>optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];</code>
+     * @return int
      */
     public function getIdempotencyLevel()
     {
@@ -94,13 +91,17 @@
     }
 
     /**
-     * <code>optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];</code>
+     * Generated from protobuf field <code>optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];</code>
+     * @param int $var
+     * @return $this
      */
     public function setIdempotencyLevel($var)
     {
         GPBUtil::checkEnum($var, \Google\Protobuf\Internal\MethodOptions_IdempotencyLevel::class);
         $this->idempotency_level = $var;
         $this->has_idempotency_level = true;
+
+        return $this;
     }
 
     public function hasIdempotencyLevel()
@@ -109,11 +110,10 @@
     }
 
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getUninterpretedOption()
     {
@@ -121,17 +121,19 @@
     }
 
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * @param \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setUninterpretedOption(&$var)
+    public function setUninterpretedOption($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class);
         $this->uninterpreted_option = $arr;
         $this->has_uninterpreted_option = true;
+
+        return $this;
     }
 
     public function hasUninterpretedOption()
diff --git a/php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php b/php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php
index ce4adfe..9e06d8e 100644
--- a/php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php
+++ b/php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php
@@ -5,34 +5,28 @@
 namespace Google\Protobuf\Internal;
 
 /**
- * <pre>
  * Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
  * or neither? HTTP based RPC implementation may choose GET verb for safe
  * methods, and PUT verb for idempotent methods instead of the default POST.
- * </pre>
  *
- * Protobuf enum <code>google.protobuf.MethodOptions.IdempotencyLevel</code>
+ * Protobuf enum <code>Google\Protobuf\Internal</code>
  */
 class MethodOptions_IdempotencyLevel
 {
     /**
-     * <code>IDEMPOTENCY_UNKNOWN = 0;</code>
+     * Generated from protobuf enum <code>IDEMPOTENCY_UNKNOWN = 0;</code>
      */
     const IDEMPOTENCY_UNKNOWN = 0;
     /**
-     * <pre>
      * implies idempotent
-     * </pre>
      *
-     * <code>NO_SIDE_EFFECTS = 1;</code>
+     * Generated from protobuf enum <code>NO_SIDE_EFFECTS = 1;</code>
      */
     const NO_SIDE_EFFECTS = 1;
     /**
-     * <pre>
      * idempotent, but may have side effects
-     * </pre>
      *
-     * <code>IDEMPOTENT = 2;</code>
+     * Generated from protobuf enum <code>IDEMPOTENT = 2;</code>
      */
     const IDEMPOTENT = 2;
 }
diff --git a/php/src/Google/Protobuf/Internal/OneofDescriptor.php b/php/src/Google/Protobuf/Internal/OneofDescriptor.php
new file mode 100644
index 0000000..0498873
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/OneofDescriptor.php
@@ -0,0 +1,67 @@
+<?php
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+namespace Google\Protobuf\Internal;
+
+class OneofDescriptor
+{
+
+    private $name;
+    private $fields;
+
+    public function setName($name)
+    {
+        $this->name = $name;
+    }
+
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    public function addField(&$field)
+    {
+        $this->fields[] = $field;
+    }
+
+    public function getFields()
+    {
+        return $this->fields;
+    }
+
+    public static function buildFromProto($oneof_proto)
+    {
+        $oneof = new OneofDescriptor();
+        $oneof->setName($oneof_proto->getName());
+        return $oneof;
+    }
+}
diff --git a/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php b/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php
index e5fbe37..15ff061 100644
--- a/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php
+++ b/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php
@@ -8,25 +8,22 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * <pre>
  * Describes a oneof.
- * </pre>
  *
- * Protobuf type <code>google.protobuf.OneofDescriptorProto</code>
+ * Generated from protobuf message <code>google.protobuf.OneofDescriptorProto</code>
  */
 class OneofDescriptorProto extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
      */
     private $name = '';
     private $has_name = false;
     /**
-     * <code>optional .google.protobuf.OneofOptions options = 2;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.OneofOptions options = 2;</code>
      */
     private $options = null;
     private $has_options = false;
@@ -37,7 +34,8 @@
     }
 
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
+     * @return string
      */
     public function getName()
     {
@@ -45,13 +43,17 @@
     }
 
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
+     * @param string $var
+     * @return $this
      */
     public function setName($var)
     {
         GPBUtil::checkString($var, True);
         $this->name = $var;
         $this->has_name = true;
+
+        return $this;
     }
 
     public function hasName()
@@ -60,7 +62,8 @@
     }
 
     /**
-     * <code>optional .google.protobuf.OneofOptions options = 2;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.OneofOptions options = 2;</code>
+     * @return \Google\Protobuf\Internal\OneofOptions
      */
     public function getOptions()
     {
@@ -68,13 +71,17 @@
     }
 
     /**
-     * <code>optional .google.protobuf.OneofOptions options = 2;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.OneofOptions options = 2;</code>
+     * @param \Google\Protobuf\Internal\OneofOptions $var
+     * @return $this
      */
-    public function setOptions(&$var)
+    public function setOptions($var)
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\OneofOptions::class);
         $this->options = $var;
         $this->has_options = true;
+
+        return $this;
     }
 
     public function hasOptions()
diff --git a/php/src/Google/Protobuf/Internal/OneofOptions.php b/php/src/Google/Protobuf/Internal/OneofOptions.php
index b61325d..e5b4633 100644
--- a/php/src/Google/Protobuf/Internal/OneofOptions.php
+++ b/php/src/Google/Protobuf/Internal/OneofOptions.php
@@ -8,20 +8,17 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * Protobuf type <code>google.protobuf.OneofOptions</code>
+ * Generated from protobuf message <code>google.protobuf.OneofOptions</code>
  */
 class OneofOptions extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
      */
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
@@ -32,11 +29,10 @@
     }
 
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getUninterpretedOption()
     {
@@ -44,17 +40,19 @@
     }
 
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * @param \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setUninterpretedOption(&$var)
+    public function setUninterpretedOption($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class);
         $this->uninterpreted_option = $arr;
         $this->has_uninterpreted_option = true;
+
+        return $this;
     }
 
     public function hasUninterpretedOption()
diff --git a/php/src/Google/Protobuf/Internal/RawInputStream.php b/php/src/Google/Protobuf/Internal/RawInputStream.php
new file mode 100644
index 0000000..4e7ed5c
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/RawInputStream.php
@@ -0,0 +1,50 @@
+<?php
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+namespace Google\Protobuf\Internal;
+
+class RawInputStream
+{
+
+    private $buffer;
+
+    public function __construct($buffer)
+    {
+        $this->buffer = $buffer;
+    }
+
+    public function getData()
+    {
+        return $this->buffer;
+    }
+
+}
diff --git a/php/src/Google/Protobuf/Internal/RepeatedField.php b/php/src/Google/Protobuf/Internal/RepeatedField.php
index 2ad4709..797b3b3 100644
--- a/php/src/Google/Protobuf/Internal/RepeatedField.php
+++ b/php/src/Google/Protobuf/Internal/RepeatedField.php
@@ -41,86 +41,6 @@
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * RepeatedFieldIter is used to iterate RepeatedField. It is also need for the
- * foreach syntax.
- */
-class RepeatedFieldIter implements \Iterator
-{
-
-    /**
-     * @ignore
-     */
-    private $position;
-    /**
-     * @ignore
-     */
-    private $container;
-
-    /**
-     * Create iterator instance for RepeatedField.
-     *
-     * @param RepeatedField The RepeatedField instance for which this iterator
-     * is created.
-     * @ignore
-     */
-    public function __construct($container)
-    {
-        $this->position = 0;
-        $this->container = $container;
-    }
-
-    /**
-     * Reset the status of the iterator
-     *
-     * @return void
-     */
-    public function rewind()
-    {
-        $this->position = 0;
-    }
-
-    /**
-     * Return the element at the current position.
-     *
-     * @return object The element at the current position.
-     */
-    public function current()
-    {
-        return $this->container[$this->position];
-    }
-
-    /**
-     * Return the current position.
-     *
-     * @return integer The current position.
-     */
-    public function key()
-    {
-        return $this->position;
-    }
-
-    /**
-     * Move to the next position.
-     *
-     * @return void
-     */
-    public function next()
-    {
-        ++$this->position;
-    }
-
-    /**
-     * Check whether there are more elements to iterate.
-     *
-     * @return bool True if there are more elements to iterate.
-     */
-    public function valid()
-    {
-        return isset($this->container[$this->position]);
-    }
-}
-
-/**
  * RepeatedField is used by generated protocol message classes to manipulate
  * repeated fields. It can be used like native PHP array.
  */
diff --git a/php/src/Google/Protobuf/Internal/RepeatedFieldIter.php b/php/src/Google/Protobuf/Internal/RepeatedFieldIter.php
new file mode 100644
index 0000000..2b6f823
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/RepeatedFieldIter.php
@@ -0,0 +1,118 @@
+<?php
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * RepeatedField and RepeatedFieldIter are used by generated protocol message
+ * classes to manipulate repeated fields.
+ */
+
+namespace Google\Protobuf\Internal;
+
+/**
+ * RepeatedFieldIter is used to iterate RepeatedField. It is also need for the
+ * foreach syntax.
+ */
+class RepeatedFieldIter implements \Iterator
+{
+
+    /**
+     * @ignore
+     */
+    private $position;
+    /**
+     * @ignore
+     */
+    private $container;
+
+    /**
+     * Create iterator instance for RepeatedField.
+     *
+     * @param RepeatedField The RepeatedField instance for which this iterator
+     * is created.
+     * @ignore
+     */
+    public function __construct($container)
+    {
+        $this->position = 0;
+        $this->container = $container;
+    }
+
+    /**
+     * Reset the status of the iterator
+     *
+     * @return void
+     */
+    public function rewind()
+    {
+        $this->position = 0;
+    }
+
+    /**
+     * Return the element at the current position.
+     *
+     * @return object The element at the current position.
+     */
+    public function current()
+    {
+        return $this->container[$this->position];
+    }
+
+    /**
+     * Return the current position.
+     *
+     * @return integer The current position.
+     */
+    public function key()
+    {
+        return $this->position;
+    }
+
+    /**
+     * Move to the next position.
+     *
+     * @return void
+     */
+    public function next()
+    {
+        ++$this->position;
+    }
+
+    /**
+     * Check whether there are more elements to iterate.
+     *
+     * @return bool True if there are more elements to iterate.
+     */
+    public function valid()
+    {
+        return isset($this->container[$this->position]);
+    }
+}
diff --git a/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php b/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php
index 4777620..da88e9c 100644
--- a/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php
+++ b/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php
@@ -8,30 +8,27 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * <pre>
  * Describes a service.
- * </pre>
  *
- * Protobuf type <code>google.protobuf.ServiceDescriptorProto</code>
+ * Generated from protobuf message <code>google.protobuf.ServiceDescriptorProto</code>
  */
 class ServiceDescriptorProto extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
      */
     private $name = '';
     private $has_name = false;
     /**
-     * <code>repeated .google.protobuf.MethodDescriptorProto method = 2;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.MethodDescriptorProto method = 2;</code>
      */
     private $method;
     private $has_method = false;
     /**
-     * <code>optional .google.protobuf.ServiceOptions options = 3;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.ServiceOptions options = 3;</code>
      */
     private $options = null;
     private $has_options = false;
@@ -42,7 +39,8 @@
     }
 
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
+     * @return string
      */
     public function getName()
     {
@@ -50,13 +48,17 @@
     }
 
     /**
-     * <code>optional string name = 1;</code>
+     * Generated from protobuf field <code>optional string name = 1;</code>
+     * @param string $var
+     * @return $this
      */
     public function setName($var)
     {
         GPBUtil::checkString($var, True);
         $this->name = $var;
         $this->has_name = true;
+
+        return $this;
     }
 
     public function hasName()
@@ -65,7 +67,8 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.MethodDescriptorProto method = 2;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.MethodDescriptorProto method = 2;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getMethod()
     {
@@ -73,13 +76,17 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.MethodDescriptorProto method = 2;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.MethodDescriptorProto method = 2;</code>
+     * @param \Google\Protobuf\Internal\MethodDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setMethod(&$var)
+    public function setMethod($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\MethodDescriptorProto::class);
         $this->method = $arr;
         $this->has_method = true;
+
+        return $this;
     }
 
     public function hasMethod()
@@ -88,7 +95,8 @@
     }
 
     /**
-     * <code>optional .google.protobuf.ServiceOptions options = 3;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.ServiceOptions options = 3;</code>
+     * @return \Google\Protobuf\Internal\ServiceOptions
      */
     public function getOptions()
     {
@@ -96,13 +104,17 @@
     }
 
     /**
-     * <code>optional .google.protobuf.ServiceOptions options = 3;</code>
+     * Generated from protobuf field <code>optional .google.protobuf.ServiceOptions options = 3;</code>
+     * @param \Google\Protobuf\Internal\ServiceOptions $var
+     * @return $this
      */
-    public function setOptions(&$var)
+    public function setOptions($var)
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\ServiceOptions::class);
         $this->options = $var;
         $this->has_options = true;
+
+        return $this;
     }
 
     public function hasOptions()
diff --git a/php/src/Google/Protobuf/Internal/ServiceOptions.php b/php/src/Google/Protobuf/Internal/ServiceOptions.php
index 62323db..3e7214a 100644
--- a/php/src/Google/Protobuf/Internal/ServiceOptions.php
+++ b/php/src/Google/Protobuf/Internal/ServiceOptions.php
@@ -8,32 +8,27 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * Protobuf type <code>google.protobuf.ServiceOptions</code>
+ * Generated from protobuf message <code>google.protobuf.ServiceOptions</code>
  */
 class ServiceOptions extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <pre>
      * Is this service deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for the service, or it will be completely ignored; in the very least,
      * this is a formalization for deprecating services.
-     * </pre>
      *
-     * <code>optional bool deprecated = 33 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 33 [default = false];</code>
      */
     private $deprecated = false;
     private $has_deprecated = false;
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
      */
     private $uninterpreted_option;
     private $has_uninterpreted_option = false;
@@ -44,14 +39,13 @@
     }
 
     /**
-     * <pre>
      * Is this service deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for the service, or it will be completely ignored; in the very least,
      * this is a formalization for deprecating services.
-     * </pre>
      *
-     * <code>optional bool deprecated = 33 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 33 [default = false];</code>
+     * @return bool
      */
     public function getDeprecated()
     {
@@ -59,20 +53,22 @@
     }
 
     /**
-     * <pre>
      * Is this service deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
      * for the service, or it will be completely ignored; in the very least,
      * this is a formalization for deprecating services.
-     * </pre>
      *
-     * <code>optional bool deprecated = 33 [default = false];</code>
+     * Generated from protobuf field <code>optional bool deprecated = 33 [default = false];</code>
+     * @param bool $var
+     * @return $this
      */
     public function setDeprecated($var)
     {
         GPBUtil::checkBool($var);
         $this->deprecated = $var;
         $this->has_deprecated = true;
+
+        return $this;
     }
 
     public function hasDeprecated()
@@ -81,11 +77,10 @@
     }
 
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getUninterpretedOption()
     {
@@ -93,17 +88,19 @@
     }
 
     /**
-     * <pre>
      * The parser stores options it doesn't recognize here. See above.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
+     * @param \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setUninterpretedOption(&$var)
+    public function setUninterpretedOption($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class);
         $this->uninterpreted_option = $arr;
         $this->has_uninterpreted_option = true;
+
+        return $this;
     }
 
     public function hasUninterpretedOption()
diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo.php
index eab6088..6ce05ed 100644
--- a/php/src/Google/Protobuf/Internal/SourceCodeInfo.php
+++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo.php
@@ -8,21 +8,17 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * <pre>
  * Encapsulates information about the original source file from which a
  * FileDescriptorProto was generated.
- * </pre>
  *
- * Protobuf type <code>google.protobuf.SourceCodeInfo</code>
+ * Generated from protobuf message <code>google.protobuf.SourceCodeInfo</code>
  */
 class SourceCodeInfo extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <pre>
      * A Location identifies a piece of source code in a .proto file which
      * corresponds to a particular definition.  This information is intended
      * to be useful to IDEs, code indexers, documentation generators, and similar
@@ -64,9 +60,8 @@
      * - Code which tries to interpret locations should probably be designed to
      *   ignore those that it doesn't understand, as more types of locations could
      *   be recorded in the future.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.SourceCodeInfo.Location location = 1;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.SourceCodeInfo.Location location = 1;</code>
      */
     private $location;
     private $has_location = false;
@@ -77,7 +72,6 @@
     }
 
     /**
-     * <pre>
      * A Location identifies a piece of source code in a .proto file which
      * corresponds to a particular definition.  This information is intended
      * to be useful to IDEs, code indexers, documentation generators, and similar
@@ -119,9 +113,9 @@
      * - Code which tries to interpret locations should probably be designed to
      *   ignore those that it doesn't understand, as more types of locations could
      *   be recorded in the future.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.SourceCodeInfo.Location location = 1;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.SourceCodeInfo.Location location = 1;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getLocation()
     {
@@ -129,7 +123,6 @@
     }
 
     /**
-     * <pre>
      * A Location identifies a piece of source code in a .proto file which
      * corresponds to a particular definition.  This information is intended
      * to be useful to IDEs, code indexers, documentation generators, and similar
@@ -171,15 +164,18 @@
      * - Code which tries to interpret locations should probably be designed to
      *   ignore those that it doesn't understand, as more types of locations could
      *   be recorded in the future.
-     * </pre>
      *
-     * <code>repeated .google.protobuf.SourceCodeInfo.Location location = 1;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.SourceCodeInfo.Location location = 1;</code>
+     * @param \Google\Protobuf\Internal\SourceCodeInfo_Location[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setLocation(&$var)
+    public function setLocation($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\SourceCodeInfo_Location::class);
         $this->location = $arr;
         $this->has_location = true;
+
+        return $this;
     }
 
     public function hasLocation()
diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php
index 5a02b26..19ed2bc 100644
--- a/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php
+++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php
@@ -8,16 +8,14 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * Protobuf type <code>google.protobuf.SourceCodeInfo.Location</code>
+ * Generated from protobuf message <code>google.protobuf.SourceCodeInfo.Location</code>
  */
 class SourceCodeInfo_Location extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <pre>
      * Identifies which part of the FileDescriptorProto was defined at this
      * location.
      * Each element is a field number or an index.  They form a path from
@@ -39,27 +37,23 @@
      *   [ 4, 3, 2, 7 ]
      * this path refers to the whole field declaration (from the beginning
      * of the label to the terminating semicolon).
-     * </pre>
      *
-     * <code>repeated int32 path = 1 [packed = true];</code>
+     * Generated from protobuf field <code>repeated int32 path = 1 [packed = true];</code>
      */
     private $path;
     private $has_path = false;
     /**
-     * <pre>
      * Always has exactly three or four elements: start line, start column,
      * end line (optional, otherwise assumed same as start line), end column.
      * These are packed into a single field for efficiency.  Note that line
      * and column numbers are zero-based -- typically you will want to add
      * 1 to each before displaying to a user.
-     * </pre>
      *
-     * <code>repeated int32 span = 2 [packed = true];</code>
+     * Generated from protobuf field <code>repeated int32 span = 2 [packed = true];</code>
      */
     private $span;
     private $has_span = false;
     /**
-     * <pre>
      * If this SourceCodeInfo represents a complete declaration, these are any
      * comments appearing before and after the declaration which appear to be
      * attached to the declaration.
@@ -96,19 +90,18 @@
      *    * grault. *&#47;
      *   optional int32 grault = 6;
      *   // ignored detached comments.
-     * </pre>
      *
-     * <code>optional string leading_comments = 3;</code>
+     * Generated from protobuf field <code>optional string leading_comments = 3;</code>
      */
     private $leading_comments = '';
     private $has_leading_comments = false;
     /**
-     * <code>optional string trailing_comments = 4;</code>
+     * Generated from protobuf field <code>optional string trailing_comments = 4;</code>
      */
     private $trailing_comments = '';
     private $has_trailing_comments = false;
     /**
-     * <code>repeated string leading_detached_comments = 6;</code>
+     * Generated from protobuf field <code>repeated string leading_detached_comments = 6;</code>
      */
     private $leading_detached_comments;
     private $has_leading_detached_comments = false;
@@ -119,7 +112,6 @@
     }
 
     /**
-     * <pre>
      * Identifies which part of the FileDescriptorProto was defined at this
      * location.
      * Each element is a field number or an index.  They form a path from
@@ -141,9 +133,9 @@
      *   [ 4, 3, 2, 7 ]
      * this path refers to the whole field declaration (from the beginning
      * of the label to the terminating semicolon).
-     * </pre>
      *
-     * <code>repeated int32 path = 1 [packed = true];</code>
+     * Generated from protobuf field <code>repeated int32 path = 1 [packed = true];</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getPath()
     {
@@ -151,7 +143,6 @@
     }
 
     /**
-     * <pre>
      * Identifies which part of the FileDescriptorProto was defined at this
      * location.
      * Each element is a field number or an index.  They form a path from
@@ -173,15 +164,18 @@
      *   [ 4, 3, 2, 7 ]
      * this path refers to the whole field declaration (from the beginning
      * of the label to the terminating semicolon).
-     * </pre>
      *
-     * <code>repeated int32 path = 1 [packed = true];</code>
+     * Generated from protobuf field <code>repeated int32 path = 1 [packed = true];</code>
+     * @param int[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setPath(&$var)
+    public function setPath($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
         $this->path = $arr;
         $this->has_path = true;
+
+        return $this;
     }
 
     public function hasPath()
@@ -190,15 +184,14 @@
     }
 
     /**
-     * <pre>
      * Always has exactly three or four elements: start line, start column,
      * end line (optional, otherwise assumed same as start line), end column.
      * These are packed into a single field for efficiency.  Note that line
      * and column numbers are zero-based -- typically you will want to add
      * 1 to each before displaying to a user.
-     * </pre>
      *
-     * <code>repeated int32 span = 2 [packed = true];</code>
+     * Generated from protobuf field <code>repeated int32 span = 2 [packed = true];</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getSpan()
     {
@@ -206,21 +199,23 @@
     }
 
     /**
-     * <pre>
      * Always has exactly three or four elements: start line, start column,
      * end line (optional, otherwise assumed same as start line), end column.
      * These are packed into a single field for efficiency.  Note that line
      * and column numbers are zero-based -- typically you will want to add
      * 1 to each before displaying to a user.
-     * </pre>
      *
-     * <code>repeated int32 span = 2 [packed = true];</code>
+     * Generated from protobuf field <code>repeated int32 span = 2 [packed = true];</code>
+     * @param int[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setSpan(&$var)
+    public function setSpan($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
         $this->span = $arr;
         $this->has_span = true;
+
+        return $this;
     }
 
     public function hasSpan()
@@ -229,7 +224,6 @@
     }
 
     /**
-     * <pre>
      * If this SourceCodeInfo represents a complete declaration, these are any
      * comments appearing before and after the declaration which appear to be
      * attached to the declaration.
@@ -266,9 +260,9 @@
      *    * grault. *&#47;
      *   optional int32 grault = 6;
      *   // ignored detached comments.
-     * </pre>
      *
-     * <code>optional string leading_comments = 3;</code>
+     * Generated from protobuf field <code>optional string leading_comments = 3;</code>
+     * @return string
      */
     public function getLeadingComments()
     {
@@ -276,7 +270,6 @@
     }
 
     /**
-     * <pre>
      * If this SourceCodeInfo represents a complete declaration, these are any
      * comments appearing before and after the declaration which appear to be
      * attached to the declaration.
@@ -313,15 +306,18 @@
      *    * grault. *&#47;
      *   optional int32 grault = 6;
      *   // ignored detached comments.
-     * </pre>
      *
-     * <code>optional string leading_comments = 3;</code>
+     * Generated from protobuf field <code>optional string leading_comments = 3;</code>
+     * @param string $var
+     * @return $this
      */
     public function setLeadingComments($var)
     {
         GPBUtil::checkString($var, True);
         $this->leading_comments = $var;
         $this->has_leading_comments = true;
+
+        return $this;
     }
 
     public function hasLeadingComments()
@@ -330,7 +326,8 @@
     }
 
     /**
-     * <code>optional string trailing_comments = 4;</code>
+     * Generated from protobuf field <code>optional string trailing_comments = 4;</code>
+     * @return string
      */
     public function getTrailingComments()
     {
@@ -338,13 +335,17 @@
     }
 
     /**
-     * <code>optional string trailing_comments = 4;</code>
+     * Generated from protobuf field <code>optional string trailing_comments = 4;</code>
+     * @param string $var
+     * @return $this
      */
     public function setTrailingComments($var)
     {
         GPBUtil::checkString($var, True);
         $this->trailing_comments = $var;
         $this->has_trailing_comments = true;
+
+        return $this;
     }
 
     public function hasTrailingComments()
@@ -353,7 +354,8 @@
     }
 
     /**
-     * <code>repeated string leading_detached_comments = 6;</code>
+     * Generated from protobuf field <code>repeated string leading_detached_comments = 6;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getLeadingDetachedComments()
     {
@@ -361,13 +363,17 @@
     }
 
     /**
-     * <code>repeated string leading_detached_comments = 6;</code>
+     * Generated from protobuf field <code>repeated string leading_detached_comments = 6;</code>
+     * @param string[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setLeadingDetachedComments(&$var)
+    public function setLeadingDetachedComments($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING);
         $this->leading_detached_comments = $arr;
         $this->has_leading_detached_comments = true;
+
+        return $this;
     }
 
     public function hasLeadingDetachedComments()
diff --git a/php/src/Google/Protobuf/Internal/UninterpretedOption.php b/php/src/Google/Protobuf/Internal/UninterpretedOption.php
index 2865501..4d342eb 100644
--- a/php/src/Google/Protobuf/Internal/UninterpretedOption.php
+++ b/php/src/Google/Protobuf/Internal/UninterpretedOption.php
@@ -8,60 +8,55 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * <pre>
  * A message representing a option the parser does not recognize. This only
  * appears in options protos created by the compiler::Parser class.
  * DescriptorPool resolves these when building Descriptor objects. Therefore,
  * options protos in descriptor objects (e.g. returned by Descriptor::options(),
  * or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
  * in them.
- * </pre>
  *
- * Protobuf type <code>google.protobuf.UninterpretedOption</code>
+ * Generated from protobuf message <code>google.protobuf.UninterpretedOption</code>
  */
 class UninterpretedOption extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <code>repeated .google.protobuf.UninterpretedOption.NamePart name = 2;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption.NamePart name = 2;</code>
      */
     private $name;
     private $has_name = false;
     /**
-     * <pre>
      * The value of the uninterpreted option, in whatever type the tokenizer
      * identified it as during parsing. Exactly one of these should be set.
-     * </pre>
      *
-     * <code>optional string identifier_value = 3;</code>
+     * Generated from protobuf field <code>optional string identifier_value = 3;</code>
      */
     private $identifier_value = '';
     private $has_identifier_value = false;
     /**
-     * <code>optional uint64 positive_int_value = 4;</code>
+     * Generated from protobuf field <code>optional uint64 positive_int_value = 4;</code>
      */
     private $positive_int_value = 0;
     private $has_positive_int_value = false;
     /**
-     * <code>optional int64 negative_int_value = 5;</code>
+     * Generated from protobuf field <code>optional int64 negative_int_value = 5;</code>
      */
     private $negative_int_value = 0;
     private $has_negative_int_value = false;
     /**
-     * <code>optional double double_value = 6;</code>
+     * Generated from protobuf field <code>optional double double_value = 6;</code>
      */
     private $double_value = 0.0;
     private $has_double_value = false;
     /**
-     * <code>optional bytes string_value = 7;</code>
+     * Generated from protobuf field <code>optional bytes string_value = 7;</code>
      */
     private $string_value = '';
     private $has_string_value = false;
     /**
-     * <code>optional string aggregate_value = 8;</code>
+     * Generated from protobuf field <code>optional string aggregate_value = 8;</code>
      */
     private $aggregate_value = '';
     private $has_aggregate_value = false;
@@ -72,7 +67,8 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.UninterpretedOption.NamePart name = 2;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption.NamePart name = 2;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
      */
     public function getName()
     {
@@ -80,13 +76,17 @@
     }
 
     /**
-     * <code>repeated .google.protobuf.UninterpretedOption.NamePart name = 2;</code>
+     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption.NamePart name = 2;</code>
+     * @param \Google\Protobuf\Internal\UninterpretedOption_NamePart[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
      */
-    public function setName(&$var)
+    public function setName($var)
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption_NamePart::class);
         $this->name = $arr;
         $this->has_name = true;
+
+        return $this;
     }
 
     public function hasName()
@@ -95,12 +95,11 @@
     }
 
     /**
-     * <pre>
      * The value of the uninterpreted option, in whatever type the tokenizer
      * identified it as during parsing. Exactly one of these should be set.
-     * </pre>
      *
-     * <code>optional string identifier_value = 3;</code>
+     * Generated from protobuf field <code>optional string identifier_value = 3;</code>
+     * @return string
      */
     public function getIdentifierValue()
     {
@@ -108,18 +107,20 @@
     }
 
     /**
-     * <pre>
      * The value of the uninterpreted option, in whatever type the tokenizer
      * identified it as during parsing. Exactly one of these should be set.
-     * </pre>
      *
-     * <code>optional string identifier_value = 3;</code>
+     * Generated from protobuf field <code>optional string identifier_value = 3;</code>
+     * @param string $var
+     * @return $this
      */
     public function setIdentifierValue($var)
     {
         GPBUtil::checkString($var, True);
         $this->identifier_value = $var;
         $this->has_identifier_value = true;
+
+        return $this;
     }
 
     public function hasIdentifierValue()
@@ -128,7 +129,8 @@
     }
 
     /**
-     * <code>optional uint64 positive_int_value = 4;</code>
+     * Generated from protobuf field <code>optional uint64 positive_int_value = 4;</code>
+     * @return int|string
      */
     public function getPositiveIntValue()
     {
@@ -136,13 +138,17 @@
     }
 
     /**
-     * <code>optional uint64 positive_int_value = 4;</code>
+     * Generated from protobuf field <code>optional uint64 positive_int_value = 4;</code>
+     * @param int|string $var
+     * @return $this
      */
     public function setPositiveIntValue($var)
     {
         GPBUtil::checkUint64($var);
         $this->positive_int_value = $var;
         $this->has_positive_int_value = true;
+
+        return $this;
     }
 
     public function hasPositiveIntValue()
@@ -151,7 +157,8 @@
     }
 
     /**
-     * <code>optional int64 negative_int_value = 5;</code>
+     * Generated from protobuf field <code>optional int64 negative_int_value = 5;</code>
+     * @return int|string
      */
     public function getNegativeIntValue()
     {
@@ -159,13 +166,17 @@
     }
 
     /**
-     * <code>optional int64 negative_int_value = 5;</code>
+     * Generated from protobuf field <code>optional int64 negative_int_value = 5;</code>
+     * @param int|string $var
+     * @return $this
      */
     public function setNegativeIntValue($var)
     {
         GPBUtil::checkInt64($var);
         $this->negative_int_value = $var;
         $this->has_negative_int_value = true;
+
+        return $this;
     }
 
     public function hasNegativeIntValue()
@@ -174,7 +185,8 @@
     }
 
     /**
-     * <code>optional double double_value = 6;</code>
+     * Generated from protobuf field <code>optional double double_value = 6;</code>
+     * @return float
      */
     public function getDoubleValue()
     {
@@ -182,13 +194,17 @@
     }
 
     /**
-     * <code>optional double double_value = 6;</code>
+     * Generated from protobuf field <code>optional double double_value = 6;</code>
+     * @param float $var
+     * @return $this
      */
     public function setDoubleValue($var)
     {
         GPBUtil::checkDouble($var);
         $this->double_value = $var;
         $this->has_double_value = true;
+
+        return $this;
     }
 
     public function hasDoubleValue()
@@ -197,7 +213,8 @@
     }
 
     /**
-     * <code>optional bytes string_value = 7;</code>
+     * Generated from protobuf field <code>optional bytes string_value = 7;</code>
+     * @return string
      */
     public function getStringValue()
     {
@@ -205,13 +222,17 @@
     }
 
     /**
-     * <code>optional bytes string_value = 7;</code>
+     * Generated from protobuf field <code>optional bytes string_value = 7;</code>
+     * @param string $var
+     * @return $this
      */
     public function setStringValue($var)
     {
         GPBUtil::checkString($var, False);
         $this->string_value = $var;
         $this->has_string_value = true;
+
+        return $this;
     }
 
     public function hasStringValue()
@@ -220,7 +241,8 @@
     }
 
     /**
-     * <code>optional string aggregate_value = 8;</code>
+     * Generated from protobuf field <code>optional string aggregate_value = 8;</code>
+     * @return string
      */
     public function getAggregateValue()
     {
@@ -228,13 +250,17 @@
     }
 
     /**
-     * <code>optional string aggregate_value = 8;</code>
+     * Generated from protobuf field <code>optional string aggregate_value = 8;</code>
+     * @param string $var
+     * @return $this
      */
     public function setAggregateValue($var)
     {
         GPBUtil::checkString($var, True);
         $this->aggregate_value = $var;
         $this->has_aggregate_value = true;
+
+        return $this;
     }
 
     public function hasAggregateValue()
diff --git a/php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php b/php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php
index 86484d2..c9a6fc3 100644
--- a/php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php
+++ b/php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php
@@ -8,29 +8,26 @@
 use Google\Protobuf\Internal\GPBWire;
 use Google\Protobuf\Internal\RepeatedField;
 use Google\Protobuf\Internal\InputStream;
-
 use Google\Protobuf\Internal\GPBUtil;
 
 /**
- * <pre>
  * The name of the uninterpreted option.  Each string represents a segment in
  * a dot-separated name.  is_extension is true iff a segment represents an
  * extension (denoted with parentheses in options specs in .proto files).
  * E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
  * "foo.(bar.baz).qux".
- * </pre>
  *
- * Protobuf type <code>google.protobuf.UninterpretedOption.NamePart</code>
+ * Generated from protobuf message <code>google.protobuf.UninterpretedOption.NamePart</code>
  */
 class UninterpretedOption_NamePart extends \Google\Protobuf\Internal\Message
 {
     /**
-     * <code>required string name_part = 1;</code>
+     * Generated from protobuf field <code>required string name_part = 1;</code>
      */
     private $name_part = '';
     private $has_name_part = false;
     /**
-     * <code>required bool is_extension = 2;</code>
+     * Generated from protobuf field <code>required bool is_extension = 2;</code>
      */
     private $is_extension = false;
     private $has_is_extension = false;
@@ -41,7 +38,8 @@
     }
 
     /**
-     * <code>required string name_part = 1;</code>
+     * Generated from protobuf field <code>required string name_part = 1;</code>
+     * @return string
      */
     public function getNamePart()
     {
@@ -49,13 +47,17 @@
     }
 
     /**
-     * <code>required string name_part = 1;</code>
+     * Generated from protobuf field <code>required string name_part = 1;</code>
+     * @param string $var
+     * @return $this
      */
     public function setNamePart($var)
     {
         GPBUtil::checkString($var, True);
         $this->name_part = $var;
         $this->has_name_part = true;
+
+        return $this;
     }
 
     public function hasNamePart()
@@ -64,7 +66,8 @@
     }
 
     /**
-     * <code>required bool is_extension = 2;</code>
+     * Generated from protobuf field <code>required bool is_extension = 2;</code>
+     * @return bool
      */
     public function getIsExtension()
     {
@@ -72,13 +75,17 @@
     }
 
     /**
-     * <code>required bool is_extension = 2;</code>
+     * Generated from protobuf field <code>required bool is_extension = 2;</code>
+     * @param bool $var
+     * @return $this
      */
     public function setIsExtension($var)
     {
         GPBUtil::checkBool($var);
         $this->is_extension = $var;
         $this->has_is_extension = true;
+
+        return $this;
     }
 
     public function hasIsExtension()
diff --git a/php/src/Google/Protobuf/descriptor.php b/php/src/Google/Protobuf/descriptor.php
deleted file mode 100644
index fb69eda..0000000
--- a/php/src/Google/Protobuf/descriptor.php
+++ /dev/null
@@ -1,587 +0,0 @@
-<?php
-
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-namespace Google\Protobuf\Internal;
-
-use Google\Protobuf\Internal\GPBType;
-use Google\Protobuf\Internal\MessageOptions;
-
-class FileDescriptor
-{
-
-    private $package;
-    private $message_type = [];
-    private $enum_type = [];
-
-    public function setPackage($package)
-    {
-        $this->package = $package;
-    }
-
-    public function getPackage()
-    {
-        return $this->package;
-    }
-
-    public function getMessageType()
-    {
-        return $this->message_type;
-    }
-
-    public function addMessageType($desc)
-    {
-        $this->message_type[] = $desc;
-    }
-
-    public function getEnumType()
-    {
-        return $this->enum_type;
-    }
-
-    public function addEnumType($desc)
-    {
-        $this->enum_type[]= $desc;
-    }
-
-    public static function buildFromProto($proto)
-    {
-        $file = new FileDescriptor();
-        $file->setPackage($proto->getPackage());
-        foreach ($proto->getMessageType() as $message_proto) {
-            $file->addMessageType(Descriptor::buildFromProto(
-                $message_proto, $proto, ""));
-        }
-        foreach ($proto->getEnumType() as $enum_proto) {
-            $file->getEnumType()[] =
-                $file->addEnumType(
-                    EnumDescriptor::buildFromProto(
-                        $enum_proto,
-                        $proto,
-                        ""));
-        }
-        return $file;
-    }
-}
-
-class Descriptor
-{
-
-    private $full_name;
-    private $field = [];
-    private $nested_type = [];
-    private $enum_type = [];
-    private $klass;
-    private $options;
-    private $oneof_decl = [];
-
-    public function addOneofDecl($oneof)
-    {
-        $this->oneof_decl[] = $oneof;
-    }
-
-    public function getOneofDecl()
-    {
-        return $this->oneof_decl;
-    }
-
-    public function setFullName($full_name)
-    {
-        $this->full_name = $full_name;
-    }
-
-    public function getFullName()
-    {
-        return $this->full_name;
-    }
-
-    public function addField($field)
-    {
-        $this->field[$field->getNumber()] = $field;
-    }
-
-    public function getField()
-    {
-        return $this->field;
-    }
-
-    public function addNestedType($desc)
-    {
-        $this->nested_type[] = $desc;
-    }
-
-    public function getNestedType()
-    {
-        return $this->nested_type;
-    }
-
-    public function addEnumType($desc)
-    {
-        $this->enum_type[] = $desc;
-    }
-
-    public function getEnumType()
-    {
-        return $this->enum_type;
-    }
-
-    public function getFieldByNumber($number)
-    {
-      if (!isset($this->field[$number])) {
-        return NULL;
-      } else {
-        return $this->field[$number];
-      }
-    }
-
-    public function setClass($klass)
-    {
-        $this->klass = $klass;
-    }
-
-    public function getClass()
-    {
-        return $this->klass;
-    }
-
-    public function setOptions($options)
-    {
-        $this->options = $options;
-    }
-
-    public function getOptions()
-    {
-        return $this->options;
-    }
-
-    public static function buildFromProto($proto, $file_proto, $containing)
-    {
-        $desc = new Descriptor();
-
-        $message_name_without_package  = "";
-        $classname = "";
-        $fullname = "";
-        getFullClassName(
-            $proto,
-            $containing,
-            $file_proto,
-            $message_name_without_package,
-            $classname,
-            $fullname);
-        $desc->setFullName($fullname);
-        $desc->setClass($classname);
-        $desc->setOptions($proto->getOptions());
-
-        foreach ($proto->getField() as $field_proto) {
-            $desc->addField(FieldDescriptor::buildFromProto($field_proto));
-        }
-
-        // Handle nested types.
-        foreach ($proto->getNestedType() as $nested_proto) {
-            $desc->addNestedType(Descriptor::buildFromProto(
-              $nested_proto, $file_proto, $message_name_without_package));
-        }
-
-        // Handle nested enum.
-        foreach ($proto->getEnumType() as $enum_proto) {
-            $desc->addEnumType(EnumDescriptor::buildFromProto(
-              $enum_proto, $file_proto, $message_name_without_package));
-        }
-
-        // Handle oneof fields.
-        foreach ($proto->getOneofDecl() as $oneof_proto) {
-            $desc->addOneofDecl(
-                OneofDescriptor::buildFromProto($oneof_proto, $desc));
-        }
-
-        return $desc;
-    }
-}
-
-function getClassNamePrefix(
-    $classname,
-    $file_proto)
-{
-    $option = $file_proto->getOptions();
-    $prefix = is_null($option) ? "" : $option->getPhpClassPrefix();
-    if ($prefix !== "") {
-        return $prefix;
-    }
-
-    $reserved_words = array("Empty");
-    foreach ($reserved_words as $reserved_word) {
-        if ($classname === $reserved_word) {
-            if ($file_proto->getPackage() === "google.protobuf") {
-                return "GPB";
-            } else {
-                return "PB";
-            }
-        }
-    }
-
-    return "";
-}
-
-function getClassNameWithoutPackage(
-    $name,
-    $file_proto)
-{
-    $classname = implode('_', array_map('ucwords', explode('.', $name)));
-    return getClassNamePrefix($classname, $file_proto) . $classname;
-}
-
-function getFullClassName(
-    $proto,
-    $containing,
-    $file_proto,
-    &$message_name_without_package,
-    &$classname,
-    &$fullname)
-{
-    // Full name needs to start with '.'.
-    $message_name_without_package = $proto->getName();
-    if ($containing !== "") {
-        $message_name_without_package =
-            $containing . "." . $message_name_without_package;
-    }
-
-    $package = $file_proto->getPackage();
-    if ($package === "") {
-        $fullname = "." . $message_name_without_package;
-    } else {
-        $fullname = "." . $package . "." . $message_name_without_package;
-    }
-
-    $class_name_without_package =
-        getClassNameWithoutPackage($message_name_without_package, $file_proto);
-    if ($package === "") {
-        $classname = $class_name_without_package;
-    } else {
-        $classname =
-            implode('\\', array_map('ucwords', explode('.', $package))).
-            "\\".$class_name_without_package;
-    }
-}
-
-class OneofDescriptor
-{
-
-    private $name;
-    private $fields;
-
-    public function setName($name)
-    {
-        $this->name = $name;
-    }
-
-    public function getName()
-    {
-        return $this->name;
-    }
-
-    public function addField(&$field)
-    {
-        $this->fields[] = $field;
-    }
-
-    public function getFields()
-    {
-        return $this->fields;
-    }
-
-    public static function buildFromProto($oneof_proto)
-    {
-        $oneof = new OneofDescriptor();
-        $oneof->setName($oneof_proto->getName());
-        return $oneof;
-    }
-}
-
-
-class EnumDescriptor
-{
-
-    private $klass;
-    private $full_name;
-    private $value;
-
-    public function setFullName($full_name)
-    {
-        $this->full_name = $full_name;
-    }
-
-    public function getFullName()
-    {
-        return $this->full_name;
-    }
-
-    public function addValue($number, $value)
-    {
-        $this->value[$number] = $value;
-    }
-
-    public function setClass($klass)
-    {
-        $this->klass = $klass;
-    }
-
-    public function getClass()
-    {
-        return $this->klass;
-    }
-
-    public static function buildFromProto($proto, $file_proto, $containing)
-    {
-        $desc = new EnumDescriptor();
-
-        $enum_name_without_package  = "";
-        $classname = "";
-        $fullname = "";
-        getFullClassName(
-            $proto,
-            $containing,
-            $file_proto,
-            $enum_name_without_package,
-            $classname,
-            $fullname);
-        $desc->setFullName($fullname);
-        $desc->setClass($classname);
-
-        return $desc;
-    }
-}
-
-class EnumValueDescriptor
-{
-}
-
-class FieldDescriptor
-{
-
-    private $name;
-    private $setter;
-    private $getter;
-    private $number;
-    private $label;
-    private $type;
-    private $message_type;
-    private $enum_type;
-    private $packed;
-    private $is_map;
-    private $oneof_index = -1;
-
-    public function setOneofIndex($index)
-    {
-        $this->oneof_index = $index;
-    }
-
-    public function getOneofIndex()
-    {
-        return $this->oneof_index;
-    }
-
-    public function setName($name)
-    {
-        $this->name = $name;
-    }
-
-    public function getName()
-    {
-        return $this->name;
-    }
-
-    public function setSetter($setter)
-    {
-        $this->setter = $setter;
-    }
-
-    public function getSetter()
-    {
-        return $this->setter;
-    }
-
-    public function setGetter($getter)
-    {
-        $this->getter = $getter;
-    }
-
-    public function getGetter()
-    {
-        return $this->getter;
-    }
-
-    public function setNumber($number)
-    {
-        $this->number = $number;
-    }
-
-    public function getNumber()
-    {
-        return $this->number;
-    }
-
-    public function setLabel($label)
-    {
-        $this->label = $label;
-    }
-
-    public function getLabel()
-    {
-        return $this->label;
-    }
-
-    public function isRepeated()
-    {
-        return $this->label === GPBLabel::REPEATED;
-    }
-
-    public function setType($type)
-    {
-        $this->type = $type;
-    }
-
-    public function getType()
-    {
-        return $this->type;
-    }
-
-    public function setMessageType($message_type)
-    {
-        $this->message_type = $message_type;
-    }
-
-    public function getMessageType()
-    {
-        return $this->message_type;
-    }
-
-    public function setEnumType($enum_type)
-    {
-        $this->enum_type = $enum_type;
-    }
-
-    public function getEnumType()
-    {
-        return $this->enum_type;
-    }
-
-    public function setPacked($packed)
-    {
-        $this->packed = $packed;
-    }
-
-    public function getPacked()
-    {
-        return $this->packed;
-    }
-
-    public function isPackable()
-    {
-        return $this->isRepeated() && self::isTypePackable($this->type);
-    }
-
-    public function isMap()
-    {
-        return $this->getType() == GPBType::MESSAGE &&
-               !is_null($this->getMessageType()->getOptions()) &&
-               $this->getMessageType()->getOptions()->getMapEntry();
-    }
-
-    private static function isTypePackable($field_type)
-    {
-        return ($field_type !== GPBType::STRING  &&
-            $field_type !== GPBType::GROUP   &&
-            $field_type !== GPBType::MESSAGE &&
-            $field_type !== GPBType::BYTES);
-    }
-
-    public static function getFieldDescriptor(
-        $name,
-        $label,
-        $type,
-        $number,
-        $oneof_index,
-        $packed,
-        $type_name = null)
-    {
-        $field = new FieldDescriptor();
-        $field->setName($name);
-        $camel_name = implode('', array_map('ucwords', explode('_', $name)));
-        $field->setGetter('get' . $camel_name);
-        $field->setSetter('set' . $camel_name);
-        $field->setType($type);
-        $field->setNumber($number);
-        $field->setLabel($label);
-        $field->setPacked($packed);
-        $field->setOneofIndex($oneof_index);
-
-        // At this time, the message/enum type may have not been added to pool.
-        // So we use the type name as place holder and will replace it with the
-        // actual descriptor in cross building.
-        switch ($type) {
-            case GPBType::MESSAGE:
-                $field->setMessageType($type_name);
-                break;
-            case GPBType::ENUM:
-                $field->setEnumType($type_name);
-                break;
-            default:
-                break;
-        }
-
-        return $field;
-    }
-
-    public static function buildFromProto($proto)
-    {
-        $type_name = null;
-        switch ($proto->getType()) {
-            case GPBType::MESSAGE:
-            case GPBType::GROUP:
-            case GPBType::ENUM:
-                $type_name = $proto->getTypeName();
-                break;
-            default:
-                break;
-        }
-
-        $oneof_index = $proto->hasOneofIndex() ? $proto->getOneofIndex() : -1;
-        $packed = false;
-        $options = $proto->getOptions();
-        if ($options !== null) {
-            $packed = $options->getPacked();
-        }
-
-        return FieldDescriptor::getFieldDescriptor(
-            $proto->getName(), $proto->getLabel(), $proto->getType(),
-            $proto->getNumber(), $oneof_index, $packed, $type_name);
-    }
-}
diff --git a/php/tests/array_test.php b/php/tests/array_test.php
index b55408d..e57f0a7 100644
--- a/php/tests/array_test.php
+++ b/php/tests/array_test.php
@@ -19,23 +19,23 @@
         $arr = new RepeatedField(GPBType::INT32);
 
         // Test append.
-        $arr []= MAX_INT32;
+        $arr[] = MAX_INT32;
         $this->assertSame(MAX_INT32, $arr[0]);
-        $arr []= MIN_INT32;
+        $arr[] = MIN_INT32;
         $this->assertSame(MIN_INT32, $arr[1]);
 
-        $arr []= 1.1;
+        $arr[] = 1.1;
         $this->assertSame(1, $arr[2]);
-        $arr []= MAX_INT32_FLOAT;
+        $arr[] = MAX_INT32_FLOAT;
         $this->assertSame(MAX_INT32, $arr[3]);
-        $arr []= MAX_INT32_FLOAT;
+        $arr[] = MAX_INT32_FLOAT;
         $this->assertSame(MAX_INT32, $arr[4]);
 
-        $arr []= '2';
+        $arr[] = '2';
         $this->assertSame(2, $arr[5]);
-        $arr []= '3.1';
+        $arr[] = '3.1';
         $this->assertSame(3, $arr[6]);
-        $arr []= MAX_INT32_STRING;
+        $arr[] = MAX_INT32_STRING;
         $this->assertSame(MAX_INT32, $arr[7]);
 
         $this->assertEquals(8, count($arr));
@@ -46,29 +46,29 @@
         }
 
         // Test set.
-        $arr [0]= MAX_INT32;
+        $arr[0] = MAX_INT32;
         $this->assertSame(MAX_INT32, $arr[0]);
-        $arr [1]= MIN_INT32;
+        $arr[1] = MIN_INT32;
         $this->assertSame(MIN_INT32, $arr[1]);
 
-        $arr [2]= 1.1;
+        $arr[2] = 1.1;
         $this->assertSame(1, $arr[2]);
-        $arr [3]= MAX_INT32_FLOAT;
+        $arr[3] = MAX_INT32_FLOAT;
         $this->assertSame(MAX_INT32, $arr[3]);
-        $arr [4]= MAX_INT32_FLOAT;
+        $arr[4] = MAX_INT32_FLOAT;
         $this->assertSame(MAX_INT32, $arr[4]);
 
-        $arr [5]= '2';
+        $arr[5] = '2';
         $this->assertSame(2, $arr[5]);
-        $arr [6]= '3.1';
+        $arr[6] = '3.1';
         $this->assertSame(3, $arr[6]);
-        $arr [7]= MAX_INT32_STRING;
+        $arr[7] = MAX_INT32_STRING;
         $this->assertSame(MAX_INT32, $arr[7]);
 
         // Test foreach.
         $arr = new RepeatedField(GPBType::INT32);
         for ($i = 0; $i < 3; $i++) {
-          $arr []= $i;
+          $arr[] = $i;
         }
         $i = 0;
         foreach ($arr as $val) {
@@ -77,44 +77,6 @@
         $this->assertSame(3, $i);
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt32AppendStringFail()
-    {
-        $arr = new RepeatedField(GPBType::INT32);
-        $arr []= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt32SetStringFail()
-    {
-        $arr = new RepeatedField(GPBType::INT32);
-        $arr []= 0;
-        $arr [0]= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt32AppendMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::INT32);
-        $arr []= new TestMessage_Sub();
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt32SetMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::INT32);
-        $arr []= 0;
-        $arr [0]= new TestMessage_Sub();
-    }
-
     #########################################################
     # Test uint32 field.
     #########################################################
@@ -124,31 +86,31 @@
         $arr = new RepeatedField(GPBType::UINT32);
 
         // Test append.
-        $arr []= MAX_UINT32;
+        $arr[] = MAX_UINT32;
         $this->assertSame(-1, $arr[0]);
-        $arr []= -1;
+        $arr[] = -1;
         $this->assertSame(-1, $arr[1]);
-        $arr []= MIN_UINT32;
+        $arr[] = MIN_UINT32;
         $this->assertSame(MIN_UINT32, $arr[2]);
 
-        $arr []= 1.1;
+        $arr[] = 1.1;
         $this->assertSame(1, $arr[3]);
-        $arr []= MAX_UINT32_FLOAT;
+        $arr[] = MAX_UINT32_FLOAT;
         $this->assertSame(-1, $arr[4]);
-        $arr []= -1.0;
+        $arr[] = -1.0;
         $this->assertSame(-1, $arr[5]);
-        $arr []= MIN_UINT32_FLOAT;
+        $arr[] = MIN_UINT32_FLOAT;
         $this->assertSame(MIN_UINT32, $arr[6]);
 
-        $arr []= '2';
+        $arr[] = '2';
         $this->assertSame(2, $arr[7]);
-        $arr []= '3.1';
+        $arr[] = '3.1';
         $this->assertSame(3, $arr[8]);
-        $arr []= MAX_UINT32_STRING;
+        $arr[] = MAX_UINT32_STRING;
         $this->assertSame(-1, $arr[9]);
-        $arr []= '-1.0';
+        $arr[] = '-1.0';
         $this->assertSame(-1, $arr[10]);
-        $arr []= MIN_UINT32_STRING;
+        $arr[] = MIN_UINT32_STRING;
         $this->assertSame(MIN_UINT32, $arr[11]);
 
         $this->assertEquals(12, count($arr));
@@ -159,72 +121,34 @@
         }
 
         // Test set.
-        $arr [0]= MAX_UINT32;
+        $arr[0] = MAX_UINT32;
         $this->assertSame(-1, $arr[0]);
-        $arr [1]= -1;
+        $arr[1] = -1;
         $this->assertSame(-1, $arr[1]);
-        $arr [2]= MIN_UINT32;
+        $arr[2] = MIN_UINT32;
         $this->assertSame(MIN_UINT32, $arr[2]);
 
-        $arr [3]= 1.1;
+        $arr[3] = 1.1;
         $this->assertSame(1, $arr[3]);
-        $arr [4]= MAX_UINT32_FLOAT;
+        $arr[4] = MAX_UINT32_FLOAT;
         $this->assertSame(-1, $arr[4]);
-        $arr [5]= -1.0;
+        $arr[5] = -1.0;
         $this->assertSame(-1, $arr[5]);
-        $arr [6]= MIN_UINT32_FLOAT;
+        $arr[6] = MIN_UINT32_FLOAT;
         $this->assertSame(MIN_UINT32, $arr[6]);
 
-        $arr [7]= '2';
+        $arr[7] = '2';
         $this->assertSame(2, $arr[7]);
-        $arr [8]= '3.1';
+        $arr[8] = '3.1';
         $this->assertSame(3, $arr[8]);
-        $arr [9]= MAX_UINT32_STRING;
+        $arr[9] = MAX_UINT32_STRING;
         $this->assertSame(-1, $arr[9]);
-        $arr [10]= '-1.0';
+        $arr[10] = '-1.0';
         $this->assertSame(-1, $arr[10]);
-        $arr [11]= MIN_UINT32_STRING;
+        $arr[11] = MIN_UINT32_STRING;
         $this->assertSame(MIN_UINT32, $arr[11]);
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint32AppendStringFail()
-    {
-        $arr = new RepeatedField(GPBType::UINT32);
-        $arr []= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint32SetStringFail()
-    {
-        $arr = new RepeatedField(GPBType::UINT32);
-        $arr []= 0;
-        $arr [0]= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint32AppendMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::UINT32);
-        $arr []= new TestMessage_Sub();
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint32SetMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::UINT32);
-        $arr []= 0;
-        $arr [0]= new TestMessage_Sub();
-    }
-
     #########################################################
     # Test int64 field.
     #########################################################
@@ -234,13 +158,13 @@
         $arr = new RepeatedField(GPBType::INT64);
 
         // Test append.
-        $arr []= MAX_INT64;
-        $arr []= MIN_INT64;
-        $arr []= 1.1;
-        $arr []= '2';
-        $arr []= '3.1';
-        $arr []= MAX_INT64_STRING;
-        $arr []= MIN_INT64_STRING;
+        $arr[] = MAX_INT64;
+        $arr[] = MIN_INT64;
+        $arr[] = 1.1;
+        $arr[] = '2';
+        $arr[] = '3.1';
+        $arr[] = MAX_INT64_STRING;
+        $arr[] = MIN_INT64_STRING;
         if (PHP_INT_SIZE == 4) {
             $this->assertSame(MAX_INT64, $arr[0]);
             $this->assertSame(MIN_INT64, $arr[1]);
@@ -272,13 +196,13 @@
         }
 
         // Test set.
-        $arr [0]= MAX_INT64;
-        $arr [1]= MIN_INT64;
-        $arr [2]= 1.1;
-        $arr [3]= '2';
-        $arr [4]= '3.1';
-        $arr [5]= MAX_INT64_STRING;
-        $arr [6]= MIN_INT64_STRING;
+        $arr[0] = MAX_INT64;
+        $arr[1] = MIN_INT64;
+        $arr[2] = 1.1;
+        $arr[3] = '2';
+        $arr[4] = '3.1';
+        $arr[5] = MAX_INT64_STRING;
+        $arr[6] = MIN_INT64_STRING;
 
         if (PHP_INT_SIZE == 4) {
             $this->assertSame(MAX_INT64_STRING, $arr[0]);
@@ -299,44 +223,6 @@
         }
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt64AppendStringFail()
-    {
-        $arr = new RepeatedField(GPBType::INT64);
-        $arr []= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt64SetStringFail()
-    {
-        $arr = new RepeatedField(GPBType::INT64);
-        $arr []= 0;
-        $arr [0]= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt64AppendMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::INT64);
-        $arr []= new TestMessage_Sub();
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt64SetMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::INT64);
-        $arr []= 0;
-        $arr [0]= new TestMessage_Sub();
-    }
-
     #########################################################
     # Test uint64 field.
     #########################################################
@@ -346,11 +232,11 @@
         $arr = new RepeatedField(GPBType::UINT64);
 
         // Test append.
-        $arr []= MAX_UINT64;
-        $arr []= 1.1;
-        $arr []= '2';
-        $arr []= '3.1';
-        $arr []= MAX_UINT64_STRING;
+        $arr[] = MAX_UINT64;
+        $arr[] = 1.1;
+        $arr[] = '2';
+        $arr[] = '3.1';
+        $arr[] = MAX_UINT64_STRING;
 
         if (PHP_INT_SIZE == 4) {
             $this->assertSame(MAX_UINT64_STRING, $arr[0]);
@@ -379,11 +265,11 @@
         }
 
         // Test set.
-        $arr [0]= MAX_UINT64;
-        $arr [1]= 1.1;
-        $arr [2]= '2';
-        $arr [3]= '3.1';
-        $arr [4]= MAX_UINT64_STRING;
+        $arr[0] = MAX_UINT64;
+        $arr[1] = 1.1;
+        $arr[2] = '2';
+        $arr[3] = '3.1';
+        $arr[4] = MAX_UINT64_STRING;
 
         if (PHP_INT_SIZE == 4) {
             $this->assertSame(MAX_UINT64_STRING, $arr[0]);
@@ -400,44 +286,6 @@
         }
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint64AppendStringFail()
-    {
-        $arr = new RepeatedField(GPBType::UINT64);
-        $arr []= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint64SetStringFail()
-    {
-        $arr = new RepeatedField(GPBType::UINT64);
-        $arr []= 0;
-        $arr [0]= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint64AppendMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::UINT64);
-        $arr []= new TestMessage_Sub();
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint64SetMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::UINT64);
-        $arr []= 0;
-        $arr [0]= new TestMessage_Sub();
-    }
-
     #########################################################
     # Test float field.
     #########################################################
@@ -447,15 +295,15 @@
         $arr = new RepeatedField(GPBType::FLOAT);
 
         // Test append.
-        $arr []= 1;
+        $arr[] = 1;
         $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
 
-        $arr []= 1.1;
+        $arr[] = 1.1;
         $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
 
-        $arr []= '2';
+        $arr[] = '2';
         $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
-        $arr []= '3.1';
+        $arr[] = '3.1';
         $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
 
         $this->assertEquals(4, count($arr));
@@ -466,56 +314,18 @@
         }
 
         // Test set.
-        $arr [0]= 1;
+        $arr[0] = 1;
         $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
 
-        $arr [1]= 1.1;
+        $arr[1] = 1.1;
         $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
 
-        $arr [2]= '2';
+        $arr[2] = '2';
         $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
-        $arr [3]= '3.1';
+        $arr[3] = '3.1';
         $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testFloatAppendStringFail()
-    {
-        $arr = new RepeatedField(GPBType::FLOAT);
-        $arr []= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testFloatSetStringFail()
-    {
-        $arr = new RepeatedField(GPBType::FLOAT);
-        $arr []= 0.0;
-        $arr [0]= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testFloatAppendMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::FLOAT);
-        $arr []= new TestMessage_Sub();
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testFloatSetMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::FLOAT);
-        $arr []= 0.0;
-        $arr [0]= new TestMessage_Sub();
-    }
-
     #########################################################
     # Test double field.
     #########################################################
@@ -525,15 +335,15 @@
         $arr = new RepeatedField(GPBType::DOUBLE);
 
         // Test append.
-        $arr []= 1;
+        $arr[] = 1;
         $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
 
-        $arr []= 1.1;
+        $arr[] = 1.1;
         $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
 
-        $arr []= '2';
+        $arr[] = '2';
         $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
-        $arr []= '3.1';
+        $arr[] = '3.1';
         $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
 
         $this->assertEquals(4, count($arr));
@@ -544,56 +354,18 @@
         }
 
         // Test set.
-        $arr [0]= 1;
+        $arr[0] = 1;
         $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
 
-        $arr [1]= 1.1;
+        $arr[1] = 1.1;
         $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
 
-        $arr [2]= '2';
+        $arr[2] = '2';
         $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
-        $arr [3]= '3.1';
+        $arr[3] = '3.1';
         $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testDoubleAppendStringFail()
-    {
-        $arr = new RepeatedField(GPBType::DOUBLE);
-        $arr []= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testDoubleSetStringFail()
-    {
-        $arr = new RepeatedField(GPBType::DOUBLE);
-        $arr []= 0.0;
-        $arr [0]= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testDoubleAppendMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::DOUBLE);
-        $arr []= new TestMessage_Sub();
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testDoubleSetMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::DOUBLE);
-        $arr []= 0.0;
-        $arr [0]= new TestMessage_Sub();
-    }
-
     #########################################################
     # Test bool field.
     #########################################################
@@ -603,16 +375,16 @@
         $arr = new RepeatedField(GPBType::BOOL);
 
         // Test append.
-        $arr []= true;
+        $arr[] = true;
         $this->assertSame(true, $arr[0]);
 
-        $arr []= -1;
+        $arr[] = -1;
         $this->assertSame(true, $arr[1]);
 
-        $arr []= 1.1;
+        $arr[] = 1.1;
         $this->assertSame(true, $arr[2]);
 
-        $arr []= '';
+        $arr[] = '';
         $this->assertSame(false, $arr[3]);
 
         $this->assertEquals(4, count($arr));
@@ -623,38 +395,19 @@
         }
 
         // Test set.
-        $arr [0]= true;
+        $arr[0] = true;
         $this->assertSame(true, $arr[0]);
 
-        $arr [1]= -1;
+        $arr[1] = -1;
         $this->assertSame(true, $arr[1]);
 
-        $arr [2]= 1.1;
+        $arr[2] = 1.1;
         $this->assertSame(true, $arr[2]);
 
-        $arr [3]= '';
+        $arr[3] = '';
         $this->assertSame(false, $arr[3]);
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testBoolAppendMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::BOOL);
-        $arr []= new TestMessage_Sub();
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testBoolSetMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::BOOL);
-        $arr []= true;
-        $arr [0]= new TestMessage_Sub();
-    }
-
     #########################################################
     # Test string field.
     #########################################################
@@ -664,16 +417,16 @@
         $arr = new RepeatedField(GPBType::STRING);
 
         // Test append.
-        $arr []= 'abc';
+        $arr[] = 'abc';
         $this->assertSame('abc', $arr[0]);
 
-        $arr []= 1;
+        $arr[] = 1;
         $this->assertSame('1', $arr[1]);
 
-        $arr []= 1.1;
+        $arr[] = 1.1;
         $this->assertSame('1.1', $arr[2]);
 
-        $arr []= true;
+        $arr[] = true;
         $this->assertSame('1', $arr[3]);
 
         $this->assertEquals(4, count($arr));
@@ -684,59 +437,19 @@
         }
 
         // Test set.
-        $arr [0]= 'abc';
+        $arr[0] = 'abc';
         $this->assertSame('abc', $arr[0]);
 
-        $arr [1]= 1;
+        $arr[1] = 1;
         $this->assertSame('1', $arr[1]);
 
-        $arr [2]= 1.1;
+        $arr[2] = 1.1;
         $this->assertSame('1.1', $arr[2]);
 
-        $arr [3]= true;
+        $arr[3] = true;
         $this->assertSame('1', $arr[3]);
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testStringAppendMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::STRING);
-        $arr []= new TestMessage_Sub();
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testStringSetMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::STRING);
-        $arr []= 'abc';
-        $arr [0]= new TestMessage_Sub();
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testStringAppendInvalidUTF8Fail()
-    {
-        $arr = new RepeatedField(GPBType::STRING);
-        $hex = hex2bin("ff");
-        $arr []= $hex;
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testStringSetInvalidUTF8Fail()
-    {
-        $arr = new RepeatedField(GPBType::STRING);
-        $arr []= 'abc';
-        $hex = hex2bin("ff");
-        $arr [0]= $hex;
-    }
-
     #########################################################
     # Test message field.
     #########################################################
@@ -748,7 +461,7 @@
         // Test append.
         $sub_m = new TestMessage_Sub();
         $sub_m->setA(1);
-        $arr []= $sub_m;
+        $arr[] = $sub_m;
         $this->assertSame(1, $arr[0]->getA());
 
         $this->assertEquals(1, count($arr));
@@ -756,78 +469,10 @@
         // Test set.
         $sub_m = new TestMessage_Sub();
         $sub_m->setA(2);
-        $arr [0]= $sub_m;
+        $arr[0] = $sub_m;
         $this->assertSame(2, $arr[0]->getA());
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMessageAppendIntFail()
-    {
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
-        $arr []= 1;
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMessageSetIntFail()
-    {
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
-        $arr []= new TestMessage_Sub;
-        $arr [0]= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMessageAppendStringFail()
-    {
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
-        $arr []= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMessageSetStringFail()
-    {
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
-        $arr []= new TestMessage_Sub;
-        $arr [0]= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMessageAppendOtherMessageFail()
-    {
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
-        $arr []= new TestMessage;
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMessageAppendNullFail()
-    {
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
-        $null = null;
-        $arr []= $null;
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMessageSetNullFail()
-    {
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
-        $arr []= new TestMessage_Sub();
-        $null = null;
-        $arr[0] = $null;
-    }
-
     #########################################################
     # Test offset type
     #########################################################
@@ -835,18 +480,18 @@
     public function testOffset()
     {
         $arr = new RepeatedField(GPBType::INT32);
-        $arr []= 0;
+        $arr[] = 0;
 
-        $arr [0]= 1;
+        $arr[0] = 1;
         $this->assertSame(1, $arr[0]);
         $this->assertSame(1, count($arr));
 
-        $arr ['0']= 2;
+        $arr['0'] = 2;
         $this->assertSame(2, $arr['0']);
         $this->assertSame(2, $arr[0]);
         $this->assertSame(1, count($arr));
 
-        $arr [0.0]= 3;
+        $arr[0.0] = 3;
         $this->assertSame(3, $arr[0.0]);
         $this->assertSame(1, count($arr));
     }
@@ -855,9 +500,9 @@
     {
         $arr = new RepeatedField(GPBType::INT32);
 
-        $arr []= 0;
-        $arr []= 1;
-        $arr []= 2;
+        $arr[] = 0;
+        $arr[] = 1;
+        $arr[] = 2;
         $this->assertSame(3, count($arr));
 
         unset($arr[2]);
@@ -865,86 +510,34 @@
         $this->assertSame(0, $arr[0]);
         $this->assertSame(1, $arr[1]);
 
-        $arr [] = 3;
+        $arr[] = 3;
         $this->assertSame(3, count($arr));
         $this->assertSame(0, $arr[0]);
         $this->assertSame(1, $arr[1]);
         $this->assertSame(3, $arr[2]);
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testRemoveMiddleFail()
-    {
-        $arr = new RepeatedField(GPBType::INT32);
-
-        $arr []= 0;
-        $arr []= 1;
-        $arr []= 2;
-        $this->assertSame(3, count($arr));
-
-        unset($arr[1]);
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testRemoveEmptyFail()
-    {
-        $arr = new RepeatedField(GPBType::INT32);
-
-        unset($arr[0]);
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMessageOffsetFail()
-    {
-        $arr = new RepeatedField(GPBType::INT32);
-        $arr []= 0;
-        $arr [new TestMessage_Sub()]= 0;
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testStringOffsetFail()
-    {
-        $arr = new RepeatedField(GPBType::INT32);
-        $arr []= 0;
-        $arr ['abc']= 0;
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testSetNonExistedOffsetFail()
-    {
-        $arr = new RepeatedField(GPBType::INT32);
-        $arr [0]= 0;
-    }
-
     #########################################################
     # Test memory leak
     #########################################################
 
-    public function testCycleLeak()
-    {
-        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage::class);
-        $arr []= new TestMessage;
-        $arr[0]->SetRepeatedRecursive($arr);
+    // COMMENTED OUT BY @bshaffer
+    // @see https://github.com/google/protobuf/pull/3344#issuecomment-315162761
+    // public function testCycleLeak()
+    // {
+    //     $arr = new RepeatedField(GPBType::MESSAGE, TestMessage::class);
+    //     $arr[] = new TestMessage;
+    //     $arr[0]->SetRepeatedRecursive($arr);
 
-        // Clean up memory before test.
-        gc_collect_cycles();
-        $start = memory_get_usage();
-        unset($arr);
+    //     // Clean up memory before test.
+    //     gc_collect_cycles();
+    //     $start = memory_get_usage();
+    //     unset($arr);
 
-        // Explicitly trigger garbage collection.
-        gc_collect_cycles();
+    //     // Explicitly trigger garbage collection.
+    //     gc_collect_cycles();
 
-        $end = memory_get_usage();
-        $this->assertLessThan($start, $end);
-    }
+    //     $end = memory_get_usage();
+    //     $this->assertLessThan($start, $end);
+    // }
 }
diff --git a/php/tests/compatibility_test.sh b/php/tests/compatibility_test.sh
new file mode 100755
index 0000000..6f1e490
--- /dev/null
+++ b/php/tests/compatibility_test.sh
@@ -0,0 +1,141 @@
+#!/bin/bash
+
+function use_php() {
+  VERSION=$1
+  PHP=`which php`
+  PHP_CONFIG=`which php-config`
+  PHPIZE=`which phpize`
+  ln -sfn "/usr/local/php-${VERSION}/bin/php" $PHP
+  ln -sfn "/usr/local/php-${VERSION}/bin/php-config" $PHP_CONFIG
+  ln -sfn "/usr/local/php-${VERSION}/bin/phpize" $PHPIZE
+}
+
+function generate_proto() {
+  PROTOC1=$1
+  PROTOC2=$2
+
+  rm -rf generated
+  mkdir generated
+
+  $PROTOC1 --php_out=generated proto/test_include.proto
+  $PROTOC2 --php_out=generated proto/test.proto proto/test_no_namespace.proto proto/test_prefix.proto
+  pushd ../../src
+  $PROTOC2 --php_out=../php/tests/generated google/protobuf/empty.proto
+  $PROTOC2 --php_out=../php/tests/generated -I../php/tests -I. ../php/tests/proto/test_import_descriptor_proto.proto
+  popd
+}
+
+# Remove tests to expect error. These were added to API tests by mistake.
+function remove_error_test() {
+  local TEMPFILE=`tempfile`
+  cat $1 | \
+  awk -v file=`basename $1` -v dir=`basename $(dirname $1)` '
+    BEGIN {
+      show = 1
+    }
+    /@expectedException PHPUnit_Framework_Error/ { show = 0; next; }
+    / *\*\//                                     { print; next; }
+    / *}/ {
+      if (!show) {
+        show = 1;
+        next;
+      }
+    }
+    show { print }
+  ' > $TEMPFILE
+  cp $TEMPFILE $1
+}
+
+set -ex
+
+# Change to the script's directory.
+cd $(dirname $0)
+
+# The old version of protobuf that we are testing compatibility against.
+case "$1" in
+  ""|3.3.0)
+    OLD_VERSION=3.3.0
+    OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.3.0/protoc-3.3.0-linux-x86_64.exe
+    ;;
+  *)
+    echo "[ERROR]: Unknown version number: $1"
+    exit 1
+    ;;
+esac
+
+# Extract the latest protobuf version number.
+VERSION_NUMBER=`grep "PHP_PROTOBUF_VERSION" ../ext/google/protobuf/protobuf.h | sed "s|#define PHP_PROTOBUF_VERSION \"\(.*\)\"|\1|"`
+
+echo "Running compatibility tests between $VERSION_NUMBER and $OLD_VERSION"
+
+# Check protoc
+[ -f ../../src/protoc ] || {
+  echo "[ERROR]: Please build protoc first."
+  exit 1
+}
+
+# Download old test.
+rm -rf protobuf
+git clone https://github.com/google/protobuf.git
+pushd protobuf
+git checkout v$OLD_VERSION
+popd
+
+# Build and copy the new runtime
+use_php 5.5
+pushd ../ext/google/protobuf
+make clean || true
+phpize && ./configure && make
+popd
+
+rm -rf protobuf/php/ext
+rm -rf protobuf/php/src
+cp -r ../ext protobuf/php/ext/
+cp -r ../src protobuf/php/src/
+
+# Download old version protoc compiler (for linux)
+wget $OLD_VERSION_PROTOC -O old_protoc
+chmod +x old_protoc
+
+NEW_PROTOC=`pwd`/../../src/protoc
+OLD_PROTOC=`pwd`/old_protoc
+cd protobuf/php
+cp -r /usr/local/vendor-5.5 vendor
+wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit
+
+# Remove implementation detail tests.
+tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php )
+sed -i.bak '/php_implementation_test.php/d' phpunit.xml
+for t in "${tests[@]}"
+do
+  remove_error_test tests/$t
+done
+
+cd tests
+
+# Test A.1:
+#   proto set 1: use old version
+#   proto set 2 which may import protos in set 1: use old version
+generate_proto $OLD_PROTOC $OLD_PROTOC
+./test.sh
+pushd ..
+phpunit
+popd
+
+# Test A.2:
+#   proto set 1: use new version
+#   proto set 2 which may import protos in set 1: use old version
+generate_proto $NEW_PROTOC $OLD_PROTOC
+./test.sh
+pushd ..
+phpunit
+popd
+
+# Test A.3:
+#   proto set 1: use old version
+#   proto set 2 which may import protos in set 1: use new version
+generate_proto $OLD_PROTOC $NEW_PROTOC
+./test.sh
+pushd ..
+phpunit
+popd
diff --git a/php/tests/encode_decode_test.php b/php/tests/encode_decode_test.php
index 288df56..b43dffb 100644
--- a/php/tests/encode_decode_test.php
+++ b/php/tests/encode_decode_test.php
@@ -9,6 +9,7 @@
 use Foo\TestMessage;
 use Foo\TestMessage_Sub;
 use Foo\TestPackedMessage;
+use Foo\TestRandomFieldOrder;
 use Foo\TestUnpackedMessage;
 
 class EncodeDecodeTest extends TestBase
@@ -88,6 +89,30 @@
         $n = new TestMessage();
         $n->mergeFromString($data);
         $this->assertSame(1, $n->getOneofMessage()->getA());
+
+        // Encode default value
+        $m->setOneofEnum(TestEnum::ZERO);
+        $data = $m->serializeToString();
+        $n = new TestMessage();
+        $n->mergeFromString($data);
+        $this->assertSame("oneof_enum", $n->getMyOneof());
+        $this->assertSame(TestEnum::ZERO, $n->getOneofEnum());
+
+        $m->setOneofString("");
+        $data = $m->serializeToString();
+        $n = new TestMessage();
+        $n->mergeFromString($data);
+        $this->assertSame("oneof_string", $n->getMyOneof());
+        $this->assertSame("", $n->getOneofString());
+
+        $sub_m = new TestMessage_Sub();
+        $m->setOneofMessage($sub_m);
+        $data = $m->serializeToString();
+        $n = new TestMessage();
+        $n->mergeFromString($data);
+        $this->assertSame("oneof_message", $n->getMyOneof());
+        $this->assertFalse(is_null($n->getOneofMessage()));
+
     }
 
     public function testPackedEncode()
@@ -211,6 +236,13 @@
         $this->assertEquals(-1, $m->getOptionalInt32());
     }
 
+    public function testRandomFieldOrder()
+    {
+        $m = new TestRandomFieldOrder();
+        $data = $m->serializeToString();
+        $this->assertSame("", $data);
+    }
+
     /**
      * @expectedException Exception
      */
@@ -409,15 +441,13 @@
         $m->mergeFromString(hex2bin('D205'));
     }
 
-    # TODO(teboring): Add test back when php implementation is ready for json
-    # encode/decode.
-    # public function testJsonEncode()
-    # {
-    #     $from = new TestMessage();
-    #     $this->setFields($from);
-    #     $data = $from->jsonEncode();
-    #     $to = new TestMessage();
-    #     $to->jsonDecode($data);
-    #     $this->expectFields($to);
-    # }
+    public function testJsonEncode()
+    {
+        $from = new TestMessage();
+        $this->setFields($from);
+        $data = $from->serializeToJsonString();
+        $to = new TestMessage();
+        $to->mergeFromJsonString($data);
+        $this->expectFields($to);
+    }
 }
diff --git a/php/tests/gdb_test.sh b/php/tests/gdb_test.sh
index 0809bef..484e2ed 100755
--- a/php/tests/gdb_test.sh
+++ b/php/tests/gdb_test.sh
@@ -3,7 +3,7 @@
 # gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which
 # phpunit` --bootstrap autoload.php tmp_test.php
 #
-gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php well_known_test.php
+gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php encode_decode_test.php
 #
 # gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php
 #
diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php
index 21ee849..56e3be2 100644
--- a/php/tests/generated_class_test.php
+++ b/php/tests/generated_class_test.php
@@ -9,9 +9,11 @@
 use Google\Protobuf\Internal\MapField;
 use Google\Protobuf\Internal\GPBType;
 use Foo\TestEnum;
+use Foo\TestIncludeNamespaceMessage;
 use Foo\TestIncludePrefixMessage;
 use Foo\TestMessage;
 use Foo\TestMessage_Sub;
+use Php\Test\TestNamespace;
 
 class GeneratedClassTest extends TestBase
 {
@@ -60,24 +62,6 @@
         $this->assertSame(MIN_INT32, $m->getOptionalInt32());
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt32FieldInvalidTypeFail()
-    {
-        $m = new TestMessage();
-        $m->setOptionalInt32(new TestMessage());
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt32FieldInvalidStringFail()
-    {
-        $m = new TestMessage();
-        $m->setOptionalInt32('abc');
-    }
-
     #########################################################
     # Test uint32 field.
     #########################################################
@@ -117,24 +101,6 @@
         $this->assertSame(MIN_INT32, $m->getOptionalUint32());
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint32FieldInvalidTypeFail()
-    {
-        $m = new TestMessage();
-        $m->setOptionalUint32(new TestMessage());
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint32FieldInvalidStringFail()
-    {
-        $m = new TestMessage();
-        $m->setOptionalUint32('abc');
-    }
-
     #########################################################
     # Test int64 field.
     #########################################################
@@ -187,24 +153,6 @@
         }
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt64FieldInvalidTypeFail()
-    {
-        $m = new TestMessage();
-        $m->setOptionalInt64(new TestMessage());
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt64FieldInvalidStringFail()
-    {
-        $m = new TestMessage();
-        $m->setOptionalInt64('abc');
-    }
-
     #########################################################
     # Test uint64 field.
     #########################################################
@@ -252,24 +200,6 @@
         }
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint64FieldInvalidTypeFail()
-    {
-        $m = new TestMessage();
-        $m->setOptionalUint64(new TestMessage());
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint64FieldInvalidStringFail()
-    {
-        $m = new TestMessage();
-        $m->setOptionalUint64('abc');
-    }
-
     #########################################################
     # Test enum field.
     #########################################################
@@ -324,24 +254,6 @@
         $this->assertEquals(3.1, $m->getOptionalFloat(), '', MAX_FLOAT_DIFF);
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testFloatFieldInvalidTypeFail()
-    {
-        $m = new TestMessage();
-        $m->setOptionalFloat(new TestMessage());
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testFloatFieldInvalidStringFail()
-    {
-        $m = new TestMessage();
-        $m->setOptionalFloat('abc');
-    }
-
     #########################################################
     # Test double field.
     #########################################################
@@ -365,24 +277,6 @@
         $this->assertEquals(3.1, $m->getOptionalDouble(), '', MAX_FLOAT_DIFF);
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testDoubleFieldInvalidTypeFail()
-    {
-        $m = new TestMessage();
-        $m->setOptionalDouble(new TestMessage());
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testDoubleFieldInvalidStringFail()
-    {
-        $m = new TestMessage();
-        $m->setOptionalDouble('abc');
-    }
-
     #########################################################
     # Test bool field.
     #########################################################
@@ -408,15 +302,6 @@
         $this->assertSame(false, $m->getOptionalBool());
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testBoolFieldInvalidStringFail()
-    {
-        $m = new TestMessage();
-        $m->setOptionalBool(new TestMessage());
-    }
-
     #########################################################
     # Test string field.
     #########################################################
@@ -442,16 +327,6 @@
         $this->assertSame('1', $m->getOptionalString());
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testStringFieldInvalidUTF8Fail()
-    {
-        $m = new TestMessage();
-        $hex = hex2bin("ff");
-        $m->setOptionalString($hex);
-    }
-
     #########################################################
     # Test bytes field.
     #########################################################
@@ -502,25 +377,6 @@
         $this->assertNull($m->getOptionalMessage());
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMessageFieldWrongTypeFail()
-    {
-        $m = new TestMessage();
-        $a = 1;
-        $m->setOptionalMessage($a);
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMessageFieldWrongClassFail()
-    {
-        $m = new TestMessage();
-        $m->setOptionalMessage(new TestMessage());
-    }
-
     #########################################################
     # Test repeated field.
     #########################################################
@@ -554,48 +410,6 @@
         $this->assertFalse($arr instanceof RepeatedField);
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testRepeatedFieldWrongTypeFail()
-    {
-        $m = new TestMessage();
-        $a = 1;
-        $m->setRepeatedInt32($a);
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testRepeatedFieldWrongObjectFail()
-    {
-        $m = new TestMessage();
-        $m->setRepeatedInt32($m);
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testRepeatedFieldWrongRepeatedTypeFail()
-    {
-        $m = new TestMessage();
-
-        $repeated_int32 = new RepeatedField(GPBType::UINT32);
-        $m->setRepeatedInt32($repeated_int32);
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testRepeatedFieldWrongRepeatedMessageClassFail()
-    {
-        $m = new TestMessage();
-
-        $repeated_message = new RepeatedField(GPBType::MESSAGE,
-                                              TestMessage::class);
-        $m->setRepeatedMessage($repeated_message);
-    }
-
     #########################################################
     # Test map field.
     #########################################################
@@ -627,49 +441,6 @@
         $this->assertFalse($dict instanceof MapField);
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMapFieldWrongTypeFail()
-    {
-        $m = new TestMessage();
-        $a = 1;
-        $m->setMapInt32Int32($a);
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMapFieldWrongObjectFail()
-    {
-        $m = new TestMessage();
-        $m->setMapInt32Int32($m);
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMapFieldWrongRepeatedTypeFail()
-    {
-        $m = new TestMessage();
-
-        $map_uint32_uint32 = new MapField(GPBType::UINT32, GPBType::UINT32);
-        $m->setMapInt32Int32($map_uint32_uint32);
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMapFieldWrongRepeatedMessageClassFail()
-    {
-        $m = new TestMessage();
-
-        $map_int32_message = new MapField(GPBType::INT32,
-                                          GPBType::MESSAGE,
-                                          TestMessage::class);
-        $m->setMapInt32Message($map_int32_message);
-    }
-
     #########################################################
     # Test oneof field.
     #########################################################
@@ -741,24 +512,44 @@
         $n->setOptionalInt32(100);
         $sub1 = new TestMessage_Sub();
         $sub1->setA(101);
-        $sub1->getB()[] = 102;
+
+        $b = $sub1->getB();
+        $b[] = 102;
+        $sub1->setB($b);
+
         $n->setOptionalMessage($sub1);
 
         // Repeated
-        $n->getRepeatedInt32()[] = 200;
-        $n->getRepeatedString()[] = 'abc';
+        $repeatedInt32 = $n->getRepeatedInt32();
+        $repeatedInt32[] = 200;
+        $n->setRepeatedInt32($repeatedInt32);
+
+        $repeatedString = $n->getRepeatedString();
+        $repeatedString[] = 'abc';
+        $n->setRepeatedString($repeatedString);
+
         $sub2 = new TestMessage_Sub();
         $sub2->setA(201);
-        $n->getRepeatedMessage()[] = $sub2;
+        $repeatedMessage = $n->getRepeatedMessage();
+        $repeatedMessage[] = $sub2;
+        $n->setRepeatedMessage($repeatedMessage);
 
         // Map
-        $n->getMapInt32Int32()[1] = 300;
-        $n->getMapInt32Int32()[-62] = 301;
-        $n->getMapStringString()['def'] = 'def';
-        $n->getMapInt32Message()[1] = new TestMessage_Sub();
-        $n->getMapInt32Message()[1]->setA(302);
-        $n->getMapInt32Message()[2] = new TestMessage_Sub();
-        $n->getMapInt32Message()[2]->setA(303);
+        $mapInt32Int32 = $n->getMapInt32Int32();
+        $mapInt32Int32[1] = 300;
+        $mapInt32Int32[-62] = 301;
+        $n->setMapInt32Int32($mapInt32Int32);
+
+        $mapStringString = $n->getMapStringString();
+        $mapStringString['def'] = 'def';
+        $n->setMapStringString($mapStringString);
+
+        $mapInt32Message = $n->getMapInt32Message();
+        $mapInt32Message[1] = new TestMessage_Sub();
+        $mapInt32Message[1]->setA(302);
+        $mapInt32Message[2] = new TestMessage_Sub();
+        $mapInt32Message[2]->setA(303);
+        $n->setMapInt32Message($mapInt32Message);
 
         $m->mergeFrom($n);
 
@@ -793,9 +584,16 @@
         // Check sub-messages are copied by value.
         $n->getOptionalMessage()->setA(-101);
         $this->assertSame(101, $m->getOptionalMessage()->getA());
-        $n->getRepeatedMessage()[0]->setA(-201);
+
+        $repeatedMessage = $n->getRepeatedMessage();
+        $repeatedMessage[0]->setA(-201);
+        $n->setRepeatedMessage($repeatedMessage);
         $this->assertSame(201, $m->getRepeatedMessage()[2]->getA());
-        $n->getMapInt32Message()[1]->setA(-302);
+
+        $mapInt32Message = $n->getMapInt32Message();
+        $mapInt32Message[1]->setA(-302);
+        $n->setMapInt32Message($mapInt32Message);
+
         $this->assertSame(302, $m->getMapInt32Message()[1]->getA());
 
         // Test merge oneof.
@@ -822,16 +620,6 @@
         $this->expectFields($n);
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMessageMergeFromInvalidTypeFail()
-    {
-        $m = new TestMessage();
-        $n = new TestMessage_Sub();
-        $m->mergeFrom($n);
-    }
-
     #########################################################
     # Test message/enum without namespace.
     #########################################################
@@ -841,7 +629,9 @@
         $m = new TestMessage();
         $sub = new NoNameSpaceMessage();
         $m->setOptionalNoNamespaceMessage($sub);
-        $m->getRepeatedNoNamespaceMessage()[] = new NoNameSpaceMessage();
+        $repeatedNoNamespaceMessage = $m->getRepeatedNoNamespaceMessage();
+        $repeatedNoNamespaceMessage[] = new NoNameSpaceMessage();
+        $m->setRepeatedNoNamespaceMessage($repeatedNoNamespaceMessage);
 
         $n = new NoNamespaceMessage();
         $n->setB(NoNamespaceMessage_NestedEnum::ZERO);
@@ -851,7 +641,9 @@
     {
         $m = new TestMessage();
         $m->setOptionalNoNamespaceEnum(NoNameSpaceEnum::VALUE_A);
-        $m->getRepeatedNoNamespaceEnum()[] = NoNameSpaceEnum::VALUE_A;
+        $repeatedNoNamespaceEnum = $m->getRepeatedNoNamespaceEnum();
+        $repeatedNoNamespaceEnum[] = NoNameSpaceEnum::VALUE_A;
+        $m->setRepeatedNoNamespaceEnum($repeatedNoNamespaceEnum);
     }
 
     #########################################################
@@ -868,6 +660,25 @@
     }
 
     #########################################################
+    # Test message with given namespace.
+    #########################################################
+
+    public function testNamespaceMessage()
+    {
+        $m = new TestIncludeNamespaceMessage();
+
+        $n = new TestNamespace();
+        $n->setA(1);
+        $m->setNamespaceMessage($n);
+        $this->assertSame(1, $m->getNamespaceMessage()->getA());
+
+        $n = new TestEmptyNamespace();
+        $n->setA(1);
+        $m->setEmptyNamespaceMessage($n);
+        $this->assertSame(1, $m->getEmptyNamespaceMessage()->getA());
+    }
+
+    #########################################################
     # Test prefix for reserved words.
     #########################################################
 
@@ -876,5 +687,19 @@
         $m = new \Foo\TestMessage_Empty();
         $m = new \Foo\PBEmpty();
         $m = new \PrefixEmpty();
+        $m = new \Foo\PBARRAY();
+    }
+
+    #########################################################
+    # Test fluent setters.
+    #########################################################
+
+    public function testFluentSetters()
+    {
+        $m = (new TestMessage())
+            ->setOptionalInt32(1)
+            ->setOptionalUInt32(2);
+        $this->assertSame(1, $m->getOptionalInt32());
+        $this->assertSame(2, $m->getOptionalUInt32());
     }
 }
diff --git a/php/tests/generated_phpdoc_test.php b/php/tests/generated_phpdoc_test.php
new file mode 100644
index 0000000..6c1a26f
--- /dev/null
+++ b/php/tests/generated_phpdoc_test.php
@@ -0,0 +1,337 @@
+<?php
+
+require_once('generated/NoNamespaceEnum.php');
+require_once('generated/NoNamespaceMessage.php');
+require_once('test_base.php');
+require_once('test_util.php');
+
+use Foo\TestMessage;
+
+class GeneratedPhpdocTest extends TestBase
+{
+    public function testPhpDocForClass()
+    {
+        $class = new ReflectionClass('Foo\TestMessage');
+        $doc = $class->getDocComment();
+        $this->assertContains('foo.TestMessage', $doc);
+    }
+
+    /**
+     * @dataProvider providePhpDocForGettersAndSetters
+     */
+    public function testPhpDocForIntGetters($methods, $expectedDoc)
+    {
+        $class = new ReflectionClass('Foo\TestMessage');
+        foreach ($methods as $method) {
+            $doc = $class->getMethod($method)->getDocComment();
+            $this->assertContains($expectedDoc, $doc);
+        }
+    }
+
+    public function providePhpDocForGettersAndSetters()
+    {
+        return [
+            [
+                [
+                    'setOptionalInt32',
+                    'setOptionalUint32',
+                    'setOptionalSint32',
+                    'setOptionalFixed32',
+                    'setOptionalSfixed32',
+                    'setOneofInt32',
+                    'setOneofUint32',
+                    'setOneofSint32',
+                    'setOneofFixed32',
+                    'setOneofSfixed32',
+                    'setOptionalEnum',
+                    'setOptionalNoNamespaceEnum',
+                    'setOptionalNestedEnum',
+                    'setOneofEnum'
+                ],
+                '@param int $var'
+            ],
+            [
+                [
+                    'setOptionalInt64',
+                    'setOptionalUint64',
+                    'setOptionalSint64',
+                    'setOptionalFixed64',
+                    'setOptionalSfixed64',
+                    'setOneofInt64',
+                    'setOneofUint64',
+                    'setOneofSint64',
+                    'setOneofFixed64',
+                    'setOneofSfixed64',
+                ],
+                '@param int|string $var'
+            ],
+            [
+                [
+                    'getOptionalInt32',
+                    'getOptionalUint32',
+                    'getOptionalSint32',
+                    'getOptionalFixed32',
+                    'getOptionalSfixed32',
+                    'getOneofInt32',
+                    'getOneofUint32',
+                    'getOneofSint32',
+                    'getOneofFixed32',
+                    'getOneofSfixed32',
+                    'getOptionalEnum',
+                    'getOptionalNoNamespaceEnum',
+                    'getOptionalNestedEnum',
+                    'getOneofEnum',
+                ],
+                '@return int'
+            ],
+            [
+                [
+                    'setOptionalInt64',
+                    'setOptionalUint64',
+                    'setOptionalSint64',
+                    'setOptionalFixed64',
+                    'setOptionalSfixed64',
+                    'setOneofInt64',
+                    'setOneofUint64',
+                    'setOneofSint64',
+                    'setOneofFixed64',
+                    'setOneofSfixed64',
+                ],
+                '@param int|string $var'
+            ],
+            [
+                [
+                    'getRepeatedInt32',
+                    'getRepeatedInt64',
+                    'getRepeatedUint32',
+                    'getRepeatedUint64',
+                    'getRepeatedSint32',
+                    'getRepeatedSint64',
+                    'getRepeatedFixed32',
+                    'getRepeatedFixed64',
+                    'getRepeatedSfixed32',
+                    'getRepeatedSfixed64',
+                    'getRepeatedFloat',
+                    'getRepeatedDouble',
+                    'getRepeatedBool',
+                    'getRepeatedString',
+                    'getRepeatedBytes',
+                    'getRepeatedEnum',
+                    'getRepeatedMessage',
+                    'getRepeatedRecursive',
+                    'getRepeatedNoNamespaceMessage',
+                    'getRepeatedNoNamespaceEnum',
+                ],
+                '@return \Google\Protobuf\Internal\RepeatedField'
+            ],
+            [
+                [
+                    'getMapInt32Int32',
+                    'getMapInt64Int64',
+                    'getMapUint32Uint32',
+                    'getMapUint64Uint64',
+                    'getMapSint32Sint32',
+                    'getMapSint64Sint64',
+                    'getMapFixed32Fixed32',
+                    'getMapFixed64Fixed64',
+                    'getMapSfixed32Sfixed32',
+                    'getMapSfixed64Sfixed64',
+                    'getMapInt32Float',
+                    'getMapInt32Double',
+                    'getMapBoolBool',
+                    'getMapStringString',
+                    'getMapInt32Bytes',
+                    'getMapInt32Enum',
+                    'getMapInt32Message',
+                    'getMapRecursive',
+                ],
+                '@return \Google\Protobuf\Internal\MapField'
+            ],
+            [
+                [
+                    'setRepeatedInt32',
+                    'setRepeatedUint32',
+                    'setRepeatedSint32',
+                    'setRepeatedFixed32',
+                    'setRepeatedSfixed32',
+                    'setRepeatedEnum',
+                    'setRepeatedNoNamespaceEnum',
+                ],
+                '@param int[]|\Google\Protobuf\Internal\RepeatedField $var'
+            ],
+            [
+                [
+                    'setRepeatedInt64',
+                    'setRepeatedUint64',
+                    'setRepeatedSint64',
+                    'setRepeatedFixed64',
+                    'setRepeatedSfixed64',
+                ],
+                '@param int[]|string[]|\Google\Protobuf\Internal\RepeatedField $var'
+            ],
+            [
+                [
+                    'setRepeatedFloat',
+                    'setRepeatedDouble',
+                ],
+                '@param float[]|\Google\Protobuf\Internal\RepeatedField $var'
+            ],
+            [
+                [
+                    'setRepeatedBool',
+                ],
+                '@param bool[]|\Google\Protobuf\Internal\RepeatedField $var'
+            ],
+            [
+                [
+                    'setRepeatedString',
+                    'setRepeatedBytes',
+                ],
+                '@param string[]|\Google\Protobuf\Internal\RepeatedField $var'
+            ],
+            [
+                [
+                    'setRepeatedMessage',
+                ],
+                '@param \Foo\TestMessage_Sub[]|\Google\Protobuf\Internal\RepeatedField $var'
+            ],
+            [
+                [
+                    'setRepeatedRecursive',
+                ],
+                '@param \Foo\TestMessage[]|\Google\Protobuf\Internal\RepeatedField $var'
+            ],
+            [
+                [
+                    'setRepeatedNoNamespaceMessage',
+                ],
+                '@param \NoNamespaceMessage[]|\Google\Protobuf\Internal\RepeatedField $var'
+            ],
+            [
+                [
+                    'setMapInt32Int32',
+                    'setMapInt64Int64',
+                    'setMapUint32Uint32',
+                    'setMapUint64Uint64',
+                    'setMapSint32Sint32',
+                    'setMapSint64Sint64',
+                    'setMapFixed32Fixed32',
+                    'setMapFixed64Fixed64',
+                    'setMapSfixed32Sfixed32',
+                    'setMapSfixed64Sfixed64',
+                    'setMapInt32Float',
+                    'setMapInt32Double',
+                    'setMapBoolBool',
+                    'setMapStringString',
+                    'setMapInt32Bytes',
+                    'setMapInt32Enum',
+                    'setMapInt32Message',
+                    'setMapRecursive',
+                ],
+                '@param array|\Google\Protobuf\Internal\MapField $var'
+            ],
+            [
+                [
+                    'getOptionalFloat',
+                    'getOptionalDouble',
+                    'getOneofDouble',
+                    'getOneofFloat',
+                ],
+                '@return float'
+            ],
+            [
+                [
+                    'setOptionalFloat',
+                    'setOptionalDouble',
+                    'setOneofDouble',
+                    'setOneofFloat',
+                ],
+                '@param float $var'
+            ],
+            [
+                [
+                    'getOptionalBool',
+                    'getOneofBool',
+                ],
+                '@return bool'],
+            [
+                [
+                    'setOptionalBool',
+                    'setOneofBool',
+                ],
+                '@param bool $var'
+            ],
+            [
+                [
+                    'getOptionalString',
+                    'getOptionalBytes',
+                    'getOneofString',
+                    'getOneofBytes',
+                    'getMyOneof',
+                ],
+                '@return string'
+            ],
+            [
+                [
+                    'setOptionalString',
+                    'setOptionalBytes',
+                    'setOneofString',
+                    'setOneofBytes',
+                ],
+                '@param string $var'
+            ],
+
+            [
+                [
+                    'getOptionalMessage',
+                    'getOneofMessage'
+                ],
+                '@return \Foo\TestMessage_Sub'
+            ],
+            [
+                [
+                    'setOptionalMessage',
+                    'setOneofMessage'
+                ],
+                '@param \Foo\TestMessage_Sub $var'
+            ],
+            [
+                [
+                    'getOptionalIncludedMessage'
+                ],
+                '@return \Bar\TestInclude'
+            ],
+            [
+                [
+                    'setOptionalIncludedMessage'
+                ],
+                '@param \Bar\TestInclude $var'
+            ],
+            [
+                [
+                    'getRecursive'
+                ],
+                '@return \Foo\TestMessage'
+            ],
+            [
+                [
+                    'setRecursive'
+                ],
+                '@param \Foo\TestMessage $var'
+            ],
+
+            [
+                [
+                    'getOptionalNoNamespaceMessage'
+                ],
+                '@return \NoNamespaceMessage'
+            ],
+            [
+                [
+                    'setOptionalNoNamespaceMessage'
+                ],
+                '@param \NoNamespaceMessage $var'
+            ],
+        ];
+    }
+}
diff --git a/php/tests/generated_service_test.php b/php/tests/generated_service_test.php
new file mode 100644
index 0000000..5407db9
--- /dev/null
+++ b/php/tests/generated_service_test.php
@@ -0,0 +1,110 @@
+<?php
+
+require_once('test_base.php');
+require_once('test_util.php');
+
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\MapField;
+use Google\Protobuf\Internal\GPBType;
+use Foo\Greeter;
+use Foo\HelloRequest;
+use Foo\HelloReply;
+
+class GeneratedServiceTest extends TestBase
+{
+    /**
+     * @var \ReflectionClass
+     */
+    private $serviceClass;
+
+    /**
+     * @var \ReflectionClass
+     */
+    private $namespacedServiceClass;
+
+    /**
+     * @var array
+     */
+    private $methodNames = [
+        'sayHello',
+        'sayHelloAgain'
+    ];
+
+    public function setUp()
+    {
+        parent::setUp();
+
+        $this->serviceClass = new ReflectionClass('Foo\GreeterInterface');
+
+        $this->namespacedServiceClass = new ReflectionClass('Bar\OtherGreeterInterface');
+    }
+
+    public function testIsInterface()
+    {
+        $this->assertTrue($this->serviceClass->isInterface());
+    }
+
+    public function testPhpDocForClass()
+    {
+        $this->assertContains('foo.Greeter', $this->serviceClass->getDocComment());
+    }
+
+    public function testPhpDocForNamespacedClass()
+    {
+        $this->assertContains('foo.OtherGreeter', $this->namespacedServiceClass->getDocComment());
+    }
+
+    public function testServiceMethodsAreGenerated()
+    {
+        $this->assertCount(count($this->methodNames), $this->serviceClass->getMethods());
+        foreach ($this->methodNames as $methodName) {
+            $this->assertTrue($this->serviceClass->hasMethod($methodName));
+        }
+    }
+
+    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);
+        }
+    }
+
+    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);
+        }
+    }
+
+    public function testParamForServiceMethod()
+    {
+        foreach ($this->methodNames as $methodName) {
+            $method = $this->serviceClass->getMethod($methodName);
+            $this->assertCount(1, $method->getParameters());
+            $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);
+        }
+    }
+
+    public function testParamForServiceMethodInNamespacedClass()
+    {
+        foreach ($this->methodNames as $methodName) {
+            $method = $this->serviceClass->getMethod($methodName);
+            $this->assertCount(1, $method->getParameters());
+            $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);
+        }
+    }
+}
diff --git a/php/tests/map_field_test.php b/php/tests/map_field_test.php
index 2fda913..120b1bd 100644
--- a/php/tests/map_field_test.php
+++ b/php/tests/map_field_test.php
@@ -56,42 +56,23 @@
         unset($arr['3.1']);
         unset($arr[MAX_INT32_STRING]);
         $this->assertEquals(0, count($arr));
-    }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt32SetStringKeyFail()
-    {
+        // Test foreach.
         $arr = new MapField(GPBType::INT32, GPBType::INT32);
-        $arr ['abc']= 0;
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt32SetStringValueFail()
-    {
-        $arr = new MapField(GPBType::INT32, GPBType::INT32);
-        $arr [0]= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt32SetMessageKeyFail()
-    {
-        $arr = new MapField(GPBType::INT32, GPBType::INT32);
-        $arr [new TestMessage_Sub()]= 0;
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt32SetMessageValueFail()
-    {
-        $arr = new MapField(GPBType::INT32, GPBType::INT32);
-        $arr [0]= new TestMessage_Sub();
+        for ($i = 0; $i < 3; $i++) {
+          $arr[$i] = $i;
+        }
+        $i = 0;
+        $arr_test = [];
+        foreach ($arr as $key => $val) {
+          $this->assertSame($key, $val);
+          $arr_test[] = $key;
+          $i++;
+        }
+        $this->assertTrue(isset($arr_test[0]));
+        $this->assertTrue(isset($arr_test[1]));
+        $this->assertTrue(isset($arr_test[2]));
+        $this->assertSame(3, $i);
     }
 
     #########################################################
@@ -159,42 +140,6 @@
         $this->assertEquals(0, count($arr));
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint32SetStringKeyFail()
-    {
-        $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
-        $arr ['abc']= 0;
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint32SetStringValueFail()
-    {
-        $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
-        $arr [0]= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint32SetMessageKeyFail()
-    {
-        $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
-        $arr [new TestMessage_Sub()]= 0;
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint32SetMessageValueFail()
-    {
-        $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
-        $arr [0]= new TestMessage_Sub();
-    }
-
     #########################################################
     # Test int64 field.
     #########################################################
@@ -252,42 +197,6 @@
         $this->assertEquals(0, count($arr));
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt64SetStringKeyFail()
-    {
-        $arr = new MapField(GPBType::INT64, GPBType::INT64);
-        $arr ['abc']= 0;
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt64SetStringValueFail()
-    {
-        $arr = new MapField(GPBType::INT64, GPBType::INT64);
-        $arr [0]= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt64SetMessageKeyFail()
-    {
-        $arr = new MapField(GPBType::INT64, GPBType::INT64);
-        $arr [new TestMessage_Sub()]= 0;
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testInt64SetMessageValueFail()
-    {
-        $arr = new MapField(GPBType::INT64, GPBType::INT64);
-        $arr [0]= new TestMessage_Sub();
-    }
-
     #########################################################
     # Test uint64 field.
     #########################################################
@@ -339,42 +248,6 @@
         $this->assertEquals(0, count($arr));
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint64SetStringKeyFail()
-    {
-        $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
-        $arr ['abc']= 0;
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint64SetStringValueFail()
-    {
-        $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
-        $arr [0]= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint64SetMessageKeyFail()
-    {
-        $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
-        $arr [new TestMessage_Sub()]= 0;
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testUint64SetMessageValueFail()
-    {
-        $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
-        $arr [0]= new TestMessage_Sub();
-    }
-
     #########################################################
     # Test float field.
     #########################################################
@@ -397,24 +270,6 @@
         $this->assertEquals(4, count($arr));
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testFloatSetStringValueFail()
-    {
-        $arr = new MapField(GPBType::INT64, GPBType::FLOAT);
-        $arr [0]= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testFloatSetMessageValueFail()
-    {
-        $arr = new MapField(GPBType::INT64, GPBType::FLOAT);
-        $arr [0]= new TestMessage_Sub();
-    }
-
     #########################################################
     # Test double field.
     #########################################################
@@ -437,24 +292,6 @@
         $this->assertEquals(4, count($arr));
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testDoubleSetStringValueFail()
-    {
-        $arr = new MapField(GPBType::INT64, GPBType::DOUBLE);
-        $arr [0]= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testDoubleSetMessageValueFail()
-    {
-        $arr = new MapField(GPBType::INT64, GPBType::DOUBLE);
-        $arr [0]= new TestMessage_Sub();
-    }
-
     #########################################################
     # Test bool field.
     #########################################################
@@ -515,24 +352,6 @@
         $this->assertEquals(0, count($arr));
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testBoolSetMessageKeyFail()
-    {
-        $arr = new MapField(GPBType::BOOL, GPBType::BOOL);
-        $arr [new TestMessage_Sub()]= true;
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testBoolSetMessageValueFail()
-    {
-        $arr = new MapField(GPBType::BOOL, GPBType::BOOL);
-        $arr [true]= new TestMessage_Sub();
-    }
-
     #########################################################
     # Test string field.
     #########################################################
@@ -564,42 +383,23 @@
         $this->assertEquals(1, count($arr));
         unset($arr[True]);
         $this->assertEquals(0, count($arr));
-    }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testStringSetInvalidUTF8KeyFail()
-    {
+        // Test foreach.
         $arr = new MapField(GPBType::STRING, GPBType::STRING);
-        $arr[hex2bin("ff")]= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testStringSetInvalidUTF8ValueFail()
-    {
-        $arr = new MapField(GPBType::STRING, GPBType::STRING);
-        $arr ['abc']= hex2bin("ff");
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testStringSetMessageKeyFail()
-    {
-        $arr = new MapField(GPBType::STRING, GPBType::STRING);
-        $arr [new TestMessage_Sub()]= 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testStringSetMessageValueFail()
-    {
-        $arr = new MapField(GPBType::STRING, GPBType::STRING);
-        $arr ['abc']= new TestMessage_Sub();
+        for ($i = 0; $i < 3; $i++) {
+          $arr[$i] = $i;
+        }
+        $i = 0;
+        $arr_test = [];
+        foreach ($arr as $key => $val) {
+          $this->assertSame($key, $val);
+          $arr_test[] = $key;
+          $i++;
+        }
+        $this->assertTrue(isset($arr_test['0']));
+        $this->assertTrue(isset($arr_test['1']));
+        $this->assertTrue(isset($arr_test['2']));
+        $this->assertSame(3, $i);
     }
 
     #########################################################
@@ -619,47 +419,6 @@
         $this->assertEquals(1, count($arr));
     }
 
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMessageSetIntValueFail()
-    {
-       $arr =
-           new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class);
-       $arr[0] = 0;
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMessageSetStringValueFail()
-    {
-       $arr =
-           new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class);
-       $arr[0] = 'abc';
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMessageSetOtherMessageValueFail()
-    {
-       $arr =
-           new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class);
-       $arr[0] = new TestMessage_Sub();
-    }
-
-    /**
-     * @expectedException PHPUnit_Framework_Error
-     */
-    public function testMessageSetNullFail()
-    {
-       $arr =
-           new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class);
-       $null = NULL;
-       $arr[0] = $null;
-    }
-
     #########################################################
     # Test memory leak
     #########################################################
@@ -669,7 +428,7 @@
     // {
     //     $arr = new MapField(GPBType::INT32,
     //         GPBType::MESSAGE, TestMessage::class);
-    //     $arr [0]= new TestMessage;
+    //     $arr[0] = new TestMessage;
     //     $arr[0]->SetMapRecursive($arr);
 
     //     // Clean up memory before test.
diff --git a/php/tests/memory_leak_test.php b/php/tests/memory_leak_test.php
index 361982b..faa1833 100644
--- a/php/tests/memory_leak_test.php
+++ b/php/tests/memory_leak_test.php
@@ -7,9 +7,12 @@
 require_once('generated/NoNamespaceMessage_NestedEnum.php');
 require_once('generated/PrefixEmpty.php');
 require_once('generated/PrefixTestPrefix.php');
+require_once('generated/TestEmptyNamespace.php');
 require_once('generated/Bar/TestInclude.php');
+require_once('generated/Foo/PBARRAY.php');
 require_once('generated/Foo/PBEmpty.php');
 require_once('generated/Foo/TestEnum.php');
+require_once('generated/Foo/TestIncludeNamespaceMessage.php');
 require_once('generated/Foo/TestIncludePrefixMessage.php');
 require_once('generated/Foo/TestMessage.php');
 require_once('generated/Foo/TestMessage_Empty.php');
@@ -17,11 +20,15 @@
 require_once('generated/Foo/TestMessage_Sub.php');
 require_once('generated/Foo/TestPackedMessage.php');
 require_once('generated/Foo/TestPhpDoc.php');
+require_once('generated/Foo/TestRandomFieldOrder.php');
 require_once('generated/Foo/TestUnpackedMessage.php');
 require_once('generated/GPBMetadata/Proto/Test.php');
+require_once('generated/GPBMetadata/Proto/TestEmptyPhpNamespace.php');
 require_once('generated/GPBMetadata/Proto/TestInclude.php');
 require_once('generated/GPBMetadata/Proto/TestNoNamespace.php');
+require_once('generated/GPBMetadata/Proto/TestPhpNamespace.php');
 require_once('generated/GPBMetadata/Proto/TestPrefix.php');
+require_once('generated/Php/Test/TestNamespace.php');
 require_once('test_util.php');
 
 use Google\Protobuf\Internal\RepeatedField;
@@ -43,7 +50,7 @@
 $from->setRecursive($from);
 
 $arr = new RepeatedField(GPBType::MESSAGE, TestMessage::class);
-$arr []= new TestMessage;
+$arr[] = new TestMessage;
 $arr[0]->SetRepeatedRecursive($arr);
 
 // Test oneof fields.
diff --git a/php/tests/php_implementation_test.php b/php/tests/php_implementation_test.php
index e124980..5dbc923 100644
--- a/php/tests/php_implementation_test.php
+++ b/php/tests/php_implementation_test.php
@@ -6,12 +6,12 @@
 use Foo\TestMessage;
 use Foo\TestMessage_Sub;
 use Foo\TestPackedMessage;
-use Google\Protobuf\Internal\InputStream;
+use Google\Protobuf\Internal\CodedInputStream;
 use Google\Protobuf\Internal\FileDescriptorSet;
 use Google\Protobuf\Internal\GPBLabel;
 use Google\Protobuf\Internal\GPBType;
 use Google\Protobuf\Internal\GPBWire;
-use Google\Protobuf\Internal\OutputStream;
+use Google\Protobuf\Internal\CodedOutputStream;
 
 class ImplementationTest extends TestBase
 {
@@ -21,17 +21,17 @@
         $value = null;
 
         // Positive number.
-        $input = new InputStream(hex2bin("01"));
+        $input = new CodedInputStream(hex2bin("01"));
         GPBWire::readInt32($input, $value);
         $this->assertSame(1, $value);
 
         // Negative number.
-        $input = new InputStream(hex2bin("ffffffff0f"));
+        $input = new CodedInputStream(hex2bin("ffffffff0f"));
         GPBWire::readInt32($input, $value);
         $this->assertSame(-1, $value);
 
         // Discard overflow bits.
-        $input = new InputStream(hex2bin("ffffffff7f"));
+        $input = new CodedInputStream(hex2bin("ffffffff7f"));
         GPBWire::readInt32($input, $value);
         $this->assertSame(-1, $value);
     }
@@ -41,17 +41,17 @@
         $value = null;
 
         // Positive number.
-        $input = new InputStream(hex2bin("01"));
+        $input = new CodedInputStream(hex2bin("01"));
         GPBWire::readUint32($input, $value);
         $this->assertSame(1, $value);
 
         // Max uint32.
-        $input = new InputStream(hex2bin("ffffffff0f"));
+        $input = new CodedInputStream(hex2bin("ffffffff0f"));
         GPBWire::readUint32($input, $value);
         $this->assertSame(-1, $value);
 
         // Discard overflow bits.
-        $input = new InputStream(hex2bin("ffffffff7f"));
+        $input = new CodedInputStream(hex2bin("ffffffff7f"));
         GPBWire::readUint32($input, $value);
         $this->assertSame(-1, $value);
     }
@@ -61,17 +61,17 @@
         $value = null;
 
         // Positive number.
-        $input = new InputStream(hex2bin("01"));
+        $input = new CodedInputStream(hex2bin("01"));
         GPBWire::readInt64($input, $value);
         $this->assertEquals(1, $value);
 
         // Negative number.
-        $input = new InputStream(hex2bin("ffffffffffffffffff01"));
+        $input = new CodedInputStream(hex2bin("ffffffffffffffffff01"));
         GPBWire::readInt64($input, $value);
         $this->assertEquals(-1, $value);
 
         // Discard overflow bits.
-        $input = new InputStream(hex2bin("ffffffffffffffffff0f"));
+        $input = new CodedInputStream(hex2bin("ffffffffffffffffff0f"));
         GPBWire::readInt64($input, $value);
         $this->assertEquals(-1, $value);
     }
@@ -81,17 +81,17 @@
         $value = null;
 
         // Positive number.
-        $input = new InputStream(hex2bin("01"));
+        $input = new CodedInputStream(hex2bin("01"));
         GPBWire::readUint64($input, $value);
         $this->assertEquals(1, $value);
 
         // Negative number.
-        $input = new InputStream(hex2bin("FFFFFFFFFFFFFFFFFF01"));
+        $input = new CodedInputStream(hex2bin("FFFFFFFFFFFFFFFFFF01"));
         GPBWire::readUint64($input, $value);
         $this->assertEquals(-1, $value);
 
         // Discard overflow bits.
-        $input = new InputStream(hex2bin("FFFFFFFFFFFFFFFFFF0F"));
+        $input = new CodedInputStream(hex2bin("FFFFFFFFFFFFFFFFFF0F"));
         GPBWire::readUint64($input, $value);
         $this->assertEquals(-1, $value);
     }
@@ -100,15 +100,15 @@
     {
         $value = null;
 
-        $input = new InputStream(hex2bin("00"));
+        $input = new CodedInputStream(hex2bin("00"));
         GPBWire::readSint32($input, $value);
         $this->assertSame(0, $value);
 
-        $input = new InputStream(hex2bin("01"));
+        $input = new CodedInputStream(hex2bin("01"));
         GPBWire::readSint32($input, $value);
         $this->assertSame(-1, $value);
 
-        $input = new InputStream(hex2bin("02"));
+        $input = new CodedInputStream(hex2bin("02"));
         GPBWire::readSint32($input, $value);
         $this->assertSame(1, $value);
     }
@@ -117,15 +117,15 @@
     {
         $value = null;
 
-        $input = new InputStream(hex2bin("00"));
+        $input = new CodedInputStream(hex2bin("00"));
         GPBWire::readSint64($input, $value);
         $this->assertEquals(0, $value);
 
-        $input = new InputStream(hex2bin("01"));
+        $input = new CodedInputStream(hex2bin("01"));
         GPBWire::readSint64($input, $value);
         $this->assertEquals(-1, $value);
 
-        $input = new InputStream(hex2bin("02"));
+        $input = new CodedInputStream(hex2bin("02"));
         GPBWire::readSint64($input, $value);
         $this->assertEquals(1, $value);
     }
@@ -133,7 +133,7 @@
     public function testReadFixed32()
     {
         $value = null;
-        $input = new InputStream(hex2bin("12345678"));
+        $input = new CodedInputStream(hex2bin("12345678"));
         GPBWire::readFixed32($input, $value);
         $this->assertSame(0x78563412, $value);
     }
@@ -141,7 +141,7 @@
     public function testReadFixed64()
     {
         $value = null;
-        $input = new InputStream(hex2bin("1234567812345678"));
+        $input = new CodedInputStream(hex2bin("1234567812345678"));
         GPBWire::readFixed64($input, $value);
         if (PHP_INT_SIZE == 4) {
             $this->assertSame("8671175386481439762", $value);
@@ -153,7 +153,7 @@
     public function testReadSfixed32()
     {
         $value = null;
-        $input = new InputStream(hex2bin("12345678"));
+        $input = new CodedInputStream(hex2bin("12345678"));
         GPBWire::readSfixed32($input, $value);
         $this->assertSame(0x78563412, $value);
     }
@@ -161,7 +161,7 @@
     public function testReadFloat()
     {
         $value = null;
-        $input = new InputStream(hex2bin("0000803F"));
+        $input = new CodedInputStream(hex2bin("0000803F"));
         GPBWire::readFloat($input, $value);
         $this->assertSame(1.0, $value);
     }
@@ -170,11 +170,11 @@
     {
         $value = null;
 
-        $input = new InputStream(hex2bin("00"));
+        $input = new CodedInputStream(hex2bin("00"));
         GPBWire::readBool($input, $value);
         $this->assertSame(false, $value);
 
-        $input = new InputStream(hex2bin("01"));
+        $input = new CodedInputStream(hex2bin("01"));
         GPBWire::readBool($input, $value);
         $this->assertSame(true, $value);
     }
@@ -182,7 +182,7 @@
     public function testReadDouble()
     {
         $value = null;
-        $input = new InputStream(hex2bin("000000000000F03F"));
+        $input = new CodedInputStream(hex2bin("000000000000F03F"));
         GPBWire::readDouble($input, $value);
         $this->assertSame(1.0, $value);
     }
@@ -190,7 +190,7 @@
     public function testReadSfixed64()
     {
         $value = null;
-        $input = new InputStream(hex2bin("1234567812345678"));
+        $input = new CodedInputStream(hex2bin("1234567812345678"));
         GPBWire::readSfixed64($input, $value);
         if (PHP_INT_SIZE == 4) {
             $this->assertSame("8671175386481439762", $value);
@@ -207,8 +207,7 @@
         $this->assertSame(3, GPBWire::zigZagEncode32(-2));
         $this->assertSame(0x7FFFFFFE, GPBWire::zigZagEncode32(0x3FFFFFFF));
         $this->assertSame(0x7FFFFFFF, GPBWire::zigZagEncode32(0xC0000000));
-        $this->assertSame(-2, GPBWire::zigZagEncode32(0x7FFFFFFF));
-        $this->assertSame(-1, GPBWire::zigZagEncode32(0x80000000));
+        $this->assertSame(0x7FFFFFFF, GPBWire::zigZagEncode32(-1073741824));
 
         $this->assertSame(0,  GPBWire::zigZagDecode32(0));
         $this->assertSame(-1, GPBWire::zigZagDecode32(1));
@@ -220,6 +219,8 @@
         $this->assertSame((int)-2147483648,GPBWire::zigZagDecode32(0xFFFFFFFF));
 
         if (PHP_INT_SIZE == 4) {
+            $this->assertSame(-2, GPBWire::zigZagEncode32(0x7FFFFFFF));
+            $this->assertSame(-1, GPBWire::zigZagEncode32(0x80000000));
             $this->assertSame('0', GPBWire::zigZagEncode64(0));
             $this->assertSame('1', GPBWire::zigZagEncode64(-1));
             $this->assertSame('2', GPBWire::zigZagEncode64(1));
@@ -250,6 +251,8 @@
             $this->assertSame('1', GPBWire::zigZagDecode64(2));
             $this->assertSame('-2', GPBWire::zigZagDecode64(3));
         } else {
+            $this->assertSame(4294967294, GPBWire::zigZagEncode32(0x7FFFFFFF));
+            $this->assertSame(4294967295, GPBWire::zigZagEncode32(0x80000000));
             $this->assertSame(0, GPBWire::zigZagEncode64(0));
             $this->assertSame(1, GPBWire::zigZagEncode64(-1));
             $this->assertSame(2, GPBWire::zigZagEncode64(1));
@@ -330,19 +333,19 @@
         $var = 0;
 
         // Empty buffer.
-        $input = new InputStream(hex2bin(''));
+        $input = new CodedInputStream(hex2bin(''));
         $this->assertFalse($input->readVarint64($var));
 
         // The largest varint is 10 bytes long.
-        $input = new InputStream(hex2bin('8080808080808080808001'));
+        $input = new CodedInputStream(hex2bin('8080808080808080808001'));
         $this->assertFalse($input->readVarint64($var));
 
         // Corrupted varint.
-        $input = new InputStream(hex2bin('808080'));
+        $input = new CodedInputStream(hex2bin('808080'));
         $this->assertFalse($input->readVarint64($var));
 
         // Normal case.
-        $input = new InputStream(hex2bin('808001'));
+        $input = new CodedInputStream(hex2bin('808001'));
         $this->assertTrue($input->readVarint64($var));
         if (PHP_INT_SIZE == 4) {
             $this->assertSame('16384', $var);
@@ -352,7 +355,7 @@
         $this->assertFalse($input->readVarint64($var));
 
         // Read two varint.
-        $input = new InputStream(hex2bin('808001808002'));
+        $input = new CodedInputStream(hex2bin('808001808002'));
         $this->assertTrue($input->readVarint64($var));
         if (PHP_INT_SIZE == 4) {
             $this->assertSame('16384', $var);
@@ -390,7 +393,7 @@
         );
 
         foreach ($testVals as $original => $encoded) {
-            $input = new InputStream(hex2bin($encoded));
+            $input = new CodedInputStream(hex2bin($encoded));
             $this->assertTrue($input->readVarint64($var));
             $this->assertEquals($original, $var);
         }
@@ -401,25 +404,25 @@
         $var = 0;
 
         // Empty buffer.
-        $input = new InputStream(hex2bin(''));
+        $input = new CodedInputStream(hex2bin(''));
         $this->assertFalse($input->readVarint32($var));
 
         // The largest varint is 10 bytes long.
-        $input = new InputStream(hex2bin('8080808080808080808001'));
+        $input = new CodedInputStream(hex2bin('8080808080808080808001'));
         $this->assertFalse($input->readVarint32($var));
 
         // Corrupted varint.
-        $input = new InputStream(hex2bin('808080'));
+        $input = new CodedInputStream(hex2bin('808080'));
         $this->assertFalse($input->readVarint32($var));
 
         // Normal case.
-        $input = new InputStream(hex2bin('808001'));
+        $input = new CodedInputStream(hex2bin('808001'));
         $this->assertTrue($input->readVarint32($var));
         $this->assertSame(16384, $var);
         $this->assertFalse($input->readVarint32($var));
 
         // Read two varint.
-        $input = new InputStream(hex2bin('808001808002'));
+        $input = new CodedInputStream(hex2bin('808001808002'));
         $this->assertTrue($input->readVarint32($var));
         $this->assertSame(16384, $var);
         $this->assertTrue($input->readVarint32($var));
@@ -427,7 +430,7 @@
         $this->assertFalse($input->readVarint32($var));
 
         // Read a 64-bit integer. High-order bits should be discarded.
-        $input = new InputStream(hex2bin('808081808001'));
+        $input = new CodedInputStream(hex2bin('808081808001'));
         $this->assertTrue($input->readVarint32($var));
         $this->assertSame(16384, $var);
         $this->assertFalse($input->readVarint32($var));
@@ -435,7 +438,7 @@
 
     public function testReadTag()
     {
-        $input = new InputStream(hex2bin('808001'));
+        $input = new CodedInputStream(hex2bin('808001'));
         $tag = $input->readTag();
         $this->assertSame(16384, $tag);
         $tag = $input->readTag();
@@ -444,7 +447,7 @@
 
     public function testPushPopLimit()
     {
-        $input = new InputStream(hex2bin('808001'));
+        $input = new CodedInputStream(hex2bin('808001'));
         $old_limit = $input->pushLimit(0);
         $tag = $input->readTag();
         $this->assertSame(0, $tag);
@@ -455,7 +458,7 @@
 
     public function testReadRaw()
     {
-        $input = new InputStream(hex2bin('808001'));
+        $input = new CodedInputStream(hex2bin('808001'));
         $buffer = null;
 
         $this->assertTrue($input->readRaw(3, $buffer));
@@ -466,33 +469,33 @@
 
     public function testWriteVarint32()
     {
-        $output = new OutputStream(3);
-        $output->writeVarint32(16384);
+        $output = new CodedOutputStream(3);
+        $output->writeVarint32(16384, true);
         $this->assertSame(hex2bin('808001'), $output->getData());
 
         // Negative numbers are padded to be compatible with int64.
-        $output = new OutputStream(10);
-        $output->writeVarint32(-43);
+        $output = new CodedOutputStream(10);
+        $output->writeVarint32(-43, false);
         $this->assertSame(hex2bin('D5FFFFFFFFFFFFFFFF01'), $output->getData());
     }
 
     public function testWriteVarint64()
     {
-        $output = new OutputStream(10);
+        $output = new CodedOutputStream(10);
         $output->writeVarint64(-43);
         $this->assertSame(hex2bin('D5FFFFFFFFFFFFFFFF01'), $output->getData());
     }
 
     public function testWriteLittleEndian32()
     {
-        $output = new OutputStream(4);
+        $output = new CodedOutputStream(4);
         $output->writeLittleEndian32(46);
         $this->assertSame(hex2bin('2E000000'), $output->getData());
     }
 
     public function testWriteLittleEndian64()
     {
-        $output = new OutputStream(8);
+        $output = new CodedOutputStream(8);
         $output->writeLittleEndian64(47);
         $this->assertSame(hex2bin('2F00000000000000'), $output->getData());
     }
diff --git a/php/tests/proto/test.proto b/php/tests/proto/test.proto
index 3922925..d81f66f 100644
--- a/php/tests/proto/test.proto
+++ b/php/tests/proto/test.proto
@@ -2,6 +2,8 @@
 
 import 'proto/test_include.proto';
 import 'proto/test_no_namespace.proto';
+import 'proto/test_php_namespace.proto';
+import 'proto/test_empty_php_namespace.proto';
 import 'proto/test_prefix.proto';
 
 package foo;
@@ -127,6 +129,10 @@
   int32 a = 1;
 }
 
+message ARRAY {
+  int32 a = 1;
+}
+
 message TestPackedMessage {
   repeated int32    repeated_int32    = 90  [packed = true];
   repeated int64    repeated_int64    = 91  [packed = true];
@@ -170,3 +176,14 @@
 message TestIncludePrefixMessage {
   TestPrefix prefix_message = 1;
 }
+
+message TestIncludeNamespaceMessage {
+  TestNamespace namespace_message = 1;
+  TestEmptyNamespace empty_namespace_message = 2;
+}
+
+// This will cause upb fields not ordered by the order in the generated code.
+message TestRandomFieldOrder {
+  int64 tag13 = 150;
+  string tag14 = 160;
+}
diff --git a/php/tests/proto/test_empty_php_namespace.proto b/php/tests/proto/test_empty_php_namespace.proto
new file mode 100644
index 0000000..7b4bc74
--- /dev/null
+++ b/php/tests/proto/test_empty_php_namespace.proto
@@ -0,0 +1,8 @@
+syntax = "proto3";
+
+package foo;
+option php_namespace = "";
+
+message TestEmptyNamespace {
+  int32 a = 1;
+}
diff --git a/php/tests/proto/test_php_namespace.proto b/php/tests/proto/test_php_namespace.proto
new file mode 100644
index 0000000..713187b
--- /dev/null
+++ b/php/tests/proto/test_php_namespace.proto
@@ -0,0 +1,8 @@
+syntax = "proto3";
+
+package foo;
+option php_namespace = "Php\\Test";
+
+message TestNamespace {
+  int32 a = 1;
+}
diff --git a/php/tests/proto/test_service.proto b/php/tests/proto/test_service.proto
new file mode 100644
index 0000000..a03dbc4
--- /dev/null
+++ b/php/tests/proto/test_service.proto
@@ -0,0 +1,18 @@
+syntax = "proto3";
+
+package foo;
+
+option php_generic_services = true;
+
+service Greeter {
+  rpc SayHello (HelloRequest) returns (HelloReply) {}
+  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
+}
+
+message HelloRequest {
+  string name = 1;
+}
+
+message HelloReply {
+  string message = 1;
+}
diff --git a/php/tests/proto/test_service_namespace.proto b/php/tests/proto/test_service_namespace.proto
new file mode 100644
index 0000000..719aa48
--- /dev/null
+++ b/php/tests/proto/test_service_namespace.proto
@@ -0,0 +1,13 @@
+syntax = "proto3";
+
+import "proto/test_service.proto";
+
+package foo;
+
+option php_generic_services = true;
+option php_namespace = "Bar";
+
+service OtherGreeter {
+  rpc SayHello (HelloRequest) returns (HelloReply) {}
+  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
+}
diff --git a/php/tests/test.sh b/php/tests/test.sh
index fc3f018..b640c14 100755
--- a/php/tests/test.sh
+++ b/php/tests/test.sh
@@ -2,13 +2,13 @@
 
 # Compile c extension
 pushd ../ext/google/protobuf/
-make clean
+make clean || true
 set -e
 # Add following in configure for debug: --enable-debug CFLAGS='-g -O0'
-phpize && ./configure  --enable-debug CFLAGS='-g -O0' && make
+phpize && ./configure CFLAGS='-g -O0' && make
 popd
 
-tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php )
+tests=( array_test.php encode_decode_test.php generated_class_test.php generated_phpdoc_test.php map_field_test.php well_known_test.php generated_service_test.php )
 
 for t in "${tests[@]}"
 do
diff --git a/php/tests/test_base.php b/php/tests/test_base.php
index 67048f4..dc5e73f 100644
--- a/php/tests/test_base.php
+++ b/php/tests/test_base.php
@@ -19,6 +19,8 @@
 
     public function expectFields(TestMessage $m)
     {
+        $this->assertSame(-42,  $m->getOptionalInt32());
+        $this->assertSame(42,  $m->getOptionalUint32());
         $this->assertSame(-44,  $m->getOptionalSint32());
         $this->assertSame(46,   $m->getOptionalFixed32());
         $this->assertSame(-46,  $m->getOptionalSfixed32());
@@ -27,6 +29,7 @@
         $this->assertSame(true, $m->getOptionalBool());
         $this->assertSame('a',  $m->getOptionalString());
         $this->assertSame('b',  $m->getOptionalBytes());
+        $this->assertSame(TestEnum::ONE, $m->getOptionalEnum());
         $this->assertSame(33,   $m->getOptionalMessage()->getA());
         if (PHP_INT_SIZE == 4) {
             $this->assertSame('-43',  $m->getOptionalInt64());
diff --git a/php/tests/test_util.php b/php/tests/test_util.php
index 9dbcbb6..c8afdd3 100644
--- a/php/tests/test_util.php
+++ b/php/tests/test_util.php
@@ -71,61 +71,61 @@
         $m->setOptionalMessage($sub);
         $m->getOptionalMessage()->SetA(33);
 
-        $m->getRepeatedInt32()    []= -42;
-        $m->getRepeatedInt64()    []= -43;
-        $m->getRepeatedUint32()   []=  42;
-        $m->getRepeatedUint64()   []=  43;
-        $m->getRepeatedSint32()   []= -44;
-        $m->getRepeatedSint64()   []= -45;
-        $m->getRepeatedFixed32()  []=  46;
-        $m->getRepeatedFixed64()  []=  47;
-        $m->getRepeatedSfixed32() []= -46;
-        $m->getRepeatedSfixed64() []= -47;
-        $m->getRepeatedFloat()    []= 1.5;
-        $m->getRepeatedDouble()   []= 1.6;
-        $m->getRepeatedBool()     []= true;
-        $m->getRepeatedString()   []= 'a';
-        $m->getRepeatedBytes()    []= 'b';
-        $m->getRepeatedEnum()     []= TestEnum::ZERO;
-        $m->getRepeatedMessage()  []= new TestMessage_Sub();
+        self::appendHelper($m, 'RepeatedInt32',    -42);
+        self::appendHelper($m, 'RepeatedInt64',    -43);
+        self::appendHelper($m, 'RepeatedUint32',    42);
+        self::appendHelper($m, 'RepeatedUint64',    43);
+        self::appendHelper($m, 'RepeatedSint32',   -44);
+        self::appendHelper($m, 'RepeatedSint64',   -45);
+        self::appendHelper($m, 'RepeatedFixed32',   46);
+        self::appendHelper($m, 'RepeatedFixed64',   47);
+        self::appendHelper($m, 'RepeatedSfixed32', -46);
+        self::appendHelper($m, 'RepeatedSfixed64', -47);
+        self::appendHelper($m, 'RepeatedFloat',    1.5);
+        self::appendHelper($m, 'RepeatedDouble',   1.6);
+        self::appendHelper($m, 'RepeatedBool',     true);
+        self::appendHelper($m, 'RepeatedString',   'a');
+        self::appendHelper($m, 'RepeatedBytes',    'b');
+        self::appendHelper($m, 'RepeatedEnum',     TestEnum::ZERO);
+        self::appendHelper($m, 'RepeatedMessage',  new TestMessage_Sub());
         $m->getRepeatedMessage()[0]->setA(34);
 
-        $m->getRepeatedInt32()    []= -52;
-        $m->getRepeatedInt64()    []= -53;
-        $m->getRepeatedUint32()   []=  52;
-        $m->getRepeatedUint64()   []=  53;
-        $m->getRepeatedSint32()   []= -54;
-        $m->getRepeatedSint64()   []= -55;
-        $m->getRepeatedFixed32()  []=  56;
-        $m->getRepeatedFixed64()  []=  57;
-        $m->getRepeatedSfixed32() []= -56;
-        $m->getRepeatedSfixed64() []= -57;
-        $m->getRepeatedFloat()    []= 2.5;
-        $m->getRepeatedDouble()   []= 2.6;
-        $m->getRepeatedBool()     []= false;
-        $m->getRepeatedString()   []= 'c';
-        $m->getRepeatedBytes()    []= 'd';
-        $m->getRepeatedEnum()     []= TestEnum::ONE;
-        $m->getRepeatedMessage()  []= new TestMessage_Sub();
+        self::appendHelper($m, 'RepeatedInt32',    -52);
+        self::appendHelper($m, 'RepeatedInt64',    -53);
+        self::appendHelper($m, 'RepeatedUint32',    52);
+        self::appendHelper($m, 'RepeatedUint64',    53);
+        self::appendHelper($m, 'RepeatedSint32',   -54);
+        self::appendHelper($m, 'RepeatedSint64',   -55);
+        self::appendHelper($m, 'RepeatedFixed32',   56);
+        self::appendHelper($m, 'RepeatedFixed64',   57);
+        self::appendHelper($m, 'RepeatedSfixed32', -56);
+        self::appendHelper($m, 'RepeatedSfixed64', -57);
+        self::appendHelper($m, 'RepeatedFloat',    2.5);
+        self::appendHelper($m, 'RepeatedDouble',   2.6);
+        self::appendHelper($m, 'RepeatedBool',     false);
+        self::appendHelper($m, 'RepeatedString',   'c');
+        self::appendHelper($m, 'RepeatedBytes',    'd');
+        self::appendHelper($m, 'RepeatedEnum',     TestEnum::ONE);
+        self::appendHelper($m, 'RepeatedMessage',  new TestMessage_Sub());
         $m->getRepeatedMessage()[1]->SetA(35);
 
-        $m->getMapInt32Int32()[-62] = -62;
-        $m->getMapInt64Int64()[-63] = -63;
-        $m->getMapUint32Uint32()[62] = 62;
-        $m->getMapUint64Uint64()[63] = 63;
-        $m->getMapSint32Sint32()[-64] = -64;
-        $m->getMapSint64Sint64()[-65] = -65;
-        $m->getMapFixed32Fixed32()[66] = 66;
-        $m->getMapFixed64Fixed64()[67] = 67;
-        $m->getMapSfixed32Sfixed32()[-68] = -68;
-        $m->getMapSfixed64Sfixed64()[-69] = -69;
-        $m->getMapInt32Float()[1] = 3.5;
-        $m->getMapInt32Double()[1] = 3.6;
-        $m->getMapBoolBool()[true] = true;
-        $m->getMapStringString()['e'] = 'e';
-        $m->getMapInt32Bytes()[1] = 'f';
-        $m->getMapInt32Enum()[1] = TestEnum::ONE;
-        $m->getMapInt32Message()[1] = new TestMessage_Sub();
+        self::kvUpdateHelper($m, 'MapInt32Int32', -62, -62);
+        self::kvUpdateHelper($m, 'MapInt64Int64', -63, -63);
+        self::kvUpdateHelper($m, 'MapUint32Uint32', 62, 62);
+        self::kvUpdateHelper($m, 'MapUint64Uint64', 63, 63);
+        self::kvUpdateHelper($m, 'MapSint32Sint32', -64, -64);
+        self::kvUpdateHelper($m, 'MapSint64Sint64', -65, -65);
+        self::kvUpdateHelper($m, 'MapFixed32Fixed32', 66, 66);
+        self::kvUpdateHelper($m, 'MapFixed64Fixed64', 67, 67);
+        self::kvUpdateHelper($m, 'MapSfixed32Sfixed32', -68, -68);
+        self::kvUpdateHelper($m, 'MapSfixed64Sfixed64', -69, -69);
+        self::kvUpdateHelper($m, 'MapInt32Float', 1, 3.5);
+        self::kvUpdateHelper($m, 'MapInt32Double', 1, 3.6);
+        self::kvUpdateHelper($m, 'MapBoolBool', true, true);
+        self::kvUpdateHelper($m, 'MapStringString', 'e', 'e');
+        self::kvUpdateHelper($m, 'MapInt32Bytes', 1, 'f');
+        self::kvUpdateHelper($m, 'MapInt32Enum', 1, TestEnum::ONE);
+        self::kvUpdateHelper($m, 'MapInt32Message', 1, new TestMessage_Sub());
         $m->getMapInt32Message()[1]->SetA(36);
     }
 
@@ -152,61 +152,61 @@
         $m->setOptionalMessage($sub);
         $m->getOptionalMessage()->SetA(133);
 
-        $m->getRepeatedInt32()    []= -142;
-        $m->getRepeatedInt64()    []= -143;
-        $m->getRepeatedUint32()   []=  142;
-        $m->getRepeatedUint64()   []=  143;
-        $m->getRepeatedSint32()   []= -144;
-        $m->getRepeatedSint64()   []= -145;
-        $m->getRepeatedFixed32()  []=  146;
-        $m->getRepeatedFixed64()  []=  147;
-        $m->getRepeatedSfixed32() []= -146;
-        $m->getRepeatedSfixed64() []= -147;
-        $m->getRepeatedFloat()    []= 11.5;
-        $m->getRepeatedDouble()   []= 11.6;
-        $m->getRepeatedBool()     []= false;
-        $m->getRepeatedString()   []= 'aa';
-        $m->getRepeatedBytes()    []= 'bb';
-        $m->getRepeatedEnum()     []= TestEnum::TWO;
-        $m->getRepeatedMessage()  []= new TestMessage_Sub();
+        self::appendHelper($m, 'RepeatedInt32',    -142);
+        self::appendHelper($m, 'RepeatedInt64',    -143);
+        self::appendHelper($m, 'RepeatedUint32',    142);
+        self::appendHelper($m, 'RepeatedUint64',    143);
+        self::appendHelper($m, 'RepeatedSint32',   -144);
+        self::appendHelper($m, 'RepeatedSint64',   -145);
+        self::appendHelper($m, 'RepeatedFixed32',   146);
+        self::appendHelper($m, 'RepeatedFixed64',   147);
+        self::appendHelper($m, 'RepeatedSfixed32', -146);
+        self::appendHelper($m, 'RepeatedSfixed64', -147);
+        self::appendHelper($m, 'RepeatedFloat',    11.5);
+        self::appendHelper($m, 'RepeatedDouble',   11.6);
+        self::appendHelper($m, 'RepeatedBool',     false);
+        self::appendHelper($m, 'RepeatedString',   'aa');
+        self::appendHelper($m, 'RepeatedBytes',    'bb');
+        self::appendHelper($m, 'RepeatedEnum',     TestEnum::TWO);
+        self::appendHelper($m, 'RepeatedMessage',  new TestMessage_Sub());
         $m->getRepeatedMessage()[0]->setA(134);
 
-        $m->getMapInt32Int32()[-62] = -162;
-        $m->getMapInt64Int64()[-63] = -163;
-        $m->getMapUint32Uint32()[62] = 162;
-        $m->getMapUint64Uint64()[63] = 163;
-        $m->getMapSint32Sint32()[-64] = -164;
-        $m->getMapSint64Sint64()[-65] = -165;
-        $m->getMapFixed32Fixed32()[66] = 166;
-        $m->getMapFixed64Fixed64()[67] = 167;
-        $m->getMapSfixed32Sfixed32()[-68] = -168;
-        $m->getMapSfixed64Sfixed64()[-69] = -169;
-        $m->getMapInt32Float()[1] = 13.5;
-        $m->getMapInt32Double()[1] = 13.6;
-        $m->getMapBoolBool()[true] = false;
-        $m->getMapStringString()['e'] = 'ee';
-        $m->getMapInt32Bytes()[1] = 'ff';
-        $m->getMapInt32Enum()[1] = TestEnum::TWO;
-        $m->getMapInt32Message()[1] = new TestMessage_Sub();
+        self::kvUpdateHelper($m, 'MapInt32Int32', -62, -162);
+        self::kvUpdateHelper($m, 'MapInt64Int64', -63, -163);
+        self::kvUpdateHelper($m, 'MapUint32Uint32', 62, 162);
+        self::kvUpdateHelper($m, 'MapUint64Uint64', 63, 163);
+        self::kvUpdateHelper($m, 'MapSint32Sint32', -64, -164);
+        self::kvUpdateHelper($m, 'MapSint64Sint64', -65, -165);
+        self::kvUpdateHelper($m, 'MapFixed32Fixed32', 66, 166);
+        self::kvUpdateHelper($m, 'MapFixed64Fixed64', 67, 167);
+        self::kvUpdateHelper($m, 'MapSfixed32Sfixed32', -68, -168);
+        self::kvUpdateHelper($m, 'MapSfixed64Sfixed64', -69, -169);
+        self::kvUpdateHelper($m, 'MapInt32Float', 1, 13.5);
+        self::kvUpdateHelper($m, 'MapInt32Double', 1, 13.6);
+        self::kvUpdateHelper($m, 'MapBoolBool', true, false);
+        self::kvUpdateHelper($m, 'MapStringString', 'e', 'ee');
+        self::kvUpdateHelper($m, 'MapInt32Bytes', 1, 'ff');
+        self::kvUpdateHelper($m, 'MapInt32Enum', 1, TestEnum::TWO);
+        self::kvUpdateHelper($m, 'MapInt32Message', 1, new TestMessage_Sub());
         $m->getMapInt32Message()[1]->SetA(136);
 
-        $m->getMapInt32Int32()[-162] = -162;
-        $m->getMapInt64Int64()[-163] = -163;
-        $m->getMapUint32Uint32()[162] = 162;
-        $m->getMapUint64Uint64()[163] = 163;
-        $m->getMapSint32Sint32()[-164] = -164;
-        $m->getMapSint64Sint64()[-165] = -165;
-        $m->getMapFixed32Fixed32()[166] = 166;
-        $m->getMapFixed64Fixed64()[167] = 167;
-        $m->getMapSfixed32Sfixed32()[-168] = -168;
-        $m->getMapSfixed64Sfixed64()[-169] = -169;
-        $m->getMapInt32Float()[2] = 13.5;
-        $m->getMapInt32Double()[2] = 13.6;
-        $m->getMapBoolBool()[false] = false;
-        $m->getMapStringString()['ee'] = 'ee';
-        $m->getMapInt32Bytes()[2] = 'ff';
-        $m->getMapInt32Enum()[2] = TestEnum::TWO;
-        $m->getMapInt32Message()[2] = new TestMessage_Sub();
+        self::kvUpdateHelper($m, 'MapInt32Int32', -162, -162);
+        self::kvUpdateHelper($m, 'MapInt64Int64', -163, -163);
+        self::kvUpdateHelper($m, 'MapUint32Uint32', 162, 162);
+        self::kvUpdateHelper($m, 'MapUint64Uint64', 163, 163);
+        self::kvUpdateHelper($m, 'MapSint32Sint32', -164, -164);
+        self::kvUpdateHelper($m, 'MapSint64Sint64', -165, -165);
+        self::kvUpdateHelper($m, 'MapFixed32Fixed32', 166, 166);
+        self::kvUpdateHelper($m, 'MapFixed64Fixed64', 167, 167);
+        self::kvUpdateHelper($m, 'MapSfixed32Sfixed32', -168, -168);
+        self::kvUpdateHelper($m, 'MapSfixed64Sfixed64', -169, -169);
+        self::kvUpdateHelper($m, 'MapInt32Float', 2, 13.5);
+        self::kvUpdateHelper($m, 'MapInt32Double', 2, 13.6);
+        self::kvUpdateHelper($m, 'MapBoolBool', false, false);
+        self::kvUpdateHelper($m, 'MapStringString', 'ee', 'ee');
+        self::kvUpdateHelper($m, 'MapInt32Bytes', 2, 'ff');
+        self::kvUpdateHelper($m, 'MapInt32Enum', 2, TestEnum::TWO);
+        self::kvUpdateHelper($m, 'MapInt32Message', 2, new TestMessage_Sub());
         $m->getMapInt32Message()[2]->SetA(136);
     }
 
@@ -395,34 +395,34 @@
 
     public static function setTestPackedMessage($m)
     {
-        $m->getRepeatedInt32()[] = -42;
-        $m->getRepeatedInt32()[] = -52;
-        $m->getRepeatedInt64()[] = -43;
-        $m->getRepeatedInt64()[] = -53;
-        $m->getRepeatedUint32()[] = 42;
-        $m->getRepeatedUint32()[] = 52;
-        $m->getRepeatedUint64()[] = 43;
-        $m->getRepeatedUint64()[] = 53;
-        $m->getRepeatedSint32()[] = -44;
-        $m->getRepeatedSint32()[] = -54;
-        $m->getRepeatedSint64()[] = -45;
-        $m->getRepeatedSint64()[] = -55;
-        $m->getRepeatedFixed32()[] = 46;
-        $m->getRepeatedFixed32()[] = 56;
-        $m->getRepeatedFixed64()[] = 47;
-        $m->getRepeatedFixed64()[] = 57;
-        $m->getRepeatedSfixed32()[] = -46;
-        $m->getRepeatedSfixed32()[] = -56;
-        $m->getRepeatedSfixed64()[] = -47;
-        $m->getRepeatedSfixed64()[] = -57;
-        $m->getRepeatedFloat()[] = 1.5;
-        $m->getRepeatedFloat()[] = 2.5;
-        $m->getRepeatedDouble()[] = 1.6;
-        $m->getRepeatedDouble()[] = 2.6;
-        $m->getRepeatedBool()[] = true;
-        $m->getRepeatedBool()[] = false;
-        $m->getRepeatedEnum()[] = TestEnum::ONE;
-        $m->getRepeatedEnum()[] = TestEnum::ZERO;
+        self::appendHelper($m, 'RepeatedInt32', -42);
+        self::appendHelper($m, 'RepeatedInt32', -52);
+        self::appendHelper($m, 'RepeatedInt64', -43);
+        self::appendHelper($m, 'RepeatedInt64', -53);
+        self::appendHelper($m, 'RepeatedUint32', 42);
+        self::appendHelper($m, 'RepeatedUint32', 52);
+        self::appendHelper($m, 'RepeatedUint64', 43);
+        self::appendHelper($m, 'RepeatedUint64', 53);
+        self::appendHelper($m, 'RepeatedSint32', -44);
+        self::appendHelper($m, 'RepeatedSint32', -54);
+        self::appendHelper($m, 'RepeatedSint64', -45);
+        self::appendHelper($m, 'RepeatedSint64', -55);
+        self::appendHelper($m, 'RepeatedFixed32', 46);
+        self::appendHelper($m, 'RepeatedFixed32', 56);
+        self::appendHelper($m, 'RepeatedFixed64', 47);
+        self::appendHelper($m, 'RepeatedFixed64', 57);
+        self::appendHelper($m, 'RepeatedSfixed32', -46);
+        self::appendHelper($m, 'RepeatedSfixed32', -56);
+        self::appendHelper($m, 'RepeatedSfixed64', -47);
+        self::appendHelper($m, 'RepeatedSfixed64', -57);
+        self::appendHelper($m, 'RepeatedFloat', 1.5);
+        self::appendHelper($m, 'RepeatedFloat', 2.5);
+        self::appendHelper($m, 'RepeatedDouble', 1.6);
+        self::appendHelper($m, 'RepeatedDouble', 2.6);
+        self::appendHelper($m, 'RepeatedBool', true);
+        self::appendHelper($m, 'RepeatedBool', false);
+        self::appendHelper($m, 'RepeatedEnum', TestEnum::ONE);
+        self::appendHelper($m, 'RepeatedEnum', TestEnum::ZERO);
     }
 
     public static function assertTestPackedMessage($m)
@@ -524,4 +524,24 @@
             "B80601B80600"
         );
     }
+
+    private static function appendHelper($obj, $func_suffix, $value)
+    {
+        $getter_function = 'get'.$func_suffix;
+        $setter_function = 'set'.$func_suffix;
+
+        $arr = $obj->$getter_function();
+        $arr[] = $value;
+        $obj->$setter_function($arr);
+    }
+
+    private static function kvUpdateHelper($obj, $func_suffix, $key, $value)
+    {
+        $getter_function = 'get'.$func_suffix;
+        $setter_function = 'set'.$func_suffix;
+
+        $arr = $obj->$getter_function();
+        $arr[$key] = $value;
+        $obj->$setter_function($arr);
+    }
 }
diff --git a/php/tests/undefined_test.php b/php/tests/undefined_test.php
new file mode 100644
index 0000000..dc6b708
--- /dev/null
+++ b/php/tests/undefined_test.php
@@ -0,0 +1,920 @@
+<?php
+
+require_once('test_util.php');
+
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBType;
+use Foo\TestMessage;
+use Foo\TestMessage_Sub;
+
+class UndefinedTest extends PHPUnit_Framework_TestCase
+{
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt32AppendStringFail()
+    {
+        $arr = new RepeatedField(GPBType::INT32);
+        $arr[] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt32SetStringFail()
+    {
+        $arr = new RepeatedField(GPBType::INT32);
+        $arr[] = 0;
+        $arr[0] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt32AppendMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::INT32);
+        $arr[] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt32SetMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::INT32);
+        $arr[] = 0;
+        $arr[0] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint32AppendStringFail()
+    {
+        $arr = new RepeatedField(GPBType::UINT32);
+        $arr[] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint32SetStringFail()
+    {
+        $arr = new RepeatedField(GPBType::UINT32);
+        $arr[] = 0;
+        $arr[0] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint32AppendMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::UINT32);
+        $arr[] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint32SetMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::UINT32);
+        $arr[] = 0;
+        $arr[0] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt64AppendStringFail()
+    {
+        $arr = new RepeatedField(GPBType::INT64);
+        $arr[] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt64SetStringFail()
+    {
+        $arr = new RepeatedField(GPBType::INT64);
+        $arr[] = 0;
+        $arr[0] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt64AppendMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::INT64);
+        $arr[] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt64SetMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::INT64);
+        $arr[] = 0;
+        $arr[0] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint64AppendStringFail()
+    {
+        $arr = new RepeatedField(GPBType::UINT64);
+        $arr[] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint64SetStringFail()
+    {
+        $arr = new RepeatedField(GPBType::UINT64);
+        $arr[] = 0;
+        $arr[0] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint64AppendMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::UINT64);
+        $arr[] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint64SetMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::UINT64);
+        $arr[] = 0;
+        $arr[0] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testFloatAppendStringFail()
+    {
+        $arr = new RepeatedField(GPBType::FLOAT);
+        $arr[] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testFloatSetStringFail()
+    {
+        $arr = new RepeatedField(GPBType::FLOAT);
+        $arr[] = 0.0;
+        $arr[0] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testFloatAppendMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::FLOAT);
+        $arr[] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testFloatSetMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::FLOAT);
+        $arr[] = 0.0;
+        $arr[0] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testDoubleAppendStringFail()
+    {
+        $arr = new RepeatedField(GPBType::DOUBLE);
+        $arr[] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testDoubleSetStringFail()
+    {
+        $arr = new RepeatedField(GPBType::DOUBLE);
+        $arr[] = 0.0;
+        $arr[0] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testDoubleAppendMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::DOUBLE);
+        $arr[] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testDoubleSetMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::DOUBLE);
+        $arr[] = 0.0;
+        $arr[0] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testBoolAppendMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::BOOL);
+        $arr[] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testBoolSetMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::BOOL);
+        $arr[] = true;
+        $arr[0] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testStringAppendMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::STRING);
+        $arr[] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testStringSetMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::STRING);
+        $arr[] = 'abc';
+        $arr[0] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testStringAppendInvalidUTF8Fail()
+    {
+        $arr = new RepeatedField(GPBType::STRING);
+        $hex = hex2bin("ff");
+        $arr[] = $hex;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testStringSetInvalidUTF8Fail()
+    {
+        $arr = new RepeatedField(GPBType::STRING);
+        $arr[] = 'abc';
+        $hex = hex2bin("ff");
+        $arr[0] = $hex;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMessageAppendIntFail()
+    {
+        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
+        $arr[] = 1;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMessageSetIntFail()
+    {
+        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
+        $arr[] = new TestMessage_Sub;
+        $arr[0] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMessageAppendStringFail()
+    {
+        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
+        $arr[] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMessageSetStringFail()
+    {
+        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
+        $arr[] = new TestMessage_Sub;
+        $arr[0] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMessageAppendOtherMessageFail()
+    {
+        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
+        $arr[] = new TestMessage;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMessageAppendNullFail()
+    {
+        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
+        $null = null;
+        $arr[] = $null;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMessageSetNullFail()
+    {
+        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
+        $arr[] = new TestMessage_Sub();
+        $null = null;
+        $arr[0] = $null;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testRemoveMiddleFail()
+    {
+        $arr = new RepeatedField(GPBType::INT32);
+
+        $arr[] = 0;
+        $arr[] = 1;
+        $arr[] = 2;
+        $this->assertSame(3, count($arr));
+
+        unset($arr[1]);
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testRemoveEmptyFail()
+    {
+        $arr = new RepeatedField(GPBType::INT32);
+
+        unset($arr[0]);
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMessageOffsetFail()
+    {
+        $arr = new RepeatedField(GPBType::INT32);
+        $arr[] = 0;
+        $arr[new TestMessage_Sub()] = 0;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testStringOffsetFail()
+    {
+        $arr = new RepeatedField(GPBType::INT32);
+        $arr[] = 0;
+        $arr['abc'] = 0;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testSetNonExistedOffsetFail()
+    {
+        $arr = new RepeatedField(GPBType::INT32);
+        $arr[0] = 0;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt32FieldInvalidTypeFail()
+    {
+        $m = new TestMessage();
+        $m->setOptionalInt32(new TestMessage());
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt32FieldInvalidStringFail()
+    {
+        $m = new TestMessage();
+        $m->setOptionalInt32('abc');
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint32FieldInvalidTypeFail()
+    {
+        $m = new TestMessage();
+        $m->setOptionalUint32(new TestMessage());
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint32FieldInvalidStringFail()
+    {
+        $m = new TestMessage();
+        $m->setOptionalUint32('abc');
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt64FieldInvalidTypeFail()
+    {
+        $m = new TestMessage();
+        $m->setOptionalInt64(new TestMessage());
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt64FieldInvalidStringFail()
+    {
+        $m = new TestMessage();
+        $m->setOptionalInt64('abc');
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint64FieldInvalidTypeFail()
+    {
+        $m = new TestMessage();
+        $m->setOptionalUint64(new TestMessage());
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint64FieldInvalidStringFail()
+    {
+        $m = new TestMessage();
+        $m->setOptionalUint64('abc');
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testFloatFieldInvalidTypeFail()
+    {
+        $m = new TestMessage();
+        $m->setOptionalFloat(new TestMessage());
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testFloatFieldInvalidStringFail()
+    {
+        $m = new TestMessage();
+        $m->setOptionalFloat('abc');
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testDoubleFieldInvalidTypeFail()
+    {
+        $m = new TestMessage();
+        $m->setOptionalDouble(new TestMessage());
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testDoubleFieldInvalidStringFail()
+    {
+        $m = new TestMessage();
+        $m->setOptionalDouble('abc');
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testBoolFieldInvalidStringFail()
+    {
+        $m = new TestMessage();
+        $m->setOptionalBool(new TestMessage());
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testStringFieldInvalidUTF8Fail()
+    {
+        $m = new TestMessage();
+        $hex = hex2bin("ff");
+        $m->setOptionalString($hex);
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMessageFieldWrongTypeFail()
+    {
+        $m = new TestMessage();
+        $a = 1;
+        $m->setOptionalMessage($a);
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMessageFieldWrongClassFail()
+    {
+        $m = new TestMessage();
+        $m->setOptionalMessage(new TestMessage());
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testRepeatedFieldWrongTypeFail()
+    {
+        $m = new TestMessage();
+        $a = 1;
+        $m->setRepeatedInt32($a);
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testRepeatedFieldWrongObjectFail()
+    {
+        $m = new TestMessage();
+        $m->setRepeatedInt32($m);
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testRepeatedFieldWrongRepeatedTypeFail()
+    {
+        $m = new TestMessage();
+
+        $repeated_int32 = new RepeatedField(GPBType::UINT32);
+        $m->setRepeatedInt32($repeated_int32);
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testRepeatedFieldWrongRepeatedMessageClassFail()
+    {
+        $m = new TestMessage();
+
+        $repeated_message = new RepeatedField(GPBType::MESSAGE,
+                                              TestMessage::class);
+        $m->setRepeatedMessage($repeated_message);
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMapFieldWrongTypeFail()
+    {
+        $m = new TestMessage();
+        $a = 1;
+        $m->setMapInt32Int32($a);
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMapFieldWrongObjectFail()
+    {
+        $m = new TestMessage();
+        $m->setMapInt32Int32($m);
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMapFieldWrongRepeatedTypeFail()
+    {
+        $m = new TestMessage();
+
+        $map_uint32_uint32 = new MapField(GPBType::UINT32, GPBType::UINT32);
+        $m->setMapInt32Int32($map_uint32_uint32);
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMapFieldWrongRepeatedMessageClassFail()
+    {
+        $m = new TestMessage();
+
+        $map_int32_message = new MapField(GPBType::INT32,
+                                          GPBType::MESSAGE,
+                                          TestMessage::class);
+        $m->setMapInt32Message($map_int32_message);
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMessageMergeFromInvalidTypeFail()
+    {
+        $m = new TestMessage();
+        $n = new TestMessage_Sub();
+        $m->mergeFrom($n);
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt32SetStringKeyFail()
+    {
+        $arr = new MapField(GPBType::INT32, GPBType::INT32);
+        $arr['abc'] = 0;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt32SetStringValueFail()
+    {
+        $arr = new MapField(GPBType::INT32, GPBType::INT32);
+        $arr[0] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt32SetMessageKeyFail()
+    {
+        $arr = new MapField(GPBType::INT32, GPBType::INT32);
+        $arr[new TestMessage_Sub()] = 0;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt32SetMessageValueFail()
+    {
+        $arr = new MapField(GPBType::INT32, GPBType::INT32);
+        $arr[0] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint32SetStringKeyFail()
+    {
+        $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
+        $arr['abc'] = 0;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint32SetStringValueFail()
+    {
+        $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
+        $arr[0] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint32SetMessageKeyFail()
+    {
+        $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
+        $arr[new TestMessage_Sub()] = 0;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint32SetMessageValueFail()
+    {
+        $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
+        $arr[0] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt64SetStringKeyFail()
+    {
+        $arr = new MapField(GPBType::INT64, GPBType::INT64);
+        $arr['abc'] = 0;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt64SetStringValueFail()
+    {
+        $arr = new MapField(GPBType::INT64, GPBType::INT64);
+        $arr[0] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt64SetMessageKeyFail()
+    {
+        $arr = new MapField(GPBType::INT64, GPBType::INT64);
+        $arr[new TestMessage_Sub()] = 0;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testInt64SetMessageValueFail()
+    {
+        $arr = new MapField(GPBType::INT64, GPBType::INT64);
+        $arr[0] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint64SetStringKeyFail()
+    {
+        $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
+        $arr['abc'] = 0;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint64SetStringValueFail()
+    {
+        $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
+        $arr[0] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint64SetMessageKeyFail()
+    {
+        $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
+        $arr[new TestMessage_Sub()] = 0;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testUint64SetMessageValueFail()
+    {
+        $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
+        $arr[0] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testDoubleSetStringValueFail()
+    {
+        $arr = new MapField(GPBType::INT64, GPBType::DOUBLE);
+        $arr[0] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testDoubleSetMessageValueFail()
+    {
+        $arr = new MapField(GPBType::INT64, GPBType::DOUBLE);
+        $arr[0] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testBoolSetMessageKeyFail()
+    {
+        $arr = new MapField(GPBType::BOOL, GPBType::BOOL);
+        $arr[new TestMessage_Sub()] = true;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testBoolSetMessageValueFail()
+    {
+        $arr = new MapField(GPBType::BOOL, GPBType::BOOL);
+        $arr[true] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testStringSetInvalidUTF8KeyFail()
+    {
+        $arr = new MapField(GPBType::STRING, GPBType::STRING);
+        $arr[hex2bin("ff")] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testStringSetInvalidUTF8ValueFail()
+    {
+        $arr = new MapField(GPBType::STRING, GPBType::STRING);
+        $arr['abc'] = hex2bin("ff");
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testStringSetMessageKeyFail()
+    {
+        $arr = new MapField(GPBType::STRING, GPBType::STRING);
+        $arr[new TestMessage_Sub()] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testStringSetMessageValueFail()
+    {
+        $arr = new MapField(GPBType::STRING, GPBType::STRING);
+        $arr['abc'] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMessageSetIntValueFail()
+    {
+       $arr =
+           new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class);
+       $arr[0] = 0;
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMessageSetStringValueFail()
+    {
+       $arr =
+           new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class);
+       $arr[0] = 'abc';
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMessageSetOtherMessageValueFail()
+    {
+       $arr =
+           new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class);
+       $arr[0] = new TestMessage_Sub();
+    }
+
+    /**
+     * @expectedException PHPUnit_Framework_Error
+     */
+    public function testMessageSetNullFail()
+    {
+       $arr =
+           new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class);
+       $null = NULL;
+       $arr[0] = $null;
+    }
+
+}
diff --git a/protoc-artifacts/Dockerfile b/protoc-artifacts/Dockerfile
index 5143b02..36b547a 100644
--- a/protoc-artifacts/Dockerfile
+++ b/protoc-artifacts/Dockerfile
@@ -30,7 +30,7 @@
 RUN bash -c 'echo "enabled=1" >> /etc/yum.repos.d/devtools-1.1.repo'
 RUN bash -c "sed -e 's/\$basearch/i386/g' /etc/yum.repos.d/devtools-1.1.repo > /etc/yum.repos.d/devtools-i386-1.1.repo"
 RUN sed -e 's/testing-/testing-i386-/g' -i /etc/yum.repos.d/devtools-i386-1.1.repo
-RUN yum install -y devtoolset-1.1 \
+RUN rpm --rebuilddb && yum install -y devtoolset-1.1 \
                    devtoolset-1.1-libstdc++-devel \
                    devtoolset-1.1-libstdc++-devel.i686
 
diff --git a/protoc-artifacts/build-zip.sh b/protoc-artifacts/build-zip.sh
index 3c5e887..a124ed7 100755
--- a/protoc-artifacts/build-zip.sh
+++ b/protoc-artifacts/build-zip.sh
@@ -73,6 +73,10 @@
 Buffers in languages other than C++ but do not want to compile protoc
 themselves. To install, simply place this binary somewhere in your PATH.
 
+If you intend to use the included well known types then don't forget to
+copy the contents of the 'include' directory somewhere as well, for example
+into '/usr/local/include/'.
+
 Please refer to our official github site for more installation instructions:
   https://github.com/google/protobuf
 EOF
diff --git a/python/README.md b/python/README.md
index 8f3db78..4c19429 100644
--- a/python/README.md
+++ b/python/README.md
@@ -32,77 +32,84 @@
 
 1) Make sure you have Python 2.6 or newer.  If in doubt, run:
 
-     $ python -V
+       $ python -V
 
 2) If you do not have setuptools installed, note that it will be
-   downloaded and installed automatically as soon as you run setup.py.
+   downloaded and installed automatically as soon as you run `setup.py`.
    If you would rather install it manually, you may do so by following
-   the instructions on this page:
+   the instructions on [this page](https://packaging.python.org/en/latest/installing.html#setup-for-installing-packages).
 
-     https://packaging.python.org/en/latest/installing.html#setup-for-installing-packages
-
-3) Build the C++ code, or install a binary distribution of protoc.  If
+3) Build the C++ code, or install a binary distribution of `protoc`.  If
    you install a binary distribution, make sure that it is the same
    version as this package.  If in doubt, run:
 
-     $ protoc --version
+       $ protoc --version
 
 4) Build and run the tests:
 
-     $ python setup.py build
-     $ python setup.py test
+       $ python setup.py build
+       $ python setup.py test
 
-     To build, test, and use the C++ implementation, you must first compile
-     libprotobuf.so:
+   To build, test, and use the C++ implementation, you must first compile
+   `libprotobuf.so`:
 
-     $ (cd .. && make)
+       $ (cd .. && make)
 
-     On OS X:
+   On OS X:
 
-      If you are running a homebrew-provided python, you must make sure another
-      version of protobuf is not already installed, as homebrew's python will
-      search /usr/local/lib for libprotobuf.so before it searches ../src/.libs
-      You can either unlink homebrew's protobuf or install the libprotobuf you
-      built earlier:
+   If you are running a Homebrew-provided Python, you must make sure another
+   version of protobuf is not already installed, as Homebrew's Python will
+   search `/usr/local/lib` for `libprotobuf.so` before it searches
+   `../src/.libs`.
 
-      $ brew unlink protobuf
-      or
-      $ (cd .. && make install)
+   You can either unlink Homebrew's protobuf or install the `libprotobuf` you
+   built earlier:
 
-     On other *nix:
+       $ brew unlink protobuf
 
-      You must make libprotobuf.so dynamically available. You can either
-      install libprotobuf you built earlier, or set LD_LIBRARY_PATH:
+   or
 
-      $ export LD_LIBRARY_PATH=../src/.libs
-      or
-      $ (cd .. && make install)
+       $ (cd .. && make install)
 
-     To build the C++ implementation run:
-     $ python setup.py build --cpp_implementation
+    On other *nix:
 
-     Then run the tests like so:
-     $ python setup.py test --cpp_implementation
+    You must make `libprotobuf.so` dynamically available. You can either
+    install libprotobuf you built earlier, or set `LD_LIBRARY_PATH`:
+
+       $ export LD_LIBRARY_PATH=../src/.libs
+
+    or
+
+       $ (cd .. && make install)
+
+   To build the C++ implementation run:
+
+       $ python setup.py build --cpp_implementation
+
+   Then run the tests like so:
+
+       $ python setup.py test --cpp_implementation
 
    If some tests fail, this library may not work correctly on your
    system.  Continue at your own risk.
 
    Please note that there is a known problem with some versions of
    Python on Cygwin which causes the tests to fail after printing the
-   error:  "sem_init: Resource temporarily unavailable".  This appears
-   to be a bug either in Cygwin or in Python:
-     http://www.cygwin.com/ml/cygwin/2005-07/msg01378.html
+   error:  `sem_init: Resource temporarily unavailable`.  This appears
+   to be a [bug either in Cygwin or in
+   Python](http://www.cygwin.com/ml/cygwin/2005-07/msg01378.html).
+
    We do not know if or when it might be fixed.  We also do not know
    how likely it is that this bug will affect users in practice.
 
 5) Install:
 
-    $ python setup.py install
+       $ python setup.py install
 
-  or:
+   or:
 
-    $ (cd .. && make install)
-    $ python setup.py install --cpp_implementation
+       $ (cd .. && make install)
+       $ python setup.py install --cpp_implementation
 
    This step may require superuser privileges.
    NOTE: To use C++ implementation, you need to export an environment
diff --git a/python/release/wheel/Dockerfile b/python/release/wheel/Dockerfile
new file mode 100644
index 0000000..f38ec2f
--- /dev/null
+++ b/python/release/wheel/Dockerfile
@@ -0,0 +1,6 @@
+FROM quay.io/pypa/manylinux1_x86_64
+
+RUN yum install -y libtool
+RUN /opt/python/cp27-cp27mu/bin/pip install twine
+
+COPY protobuf_optimized_pip.sh /
diff --git a/python/release/wheel/README.md b/python/release/wheel/README.md
new file mode 100644
index 0000000..edda2cd
--- /dev/null
+++ b/python/release/wheel/README.md
@@ -0,0 +1,17 @@
+Description
+------------------------------
+This directory is used to build released wheels according to PEP513 and upload
+them to pypi.
+
+Usage
+------------------------------
+For example, to release 3.3.0:
+    ./protobuf_optimized_pip.sh 3.3.0 PYPI_USERNAME PYPI_PASSWORD
+
+Structure
+------------------------------
+| Source                    | Source                                                       |
+|--------------------------------------|---------------------------------------------------|
+| protobuf_optimized_pip.sh | Entry point. Calling Dockerfile and build_wheel_manylinux.sh |
+| Dockerfile                | Build docker image according to PEP513.                      |
+| build_wheel_manylinux.sh  | Build wheel packages in the docker container.                |
diff --git a/python/release/wheel/build_wheel_manylinux.sh b/python/release/wheel/build_wheel_manylinux.sh
new file mode 100755
index 0000000..39fd8c1
--- /dev/null
+++ b/python/release/wheel/build_wheel_manylinux.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+# Print usage and fail.
+function usage() {
+  echo "Usage: protobuf_optimized_pip.sh PROTOBUF_VERSION PYPI_USERNAME PYPI_PASSWORD" >&2
+  exit 1   # Causes caller to exit because we use -e.
+}
+
+# Validate arguments.
+if [ $0 != ./build_wheel_manylinux.sh ]; then
+  echo "Please run this script from the directory in which it is located." >&2
+  exit 1
+fi
+
+if [ $# -lt 3 ]; then
+  usage
+  exit 1
+fi
+
+PROTOBUF_VERSION=$1
+PYPI_USERNAME=$2
+PYPI_PASSWORD=$3
+
+docker rmi protobuf-python-wheel
+docker build . -t protobuf-python-wheel
+docker run --rm protobuf-python-wheel ./protobuf_optimized_pip.sh $PROTOBUF_VERSION $PYPI_USERNAME $PYPI_PASSWORD
+docker rmi protobuf-python-wheel
diff --git a/python/release/wheel/protobuf_optimized_pip.sh b/python/release/wheel/protobuf_optimized_pip.sh
new file mode 100755
index 0000000..469661a
--- /dev/null
+++ b/python/release/wheel/protobuf_optimized_pip.sh
@@ -0,0 +1,66 @@
+#!/usr/bin/env bash
+
+# DO NOT use this script manually! Called by docker.
+
+set -ex
+
+# Print usage and fail.
+function usage() {
+  echo "Usage: protobuf_optimized_pip.sh PROTOBUF_VERSION PYPI_USERNAME PYPI_PASSWORD" >&2
+  exit 1   # Causes caller to exit because we use -e.
+}
+
+# Build wheel
+function build_wheel() {
+  PYTHON_VERSION=$1
+  PYTHON_BIN=/opt/python/${PYTHON_VERSION}/bin/python
+
+  $PYTHON_BIN setup.py bdist_wheel --cpp_implementation --compile_static_extension
+  auditwheel repair dist/protobuf-${PROTOBUF_VERSION}-${PYTHON_VERSION}-linux_x86_64.whl
+}
+
+# Validate arguments.
+if [ $0 != ./protobuf_optimized_pip.sh ]; then
+  echo "Please run this script from the directory in which it is located." >&2
+  exit 1
+fi
+
+if [ $# -lt 3 ]; then
+  usage
+  exit 1
+fi
+
+PROTOBUF_VERSION=$1
+PYPI_USERNAME=$2
+PYPI_PASSWORD=$3
+
+DIR=${PWD}/'protobuf-python-build'
+PYTHON_VERSIONS=('cp27-cp27mu' 'cp33-cp33m' 'cp34-cp34m' 'cp35-cp35m' 'cp36-cp36m')
+
+mkdir -p ${DIR}
+cd ${DIR}
+curl -SsL -O https://github.com/google/protobuf/archive/v${PROTOBUF_VERSION}.tar.gz
+tar xzf v${PROTOBUF_VERSION}.tar.gz
+cd $DIR/protobuf-${PROTOBUF_VERSION}
+
+# Autoconf on centos 5.11 cannot recognize AC_PROG_OBJC.
+sed -i '/AC_PROG_OBJC/d' configure.ac
+sed -i 's/conformance\/Makefile//g' configure.ac
+
+# Build protoc
+./autogen.sh
+CXXFLAGS="-fPIC -g -O2" ./configure
+make -j8
+export PROTOC=$DIR/src/protoc
+
+cd python
+
+for PYTHON_VERSION in "${PYTHON_VERSIONS[@]}"
+do
+  build_wheel $PYTHON_VERSION
+done
+
+/opt/python/cp27-cp27mu/bin/twine upload wheelhouse/* <<!
+$PYPI_USERNAME
+$PYPI_PASSWORD
+!
diff --git a/python/tox.ini b/python/tox.ini
index 1600db2..baa96db 100644
--- a/python/tox.ini
+++ b/python/tox.ini
@@ -9,6 +9,7 @@
     cpp: LD_LIBRARY_PATH={toxinidir}/../src/.libs
     cpp: DYLD_LIBRARY_PATH={toxinidir}/../src/.libs
     cpp: PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp
+    python: PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
 commands =
     python setup.py -q build_py
     python: python setup.py -q build
diff --git a/ruby/ext/google/protobuf_c/encode_decode.c b/ruby/ext/google/protobuf_c/encode_decode.c
index d86a114..6ce6d08 100644
--- a/ruby/ext/google/protobuf_c/encode_decode.c
+++ b/ruby/ext/google/protobuf_c/encode_decode.c
@@ -914,13 +914,9 @@
 // semantics, which means that we have true field presence, we will want to
 // modify msgvisitor so that it emits all present fields rather than all
 // non-default-value fields.
-//
-// Likewise, when implementing JSON serialization, we may need to have a
-// 'verbose' mode that outputs all fields and a 'concise' mode that outputs only
-// those with non-default values.
 
 static void putmsg(VALUE msg, const Descriptor* desc,
-                   upb_sink *sink, int depth);
+                   upb_sink *sink, int depth, bool emit_defaults);
 
 static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) {
   upb_selector_t ret;
@@ -952,7 +948,7 @@
 }
 
 static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink,
-                      int depth) {
+                      int depth, bool emit_defaults) {
   upb_sink subsink;
   VALUE descriptor;
   Descriptor* subdesc;
@@ -963,12 +959,12 @@
   subdesc = ruby_to_Descriptor(descriptor);
 
   upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink);
-  putmsg(submsg, subdesc, &subsink, depth + 1);
+  putmsg(submsg, subdesc, &subsink, depth + 1, emit_defaults);
   upb_sink_endsubmsg(sink, getsel(f, UPB_HANDLER_ENDSUBMSG));
 }
 
 static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink,
-                   int depth) {
+                   int depth, bool emit_defaults) {
   upb_sink subsink;
   upb_fieldtype_t type = upb_fielddef_type(f);
   upb_selector_t sel = 0;
@@ -1005,7 +1001,7 @@
         putstr(*((VALUE *)memory), f, &subsink);
         break;
       case UPB_TYPE_MESSAGE:
-        putsubmsg(*((VALUE *)memory), f, &subsink, depth);
+        putsubmsg(*((VALUE *)memory), f, &subsink, depth, emit_defaults);
         break;
 
 #undef T
@@ -1019,7 +1015,8 @@
                            const upb_fielddef *f,
                            VALUE type_class,
                            int depth,
-                           upb_sink *sink) {
+                           upb_sink *sink,
+                           bool emit_defaults) {
   upb_selector_t sel = 0;
   if (upb_fielddef_isprimitive(f)) {
     sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
@@ -1059,12 +1056,12 @@
       putstr(value, f, sink);
       break;
     case UPB_TYPE_MESSAGE:
-      putsubmsg(value, f, sink, depth);
+      putsubmsg(value, f, sink, depth, emit_defaults);
   }
 }
 
 static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
-                   int depth) {
+                   int depth, bool emit_defaults) {
   Map* self;
   upb_sink subsink;
   const upb_fielddef* key_field;
@@ -1090,9 +1087,9 @@
                          &entry_sink);
     upb_sink_startmsg(&entry_sink);
 
-    put_ruby_value(key, key_field, Qnil, depth + 1, &entry_sink);
+    put_ruby_value(key, key_field, Qnil, depth + 1, &entry_sink, emit_defaults);
     put_ruby_value(value, value_field, self->value_type_class, depth + 1,
-                   &entry_sink);
+                   &entry_sink, emit_defaults);
 
     upb_sink_endmsg(&entry_sink, &status);
     upb_sink_endsubmsg(&subsink, getsel(f, UPB_HANDLER_ENDSUBMSG));
@@ -1102,7 +1099,7 @@
 }
 
 static void putmsg(VALUE msg_rb, const Descriptor* desc,
-                   upb_sink *sink, int depth) {
+                   upb_sink *sink, int depth, bool emit_defaults) {
   MessageHeader* msg;
   upb_msg_field_iter i;
   upb_status status;
@@ -1144,31 +1141,31 @@
 
     if (is_map_field(f)) {
       VALUE map = DEREF(msg, offset, VALUE);
-      if (map != Qnil) {
-        putmap(map, f, sink, depth);
+      if (map != Qnil || emit_defaults) {
+        putmap(map, f, sink, depth, emit_defaults);
       }
     } else if (upb_fielddef_isseq(f)) {
       VALUE ary = DEREF(msg, offset, VALUE);
       if (ary != Qnil) {
-        putary(ary, f, sink, depth);
+        putary(ary, f, sink, depth, emit_defaults);
       }
     } else if (upb_fielddef_isstring(f)) {
       VALUE str = DEREF(msg, offset, VALUE);
-      if (is_matching_oneof || RSTRING_LEN(str) > 0) {
+      if (is_matching_oneof || emit_defaults || RSTRING_LEN(str) > 0) {
         putstr(str, f, sink);
       }
     } else if (upb_fielddef_issubmsg(f)) {
-      putsubmsg(DEREF(msg, offset, VALUE), f, sink, depth);
+      putsubmsg(DEREF(msg, offset, VALUE), f, sink, depth, emit_defaults);
     } else {
       upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
 
-#define T(upbtypeconst, upbtype, ctype, default_value)                \
-  case upbtypeconst: {                                                \
-      ctype value = DEREF(msg, offset, ctype);                        \
-      if (is_matching_oneof || value != default_value) {              \
-        upb_sink_put##upbtype(sink, sel, value);                      \
-      }                                                               \
-    }                                                                 \
+#define T(upbtypeconst, upbtype, ctype, default_value)                    \
+  case upbtypeconst: {                                                    \
+      ctype value = DEREF(msg, offset, ctype);                            \
+      if (is_matching_oneof || emit_defaults || value != default_value) { \
+        upb_sink_put##upbtype(sink, sel, value);                          \
+      }                                                                   \
+    }                                                                     \
     break;
 
       switch (upb_fielddef_type(f)) {
@@ -1246,7 +1243,7 @@
     stackenv_init(&se, "Error occurred during encoding: %s");
     encoder = upb_pb_encoder_create(&se.env, serialize_handlers, &sink.sink);
 
-    putmsg(msg_rb, desc, upb_pb_encoder_input(encoder), 0);
+    putmsg(msg_rb, desc, upb_pb_encoder_input(encoder), 0, false);
 
     ret = rb_str_new(sink.ptr, sink.len);
 
@@ -1268,6 +1265,7 @@
   Descriptor* desc = ruby_to_Descriptor(descriptor);
   VALUE msg_rb;
   VALUE preserve_proto_fieldnames = Qfalse;
+  VALUE emit_defaults = Qfalse;
   stringsink sink;
 
   if (argc < 1 || argc > 2) {
@@ -1283,6 +1281,9 @@
     }
     preserve_proto_fieldnames = rb_hash_lookup2(
         hash_args, ID2SYM(rb_intern("preserve_proto_fieldnames")), Qfalse);
+
+    emit_defaults = rb_hash_lookup2(
+        hash_args, ID2SYM(rb_intern("emit_defaults")), Qfalse);
   }
 
   stringsink_init(&sink);
@@ -1297,7 +1298,7 @@
     stackenv_init(&se, "Error occurred during encoding: %s");
     printer = upb_json_printer_create(&se.env, serialize_handlers, &sink.sink);
 
-    putmsg(msg_rb, desc, upb_json_printer_input(printer), 0);
+    putmsg(msg_rb, desc, upb_json_printer_input(printer), 0, RTEST(emit_defaults));
 
     ret = rb_enc_str_new(sink.ptr, sink.len, rb_utf8_encoding());
 
diff --git a/ruby/ext/google/protobuf_c/upb.c b/ruby/ext/google/protobuf_c/upb.c
index e0c56f8..90d1f0c 100644
--- a/ruby/ext/google/protobuf_c/upb.c
+++ b/ruby/ext/google/protobuf_c/upb.c
@@ -377,13 +377,14 @@
     } else if (def->type == UPB_DEF_FIELD) {
       upb_status_seterrmsg(s, "standalone fielddefs can not be frozen");
       goto err;
-    } else if (def->type == UPB_DEF_ENUM) {
-      if (!upb_validate_enumdef(upb_dyncast_enumdef(def), s)) {
-        goto err;
-      }
     } else {
       /* Set now to detect transitive closure in the second pass. */
       def->came_from_user = true;
+
+      if (def->type == UPB_DEF_ENUM &&
+          !upb_validate_enumdef(upb_dyncast_enumdef(def), s)) {
+        goto err;
+      }
     }
   }
 
@@ -710,43 +711,6 @@
   return f;
 }
 
-static upb_fielddef *upb_fielddef_dup(const upb_fielddef *f,
-                                      const void *owner) {
-  const char *srcname;
-  upb_fielddef *newf = upb_fielddef_new(owner);
-  if (!newf) return NULL;
-  upb_fielddef_settype(newf, upb_fielddef_type(f));
-  upb_fielddef_setlabel(newf, upb_fielddef_label(f));
-  upb_fielddef_setnumber(newf, upb_fielddef_number(f), NULL);
-  upb_fielddef_setname(newf, upb_fielddef_name(f), NULL);
-  if (f->default_is_string && f->defaultval.bytes) {
-    str_t *s = f->defaultval.bytes;
-    upb_fielddef_setdefaultstr(newf, s->str, s->len, NULL);
-  } else {
-    newf->default_is_string = f->default_is_string;
-    newf->defaultval = f->defaultval;
-  }
-
-  if (f->subdef_is_symbolic) {
-    srcname = f->sub.name;  /* Might be NULL. */
-  } else {
-    srcname = f->sub.def ? upb_def_fullname(f->sub.def) : NULL;
-  }
-  if (srcname) {
-    char *newname = upb_gmalloc(strlen(f->sub.def->fullname) + 2);
-    if (!newname) {
-      upb_fielddef_unref(newf, owner);
-      return NULL;
-    }
-    strcpy(newname, ".");
-    strcat(newname, f->sub.def->fullname);
-    upb_fielddef_setsubdefname(newf, newname, NULL);
-    upb_gfree(newname);
-  }
-
-  return newf;
-}
-
 bool upb_fielddef_typeisset(const upb_fielddef *f) {
   return f->type_is_set_;
 }
@@ -1426,44 +1390,6 @@
   return NULL;
 }
 
-static upb_oneofdef *upb_oneofdef_dup(const upb_oneofdef *o, const void *owner);
-
-static upb_msgdef *upb_msgdef_dup(const upb_msgdef *m, const void *owner) {
-  bool ok;
-  upb_msg_field_iter i;
-  upb_msg_oneof_iter o;
-
-  upb_msgdef *newm = upb_msgdef_new(owner);
-  if (!newm) return NULL;
-  ok = upb_def_setfullname(upb_msgdef_upcast_mutable(newm),
-                           upb_def_fullname(upb_msgdef_upcast(m)),
-                           NULL);
-  newm->map_entry = m->map_entry;
-  newm->syntax = m->syntax;
-  UPB_ASSERT(ok);
-  for(upb_msg_field_begin(&i, m);
-      !upb_msg_field_done(&i);
-      upb_msg_field_next(&i)) {
-    upb_fielddef *f = upb_fielddef_dup(upb_msg_iter_field(&i), &f);
-    /* Fields in oneofs are dup'd below. */
-    if (upb_fielddef_containingoneof(f)) continue;
-    if (!f || !upb_msgdef_addfield(newm, f, &f, NULL)) {
-      upb_msgdef_unref(newm, owner);
-      return NULL;
-    }
-  }
-  for(upb_msg_oneof_begin(&o, m);
-      !upb_msg_oneof_done(&o);
-      upb_msg_oneof_next(&o)) {
-    upb_oneofdef *f = upb_oneofdef_dup(upb_msg_iter_oneof(&o), &f);
-    if (!f || !upb_msgdef_addoneof(newm, f, &f, NULL)) {
-      upb_msgdef_unref(newm, owner);
-      return NULL;
-    }
-  }
-  return newm;
-}
-
 bool upb_msgdef_freeze(upb_msgdef *m, upb_status *status) {
   upb_def *d = upb_msgdef_upcast_mutable(m);
   return upb_def_freeze(&d, 1, status);
@@ -1764,24 +1690,6 @@
   return NULL;
 }
 
-static upb_oneofdef *upb_oneofdef_dup(const upb_oneofdef *o,
-                                      const void *owner) {
-  bool ok;
-  upb_oneof_iter i;
-  upb_oneofdef *newo = upb_oneofdef_new(owner);
-  if (!newo) return NULL;
-  ok = upb_oneofdef_setname(newo, upb_oneofdef_name(o), NULL);
-  UPB_ASSERT(ok);
-  for (upb_oneof_begin(&i, o); !upb_oneof_done(&i); upb_oneof_next(&i)) {
-    upb_fielddef *f = upb_fielddef_dup(upb_oneof_iter_field(&i), &f);
-    if (!f || !upb_oneofdef_addfield(newo, f, &f, NULL)) {
-      upb_oneofdef_unref(newo, owner);
-      return NULL;
-    }
-  }
-  return newo;
-}
-
 const char *upb_oneofdef_name(const upb_oneofdef *o) { return o->name; }
 
 bool upb_oneofdef_setname(upb_oneofdef *o, const char *name, upb_status *s) {
@@ -1950,6 +1858,8 @@
   upb_inttable_uninit(&f->deps);
   upb_gfree((void*)f->name);
   upb_gfree((void*)f->package);
+  upb_gfree((void*)f->phpprefix);
+  upb_gfree((void*)f->phpnamespace);
   upb_gfree(f);
 }
 
@@ -1964,6 +1874,8 @@
 
   f->package = NULL;
   f->name = NULL;
+  f->phpprefix = NULL;
+  f->phpnamespace = NULL;
   f->syntax = UPB_SYNTAX_PROTO2;
 
   if (!upb_refcounted_init(upb_filedef_upcast_mutable(f), &upb_filedef_vtbl,
@@ -1998,6 +1910,14 @@
   return f->package;
 }
 
+const char *upb_filedef_phpprefix(const upb_filedef *f) {
+  return f->phpprefix;
+}
+
+const char *upb_filedef_phpnamespace(const upb_filedef *f) {
+  return f->phpnamespace;
+}
+
 upb_syntax_t upb_filedef_syntax(const upb_filedef *f) {
   return f->syntax;
 }
@@ -2054,6 +1974,30 @@
   return true;
 }
 
+bool upb_filedef_setphpprefix(upb_filedef *f, const char *phpprefix,
+                              upb_status *s) {
+  phpprefix = upb_gstrdup(phpprefix);
+  if (!phpprefix) {
+    upb_upberr_setoom(s);
+    return false;
+  }
+  upb_gfree((void*)f->phpprefix);
+  f->phpprefix = phpprefix;
+  return true;
+}
+
+bool upb_filedef_setphpnamespace(upb_filedef *f, const char *phpnamespace,
+                                 upb_status *s) {
+  phpnamespace = upb_gstrdup(phpnamespace);
+  if (!phpnamespace) {
+    upb_upberr_setoom(s);
+    return false;
+  }
+  upb_gfree((void*)f->phpnamespace);
+  f->phpnamespace = phpnamespace;
+  return true;
+}
+
 bool upb_filedef_setsyntax(upb_filedef *f, upb_syntax_t syntax,
                            upb_status *s) {
   UPB_UNUSED(s);
@@ -2240,57 +2184,14 @@
                            fullname);
         goto err;
       }
-      upb_def_donateref(def, ref_donor, s);
       if (!upb_strtable_insert(&addtab, fullname, upb_value_ptr(def)))
         goto oom_err;
-      def->came_from_user = true;
-    }
-  }
-
-  /* Add standalone fielddefs (ie. extensions) to the appropriate messages.
-   * If the appropriate message only exists in the existing symtab, duplicate
-   * it so we have a mutable copy we can add the fields to. */
-  for (i = 0; i < n; i++) {
-    upb_def *def = defs[i];
-    upb_fielddef *f = upb_dyncast_fielddef_mutable(def);
-    const char *msgname;
-    upb_value v;
-    upb_msgdef *m;
-
-    if (!f) continue;
-    msgname = upb_fielddef_containingtypename(f);
-    /* We validated this earlier in this function. */
-    UPB_ASSERT(msgname);
-
-    /* If the extendee name is absolutely qualified, move past the initial ".".
-     * TODO(haberman): it is not obvious what it would mean if this was not
-     * absolutely qualified. */
-    if (msgname[0] == '.') {
-      msgname++;
+      upb_def_donateref(def, ref_donor, s);
     }
 
-    if (upb_strtable_lookup(&addtab, msgname, &v)) {
-      /* Extendee is in the set of defs the user asked us to add. */
-      m = upb_value_getptr(v);
-    } else {
-      /* Need to find and dup the extendee from the existing symtab. */
-      const upb_msgdef *frozen_m = upb_symtab_lookupmsg(s, msgname);
-      if (!frozen_m) {
-        upb_status_seterrf(status,
-                           "Tried to extend message %s that does not exist "
-                           "in this SymbolTable.",
-                           msgname);
-        goto err;
-      }
-      m = upb_msgdef_dup(frozen_m, s);
-      if (!m) goto oom_err;
-      if (!upb_strtable_insert(&addtab, msgname, upb_value_ptr(m))) {
-        upb_msgdef_unref(m, s);
-        goto oom_err;
-      }
-    }
-
-    if (!upb_msgdef_addfield(m, f, ref_donor, status)) {
+    if (upb_dyncast_fielddef_mutable(def)) {
+      /* TODO(haberman): allow adding extensions attached to files. */
+      upb_status_seterrf(status, "Can't add extensions to symtab.\n");
       goto err;
     }
   }
@@ -2372,15 +2273,9 @@
   for (i = 0; i < add_n; i++) {
     upb_def *def = (upb_def*)add_objs[i];
     const char *name = upb_def_fullname(def);
-    upb_value v;
     bool success;
-
-    if (upb_strtable_remove(&s->symtab, name, &v)) {
-      const upb_def *def = upb_value_getptr(v);
-      upb_def_unref(def, s);
-    }
     success = upb_strtable_insert(&s->symtab, name, upb_value_ptr(def));
-    UPB_ASSERT(success == true);
+    UPB_ASSERT(success);
   }
   upb_gfree(add_defs);
   return true;
@@ -3737,8 +3632,7 @@
           CHECK_TRUE(upb_sink_putfloat(sink, sel, upb_msgval_getfloat(val)));
           break;
         case UPB_TYPE_DOUBLE:
-          CHECK_TRUE(
-              upb_sink_putdouble(sink, sel, upb_msgval_getdouble(val)));
+          CHECK_TRUE(upb_sink_putdouble(sink, sel, upb_msgval_getdouble(val)));
           break;
         case UPB_TYPE_BOOL:
           CHECK_TRUE(upb_sink_putbool(sink, sel, upb_msgval_getbool(val)));
@@ -3748,15 +3642,13 @@
           CHECK_TRUE(upb_sink_putint32(sink, sel, upb_msgval_getint32(val)));
           break;
         case UPB_TYPE_UINT32:
-          CHECK_TRUE(
-              upb_sink_putuint32(sink, sel, upb_msgval_getuint32(val)));
+          CHECK_TRUE(upb_sink_putuint32(sink, sel, upb_msgval_getuint32(val)));
           break;
         case UPB_TYPE_INT64:
           CHECK_TRUE(upb_sink_putint64(sink, sel, upb_msgval_getint64(val)));
           break;
         case UPB_TYPE_UINT64:
-          CHECK_TRUE(
-              upb_sink_putuint64(sink, sel, upb_msgval_getuint64(val)));
+          CHECK_TRUE(upb_sink_putuint64(sink, sel, upb_msgval_getuint64(val)));
           break;
         case UPB_TYPE_STRING:
         case UPB_TYPE_BYTES:
@@ -6545,14 +6437,14 @@
 
 
 static const upb_msgdef msgs[22];
-static const upb_fielddef fields[105];
+static const upb_fielddef fields[107];
 static const upb_enumdef enums[5];
 static const upb_tabent strentries[236];
 static const upb_tabent intentries[18];
-static const upb_tabval arrays[184];
+static const upb_tabval arrays[187];
 
 #ifdef UPB_DEBUG_REFS
-static upb_inttable reftables[264];
+static upb_inttable reftables[268];
 #endif
 
 static const upb_msgdef msgs[22] = {
@@ -6567,20 +6459,20 @@
   UPB_MSGDEF_INIT("google.protobuf.FieldOptions", 12, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[4], &arrays[42], 11, 6), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[56]), false, UPB_SYNTAX_PROTO2, &reftables[16], &reftables[17]),
   UPB_MSGDEF_INIT("google.protobuf.FileDescriptorProto", 42, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[53], 13, 12), UPB_STRTABLE_INIT(12, 15, UPB_CTYPE_PTR, 4, &strentries[72]), false, UPB_SYNTAX_PROTO2, &reftables[18], &reftables[19]),
   UPB_MSGDEF_INIT("google.protobuf.FileDescriptorSet", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[66], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[88]), false, UPB_SYNTAX_PROTO2, &reftables[20], &reftables[21]),
-  UPB_MSGDEF_INIT("google.protobuf.FileOptions", 31, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[68], 39, 15), UPB_STRTABLE_INIT(16, 31, UPB_CTYPE_PTR, 5, &strentries[92]), false, UPB_SYNTAX_PROTO2, &reftables[22], &reftables[23]),
-  UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 10, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[107], 8, 4), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[124]), false, UPB_SYNTAX_PROTO2, &reftables[24], &reftables[25]),
-  UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 15, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[115], 7, 6), UPB_STRTABLE_INIT(6, 7, UPB_CTYPE_PTR, 3, &strentries[132]), false, UPB_SYNTAX_PROTO2, &reftables[26], &reftables[27]),
-  UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[10], &arrays[122], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[140]), false, UPB_SYNTAX_PROTO2, &reftables[28], &reftables[29]),
-  UPB_MSGDEF_INIT("google.protobuf.OneofDescriptorProto", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[123], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[144]), false, UPB_SYNTAX_PROTO2, &reftables[30], &reftables[31]),
-  UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[125], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[148]), false, UPB_SYNTAX_PROTO2, &reftables[32], &reftables[33]),
-  UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[14], &arrays[129], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[152]), false, UPB_SYNTAX_PROTO2, &reftables[34], &reftables[35]),
-  UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[130], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[156]), false, UPB_SYNTAX_PROTO2, &reftables[36], &reftables[37]),
-  UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 19, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[132], 7, 5), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[160]), false, UPB_SYNTAX_PROTO2, &reftables[38], &reftables[39]),
-  UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 18, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[139], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[168]), false, UPB_SYNTAX_PROTO2, &reftables[40], &reftables[41]),
-  UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[148], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[184]), false, UPB_SYNTAX_PROTO2, &reftables[42], &reftables[43]),
+  UPB_MSGDEF_INIT("google.protobuf.FileOptions", 37, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[68], 42, 17), UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_PTR, 5, &strentries[92]), false, UPB_SYNTAX_PROTO2, &reftables[22], &reftables[23]),
+  UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 10, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[110], 8, 4), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[124]), false, UPB_SYNTAX_PROTO2, &reftables[24], &reftables[25]),
+  UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 15, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[118], 7, 6), UPB_STRTABLE_INIT(6, 7, UPB_CTYPE_PTR, 3, &strentries[132]), false, UPB_SYNTAX_PROTO2, &reftables[26], &reftables[27]),
+  UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[10], &arrays[125], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[140]), false, UPB_SYNTAX_PROTO2, &reftables[28], &reftables[29]),
+  UPB_MSGDEF_INIT("google.protobuf.OneofDescriptorProto", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[126], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[144]), false, UPB_SYNTAX_PROTO2, &reftables[30], &reftables[31]),
+  UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[128], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[148]), false, UPB_SYNTAX_PROTO2, &reftables[32], &reftables[33]),
+  UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[14], &arrays[132], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[152]), false, UPB_SYNTAX_PROTO2, &reftables[34], &reftables[35]),
+  UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[133], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[156]), false, UPB_SYNTAX_PROTO2, &reftables[36], &reftables[37]),
+  UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 19, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[135], 7, 5), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[160]), false, UPB_SYNTAX_PROTO2, &reftables[38], &reftables[39]),
+  UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 18, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[142], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[168]), false, UPB_SYNTAX_PROTO2, &reftables[40], &reftables[41]),
+  UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[151], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[184]), false, UPB_SYNTAX_PROTO2, &reftables[42], &reftables[43]),
 };
 
-static const upb_fielddef fields[105] = {
+static const upb_fielddef fields[107] = {
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "aggregate_value", 8, &msgs[20], NULL, 15, 6, {0},&reftables[44], &reftables[45]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "allow_alias", 2, &msgs[4], NULL, 6, 1, {0},&reftables[46], &reftables[47]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_enable_arenas", 31, &msgs[11], NULL, 23, 12, {0},&reftables[48], &reftables[49]),
@@ -6590,18 +6482,18 @@
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "ctype", 1, &msgs[8], (const upb_def*)(&enums[2]), 6, 1, {0},&reftables[56], &reftables[57]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "default_value", 7, &msgs[7], NULL, 16, 7, {0},&reftables[58], &reftables[59]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "dependency", 3, &msgs[9], NULL, 30, 8, {0},&reftables[60], &reftables[61]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[12], NULL, 8, 3, {0},&reftables[62], &reftables[63]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[8], NULL, 8, 3, {0},&reftables[64], &reftables[65]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[14], NULL, 6, 1, {0},&reftables[66], &reftables[67]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[8], NULL, 8, 3, {0},&reftables[62], &reftables[63]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[14], NULL, 6, 1, {0},&reftables[64], &reftables[65]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[12], NULL, 8, 3, {0},&reftables[66], &reftables[67]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 23, &msgs[11], NULL, 21, 10, {0},&reftables[68], &reftables[69]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[4], NULL, 7, 2, {0},&reftables[70], &reftables[71]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[17], NULL, 6, 1, {0},&reftables[72], &reftables[73]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 1, &msgs[6], NULL, 6, 1, {0},&reftables[74], &reftables[75]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 1, &msgs[6], NULL, 6, 1, {0},&reftables[70], &reftables[71]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[4], NULL, 7, 2, {0},&reftables[72], &reftables[73]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[17], NULL, 6, 1, {0},&reftables[74], &reftables[75]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_DOUBLE, 0, false, false, false, false, "double_value", 6, &msgs[20], NULL, 11, 4, {0},&reftables[76], &reftables[77]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[2], NULL, 3, 1, {0},&reftables[78], &reftables[79]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[1], NULL, 3, 1, {0},&reftables[80], &reftables[81]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 4, &msgs[0], (const upb_def*)(&msgs[3]), 18, 2, {0},&reftables[82], &reftables[83]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 5, &msgs[9], (const upb_def*)(&msgs[3]), 13, 1, {0},&reftables[84], &reftables[85]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 5, &msgs[9], (const upb_def*)(&msgs[3]), 13, 1, {0},&reftables[82], &reftables[83]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 4, &msgs[0], (const upb_def*)(&msgs[3]), 18, 2, {0},&reftables[84], &reftables[85]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "extendee", 2, &msgs[7], NULL, 7, 2, {0},&reftables[86], &reftables[87]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 6, &msgs[0], (const upb_def*)(&msgs[7]), 24, 4, {0},&reftables[88], &reftables[89]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 7, &msgs[9], (const upb_def*)(&msgs[7]), 19, 3, {0},&reftables[90], &reftables[91]),
@@ -6630,77 +6522,79 @@
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "message_set_wire_format", 1, &msgs[12], NULL, 6, 1, {0},&reftables[136], &reftables[137]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "message_type", 4, &msgs[9], (const upb_def*)(&msgs[0]), 10, 0, {0},&reftables[138], &reftables[139]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "method", 2, &msgs[16], (const upb_def*)(&msgs[13]), 6, 0, {0},&reftables[140], &reftables[141]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[3], NULL, 8, 2, {0},&reftables[142], &reftables[143]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[15], NULL, 2, 0, {0},&reftables[144], &reftables[145]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "name", 2, &msgs[20], (const upb_def*)(&msgs[21]), 5, 0, {0},&reftables[146], &reftables[147]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[0], NULL, 32, 8, {0},&reftables[148], &reftables[149]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[5], NULL, 4, 1, {0},&reftables[150], &reftables[151]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[9], NULL, 22, 6, {0},&reftables[152], &reftables[153]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[7], NULL, 4, 1, {0},&reftables[154], &reftables[155]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[13], NULL, 4, 1, {0},&reftables[156], &reftables[157]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[16], NULL, 8, 2, {0},&reftables[158], &reftables[159]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "name", 2, &msgs[20], (const upb_def*)(&msgs[21]), 5, 0, {0},&reftables[142], &reftables[143]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[5], NULL, 4, 1, {0},&reftables[144], &reftables[145]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[9], NULL, 22, 6, {0},&reftables[146], &reftables[147]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[3], NULL, 8, 2, {0},&reftables[148], &reftables[149]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[16], NULL, 8, 2, {0},&reftables[150], &reftables[151]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[15], NULL, 2, 0, {0},&reftables[152], &reftables[153]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[13], NULL, 4, 1, {0},&reftables[154], &reftables[155]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[7], NULL, 4, 1, {0},&reftables[156], &reftables[157]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[0], NULL, 32, 8, {0},&reftables[158], &reftables[159]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_STRING, 0, false, false, false, false, "name_part", 1, &msgs[21], NULL, 2, 0, {0},&reftables[160], &reftables[161]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, false, "negative_int_value", 5, &msgs[20], NULL, 10, 3, {0},&reftables[162], &reftables[163]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "nested_type", 3, &msgs[0], (const upb_def*)(&msgs[0]), 15, 1, {0},&reftables[164], &reftables[165]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "no_standard_descriptor_accessor", 2, &msgs[12], NULL, 7, 2, {0},&reftables[166], &reftables[167]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 2, &msgs[5], NULL, 7, 2, {0},&reftables[168], &reftables[169]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 3, &msgs[7], NULL, 10, 3, {0},&reftables[170], &reftables[171]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 3, &msgs[7], NULL, 10, 3, {0},&reftables[168], &reftables[169]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 2, &msgs[5], NULL, 7, 2, {0},&reftables[170], &reftables[171]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "objc_class_prefix", 36, &msgs[11], NULL, 24, 13, {0},&reftables[172], &reftables[173]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "oneof_decl", 8, &msgs[0], (const upb_def*)(&msgs[15]), 28, 6, {0},&reftables[174], &reftables[175]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "oneof_index", 9, &msgs[7], NULL, 19, 8, {0},&reftables[176], &reftables[177]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "optimize_for", 9, &msgs[11], (const upb_def*)(&enums[4]), 12, 3, {0},&reftables[178], &reftables[179]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 7, &msgs[0], (const upb_def*)(&msgs[12]), 25, 5, {0},&reftables[180], &reftables[181]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[9], (const upb_def*)(&msgs[11]), 20, 4, {0},&reftables[182], &reftables[183]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 4, &msgs[13], (const upb_def*)(&msgs[14]), 3, 0, {0},&reftables[184], &reftables[185]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[7], (const upb_def*)(&msgs[8]), 3, 0, {0},&reftables[186], &reftables[187]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[7], (const upb_def*)(&msgs[8]), 3, 0, {0},&reftables[184], &reftables[185]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 4, &msgs[13], (const upb_def*)(&msgs[14]), 3, 0, {0},&reftables[186], &reftables[187]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[16], (const upb_def*)(&msgs[17]), 7, 1, {0},&reftables[188], &reftables[189]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[5], (const upb_def*)(&msgs[6]), 3, 0, {0},&reftables[190], &reftables[191]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[3], (const upb_def*)(&msgs[4]), 7, 1, {0},&reftables[192], &reftables[193]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[3], (const upb_def*)(&msgs[4]), 7, 1, {0},&reftables[190], &reftables[191]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[5], (const upb_def*)(&msgs[6]), 3, 0, {0},&reftables[192], &reftables[193]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "output_type", 3, &msgs[13], NULL, 10, 3, {0},&reftables[194], &reftables[195]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "package", 2, &msgs[9], NULL, 25, 7, {0},&reftables[196], &reftables[197]),
   UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "packed", 2, &msgs[8], NULL, 7, 2, {0},&reftables[198], &reftables[199]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "path", 1, &msgs[19], NULL, 4, 0, {0},&reftables[200], &reftables[201]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, false, "positive_int_value", 4, &msgs[20], NULL, 9, 2, {0},&reftables[202], &reftables[203]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "public_dependency", 10, &msgs[9], NULL, 35, 9, {0},&reftables[204], &reftables[205]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "py_generic_services", 18, &msgs[11], NULL, 19, 8, {0},&reftables[206], &reftables[207]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "reserved_name", 10, &msgs[0], NULL, 37, 9, {0},&reftables[208], &reftables[209]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "reserved_range", 9, &msgs[0], (const upb_def*)(&msgs[2]), 31, 7, {0},&reftables[210], &reftables[211]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "server_streaming", 6, &msgs[13], NULL, 14, 5, {0},&reftables[212], &reftables[213]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "service", 6, &msgs[9], (const upb_def*)(&msgs[16]), 16, 2, {0},&reftables[214], &reftables[215]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "source_code_info", 9, &msgs[9], (const upb_def*)(&msgs[18]), 21, 5, {0},&reftables[216], &reftables[217]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "span", 2, &msgs[19], NULL, 7, 1, {0},&reftables[218], &reftables[219]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[2], NULL, 2, 0, {0},&reftables[220], &reftables[221]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[1], NULL, 2, 0, {0},&reftables[222], &reftables[223]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, false, "string_value", 7, &msgs[20], NULL, 12, 5, {0},&reftables[224], &reftables[225]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "syntax", 12, &msgs[9], NULL, 39, 11, {0},&reftables[226], &reftables[227]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "trailing_comments", 4, &msgs[19], NULL, 11, 3, {0},&reftables[228], &reftables[229]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "type", 5, &msgs[7], (const upb_def*)(&enums[1]), 12, 5, {0},&reftables[230], &reftables[231]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "type_name", 6, &msgs[7], NULL, 13, 6, {0},&reftables[232], &reftables[233]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[11], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[234], &reftables[235]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[12], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[236], &reftables[237]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[6], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[238], &reftables[239]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[4], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[240], &reftables[241]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[8], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[242], &reftables[243]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_class_prefix", 40, &msgs[11], NULL, 31, 16, {0},&reftables[202], &reftables[203]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_namespace", 41, &msgs[11], NULL, 34, 17, {0},&reftables[204], &reftables[205]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, false, "positive_int_value", 4, &msgs[20], NULL, 9, 2, {0},&reftables[206], &reftables[207]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "public_dependency", 10, &msgs[9], NULL, 35, 9, {0},&reftables[208], &reftables[209]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "py_generic_services", 18, &msgs[11], NULL, 19, 8, {0},&reftables[210], &reftables[211]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "reserved_name", 10, &msgs[0], NULL, 37, 9, {0},&reftables[212], &reftables[213]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "reserved_range", 9, &msgs[0], (const upb_def*)(&msgs[2]), 31, 7, {0},&reftables[214], &reftables[215]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "server_streaming", 6, &msgs[13], NULL, 14, 5, {0},&reftables[216], &reftables[217]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "service", 6, &msgs[9], (const upb_def*)(&msgs[16]), 16, 2, {0},&reftables[218], &reftables[219]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "source_code_info", 9, &msgs[9], (const upb_def*)(&msgs[18]), 21, 5, {0},&reftables[220], &reftables[221]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "span", 2, &msgs[19], NULL, 7, 1, {0},&reftables[222], &reftables[223]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[2], NULL, 2, 0, {0},&reftables[224], &reftables[225]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[1], NULL, 2, 0, {0},&reftables[226], &reftables[227]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, false, "string_value", 7, &msgs[20], NULL, 12, 5, {0},&reftables[228], &reftables[229]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "syntax", 12, &msgs[9], NULL, 39, 11, {0},&reftables[230], &reftables[231]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "trailing_comments", 4, &msgs[19], NULL, 11, 3, {0},&reftables[232], &reftables[233]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "type", 5, &msgs[7], (const upb_def*)(&enums[1]), 12, 5, {0},&reftables[234], &reftables[235]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "type_name", 6, &msgs[7], NULL, 13, 6, {0},&reftables[236], &reftables[237]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[12], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[238], &reftables[239]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[17], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[240], &reftables[241]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[11], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[242], &reftables[243]),
   UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[14], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[244], &reftables[245]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[17], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[246], &reftables[247]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "value", 2, &msgs[3], (const upb_def*)(&msgs[5]), 6, 0, {0},&reftables[248], &reftables[249]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "weak", 10, &msgs[8], NULL, 11, 6, {0},&reftables[250], &reftables[251]),
-  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "weak_dependency", 11, &msgs[9], NULL, 38, 10, {0},&reftables[252], &reftables[253]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[8], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[246], &reftables[247]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[6], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[248], &reftables[249]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[4], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[250], &reftables[251]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "value", 2, &msgs[3], (const upb_def*)(&msgs[5]), 6, 0, {0},&reftables[252], &reftables[253]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "weak", 10, &msgs[8], NULL, 11, 6, {0},&reftables[254], &reftables[255]),
+  UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "weak_dependency", 11, &msgs[9], NULL, 38, 10, {0},&reftables[256], &reftables[257]),
 };
 
 static const upb_enumdef enums[5] = {
-  UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Label", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[188]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[151], 4, 3), 0, &reftables[254], &reftables[255]),
-  UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Type", UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_INT32, 5, &strentries[192]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[155], 19, 18), 0, &reftables[256], &reftables[257]),
-  UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.CType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[224]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[174], 3, 3), 0, &reftables[258], &reftables[259]),
-  UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.JSType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[228]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[177], 3, 3), 0, &reftables[260], &reftables[261]),
-  UPB_ENUMDEF_INIT("google.protobuf.FileOptions.OptimizeMode", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[232]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[180], 4, 3), 0, &reftables[262], &reftables[263]),
+  UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Label", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[188]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[154], 4, 3), 0, &reftables[258], &reftables[259]),
+  UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Type", UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_INT32, 5, &strentries[192]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[158], 19, 18), 0, &reftables[260], &reftables[261]),
+  UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.CType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[224]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[177], 3, 3), 0, &reftables[262], &reftables[263]),
+  UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.JSType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[228]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[180], 3, 3), 0, &reftables[264], &reftables[265]),
+  UPB_ENUMDEF_INIT("google.protobuf.FileOptions.OptimizeMode", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[232]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[183], 4, 3), 0, &reftables[266], &reftables[267]),
 };
 
 static const upb_tabent strentries[236] = {
   {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[22]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "reserved_name"), UPB_TABVALUE_PTR_INIT(&fields[82]), NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[52]), NULL},
+  {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "reserved_name"), UPB_TABVALUE_PTR_INIT(&fields[84]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[57]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
@@ -6709,53 +6603,53 @@
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "nested_type"), UPB_TABVALUE_PTR_INIT(&fields[60]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "reserved_range"), UPB_TABVALUE_PTR_INIT(&fields[83]), NULL},
+  {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "reserved_range"), UPB_TABVALUE_PTR_INIT(&fields[85]), NULL},
   {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[68]), NULL},
   {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "oneof_decl"), UPB_TABVALUE_PTR_INIT(&fields[65]), NULL},
-  {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[19]), &strentries[13]},
-  {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[89]), NULL},
+  {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[20]), &strentries[13]},
+  {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[91]), NULL},
   {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "end"), UPB_TABVALUE_PTR_INIT(&fields[18]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[88]), NULL},
+  {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[90]), NULL},
   {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "end"), UPB_TABVALUE_PTR_INIT(&fields[17]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[102]), NULL},
-  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[74]), NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[49]), &strentries[26]},
-  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL},
-  {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[13]), NULL},
+  {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[104]), NULL},
+  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[73]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[52]), &strentries[26]},
+  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[103]), NULL},
+  {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[14]), NULL},
   {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "allow_alias"), UPB_TABVALUE_PTR_INIT(&fields[1]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[62]), NULL},
+  {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[63]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[73]), NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[53]), &strentries[34]},
-  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL},
-  {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[15]), NULL},
+  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[74]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[50]), &strentries[34]},
+  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[102]), NULL},
+  {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[13]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "oneof_index"), UPB_TABVALUE_PTR_INIT(&fields[66]), NULL},
   {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "label"), UPB_TABVALUE_PTR_INIT(&fields[40]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[55]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[56]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[63]), &strentries[53]},
+  {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[62]), &strentries[53]},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\010", "\000", "\000", "\000", "extendee"), UPB_TABVALUE_PTR_INIT(&fields[21]), NULL},
-  {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "type_name"), UPB_TABVALUE_PTR_INIT(&fields[94]), NULL},
+  {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "type_name"), UPB_TABVALUE_PTR_INIT(&fields[96]), NULL},
   {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "json_name"), UPB_TABVALUE_PTR_INIT(&fields[38]), NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "type"), UPB_TABVALUE_PTR_INIT(&fields[93]), &strentries[50]},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "type"), UPB_TABVALUE_PTR_INIT(&fields[95]), &strentries[50]},
   {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "default_value"), UPB_TABVALUE_PTR_INIT(&fields[7]), NULL},
-  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[71]), NULL},
-  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[99]), NULL},
+  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[70]), NULL},
+  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "weak"), UPB_TABVALUE_PTR_INIT(&fields[103]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "weak"), UPB_TABVALUE_PTR_INIT(&fields[105]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
@@ -6766,25 +6660,25 @@
   {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "ctype"), UPB_TABVALUE_PTR_INIT(&fields[6]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "jstype"), UPB_TABVALUE_PTR_INIT(&fields[39]), NULL},
-  {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL},
+  {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[9]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[23]), NULL},
-  {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "weak_dependency"), UPB_TABVALUE_PTR_INIT(&fields[104]), NULL},
+  {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "weak_dependency"), UPB_TABVALUE_PTR_INIT(&fields[106]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[54]), NULL},
-  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "service"), UPB_TABVALUE_PTR_INIT(&fields[85]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[51]), NULL},
+  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "service"), UPB_TABVALUE_PTR_INIT(&fields[87]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "source_code_info"), UPB_TABVALUE_PTR_INIT(&fields[86]), NULL},
+  {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "source_code_info"), UPB_TABVALUE_PTR_INIT(&fields[88]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "syntax"), UPB_TABVALUE_PTR_INIT(&fields[91]), NULL},
+  {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "syntax"), UPB_TABVALUE_PTR_INIT(&fields[93]), NULL},
   {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "dependency"), UPB_TABVALUE_PTR_INIT(&fields[8]), NULL},
   {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "message_type"), UPB_TABVALUE_PTR_INIT(&fields[47]), NULL},
   {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "package"), UPB_TABVALUE_PTR_INIT(&fields[76]), NULL},
   {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[69]), &strentries[86]},
-  {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[20]), NULL},
-  {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "public_dependency"), UPB_TABVALUE_PTR_INIT(&fields[80]), &strentries[85]},
+  {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[19]), NULL},
+  {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "public_dependency"), UPB_TABVALUE_PTR_INIT(&fields[82]), &strentries[85]},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "file"), UPB_TABVALUE_PTR_INIT(&fields[26]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
@@ -6792,7 +6686,7 @@
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "cc_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[3]), NULL},
-  {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "csharp_namespace"), UPB_TABVALUE_PTR_INIT(&fields[5]), NULL},
+  {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "csharp_namespace"), UPB_TABVALUE_PTR_INIT(&fields[5]), &strentries[116]},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
@@ -6805,17 +6699,17 @@
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "java_outer_classname"), UPB_TABVALUE_PTR_INIT(&fields[34]), NULL},
-  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[95]), NULL},
+  {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "php_namespace"), UPB_TABVALUE_PTR_INIT(&fields[80]), &strentries[113]},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "java_multiple_files"), UPB_TABVALUE_PTR_INIT(&fields[33]), &strentries[117]},
-  {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[99]), NULL},
   {UPB_TABKEY_STR("\025", "\000", "\000", "\000", "java_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[32]), &strentries[118]},
   {UPB_TABKEY_STR("\035", "\000", "\000", "\000", "java_generate_equals_and_hash"), UPB_TABVALUE_PTR_INIT(&fields[31]), NULL},
-  {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+  {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "php_class_prefix"), UPB_TABVALUE_PTR_INIT(&fields[79]), NULL},
   {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "javanano_use_deprecated_package"), UPB_TABVALUE_PTR_INIT(&fields[37]), &strentries[123]},
-  {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "py_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[81]), NULL},
+  {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "py_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[83]), NULL},
   {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "optimize_for"), UPB_TABVALUE_PTR_INIT(&fields[67]), NULL},
   {UPB_TABKEY_STR("\026", "\000", "\000", "\000", "java_string_check_utf8"), UPB_TABVALUE_PTR_INIT(&fields[36]), NULL},
   {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[12]), &strentries[119]},
@@ -6825,32 +6719,32 @@
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[96]), NULL},
-  {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[9]), NULL},
+  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL},
+  {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[11]), NULL},
   {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "map_entry"), UPB_TABVALUE_PTR_INIT(&fields[45]), NULL},
   {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "no_standard_descriptor_accessor"), UPB_TABVALUE_PTR_INIT(&fields[61]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "client_streaming"), UPB_TABVALUE_PTR_INIT(&fields[4]), NULL},
-  {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "server_streaming"), UPB_TABVALUE_PTR_INIT(&fields[84]), NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[56]), NULL},
+  {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "server_streaming"), UPB_TABVALUE_PTR_INIT(&fields[86]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[55]), NULL},
   {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "input_type"), UPB_TABVALUE_PTR_INIT(&fields[29]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "output_type"), UPB_TABVALUE_PTR_INIT(&fields[75]), NULL},
-  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[70]), NULL},
+  {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[71]), NULL},
   {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL},
-  {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[11]), NULL},
+  {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[50]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[54]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[72]), &strentries[150]},
   {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "method"), UPB_TABVALUE_PTR_INIT(&fields[48]), NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[57]), &strentries[149]},
-  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL},
-  {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[14]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[53]), &strentries[149]},
+  {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL},
+  {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[15]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
@@ -6860,15 +6754,15 @@
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "span"), UPB_TABVALUE_PTR_INIT(&fields[87]), &strentries[167]},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "span"), UPB_TABVALUE_PTR_INIT(&fields[89]), &strentries[167]},
   {UPB_TABKEY_STR("\031", "\000", "\000", "\000", "leading_detached_comments"), UPB_TABVALUE_PTR_INIT(&fields[43]), &strentries[165]},
-  {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "trailing_comments"), UPB_TABVALUE_PTR_INIT(&fields[92]), NULL},
+  {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "trailing_comments"), UPB_TABVALUE_PTR_INIT(&fields[94]), NULL},
   {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "leading_comments"), UPB_TABVALUE_PTR_INIT(&fields[42]), &strentries[164]},
   {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "path"), UPB_TABVALUE_PTR_INIT(&fields[78]), NULL},
   {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "double_value"), UPB_TABVALUE_PTR_INIT(&fields[16]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[51]), NULL},
+  {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[49]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
@@ -6878,9 +6772,9 @@
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "positive_int_value"), UPB_TABVALUE_PTR_INIT(&fields[79]), NULL},
+  {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "positive_int_value"), UPB_TABVALUE_PTR_INIT(&fields[81]), NULL},
   {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "identifier_value"), UPB_TABVALUE_PTR_INIT(&fields[28]), NULL},
-  {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "string_value"), UPB_TABVALUE_PTR_INIT(&fields[90]), &strentries[182]},
+  {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "string_value"), UPB_TABVALUE_PTR_INIT(&fields[92]), &strentries[182]},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "is_extension"), UPB_TABVALUE_PTR_INIT(&fields[30]), NULL},
@@ -6937,92 +6831,92 @@
 
 static const upb_tabent intentries[18] = {
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL},
+  {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[103]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL},
+  {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[102]), NULL},
+  {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+  {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[99]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[95]), NULL},
+  {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[96]), NULL},
-  {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[11]), NULL},
+  {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
   {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[14]), NULL},
+  {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[15]), NULL},
   {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
-  {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL},
+  {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL},
 };
 
-static const upb_tabval arrays[184] = {
+static const upb_tabval arrays[187] = {
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[52]),
+  UPB_TABVALUE_PTR_INIT(&fields[57]),
   UPB_TABVALUE_PTR_INIT(&fields[25]),
   UPB_TABVALUE_PTR_INIT(&fields[60]),
-  UPB_TABVALUE_PTR_INIT(&fields[19]),
+  UPB_TABVALUE_PTR_INIT(&fields[20]),
   UPB_TABVALUE_PTR_INIT(&fields[24]),
   UPB_TABVALUE_PTR_INIT(&fields[22]),
   UPB_TABVALUE_PTR_INIT(&fields[68]),
   UPB_TABVALUE_PTR_INIT(&fields[65]),
-  UPB_TABVALUE_PTR_INIT(&fields[83]),
-  UPB_TABVALUE_PTR_INIT(&fields[82]),
+  UPB_TABVALUE_PTR_INIT(&fields[85]),
+  UPB_TABVALUE_PTR_INIT(&fields[84]),
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[89]),
+  UPB_TABVALUE_PTR_INIT(&fields[91]),
   UPB_TABVALUE_PTR_INIT(&fields[18]),
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[88]),
+  UPB_TABVALUE_PTR_INIT(&fields[90]),
   UPB_TABVALUE_PTR_INIT(&fields[17]),
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[49]),
-  UPB_TABVALUE_PTR_INIT(&fields[102]),
-  UPB_TABVALUE_PTR_INIT(&fields[74]),
+  UPB_TABVALUE_PTR_INIT(&fields[52]),
+  UPB_TABVALUE_PTR_INIT(&fields[104]),
+  UPB_TABVALUE_PTR_INIT(&fields[73]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[1]),
+  UPB_TABVALUE_PTR_INIT(&fields[14]),
+  UPB_TABVALUE_EMPTY_INIT,
+  UPB_TABVALUE_PTR_INIT(&fields[50]),
+  UPB_TABVALUE_PTR_INIT(&fields[63]),
+  UPB_TABVALUE_PTR_INIT(&fields[74]),
+  UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[13]),
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[53]),
-  UPB_TABVALUE_PTR_INIT(&fields[62]),
-  UPB_TABVALUE_PTR_INIT(&fields[73]),
-  UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[15]),
-  UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[55]),
+  UPB_TABVALUE_PTR_INIT(&fields[56]),
   UPB_TABVALUE_PTR_INIT(&fields[21]),
-  UPB_TABVALUE_PTR_INIT(&fields[63]),
+  UPB_TABVALUE_PTR_INIT(&fields[62]),
   UPB_TABVALUE_PTR_INIT(&fields[40]),
-  UPB_TABVALUE_PTR_INIT(&fields[93]),
-  UPB_TABVALUE_PTR_INIT(&fields[94]),
+  UPB_TABVALUE_PTR_INIT(&fields[95]),
+  UPB_TABVALUE_PTR_INIT(&fields[96]),
   UPB_TABVALUE_PTR_INIT(&fields[7]),
-  UPB_TABVALUE_PTR_INIT(&fields[71]),
+  UPB_TABVALUE_PTR_INIT(&fields[70]),
   UPB_TABVALUE_PTR_INIT(&fields[66]),
   UPB_TABVALUE_PTR_INIT(&fields[38]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[6]),
   UPB_TABVALUE_PTR_INIT(&fields[77]),
-  UPB_TABVALUE_PTR_INIT(&fields[10]),
+  UPB_TABVALUE_PTR_INIT(&fields[9]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[41]),
   UPB_TABVALUE_PTR_INIT(&fields[39]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[103]),
+  UPB_TABVALUE_PTR_INIT(&fields[105]),
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[54]),
+  UPB_TABVALUE_PTR_INIT(&fields[51]),
   UPB_TABVALUE_PTR_INIT(&fields[76]),
   UPB_TABVALUE_PTR_INIT(&fields[8]),
   UPB_TABVALUE_PTR_INIT(&fields[47]),
-  UPB_TABVALUE_PTR_INIT(&fields[20]),
-  UPB_TABVALUE_PTR_INIT(&fields[85]),
+  UPB_TABVALUE_PTR_INIT(&fields[19]),
+  UPB_TABVALUE_PTR_INIT(&fields[87]),
   UPB_TABVALUE_PTR_INIT(&fields[23]),
   UPB_TABVALUE_PTR_INIT(&fields[69]),
-  UPB_TABVALUE_PTR_INIT(&fields[86]),
-  UPB_TABVALUE_PTR_INIT(&fields[80]),
-  UPB_TABVALUE_PTR_INIT(&fields[104]),
-  UPB_TABVALUE_PTR_INIT(&fields[91]),
+  UPB_TABVALUE_PTR_INIT(&fields[88]),
+  UPB_TABVALUE_PTR_INIT(&fields[82]),
+  UPB_TABVALUE_PTR_INIT(&fields[106]),
+  UPB_TABVALUE_PTR_INIT(&fields[93]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[26]),
   UPB_TABVALUE_EMPTY_INIT,
@@ -7043,7 +6937,7 @@
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[3]),
   UPB_TABVALUE_PTR_INIT(&fields[32]),
-  UPB_TABVALUE_PTR_INIT(&fields[81]),
+  UPB_TABVALUE_PTR_INIT(&fields[83]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[31]),
   UPB_TABVALUE_EMPTY_INIT,
@@ -7065,25 +6959,28 @@
   UPB_TABVALUE_PTR_INIT(&fields[5]),
   UPB_TABVALUE_PTR_INIT(&fields[37]),
   UPB_TABVALUE_EMPTY_INIT,
+  UPB_TABVALUE_PTR_INIT(&fields[79]),
+  UPB_TABVALUE_PTR_INIT(&fields[80]),
+  UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[46]),
   UPB_TABVALUE_PTR_INIT(&fields[61]),
-  UPB_TABVALUE_PTR_INIT(&fields[9]),
+  UPB_TABVALUE_PTR_INIT(&fields[11]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[45]),
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[56]),
+  UPB_TABVALUE_PTR_INIT(&fields[55]),
   UPB_TABVALUE_PTR_INIT(&fields[29]),
   UPB_TABVALUE_PTR_INIT(&fields[75]),
-  UPB_TABVALUE_PTR_INIT(&fields[70]),
+  UPB_TABVALUE_PTR_INIT(&fields[71]),
   UPB_TABVALUE_PTR_INIT(&fields[4]),
-  UPB_TABVALUE_PTR_INIT(&fields[84]),
+  UPB_TABVALUE_PTR_INIT(&fields[86]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[50]),
+  UPB_TABVALUE_PTR_INIT(&fields[54]),
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[57]),
+  UPB_TABVALUE_PTR_INIT(&fields[53]),
   UPB_TABVALUE_PTR_INIT(&fields[48]),
   UPB_TABVALUE_PTR_INIT(&fields[72]),
   UPB_TABVALUE_EMPTY_INIT,
@@ -7091,19 +6988,19 @@
   UPB_TABVALUE_PTR_INIT(&fields[44]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[78]),
-  UPB_TABVALUE_PTR_INIT(&fields[87]),
+  UPB_TABVALUE_PTR_INIT(&fields[89]),
   UPB_TABVALUE_PTR_INIT(&fields[42]),
-  UPB_TABVALUE_PTR_INIT(&fields[92]),
+  UPB_TABVALUE_PTR_INIT(&fields[94]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[43]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_EMPTY_INIT,
-  UPB_TABVALUE_PTR_INIT(&fields[51]),
+  UPB_TABVALUE_PTR_INIT(&fields[49]),
   UPB_TABVALUE_PTR_INIT(&fields[28]),
-  UPB_TABVALUE_PTR_INIT(&fields[79]),
+  UPB_TABVALUE_PTR_INIT(&fields[81]),
   UPB_TABVALUE_PTR_INIT(&fields[59]),
   UPB_TABVALUE_PTR_INIT(&fields[16]),
-  UPB_TABVALUE_PTR_INIT(&fields[90]),
+  UPB_TABVALUE_PTR_INIT(&fields[92]),
   UPB_TABVALUE_PTR_INIT(&fields[0]),
   UPB_TABVALUE_EMPTY_INIT,
   UPB_TABVALUE_PTR_INIT(&fields[58]),
@@ -7144,7 +7041,11 @@
 };
 
 #ifdef UPB_DEBUG_REFS
-static upb_inttable reftables[264] = {
+static upb_inttable reftables[268] = {
+  UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+  UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+  UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+  UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
   UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
   UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
   UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
@@ -7686,6 +7587,37 @@
   return n;
 }
 
+static size_t file_onphpnamespace(void *closure, const void *hd,
+                                  const char *buf, size_t n,
+                                  const upb_bufhandle *handle) {
+  upb_descreader *r = closure;
+  char *php_namespace;
+  bool ok;
+  UPB_UNUSED(hd);
+  UPB_UNUSED(handle);
+
+  php_namespace = upb_gstrndup(buf, n);
+  ok = upb_filedef_setphpnamespace(r->file, php_namespace, NULL);
+  upb_gfree(php_namespace);
+  UPB_ASSERT(ok);
+  return n;
+}
+
+static size_t file_onphpprefix(void *closure, const void *hd, const char *buf,
+                             size_t n, const upb_bufhandle *handle) {
+  upb_descreader *r = closure;
+  char *prefix;
+  bool ok;
+  UPB_UNUSED(hd);
+  UPB_UNUSED(handle);
+
+  prefix = upb_gstrndup(buf, n);
+  ok = upb_filedef_setphpprefix(r->file, prefix, NULL);
+  upb_gfree(prefix);
+  UPB_ASSERT(ok);
+  return n;
+}
+
 static size_t file_onsyntax(void *closure, const void *hd, const char *buf,
                             size_t n, const upb_bufhandle *handle) {
   upb_descreader *r = closure;
@@ -8212,6 +8144,11 @@
     upb_handlers_setbool(h, F(FieldOptions, packed), &field_onpacked, NULL);
   } else if (upbdefs_google_protobuf_MessageOptions_is(m)) {
     upb_handlers_setbool(h, F(MessageOptions, map_entry), &msg_onmapentry, NULL);
+  } else if (upbdefs_google_protobuf_FileOptions_is(m)) {
+    upb_handlers_setstring(h, F(FileOptions, php_class_prefix),
+                           &file_onphpprefix, NULL);
+    upb_handlers_setstring(h, F(FileOptions, php_namespace),
+                           &file_onphpnamespace, NULL);
   }
 
   UPB_ASSERT(upb_ok(upb_handlers_status(h)));
@@ -10759,7 +10696,7 @@
 T(double,   double,   dbl2uint64,   encode_fixed64)
 T(float,    float,    flt2uint32,   encode_fixed32)
 T(int64,    int64_t,  uint64_t,     encode_varint)
-T(int32,    int32_t,  uint32_t,     encode_varint)
+T(int32,    int32_t,  int64_t,      encode_varint)
 T(fixed64,  uint64_t, uint64_t,     encode_fixed64)
 T(fixed32,  uint32_t, uint32_t,     encode_fixed32)
 T(bool,     bool,     bool,         encode_varint)
@@ -11374,57 +11311,6 @@
   return r;
 }
 
-/* Given an encoded varint v, returns an integer with a single bit set that
- * indicates the end of the varint.  Subtracting one from this value will
- * yield a mask that leaves only bits that are part of the varint.  Returns
- * 0 if the varint is unterminated. */
-static uint64_t upb_get_vstopbit(uint64_t v) {
-  uint64_t cbits = v | 0x7f7f7f7f7f7f7f7fULL;
-  return ~cbits & (cbits+1);
-}
-
-/* A branchless decoder.  Credit to Pascal Massimino for the bit-twiddling. */
-upb_decoderet upb_vdecode_max8_massimino(upb_decoderet r) {
-  uint64_t b;
-  uint64_t stop_bit;
-  upb_decoderet my_r;
-  memcpy(&b, r.p, sizeof(b));
-  stop_bit = upb_get_vstopbit(b);
-  b =  (b & 0x7f7f7f7f7f7f7f7fULL) & (stop_bit - 1);
-  b +=       b & 0x007f007f007f007fULL;
-  b +=  3 * (b & 0x0000ffff0000ffffULL);
-  b += 15 * (b & 0x00000000ffffffffULL);
-  if (stop_bit == 0) {
-    /* Error: unterminated varint. */
-    upb_decoderet err_r = {(void*)0, 0};
-    return err_r;
-  }
-  my_r = upb_decoderet_make(r.p + ((__builtin_ctzll(stop_bit) + 1) / 8),
-                            r.val | (b << 7));
-  return my_r;
-}
-
-/* A branchless decoder.  Credit to Daniel Wright for the bit-twiddling. */
-upb_decoderet upb_vdecode_max8_wright(upb_decoderet r) {
-  uint64_t b;
-  uint64_t stop_bit;
-  upb_decoderet my_r;
-  memcpy(&b, r.p, sizeof(b));
-  stop_bit = upb_get_vstopbit(b);
-  b &= (stop_bit - 1);
-  b = ((b & 0x7f007f007f007f00ULL) >> 1) | (b & 0x007f007f007f007fULL);
-  b = ((b & 0xffff0000ffff0000ULL) >> 2) | (b & 0x0000ffff0000ffffULL);
-  b = ((b & 0xffffffff00000000ULL) >> 4) | (b & 0x00000000ffffffffULL);
-  if (stop_bit == 0) {
-    /* Error: unterminated varint. */
-    upb_decoderet err_r = {(void*)0, 0};
-    return err_r;
-  }
-  my_r = upb_decoderet_make(r.p + ((__builtin_ctzll(stop_bit) + 1) / 8),
-                            r.val | (b << 14));
-  return my_r;
-}
-
 #line 1 "upb/json/parser.rl"
 /*
 ** upb::json::Parser (upb_json_parser)
@@ -11447,8 +11333,9 @@
 ** - handling of keys/escape-sequences/etc that span input buffers.
 */
 
-#include <assert.h>
 #include <errno.h>
+#include <float.h>
+#include <math.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
@@ -12033,21 +11920,136 @@
   capture_begin(p, ptr);
 }
 
-static bool parse_number(upb_json_parser *p);
+static bool parse_number(upb_json_parser *p, bool is_quoted);
 
 static bool end_number(upb_json_parser *p, const char *ptr) {
   if (!capture_end(p, ptr)) {
     return false;
   }
 
-  return parse_number(p);
+  return parse_number(p, false);
 }
 
-static bool parse_number(upb_json_parser *p) {
+static bool parse_number_from_buffer(upb_json_parser *p, const char *buf,
+                                     const char *bufend, bool is_quoted) {
+  size_t len = bufend - buf;
+  char *end;
+  upb_fieldtype_t type = upb_fielddef_type(p->top->f);
+  double val;
+  double dummy;
+
+  if (buf[0] == ' ') {
+    return false;
+  }
+
+  /* For integer types, first try parsing with integer-specific routines.
+   * If these succeed, they will be more accurate for int64/uint64 than
+   * strtod().
+   */
+  switch (type) {
+    case UPB_TYPE_ENUM:
+    case UPB_TYPE_INT32: {
+      long val = strtol(buf, &end, 0);
+      if (errno == ERANGE || end != bufend) {
+        break;
+      } else if (val > INT32_MAX || val < INT32_MIN) {
+        return false;
+      } else {
+        upb_sink_putint32(&p->top->sink, parser_getsel(p), val);
+        return true;
+      }
+    }
+    case UPB_TYPE_UINT32: {
+      unsigned long val = strtoul(buf, &end, 0);
+      if (end != bufend) {
+        break;
+      } else if (val > UINT32_MAX || errno == ERANGE) {
+        return false;
+      } else {
+        upb_sink_putuint32(&p->top->sink, parser_getsel(p), val);
+        return true;
+      }
+    }
+    /* XXX: We can't handle [u]int64 properly on 32-bit machines because
+     * strto[u]ll isn't in C89. */
+    case UPB_TYPE_INT64: {
+      long val = strtol(buf, &end, 0);
+      if (errno == ERANGE || end != bufend) {
+        break;
+      } else {
+        upb_sink_putint64(&p->top->sink, parser_getsel(p), val);
+        return true;
+      }
+    }
+    case UPB_TYPE_UINT64: {
+      unsigned long val = strtoul(p->accumulated, &end, 0);
+      if (end != bufend) {
+        break;
+      } else if (errno == ERANGE) {
+        return false;
+      } else {
+        upb_sink_putuint64(&p->top->sink, parser_getsel(p), val);
+        return true;
+      }
+    }
+    default:
+      break;
+  }
+
+  if (type != UPB_TYPE_DOUBLE && type != UPB_TYPE_FLOAT && is_quoted) {
+    /* Quoted numbers shouldn't support double forms for integer types. */
+    return false;
+  }
+
+  if (len == strlen("Infinity") && strcmp(buf, "Infinity") == 0) {
+    /* C89 does not have an INFINITY macro. */
+    val = 1.0 / 0.0;
+  } else if (len == strlen("-Infinity") && strcmp(buf, "-Infinity") == 0) {
+    val = -1.0 / 0.0;
+  } else {
+    val = strtod(buf, &end);
+    if (errno == ERANGE || end != bufend) {
+      return false;
+    }
+  }
+
+  switch (type) {
+#define CASE(capitaltype, smalltype, min, max)                            \
+    case UPB_TYPE_ ## capitaltype: {                                      \
+      if (modf(val, &dummy) != 0 || val > max || val < min) {             \
+        return false;                                                     \
+      } else {                                                            \
+        upb_sink_put ## smalltype(&p->top->sink, parser_getsel(p), val);  \
+        return true;                                                      \
+      }                                                                   \
+      break;                                                              \
+    }
+    case UPB_TYPE_ENUM:
+    CASE(INT32, int32, INT32_MIN, INT32_MAX);
+    CASE(INT64, int64, INT64_MIN, INT64_MAX);
+    CASE(UINT32, uint32, 0, UINT32_MAX);
+    CASE(UINT64, uint64, 0, UINT64_MAX);
+#undef CASE
+
+    case UPB_TYPE_DOUBLE:
+      upb_sink_putdouble(&p->top->sink, parser_getsel(p), val);
+      return true;
+    case UPB_TYPE_FLOAT:
+      if (false /*val > FLT_MAX || val < -FLT_MAX*/) {
+        return false;
+      } else {
+        upb_sink_putfloat(&p->top->sink, parser_getsel(p), val);
+        return true;
+      }
+    default:
+      return false;
+  }
+}
+
+static bool parse_number(upb_json_parser *p, bool is_quoted) {
   size_t len;
   const char *buf;
-  const char *myend;
-  char *end;
+  const char *bufend;
 
   /* strtol() and friends unfortunately do not support specifying the length of
    * the input string, so we need to force a copy into a NULL-terminated buffer. */
@@ -12056,80 +12058,18 @@
   }
 
   buf = accumulate_getptr(p, &len);
-  myend = buf + len - 1;  /* One for NULL. */
+  bufend = buf + len - 1;  /* One for NULL. */
+  errno = 0;
 
-  /* XXX: We are using strtol to parse integers, but this is wrong as even
-   * integers can be represented as 1e6 (for example), which strtol can't
-   * handle correctly.
-   *
-   * XXX: Also, we can't handle large integers properly because strto[u]ll
-   * isn't in C89.
-   *
-   * XXX: Also, we don't properly check floats for overflow, since strtof
-   * isn't in C89. */
-  switch (upb_fielddef_type(p->top->f)) {
-    case UPB_TYPE_ENUM:
-    case UPB_TYPE_INT32: {
-      long val = strtol(p->accumulated, &end, 0);
-      if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || end != myend)
-        goto err;
-      else
-        upb_sink_putint32(&p->top->sink, parser_getsel(p), val);
-      break;
-    }
-    case UPB_TYPE_INT64: {
-      long long val = strtol(p->accumulated, &end, 0);
-      if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || end != myend)
-        goto err;
-      else
-        upb_sink_putint64(&p->top->sink, parser_getsel(p), val);
-      break;
-    }
-    case UPB_TYPE_UINT32: {
-      unsigned long val = strtoul(p->accumulated, &end, 0);
-      if (val > UINT32_MAX || errno == ERANGE || end != myend)
-        goto err;
-      else
-        upb_sink_putuint32(&p->top->sink, parser_getsel(p), val);
-      break;
-    }
-    case UPB_TYPE_UINT64: {
-      unsigned long long val = strtoul(p->accumulated, &end, 0);
-      if (val > UINT64_MAX || errno == ERANGE || end != myend)
-        goto err;
-      else
-        upb_sink_putuint64(&p->top->sink, parser_getsel(p), val);
-      break;
-    }
-    case UPB_TYPE_DOUBLE: {
-      double val = strtod(p->accumulated, &end);
-      if (errno == ERANGE || end != myend)
-        goto err;
-      else
-        upb_sink_putdouble(&p->top->sink, parser_getsel(p), val);
-      break;
-    }
-    case UPB_TYPE_FLOAT: {
-      float val = strtod(p->accumulated, &end);
-      if (errno == ERANGE || end != myend)
-        goto err;
-      else
-        upb_sink_putfloat(&p->top->sink, parser_getsel(p), val);
-      break;
-    }
-    default:
-      UPB_ASSERT(false);
+  if (parse_number_from_buffer(p, buf, bufend, is_quoted)) {
+    multipart_end(p);
+    return true;
+  } else {
+    upb_status_seterrf(&p->status, "error parsing number: %s", buf);
+    upb_env_reporterror(p->env, &p->status);
+    multipart_end(p);
+    return false;
   }
-
-  multipart_end(p);
-
-  return true;
-
-err:
-  upb_status_seterrf(&p->status, "error parsing number: %s", buf);
-  upb_env_reporterror(p->env, &p->status);
-  multipart_end(p);
-  return false;
 }
 
 static bool parser_putbool(upb_json_parser *p, bool val) {
@@ -12182,17 +12122,16 @@
       multipart_startaccum(p);
       return true;
     }
-  } else if (upb_fielddef_type(p->top->f) == UPB_TYPE_ENUM) {
-    /* No need to push a frame -- symbolic enum names in quotes remain in the
-     * current parser frame.
-     *
-     * Enum string values must accumulate so we can look up the value in a table
-     * once it is complete. */
+  } else if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL &&
+             upb_fielddef_type(p->top->f) != UPB_TYPE_MESSAGE) {
+    /* No need to push a frame -- numeric values in quotes remain in the
+     * current parser frame.  These values must accmulate so we can convert
+     * them all at once at the end. */
     multipart_startaccum(p);
     return true;
   } else {
     upb_status_seterrf(&p->status,
-                       "String specified for non-string/non-enum field: %s",
+                       "String specified for bool or submessage field: %s",
                        upb_fielddef_name(p->top->f));
     upb_env_reporterror(p->env, &p->status);
     return false;
@@ -12239,6 +12178,15 @@
       break;
     }
 
+    case UPB_TYPE_INT32:
+    case UPB_TYPE_INT64:
+    case UPB_TYPE_UINT32:
+    case UPB_TYPE_UINT64:
+    case UPB_TYPE_DOUBLE:
+    case UPB_TYPE_FLOAT:
+      ok = parse_number(p, true);
+      break;
+
     default:
       UPB_ASSERT(false);
       upb_status_seterrmsg(&p->status, "Internal error in JSON decoder");
@@ -12282,7 +12230,7 @@
     case UPB_TYPE_UINT32:
     case UPB_TYPE_UINT64:
       /* Invoke end_number. The accum buffer has the number's text already. */
-      if (!parse_number(p)) {
+      if (!parse_number(p, true)) {
         return false;
       }
       break;
@@ -12573,11 +12521,11 @@
  * final state once, when the closing '"' is seen. */
 
 
-#line 1244 "upb/json/parser.rl"
+#line 1306 "upb/json/parser.rl"
 
 
 
-#line 1156 "upb/json/parser.c"
+#line 1218 "upb/json/parser.c"
 static const char _json_actions[] = {
 	0, 1, 0, 1, 2, 1, 3, 1, 
 	5, 1, 6, 1, 7, 1, 8, 1, 
@@ -12726,7 +12674,7 @@
 static const int json_en_main = 1;
 
 
-#line 1247 "upb/json/parser.rl"
+#line 1309 "upb/json/parser.rl"
 
 size_t parse(void *closure, const void *hd, const char *buf, size_t size,
              const upb_bufhandle *handle) {
@@ -12748,7 +12696,7 @@
   capture_resume(parser, buf);
 
   
-#line 1327 "upb/json/parser.c"
+#line 1389 "upb/json/parser.c"
 	{
 	int _klen;
 	unsigned int _trans;
@@ -12823,118 +12771,118 @@
 		switch ( *_acts++ )
 		{
 	case 0:
-#line 1159 "upb/json/parser.rl"
+#line 1221 "upb/json/parser.rl"
 	{ p--; {cs = stack[--top]; goto _again;} }
 	break;
 	case 1:
-#line 1160 "upb/json/parser.rl"
+#line 1222 "upb/json/parser.rl"
 	{ p--; {stack[top++] = cs; cs = 10; goto _again;} }
 	break;
 	case 2:
-#line 1164 "upb/json/parser.rl"
+#line 1226 "upb/json/parser.rl"
 	{ start_text(parser, p); }
 	break;
 	case 3:
-#line 1165 "upb/json/parser.rl"
+#line 1227 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(end_text(parser, p)); }
 	break;
 	case 4:
-#line 1171 "upb/json/parser.rl"
+#line 1233 "upb/json/parser.rl"
 	{ start_hex(parser); }
 	break;
 	case 5:
-#line 1172 "upb/json/parser.rl"
+#line 1234 "upb/json/parser.rl"
 	{ hexdigit(parser, p); }
 	break;
 	case 6:
-#line 1173 "upb/json/parser.rl"
+#line 1235 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(end_hex(parser)); }
 	break;
 	case 7:
-#line 1179 "upb/json/parser.rl"
+#line 1241 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(escape(parser, p)); }
 	break;
 	case 8:
-#line 1185 "upb/json/parser.rl"
+#line 1247 "upb/json/parser.rl"
 	{ p--; {cs = stack[--top]; goto _again;} }
 	break;
 	case 9:
-#line 1188 "upb/json/parser.rl"
+#line 1250 "upb/json/parser.rl"
 	{ {stack[top++] = cs; cs = 19; goto _again;} }
 	break;
 	case 10:
-#line 1190 "upb/json/parser.rl"
+#line 1252 "upb/json/parser.rl"
 	{ p--; {stack[top++] = cs; cs = 27; goto _again;} }
 	break;
 	case 11:
-#line 1195 "upb/json/parser.rl"
+#line 1257 "upb/json/parser.rl"
 	{ start_member(parser); }
 	break;
 	case 12:
-#line 1196 "upb/json/parser.rl"
+#line 1258 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(end_membername(parser)); }
 	break;
 	case 13:
-#line 1199 "upb/json/parser.rl"
+#line 1261 "upb/json/parser.rl"
 	{ end_member(parser); }
 	break;
 	case 14:
-#line 1205 "upb/json/parser.rl"
+#line 1267 "upb/json/parser.rl"
 	{ start_object(parser); }
 	break;
 	case 15:
-#line 1208 "upb/json/parser.rl"
+#line 1270 "upb/json/parser.rl"
 	{ end_object(parser); }
 	break;
 	case 16:
-#line 1214 "upb/json/parser.rl"
+#line 1276 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(start_array(parser)); }
 	break;
 	case 17:
-#line 1218 "upb/json/parser.rl"
+#line 1280 "upb/json/parser.rl"
 	{ end_array(parser); }
 	break;
 	case 18:
-#line 1223 "upb/json/parser.rl"
+#line 1285 "upb/json/parser.rl"
 	{ start_number(parser, p); }
 	break;
 	case 19:
-#line 1224 "upb/json/parser.rl"
+#line 1286 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(end_number(parser, p)); }
 	break;
 	case 20:
-#line 1226 "upb/json/parser.rl"
+#line 1288 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(start_stringval(parser)); }
 	break;
 	case 21:
-#line 1227 "upb/json/parser.rl"
+#line 1289 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(end_stringval(parser)); }
 	break;
 	case 22:
-#line 1229 "upb/json/parser.rl"
+#line 1291 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(parser_putbool(parser, true)); }
 	break;
 	case 23:
-#line 1231 "upb/json/parser.rl"
+#line 1293 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(parser_putbool(parser, false)); }
 	break;
 	case 24:
-#line 1233 "upb/json/parser.rl"
+#line 1295 "upb/json/parser.rl"
 	{ /* null value */ }
 	break;
 	case 25:
-#line 1235 "upb/json/parser.rl"
+#line 1297 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(start_subobject(parser)); }
 	break;
 	case 26:
-#line 1236 "upb/json/parser.rl"
+#line 1298 "upb/json/parser.rl"
 	{ end_subobject(parser); }
 	break;
 	case 27:
-#line 1241 "upb/json/parser.rl"
+#line 1303 "upb/json/parser.rl"
 	{ p--; {cs = stack[--top]; goto _again;} }
 	break;
-#line 1513 "upb/json/parser.c"
+#line 1575 "upb/json/parser.c"
 		}
 	}
 
@@ -12947,7 +12895,7 @@
 	_out: {}
 	}
 
-#line 1268 "upb/json/parser.rl"
+#line 1330 "upb/json/parser.rl"
 
   if (p != pe) {
     upb_status_seterrf(&parser->status, "Parse error at '%.*s'\n", pe - p, p);
@@ -12988,13 +12936,13 @@
 
   /* Emit Ragel initialization of the parser. */
   
-#line 1567 "upb/json/parser.c"
+#line 1629 "upb/json/parser.c"
 	{
 	cs = json_start;
 	top = 0;
 	}
 
-#line 1308 "upb/json/parser.rl"
+#line 1370 "upb/json/parser.rl"
   p->current_state = cs;
   p->parser_top = top;
   accumulate_clear(p);
@@ -13291,10 +13239,23 @@
  * Right now we use %.8g and %.17g for float/double, respectively, to match
  * proto2::util::JsonFormat's defaults.  May want to change this later. */
 
+const char neginf[] = "\"-Infinity\"";
+const char inf[] = "\"Infinity\"";
+
 static size_t fmt_double(double val, char* buf, size_t length) {
-  size_t n = _upb_snprintf(buf, length, "%.17g", val);
-  CHKLENGTH(n > 0 && n < length);
-  return n;
+  if (val == (1.0 / 0.0)) {
+    CHKLENGTH(length >= strlen(inf));
+    strcpy(buf, inf);
+    return strlen(inf);
+  } else if (val == (-1.0 / 0.0)) {
+    CHKLENGTH(length >= strlen(neginf));
+    strcpy(buf, neginf);
+    return strlen(neginf);
+  } else {
+    size_t n = _upb_snprintf(buf, length, "%.17g", val);
+    CHKLENGTH(n > 0 && n < length);
+    return n;
+  }
 }
 
 static size_t fmt_float(float val, char* buf, size_t length) {
diff --git a/ruby/ext/google/protobuf_c/upb.h b/ruby/ext/google/protobuf_c/upb.h
index 6e1e6c6..3edee0d 100644
--- a/ruby/ext/google/protobuf_c/upb.h
+++ b/ruby/ext/google/protobuf_c/upb.h
@@ -2966,6 +2966,17 @@
   const char* package() const;
   bool set_package(const char* package, Status* s);
 
+  /* Sets the php class prefix which is prepended to all php generated classes
+   * from this .proto. Default is empty. */
+  const char* phpprefix() const;
+  bool set_phpprefix(const char* phpprefix, Status* s);
+
+  /* Use this option to change the namespace of php generated classes. Default
+   * is empty. When this option is empty, the package name will be used for
+   * determining the namespace. */
+  const char* phpnamespace() const;
+  bool set_phpnamespace(const char* phpnamespace, Status* s);
+
   /* Syntax for the file.  Defaults to proto2. */
   upb_syntax_t syntax() const;
   void set_syntax(upb_syntax_t syntax);
@@ -3019,6 +3030,8 @@
 
 const char *upb_filedef_name(const upb_filedef *f);
 const char *upb_filedef_package(const upb_filedef *f);
+const char *upb_filedef_phpprefix(const upb_filedef *f);
+const char *upb_filedef_phpnamespace(const upb_filedef *f);
 upb_syntax_t upb_filedef_syntax(const upb_filedef *f);
 size_t upb_filedef_defcount(const upb_filedef *f);
 size_t upb_filedef_depcount(const upb_filedef *f);
@@ -3028,6 +3041,10 @@
 bool upb_filedef_freeze(upb_filedef *f, upb_status *s);
 bool upb_filedef_setname(upb_filedef *f, const char *name, upb_status *s);
 bool upb_filedef_setpackage(upb_filedef *f, const char *package, upb_status *s);
+bool upb_filedef_setphpprefix(upb_filedef *f, const char *phpprefix,
+                              upb_status *s);
+bool upb_filedef_setphpnamespace(upb_filedef *f, const char *phpnamespace,
+                                 upb_status *s);
 bool upb_filedef_setsyntax(upb_filedef *f, upb_syntax_t syntax, upb_status *s);
 
 bool upb_filedef_adddef(upb_filedef *f, upb_def *def, const void *ref_donor,
@@ -3786,6 +3803,18 @@
 inline bool FileDef::set_package(const char* package, Status* s) {
   return upb_filedef_setpackage(this, package, s);
 }
+inline const char* FileDef::phpprefix() const {
+  return upb_filedef_phpprefix(this);
+}
+inline bool FileDef::set_phpprefix(const char* phpprefix, Status* s) {
+  return upb_filedef_setphpprefix(this, phpprefix, s);
+}
+inline const char* FileDef::phpnamespace() const {
+  return upb_filedef_phpnamespace(this);
+}
+inline bool FileDef::set_phpnamespace(const char* phpnamespace, Status* s) {
+  return upb_filedef_setphpnamespace(this, phpnamespace, s);
+}
 inline int FileDef::def_count() const {
   return upb_filedef_defcount(this);
 }
@@ -4000,6 +4029,8 @@
 
   const char *name;
   const char *package;
+  const char *phpprefix;
+  const char *phpnamespace;
   upb_syntax_t syntax;
 
   upb_inttable defs;
@@ -7206,6 +7237,8 @@
 UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_javanano_use_deprecated_package(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 38); }
 UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_objc_class_prefix(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 36); }
 UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_optimize_for(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 9); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_php_class_prefix(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 40); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_php_namespace(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 41); }
 UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_py_generic_services(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 18); }
 UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_uninterpreted_option(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 999); }
 UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_f_deprecated(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_MessageOptions_is(m)); return upb_msgdef_itof(m, 3); }
@@ -8304,16 +8337,8 @@
   return ret;
 }
 
-/* Four functions for decoding a varint of at most eight bytes.  They are all
- * functionally identical, but are implemented in different ways and likely have
- * different performance profiles.  We keep them around for performance testing.
- *
- * Note that these functions may not read byte-by-byte, so they must not be used
- * unless there are at least eight bytes left in the buffer! */
 upb_decoderet upb_vdecode_max8_branch32(upb_decoderet r);
 upb_decoderet upb_vdecode_max8_branch64(upb_decoderet r);
-upb_decoderet upb_vdecode_max8_wright(upb_decoderet r);
-upb_decoderet upb_vdecode_max8_massimino(upb_decoderet r);
 
 /* Template for a function that checks the first two bytes with branching
  * and dispatches 2-10 bytes with a separate function.  Note that this may read
@@ -8338,8 +8363,6 @@
 
 UPB_VARINT_DECODER_CHECK2(branch32, upb_vdecode_max8_branch32)
 UPB_VARINT_DECODER_CHECK2(branch64, upb_vdecode_max8_branch64)
-UPB_VARINT_DECODER_CHECK2(wright, upb_vdecode_max8_wright)
-UPB_VARINT_DECODER_CHECK2(massimino, upb_vdecode_max8_massimino)
 #undef UPB_VARINT_DECODER_CHECK2
 
 /* Our canonical functions for decoding varints, based on the currently
@@ -8351,10 +8374,6 @@
     return upb_vdecode_check2_branch32(p);
 }
 
-UPB_INLINE upb_decoderet upb_vdecode_max8_fast(upb_decoderet r) {
-  return upb_vdecode_max8_massimino(r);
-}
-
 
 /* Encoding *******************************************************************/
 
diff --git a/ruby/lib/google/protobuf/well_known_types.rb b/ruby/lib/google/protobuf/well_known_types.rb
index 547de87..921ddbc 100644
--- a/ruby/lib/google/protobuf/well_known_types.rb
+++ b/ruby/lib/google/protobuf/well_known_types.rb
@@ -80,7 +80,7 @@
       end
 
       def to_f
-        self.seconds + (self.nanos.to_f / 1_000_000_000)
+        self.seconds + (self.nanos.quo(1_000_000_000))
       end
     end
 
diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb
index 3425123..020effb 100644
--- a/ruby/tests/basic.rb
+++ b/ruby/tests/basic.rb
@@ -1,6 +1,7 @@
 #!/usr/bin/ruby
 
 require 'google/protobuf'
+require 'json'
 require 'test/unit'
 
 # ------------- generated code --------------
@@ -1173,6 +1174,8 @@
 
       json_text = TestMessage.encode_json(m)
       m2 = TestMessage.decode_json(json_text)
+      puts m.inspect
+      puts m2.inspect
       assert m == m2
 
       # Crash case from GitHub issue 283.
@@ -1184,21 +1187,135 @@
       Foo.encode_json(Foo.new(bar: bar, baz: [baz1, baz2]))
     end
 
+    def test_json_emit_defaults
+      # TODO: Fix JSON in JRuby version.
+      return if RUBY_PLATFORM == "java"
+      m = TestMessage.new
+
+      expected = {
+        optionalInt32: 0,
+        optionalInt64: 0,
+        optionalUint32: 0,
+        optionalUint64: 0,
+        optionalBool: false,
+        optionalFloat: 0,
+        optionalDouble: 0,
+        optionalString: "",
+        optionalBytes: "",
+        optionalEnum: "Default",
+        repeatedInt32: [],
+        repeatedInt64: [],
+        repeatedUint32: [],
+        repeatedUint64: [],
+        repeatedBool: [],
+        repeatedFloat: [],
+        repeatedDouble: [],
+        repeatedString: [],
+        repeatedBytes: [],
+        repeatedMsg: [],
+        repeatedEnum: []
+      }
+
+      actual = TestMessage.encode_json(m, :emit_defaults => true)
+
+      assert JSON.parse(actual, :symbolize_names => true) == expected
+    end
+
+    def test_json_emit_defaults_submsg
+      # TODO: Fix JSON in JRuby version.
+      return if RUBY_PLATFORM == "java"
+      m = TestMessage.new(optional_msg: TestMessage2.new)
+
+      expected = {
+        optionalInt32: 0,
+        optionalInt64: 0,
+        optionalUint32: 0,
+        optionalUint64: 0,
+        optionalBool: false,
+        optionalFloat: 0,
+        optionalDouble: 0,
+        optionalString: "",
+        optionalBytes: "",
+        optionalMsg: {foo: 0},
+        optionalEnum: "Default",
+        repeatedInt32: [],
+        repeatedInt64: [],
+        repeatedUint32: [],
+        repeatedUint64: [],
+        repeatedBool: [],
+        repeatedFloat: [],
+        repeatedDouble: [],
+        repeatedString: [],
+        repeatedBytes: [],
+        repeatedMsg: [],
+        repeatedEnum: []
+      }
+
+      actual = TestMessage.encode_json(m, :emit_defaults => true)
+
+      assert JSON.parse(actual, :symbolize_names => true) == expected
+    end
+
+    def test_json_emit_defaults_repeated_submsg
+      # TODO: Fix JSON in JRuby version.
+      return if RUBY_PLATFORM == "java"
+      m = TestMessage.new(repeated_msg: [TestMessage2.new])
+
+      expected = {
+        optionalInt32: 0,
+        optionalInt64: 0,
+        optionalUint32: 0,
+        optionalUint64: 0,
+        optionalBool: false,
+        optionalFloat: 0,
+        optionalDouble: 0,
+        optionalString: "",
+        optionalBytes: "",
+        optionalEnum: "Default",
+        repeatedInt32: [],
+        repeatedInt64: [],
+        repeatedUint32: [],
+        repeatedUint64: [],
+        repeatedBool: [],
+        repeatedFloat: [],
+        repeatedDouble: [],
+        repeatedString: [],
+        repeatedBytes: [],
+        repeatedMsg: [{foo: 0}],
+        repeatedEnum: []
+      }
+
+      actual = TestMessage.encode_json(m, :emit_defaults => true)
+
+      assert JSON.parse(actual, :symbolize_names => true) == expected
+    end
+
     def test_json_maps
       # TODO: Fix JSON in JRuby version.
       return if RUBY_PLATFORM == "java"
       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
+      expected = {mapStringInt32: {a: 1}, mapStringMsg: {}}
+      expected_preserve = {map_string_int32: {a: 1}, map_string_msg: {}}
+      assert JSON.parse(MapMessage.encode_json(m), :symbolize_names => true) == expected
 
       json = MapMessage.encode_json(m, :preserve_proto_fieldnames => true)
-      assert json == expected_preserve
+      assert JSON.parse(json, :symbolize_names => true) == expected_preserve
 
       m2 = MapMessage.decode_json(MapMessage.encode_json(m))
       assert m == m2
     end
 
+    def test_json_maps_emit_defaults_submsg
+      # TODO: Fix JSON in JRuby version.
+      return if RUBY_PLATFORM == "java"
+      m = MapMessage.new(:map_string_msg => {"a" => TestMessage2.new})
+      expected = {mapStringInt32: {}, mapStringMsg: {a: {foo: 0}}}
+
+      actual = MapMessage.encode_json(m, :emit_defaults => true)
+
+      assert JSON.parse(actual, :symbolize_names => true) == expected
+    end
+
     def test_comparison_with_arbitrary_object
       assert MapMessage.new != nil
     end
diff --git a/ruby/tests/well_known_types_test.rb b/ruby/tests/well_known_types_test.rb
index 9b46632..bd24c32 100644
--- a/ruby/tests/well_known_types_test.rb
+++ b/ruby/tests/well_known_types_test.rb
@@ -13,10 +13,18 @@
     assert_equal Time.at(12345), ts.to_time
     assert_equal 12345, ts.to_i
 
-    ts.from_time(Time.at(123456, 654321))
+    # millisecond accuracy
+    time = Time.at(123456, 654321)
+    ts.from_time(time)
     assert_equal 123456, ts.seconds
     assert_equal 654321000, ts.nanos
-    assert_equal Time.at(123456.654321), ts.to_time
+    assert_equal time, ts.to_time
+
+    # nanosecond accuracy
+    time = Time.at(123456, Rational(654321321, 1000))
+    ts.from_time(time)
+    assert_equal 654321321, ts.nanos
+    assert_equal time, ts.to_time
   end
 
   def test_duration
diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc
index a7a1258..7ac946e 100644
--- a/src/google/protobuf/any.pb.cc
+++ b/src/google/protobuf/any.pb.cc
@@ -237,7 +237,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_type_url()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->type_url().data(), this->type_url().length(),
+            this->type_url().data(), static_cast<int>(this->type_url().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Any.type_url"));
         } else {
@@ -287,7 +287,7 @@
   // string type_url = 1;
   if (this->type_url().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->type_url().data(), this->type_url().length(),
+      this->type_url().data(), static_cast<int>(this->type_url().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Any.type_url");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -316,7 +316,7 @@
   // string type_url = 1;
   if (this->type_url().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->type_url().data(), this->type_url().length(),
+      this->type_url().data(), static_cast<int>(this->type_url().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Any.type_url");
     target =
diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc
index 0b36f43..e767bf6 100644
--- a/src/google/protobuf/api.pb.cc
+++ b/src/google/protobuf/api.pb.cc
@@ -228,8 +228,9 @@
 void Api::SharedCtor() {
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   version_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  ::memset(&source_context_, 0, reinterpret_cast<char*>(&syntax_) -
-    reinterpret_cast<char*>(&source_context_) + sizeof(syntax_));
+  ::memset(&source_context_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&syntax_) -
+      reinterpret_cast<char*>(&source_context_)) + sizeof(syntax_));
   _cached_size_ = 0;
 }
 
@@ -303,7 +304,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Api.name"));
         } else {
@@ -343,7 +344,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_version()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->version().data(), this->version().length(),
+            this->version().data(), static_cast<int>(this->version().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Api.version"));
         } else {
@@ -420,7 +421,7 @@
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Api.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -428,21 +429,23 @@
   }
 
   // repeated .google.protobuf.Method methods = 2;
-  for (unsigned int i = 0, n = this->methods_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->methods_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      2, this->methods(i), output);
+      2, this->methods(static_cast<int>(i)), output);
   }
 
   // repeated .google.protobuf.Option options = 3;
-  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->options_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      3, this->options(i), output);
+      3, this->options(static_cast<int>(i)), output);
   }
 
   // string version = 4;
   if (this->version().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->version().data(), this->version().length(),
+      this->version().data(), static_cast<int>(this->version().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Api.version");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -456,9 +459,10 @@
   }
 
   // repeated .google.protobuf.Mixin mixins = 6;
-  for (unsigned int i = 0, n = this->mixins_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->mixins_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      6, this->mixins(i), output);
+      6, this->mixins(static_cast<int>(i)), output);
   }
 
   // .google.protobuf.Syntax syntax = 7;
@@ -483,7 +487,7 @@
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Api.name");
     target =
@@ -492,23 +496,25 @@
   }
 
   // repeated .google.protobuf.Method methods = 2;
-  for (unsigned int i = 0, n = this->methods_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->methods_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        2, this->methods(i), deterministic, target);
+        2, this->methods(static_cast<int>(i)), deterministic, target);
   }
 
   // repeated .google.protobuf.Option options = 3;
-  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->options_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        3, this->options(i), deterministic, target);
+        3, this->options(static_cast<int>(i)), deterministic, target);
   }
 
   // string version = 4;
   if (this->version().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->version().data(), this->version().length(),
+      this->version().data(), static_cast<int>(this->version().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Api.version");
     target =
@@ -524,10 +530,11 @@
   }
 
   // repeated .google.protobuf.Mixin mixins = 6;
-  for (unsigned int i = 0, n = this->mixins_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->mixins_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        6, this->mixins(i), deterministic, target);
+        6, this->mixins(static_cast<int>(i)), deterministic, target);
   }
 
   // .google.protobuf.Syntax syntax = 7;
@@ -555,34 +562,34 @@
   }
   // repeated .google.protobuf.Method methods = 2;
   {
-    unsigned int count = this->methods_size();
+    unsigned int count = static_cast<unsigned int>(this->methods_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->methods(i));
+          this->methods(static_cast<int>(i)));
     }
   }
 
   // repeated .google.protobuf.Option options = 3;
   {
-    unsigned int count = this->options_size();
+    unsigned int count = static_cast<unsigned int>(this->options_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->options(i));
+          this->options(static_cast<int>(i)));
     }
   }
 
   // repeated .google.protobuf.Mixin mixins = 6;
   {
-    unsigned int count = this->mixins_size();
+    unsigned int count = static_cast<unsigned int>(this->mixins_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->mixins(i));
+          this->mixins(static_cast<int>(i)));
     }
   }
 
@@ -995,8 +1002,8 @@
     response_type_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.response_type_url_);
   }
   ::memcpy(&request_streaming_, &from.request_streaming_,
-    reinterpret_cast<char*>(&syntax_) -
-    reinterpret_cast<char*>(&request_streaming_) + sizeof(syntax_));
+    static_cast<size_t>(reinterpret_cast<char*>(&syntax_) -
+    reinterpret_cast<char*>(&request_streaming_)) + sizeof(syntax_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Method)
 }
 
@@ -1004,8 +1011,9 @@
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   request_type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   response_type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  ::memset(&request_streaming_, 0, reinterpret_cast<char*>(&syntax_) -
-    reinterpret_cast<char*>(&request_streaming_) + sizeof(syntax_));
+  ::memset(&request_streaming_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&syntax_) -
+      reinterpret_cast<char*>(&request_streaming_)) + sizeof(syntax_));
   _cached_size_ = 0;
 }
 
@@ -1053,8 +1061,9 @@
   name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   request_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   response_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  ::memset(&request_streaming_, 0, reinterpret_cast<char*>(&syntax_) -
-    reinterpret_cast<char*>(&request_streaming_) + sizeof(syntax_));
+  ::memset(&request_streaming_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&syntax_) -
+      reinterpret_cast<char*>(&request_streaming_)) + sizeof(syntax_));
   _internal_metadata_.Clear();
 }
 
@@ -1075,7 +1084,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Method.name"));
         } else {
@@ -1091,7 +1100,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_request_type_url()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->request_type_url().data(), this->request_type_url().length(),
+            this->request_type_url().data(), static_cast<int>(this->request_type_url().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Method.request_type_url"));
         } else {
@@ -1121,7 +1130,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_response_type_url()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->response_type_url().data(), this->response_type_url().length(),
+            this->response_type_url().data(), static_cast<int>(this->response_type_url().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Method.response_type_url"));
         } else {
@@ -1200,7 +1209,7 @@
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Method.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -1210,7 +1219,7 @@
   // string request_type_url = 2;
   if (this->request_type_url().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->request_type_url().data(), this->request_type_url().length(),
+      this->request_type_url().data(), static_cast<int>(this->request_type_url().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Method.request_type_url");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -1225,7 +1234,7 @@
   // string response_type_url = 4;
   if (this->response_type_url().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->response_type_url().data(), this->response_type_url().length(),
+      this->response_type_url().data(), static_cast<int>(this->response_type_url().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Method.response_type_url");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -1238,9 +1247,10 @@
   }
 
   // repeated .google.protobuf.Option options = 6;
-  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->options_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      6, this->options(i), output);
+      6, this->options(static_cast<int>(i)), output);
   }
 
   // .google.protobuf.Syntax syntax = 7;
@@ -1265,7 +1275,7 @@
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Method.name");
     target =
@@ -1276,7 +1286,7 @@
   // string request_type_url = 2;
   if (this->request_type_url().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->request_type_url().data(), this->request_type_url().length(),
+      this->request_type_url().data(), static_cast<int>(this->request_type_url().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Method.request_type_url");
     target =
@@ -1292,7 +1302,7 @@
   // string response_type_url = 4;
   if (this->response_type_url().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->response_type_url().data(), this->response_type_url().length(),
+      this->response_type_url().data(), static_cast<int>(this->response_type_url().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Method.response_type_url");
     target =
@@ -1306,10 +1316,11 @@
   }
 
   // repeated .google.protobuf.Option options = 6;
-  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->options_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        6, this->options(i), deterministic, target);
+        6, this->options(static_cast<int>(i)), deterministic, target);
   }
 
   // .google.protobuf.Syntax syntax = 7;
@@ -1337,12 +1348,12 @@
   }
   // repeated .google.protobuf.Option options = 6;
   {
-    unsigned int count = this->options_size();
+    unsigned int count = static_cast<unsigned int>(this->options_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->options(i));
+          this->options(static_cast<int>(i)));
     }
   }
 
@@ -1810,7 +1821,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Mixin.name"));
         } else {
@@ -1826,7 +1837,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_root()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->root().data(), this->root().length(),
+            this->root().data(), static_cast<int>(this->root().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Mixin.root"));
         } else {
@@ -1864,7 +1875,7 @@
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Mixin.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -1874,7 +1885,7 @@
   // string root = 2;
   if (this->root().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->root().data(), this->root().length(),
+      this->root().data(), static_cast<int>(this->root().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Mixin.root");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -1897,7 +1908,7 @@
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Mixin.name");
     target =
@@ -1908,7 +1919,7 @@
   // string root = 2;
   if (this->root().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->root().data(), this->root().length(),
+      this->root().data(), static_cast<int>(this->root().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Mixin.root");
     target =
diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h
index 1497a6c..f8a9470 100644
--- a/src/google/protobuf/arena.h
+++ b/src/google/protobuf/arena.h
@@ -810,13 +810,13 @@
   }
   template <typename T>
   static void CreateInArenaStorageInternal(
-      T* ptr, Arena* arena, google::protobuf::internal::false_type) {
+      T* ptr, Arena* /* arena */, google::protobuf::internal::false_type) {
     new (ptr) T();
   }
 
   template <typename T>
   static void RegisterDestructorInternal(
-      T* ptr, Arena* arena, google::protobuf::internal::true_type) {}
+      T* /* ptr */, Arena* /* arena */, google::protobuf::internal::true_type) {}
   template <typename T>
   static void RegisterDestructorInternal(
       T* ptr, Arena* arena, google::protobuf::internal::false_type) {
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index afe63a7..0ef8c0d 100644
--- a/src/google/protobuf/compiler/command_line_interface.cc
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -1182,6 +1182,12 @@
     arguments.push_back(argv[i]);
   }
 
+  // if no arguments are given, show help
+  if(arguments.empty()) {
+    PrintHelpText();
+    return PARSE_ARGUMENT_DONE_AND_EXIT;  // Exit without running compiler.
+  }
+
   // Iterate through all arguments and parse them.
   for (int i = 0; i < arguments.size(); ++i) {
     string name, value;
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
index e99e7e5..08a635f 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -145,12 +145,14 @@
     if (UseUnknownFieldSet(descriptor_->file(), options_)) {
       printer->Print(variables_,
         "} else {\n"
-        "  mutable_unknown_fields()->AddVarint($number$, value);\n");
+        "  mutable_unknown_fields()->AddVarint(\n"
+        "      $number$, static_cast< ::google::protobuf::uint64>(value));\n");
     } else {
       printer->Print(
         "} else {\n"
         "  unknown_fields_stream.WriteVarint32($tag$u);\n"
-        "  unknown_fields_stream.WriteVarint32(value);\n",
+        "  unknown_fields_stream.WriteVarint32(\n"
+        "      static_cast< ::google::protobuf::uint32>(value));\n",
         "tag", SimpleItoa(internal::WireFormat::MakeTag(descriptor_)));
     }
     printer->Print(variables_,
@@ -356,12 +358,14 @@
     if (UseUnknownFieldSet(descriptor_->file(), options_)) {
       printer->Print(variables_,
         "} else {\n"
-        "  mutable_unknown_fields()->AddVarint($number$, value);\n");
+        "  mutable_unknown_fields()->AddVarint(\n"
+        "      $number$, static_cast< ::google::protobuf::uint64>(value));\n");
     } else {
       printer->Print(
         "} else {\n"
         "  unknown_fields_stream.WriteVarint32(tag);\n"
-        "  unknown_fields_stream.WriteVarint32(value);\n");
+        "  unknown_fields_stream.WriteVarint32(\n"
+        "      static_cast< ::google::protobuf::uint32>(value));\n");
     }
     printer->Print("}\n");
   }
@@ -403,7 +407,7 @@
       "::google::protobuf::uint32 length;\n"
       "DO_(input->ReadVarint32(&length));\n"
       "::google::protobuf::io::CodedInputStream::Limit limit = "
-          "input->PushLimit(length);\n"
+          "input->PushLimit(static_cast<int>(length));\n"
       "while (input->BytesUntilLimit() > 0) {\n"
       "  int value;\n"
       "  DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
@@ -419,11 +423,13 @@
       "  } else {\n");
       if (UseUnknownFieldSet(descriptor_->file(), options_)) {
         printer->Print(variables_,
-        "    mutable_unknown_fields()->AddVarint($number$, value);\n");
+        "  mutable_unknown_fields()->AddVarint(\n"
+        "      $number$, static_cast< ::google::protobuf::uint64>(value));\n");
       } else {
         printer->Print(variables_,
         "    unknown_fields_stream.WriteVarint32(tag);\n"
-        "    unknown_fields_stream.WriteVarint32(value);\n");
+        "    unknown_fields_stream.WriteVarint32(\n"
+        "        static_cast< ::google::protobuf::uint32>(value));\n");
       }
       printer->Print(
       "  }\n");
@@ -444,7 +450,8 @@
       "    $number$,\n"
       "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
       "    output);\n"
-      "  output->WriteVarint32(_$name$_cached_byte_size_);\n"
+      "  output->WriteVarint32(\n"
+      "      static_cast< ::google::protobuf::uint32>(_$name$_cached_byte_size_));\n"
       "}\n");
   }
   printer->Print(variables_,
@@ -472,7 +479,8 @@
       "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
       "    target);\n"
       "  target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray("
-      "    _$name$_cached_byte_size_, target);\n"
+      "      static_cast< ::google::protobuf::uint32>(\n"
+      "          _$name$_cached_byte_size_), target);\n"
       "  target = ::google::protobuf::internal::WireFormatLite::WriteEnumNoTagToArray(\n"
       "    this->$name$_, target);\n"
       "}\n");
@@ -488,19 +496,20 @@
   printer->Print(variables_,
     "{\n"
     "  size_t data_size = 0;\n"
-    "  unsigned int count = this->$name$_size();");
+    "  unsigned int count = static_cast<unsigned int>(this->$name$_size());");
   printer->Indent();
   printer->Print(variables_,
       "for (unsigned int i = 0; i < count; i++) {\n"
       "  data_size += ::google::protobuf::internal::WireFormatLite::EnumSize(\n"
-      "    this->$name$(i));\n"
+      "    this->$name$(static_cast<int>(i)));\n"
       "}\n");
 
   if (descriptor_->is_packed()) {
     printer->Print(variables_,
       "if (data_size > 0) {\n"
       "  total_size += $tag_size$ +\n"
-      "    ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
+      "    ::google::protobuf::internal::WireFormatLite::Int32Size(\n"
+      "        static_cast< ::google::protobuf::int32>(data_size));\n"
       "}\n"
       "int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);\n"
       "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
index 5d46140..da33d29 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
@@ -261,7 +261,8 @@
     } else {
       printer->Print(variables_,
           "    unknown_fields_stream.WriteVarint32($tag$u);\n"
-          "    unknown_fields_stream.WriteVarint32(data.size());\n"
+          "    unknown_fields_stream.WriteVarint32(\n"
+          "        static_cast<google::protobuf::uint32>(data.size()));\n"
           "    unknown_fields_stream.WriteString(data);\n");
     }
 
@@ -272,12 +273,16 @@
 
   if (key_field->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
-    key_field, options_, true, variables_,
-        StrCat(key, ".data(), ", key, ".length(),\n").data(), printer);
+        key_field, options_, true, variables_,
+        StrCat(key, ".data(), static_cast<int>(", key, ".length()),\n").data(),
+        printer);
   }
   if (value_field->type() == FieldDescriptor::TYPE_STRING) {
-    GenerateUtf8CheckCodeForString(value_field, options_, true, variables_,
-        StrCat(value, ".data(), ", value, ".length(),\n").data(), printer);
+    GenerateUtf8CheckCodeForString(
+        value_field, options_, true, variables_,
+        StrCat(value, ".data(), static_cast<int>(", value, ".length()),\n")
+            .data(),
+        printer);
   }
 
   // If entry is allocated by arena, its desctructor should be avoided.
@@ -381,14 +386,14 @@
     printer->Indent();
     printer->Indent();
     if (string_key) {
-      GenerateUtf8CheckCodeForString(key_field, options_, false, variables,
-                                     "p->first.data(), p->first.length(),\n",
-                                     printer);
+      GenerateUtf8CheckCodeForString(
+          key_field, options_, false, variables,
+          "p->first.data(), static_cast<int>(p->first.length()),\n", printer);
     }
     if (string_value) {
-      GenerateUtf8CheckCodeForString(value_field, options_, false, variables,
-                                     "p->second.data(), p->second.length(),\n",
-                                     printer);
+      GenerateUtf8CheckCodeForString(
+          value_field, options_, false, variables,
+          "p->second.data(), static_cast<int>(p->second.length()),\n", printer);
     }
     printer->Outdent();
     printer->Outdent();
@@ -409,13 +414,14 @@
       "  for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
       "      it = this->$name$().begin();\n"
       "      it != this->$name$().end(); ++it, ++n) {\n"
-      "    items[n] = SortItem(&*it);\n"
+      "    items[static_cast<ptrdiff_t>(n)] = SortItem(&*it);\n"
       "  }\n"
-      "  ::std::sort(&items[0], &items[n], Less());\n");
+      "  ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());\n");
   printer->Indent();
   GenerateSerializationLoop(printer, variables, SupportsArenas(descriptor_),
-                            utf8_check, "for (size_type i = 0; i < n; i++)",
-                            string_key ? "items[i]" : "items[i].second", false);
+      utf8_check, "for (size_type i = 0; i < n; i++)",
+      string_key ? "items[static_cast<ptrdiff_t>(i)]" :
+                   "items[static_cast<ptrdiff_t>(i)].second", false);
   printer->Outdent();
   printer->Print(
       "} else {\n");
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index 752673d..e82eebb 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -2609,12 +2609,13 @@
   if (copy_constructor) {
     pod_template =
         "::memcpy(&$first$_, &from.$first$_,\n"
-        "  reinterpret_cast<char*>(&$last$_) -\n"
-        "  reinterpret_cast<char*>(&$first$_) + sizeof($last$_));\n";
+        "  static_cast<size_t>(reinterpret_cast<char*>(&$last$_) -\n"
+        "  reinterpret_cast<char*>(&$first$_)) + sizeof($last$_));\n";
   } else {
     pod_template =
-        "::memset(&$first$_, 0, reinterpret_cast<char*>(&$last$_) -\n"
-        "  reinterpret_cast<char*>(&$first$_) + sizeof($last$_));\n";
+        "::memset(&$first$_, 0, static_cast<size_t>(\n"
+        "    reinterpret_cast<char*>(&$last$_) -\n"
+        "    reinterpret_cast<char*>(&$first$_)) + sizeof($last$_));\n";
   }
 
   for (int i = 0; i < optimized_order_.size(); ++i) {
@@ -3075,8 +3076,9 @@
               FieldName(optimized_order_[memset_run_end]);
 
           printer->Print(
-            "::memset(&$first$_, 0, reinterpret_cast<char*>(&$last$_) -\n"
-            "  reinterpret_cast<char*>(&$first$_) + sizeof($last$_));\n",
+            "::memset(&$first$_, 0, static_cast<size_t>(\n"
+            "    reinterpret_cast<char*>(&$last$_) -\n"
+            "    reinterpret_cast<char*>(&$first$_)) + sizeof($last$_));\n",
             "first", first_field_name,
             "last", last_field_name);
         }
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
index e45470f..5b260ca 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -1091,19 +1091,21 @@
 void RepeatedMessageFieldGenerator::
 GenerateSerializeWithCachedSizes(io::Printer* printer) const {
   printer->Print(variables_,
-    "for (unsigned int i = 0, n = this->$name$_size(); i < n; i++) {\n"
+    "for (unsigned int i = 0,\n"
+    "    n = static_cast<unsigned int>(this->$name$_size()); i < n; i++) {\n"
     "  ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
-    "    $number$, this->$name$(i), output);\n"
+    "    $number$, this->$name$(static_cast<int>(i)), output);\n"
     "}\n");
 }
 
 void RepeatedMessageFieldGenerator::
 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
   printer->Print(variables_,
-    "for (unsigned int i = 0, n = this->$name$_size(); i < n; i++) {\n"
+    "for (unsigned int i = 0,\n"
+    "    n = static_cast<unsigned int>(this->$name$_size()); i < n; i++) {\n"
     "  target = ::google::protobuf::internal::WireFormatLite::\n"
     "    InternalWrite$declared_type$NoVirtualToArray(\n"
-    "      $number$, this->$name$(i), deterministic, target);\n"
+    "      $number$, this->$name$(static_cast<int>(i)), deterministic, target);\n"
     "}\n");
 }
 
@@ -1111,14 +1113,14 @@
 GenerateByteSize(io::Printer* printer) const {
   printer->Print(variables_,
     "{\n"
-    "  unsigned int count = this->$name$_size();\n");
+    "  unsigned int count = static_cast<unsigned int>(this->$name$_size());\n");
   printer->Indent();
   printer->Print(variables_,
     "total_size += $tag_size$UL * count;\n"
     "for (unsigned int i = 0; i < count; i++) {\n"
     "  total_size +=\n"
     "    ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n"
-    "      this->$name$(i));\n"
+    "      this->$name$(static_cast<int>(i)));\n"
     "}\n");
   printer->Outdent();
   printer->Print("}\n");
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
index 07ac0bb..b05fcc4 100644
--- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -392,7 +392,8 @@
           "$number$, "
           "::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, "
           "output);\n"
-      "  output->WriteVarint32(_$name$_cached_byte_size_);\n");
+      "  output->WriteVarint32(static_cast< ::google::protobuf::uint32>(\n"
+      "      _$name$_cached_byte_size_));\n");
 
     if (FixedSize(descriptor_->type()) > 0) {
       // TODO(ckennelly): Use RepeatedField<T>::unsafe_data() via
@@ -432,7 +433,8 @@
       "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
       "    target);\n"
       "  target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(\n"
-      "    _$name$_cached_byte_size_, target);\n"
+      "      static_cast< ::google::protobuf::uint32>(\n"
+      "          _$name$_cached_byte_size_), target);\n"
       "  target = ::google::protobuf::internal::WireFormatLite::\n"
       "    Write$declared_type$NoTagToArray(this->$name$_, target);\n"
       "}\n");
@@ -454,7 +456,7 @@
       "  $declared_type$Size(this->$name$_);\n");
   } else {
     printer->Print(variables_,
-      "unsigned int count = this->$name$_size();\n"
+      "unsigned int count = static_cast<unsigned int>(this->$name$_size());\n"
       "size_t data_size = $fixed_size$UL * count;\n");
   }
 
@@ -462,7 +464,8 @@
     printer->Print(variables_,
       "if (data_size > 0) {\n"
       "  total_size += $tag_size$ +\n"
-      "    ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
+      "    ::google::protobuf::internal::WireFormatLite::Int32Size(\n"
+      "        static_cast< ::google::protobuf::int32>(data_size));\n"
       "}\n"
       "int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);\n"
       "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index c23dd6f..fec13b6 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -499,7 +499,8 @@
   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
         descriptor_, options_, true, variables_,
-        "this->$name$().data(), this->$name$().length(),\n", printer);
+        "this->$name$().data(), static_cast<int>(this->$name$().length()),\n",
+        printer);
   }
 }
 
@@ -508,7 +509,8 @@
   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
         descriptor_, options_, false, variables_,
-        "this->$name$().data(), this->$name$().length(),\n", printer);
+        "this->$name$().data(), static_cast<int>(this->$name$().length()),\n",
+        printer);
   }
   printer->Print(variables_,
     "::google::protobuf::internal::WireFormatLite::Write$declared_type$MaybeAliased(\n"
@@ -520,7 +522,8 @@
   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
         descriptor_, options_, false, variables_,
-        "this->$name$().data(), this->$name$().length(),\n", printer);
+        "this->$name$().data(), static_cast<int>(this->$name$().length()),\n",
+        printer);
   }
   printer->Print(variables_,
     "target =\n"
@@ -832,7 +835,8 @@
   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
         descriptor_, options_, true, variables_,
-        "this->$name$().data(), this->$name$().length(),\n", printer);
+        "this->$name$().data(), static_cast<int>(this->$name$().length()),\n",
+        printer);
   }
 }
 
@@ -1038,7 +1042,7 @@
     GenerateUtf8CheckCodeForString(
         descriptor_, options_, true, variables_,
         "this->$name$(this->$name$_size() - 1).data(),\n"
-        "this->$name$(this->$name$_size() - 1).length(),\n",
+        "static_cast<int>(this->$name$(this->$name$_size() - 1).length()),\n",
         printer);
   }
 }
@@ -1051,7 +1055,8 @@
   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
         descriptor_, options_, false, variables_,
-        "this->$name$(i).data(), this->$name$(i).length(),\n", printer);
+        "this->$name$(i).data(), static_cast<int>(this->$name$(i).length()),\n",
+        printer);
   }
   printer->Outdent();
   printer->Print(variables_,
@@ -1068,7 +1073,8 @@
   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
         descriptor_, options_, false, variables_,
-        "this->$name$(i).data(), this->$name$(i).length(),\n", printer);
+        "this->$name$(i).data(), static_cast<int>(this->$name$(i).length()),\n",
+        printer);
   }
   printer->Outdent();
   printer->Print(variables_,
diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc
index ebb8fbc..ecf29ec 100644
--- a/src/google/protobuf/compiler/csharp/csharp_field_base.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc
@@ -54,7 +54,7 @@
 namespace csharp {
 
 void FieldGeneratorBase::SetCommonFieldVariables(
-    map<string, string>* variables) {
+    std::map<string, string>* variables) {
   // Note: this will be valid even though the tag emitted for packed and unpacked versions of
   // repeated fields varies by wire format. The wire format is encoded in the bottom 3 bits, which
   // never effects the tag size.
@@ -92,7 +92,7 @@
 }
 
 void FieldGeneratorBase::SetCommonOneofFieldVariables(
-    map<string, string>* variables) {
+    std::map<string, string>* variables) {
   (*variables)["oneof_name"] = oneof_name();
   (*variables)["has_property_check"] =
     oneof_name() + "Case_ == " + oneof_property_name() +
diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.h b/src/google/protobuf/compiler/csharp/csharp_field_base.h
index 4109f3c..df26853 100644
--- a/src/google/protobuf/compiler/csharp/csharp_field_base.h
+++ b/src/google/protobuf/compiler/csharp/csharp_field_base.h
@@ -66,14 +66,14 @@
  protected:
   const FieldDescriptor* descriptor_;
   const int fieldOrdinal_;
-  map<string, string> variables_;
+  std::map<string, string> variables_;
 
   void AddDeprecatedFlag(io::Printer* printer);
   void AddNullCheck(io::Printer* printer);
   void AddNullCheck(io::Printer* printer, const std::string& name);
 
   void AddPublicMemberAttributes(io::Printer* printer);
-  void SetCommonOneofFieldVariables(map<string, string>* variables);
+  void SetCommonOneofFieldVariables(std::map<string, string>* variables);
 
   std::string oneof_property_name();
   std::string oneof_name();
@@ -89,7 +89,7 @@
   std::string capitalized_type_name();
 
  private:
-  void SetCommonFieldVariables(map<string, string>* variables);
+  void SetCommonFieldVariables(std::map<string, string>* variables);
   std::string GetStringDefaultValueInternal();
   std::string GetBytesDefaultValueInternal();
 
diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc
index 0f00a43..5ef0e4e 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_message.cc
@@ -105,7 +105,7 @@
 }
 
 void MessageGenerator::Generate(io::Printer* printer) {
-  map<string, string> vars;
+  std::map<string, string> vars;
   vars["class_name"] = class_name();
   vars["access_level"] = class_access_level();
 
@@ -280,7 +280,7 @@
 }
 
 void MessageGenerator::GenerateCloningCode(io::Printer* printer) {
-  map<string, string> vars;
+  std::map<string, string> vars;
   WriteGeneratedCodeAttributes(printer);
   vars["class_name"] = class_name();
     printer->Print(
@@ -333,7 +333,7 @@
 }
 
 void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) {
-    map<string, string> vars;
+    std::map<string, string> vars;
     vars["class_name"] = class_name();
 
     // Equality
@@ -432,7 +432,7 @@
   // Note:  These are separate from GenerateMessageSerializationMethods()
   //   because they need to be generated even for messages that are optimized
   //   for code size.
-  map<string, string> vars;
+  std::map<string, string> vars;
   vars["class_name"] = class_name();
 
   WriteGeneratedCodeAttributes(printer);
diff --git a/src/google/protobuf/compiler/java/java_message_builder.cc b/src/google/protobuf/compiler/java/java_message_builder.cc
index 5368c1d..f9bbfbf 100644
--- a/src/google/protobuf/compiler/java/java_message_builder.cc
+++ b/src/google/protobuf/compiler/java/java_message_builder.cc
@@ -462,7 +462,7 @@
     "}\n"
     "public Builder setField(\n"
     "    com.google.protobuf.Descriptors.FieldDescriptor field,\n"
-    "    Object value) {\n"
+    "    java.lang.Object value) {\n"
     "  return (Builder) super.setField(field, value);\n"
     "}\n"
     "public Builder clearField(\n"
@@ -475,12 +475,12 @@
     "}\n"
     "public Builder setRepeatedField(\n"
     "    com.google.protobuf.Descriptors.FieldDescriptor field,\n"
-    "    int index, Object value) {\n"
+    "    int index, java.lang.Object value) {\n"
     "  return (Builder) super.setRepeatedField(field, index, value);\n"
     "}\n"
     "public Builder addRepeatedField(\n"
     "    com.google.protobuf.Descriptors.FieldDescriptor field,\n"
-    "    Object value) {\n"
+    "    java.lang.Object value) {\n"
     "  return (Builder) super.addRepeatedField(field, value);\n"
     "}\n");
 
diff --git a/src/google/protobuf/compiler/java/java_options.h b/src/google/protobuf/compiler/java/java_options.h
index 7bce144..e4e7d5e 100644
--- a/src/google/protobuf/compiler/java/java_options.h
+++ b/src/google/protobuf/compiler/java/java_options.h
@@ -59,10 +59,10 @@
   bool annotate_code;
   // Name of a file where we will write a list of generated .meta file names,
   // one per line.
-  string annotation_list_file;
+  std::string annotation_list_file;
   // Name of a file where we will write a list of generated file names, one
   // per line.
-  string output_list_file;
+  std::string output_list_file;
 };
 
 }  // namespace java
diff --git a/src/google/protobuf/compiler/java/java_shared_code_generator.cc b/src/google/protobuf/compiler/java/java_shared_code_generator.cc
index 7bd5ad7..f73bfb0 100644
--- a/src/google/protobuf/compiler/java/java_shared_code_generator.cc
+++ b/src/google/protobuf/compiler/java/java_shared_code_generator.cc
@@ -182,10 +182,16 @@
   std::vector<std::pair<string, string> > dependencies;
   for (int i = 0; i < file_->dependency_count(); i++) {
     string filename = file_->dependency(i)->name();
-    string classname = FileJavaPackage(file_->dependency(i)) + "." +
-                       name_resolver_->GetDescriptorClassName(
-                           file_->dependency(i));
-    dependencies.push_back(std::make_pair(filename, classname));
+    string package = FileJavaPackage(file_->dependency(i));
+    string classname = name_resolver_->GetDescriptorClassName(
+        file_->dependency(i));
+    string full_name;
+    if (package.empty()) {
+      full_name = classname;
+    } else {
+      full_name = package + "." + classname;
+    }
+    dependencies.push_back(std::make_pair(filename, full_name));
   }
 
   // -----------------------------------------------------------------
diff --git a/src/google/protobuf/compiler/javanano/javanano_enum_field.cc b/src/google/protobuf/compiler/javanano/javanano_enum_field.cc
index 7666db3..26bc7f8 100644
--- a/src/google/protobuf/compiler/javanano/javanano_enum_field.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_enum_field.cc
@@ -52,7 +52,7 @@
 // TODO(kenton):  Factor out a "SetCommonFieldVariables()" to get rid of
 //   repeat code between this and the other field types.
 void SetEnumVariables(const Params& params,
-    const FieldDescriptor* descriptor, map<string, string>* variables) {
+    const FieldDescriptor* descriptor, std::map<string, string>* variables) {
   (*variables)["name"] =
     RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
   (*variables)["capitalized_name"] =
diff --git a/src/google/protobuf/compiler/javanano/javanano_enum_field.h b/src/google/protobuf/compiler/javanano/javanano_enum_field.h
index b94790d..1be25d1 100644
--- a/src/google/protobuf/compiler/javanano/javanano_enum_field.h
+++ b/src/google/protobuf/compiler/javanano/javanano_enum_field.h
@@ -62,7 +62,7 @@
 
  private:
   const FieldDescriptor* descriptor_;
-  map<string, string> variables_;
+  std::map<string, string> variables_;
   vector<string> canonical_values_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
@@ -85,7 +85,7 @@
 
  private:
   const FieldDescriptor* descriptor_;
-  map<string, string> variables_;
+  std::map<string, string> variables_;
   vector<string> canonical_values_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AccessorEnumFieldGenerator);
@@ -112,7 +112,7 @@
   void GenerateRepeatedDataSizeCode(io::Printer* printer) const;
 
   const FieldDescriptor* descriptor_;
-  map<string, string> variables_;
+  std::map<string, string> variables_;
   vector<string> canonical_values_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);
diff --git a/src/google/protobuf/compiler/javanano/javanano_extension.cc b/src/google/protobuf/compiler/javanano/javanano_extension.cc
index 0b9d1d8..4c61f91 100644
--- a/src/google/protobuf/compiler/javanano/javanano_extension.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_extension.cc
@@ -78,7 +78,7 @@
 }  // namespace
 
 void SetVariables(const FieldDescriptor* descriptor, const Params params,
-                  map<string, string>* variables) {
+                  std::map<string, string>* variables) {
   (*variables)["extends"] = ClassName(params, descriptor->containing_type());
   (*variables)["name"] = RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
   bool repeated = descriptor->is_repeated();
diff --git a/src/google/protobuf/compiler/javanano/javanano_extension.h b/src/google/protobuf/compiler/javanano/javanano_extension.h
index 4843e29..f4e9eb2 100644
--- a/src/google/protobuf/compiler/javanano/javanano_extension.h
+++ b/src/google/protobuf/compiler/javanano/javanano_extension.h
@@ -61,7 +61,7 @@
  private:
   const Params& params_;
   const FieldDescriptor* descriptor_;
-  map<string, string> variables_;
+  std::map<string, string> variables_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
 };
diff --git a/src/google/protobuf/compiler/javanano/javanano_field.cc b/src/google/protobuf/compiler/javanano/javanano_field.cc
index 85257f3..e31d117 100644
--- a/src/google/protobuf/compiler/javanano/javanano_field.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_field.cc
@@ -151,7 +151,7 @@
 }
 
 void SetCommonOneofVariables(const FieldDescriptor* descriptor,
-                             map<string, string>* variables) {
+                             std::map<string, string>* variables) {
   (*variables)["oneof_name"] =
       UnderscoresToCamelCase(descriptor->containing_oneof());
   (*variables)["oneof_capitalized_name"] =
@@ -169,7 +169,7 @@
 }
 
 void GenerateOneofFieldEquals(const FieldDescriptor* descriptor,
-                              const map<string, string>& variables,
+                              const std::map<string, string>& variables,
                               io::Printer* printer) {
   if (GetJavaType(descriptor) == JAVATYPE_BYTES) {
     printer->Print(variables,
@@ -190,7 +190,7 @@
 }
 
 void GenerateOneofFieldHashCode(const FieldDescriptor* descriptor,
-                                const map<string, string>& variables,
+                                const std::map<string, string>& variables,
                                 io::Printer* printer) {
   if (GetJavaType(descriptor) == JAVATYPE_BYTES) {
     printer->Print(variables,
diff --git a/src/google/protobuf/compiler/javanano/javanano_field.h b/src/google/protobuf/compiler/javanano/javanano_field.h
index 57c221f..347c888 100644
--- a/src/google/protobuf/compiler/javanano/javanano_field.h
+++ b/src/google/protobuf/compiler/javanano/javanano_field.h
@@ -114,12 +114,12 @@
 };
 
 void SetCommonOneofVariables(const FieldDescriptor* descriptor,
-                             map<string, string>* variables);
+                             std::map<string, string>* variables);
 void GenerateOneofFieldEquals(const FieldDescriptor* descriptor,
-                              const map<string, string>& variables,
+                              const std::map<string, string>& variables,
                               io::Printer* printer);
 void GenerateOneofFieldHashCode(const FieldDescriptor* descriptor,
-                                const map<string, string>& variables,
+                                const std::map<string, string>& variables,
                                 io::Printer* printer);
 
 }  // namespace javanano
diff --git a/src/google/protobuf/compiler/javanano/javanano_helpers.cc b/src/google/protobuf/compiler/javanano/javanano_helpers.cc
index 5018250..1927ba1 100644
--- a/src/google/protobuf/compiler/javanano/javanano_helpers.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_helpers.cc
@@ -567,7 +567,7 @@
 }
 
 void SetBitOperationVariables(const string name,
-    int bitIndex, map<string, string>* variables) {
+    int bitIndex, std::map<string, string>* variables) {
   (*variables)["get_" + name] = GenerateGetBit(bitIndex);
   (*variables)["set_" + name] = GenerateSetBit(bitIndex);
   (*variables)["clear_" + name] = GenerateClearBit(bitIndex);
diff --git a/src/google/protobuf/compiler/javanano/javanano_helpers.h b/src/google/protobuf/compiler/javanano/javanano_helpers.h
index 014c85a..04b2d63 100644
--- a/src/google/protobuf/compiler/javanano/javanano_helpers.h
+++ b/src/google/protobuf/compiler/javanano/javanano_helpers.h
@@ -181,7 +181,7 @@
 // the given name of the bit, to the appropriate Java expressions for the given
 // bit index.
 void SetBitOperationVariables(const string name,
-    int bitIndex, map<string, string>* variables);
+    int bitIndex, std::map<string, string>* variables);
 
 inline bool IsMapEntry(const Descriptor* descriptor) {
   // TODO(liujisi): Add an option to turn on maps for proto2 syntax as well.
diff --git a/src/google/protobuf/compiler/javanano/javanano_map_field.cc b/src/google/protobuf/compiler/javanano/javanano_map_field.cc
index 83b2b0c..a4ab885 100644
--- a/src/google/protobuf/compiler/javanano/javanano_map_field.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_map_field.cc
@@ -84,7 +84,7 @@
 }
 
 void SetMapVariables(const Params& params,
-    const FieldDescriptor* descriptor, map<string, string>* variables) {
+    const FieldDescriptor* descriptor, std::map<string, string>* variables) {
   const FieldDescriptor* key = KeyField(descriptor);
   const FieldDescriptor* value = ValueField(descriptor);
   (*variables)["name"] =
diff --git a/src/google/protobuf/compiler/javanano/javanano_map_field.h b/src/google/protobuf/compiler/javanano/javanano_map_field.h
index c01bde3..81e5915 100644
--- a/src/google/protobuf/compiler/javanano/javanano_map_field.h
+++ b/src/google/protobuf/compiler/javanano/javanano_map_field.h
@@ -58,7 +58,7 @@
 
  private:
   const FieldDescriptor* descriptor_;
-  map<string, string> variables_;
+  std::map<string, string> variables_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldGenerator);
 };
diff --git a/src/google/protobuf/compiler/javanano/javanano_message.cc b/src/google/protobuf/compiler/javanano/javanano_message.cc
index f81f7f9..7842188 100644
--- a/src/google/protobuf/compiler/javanano/javanano_message.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_message.cc
@@ -182,7 +182,7 @@
   }
 
   // oneof
-  map<string, string> vars;
+  std::map<string, string> vars;
   vars["message_name"] = descriptor_->name();
   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
     const OneofDescriptor* oneof_desc = descriptor_->oneof_decl(i);
diff --git a/src/google/protobuf/compiler/javanano/javanano_message_field.cc b/src/google/protobuf/compiler/javanano/javanano_message_field.cc
index d1d04b5..2ed8a3a 100644
--- a/src/google/protobuf/compiler/javanano/javanano_message_field.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_message_field.cc
@@ -54,7 +54,7 @@
 // TODO(kenton):  Factor out a "SetCommonFieldVariables()" to get rid of
 //   repeat code between this and the other field types.
 void SetMessageVariables(const Params& params,
-    const FieldDescriptor* descriptor, map<string, string>* variables) {
+    const FieldDescriptor* descriptor, std::map<string, string>* variables) {
   (*variables)["name"] =
     RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
   (*variables)["capitalized_name"] =
diff --git a/src/google/protobuf/compiler/javanano/javanano_message_field.h b/src/google/protobuf/compiler/javanano/javanano_message_field.h
index e074735..0ae8879 100644
--- a/src/google/protobuf/compiler/javanano/javanano_message_field.h
+++ b/src/google/protobuf/compiler/javanano/javanano_message_field.h
@@ -62,7 +62,7 @@
 
  private:
   const FieldDescriptor* descriptor_;
-  map<string, string> variables_;
+  std::map<string, string> variables_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
 };
@@ -85,7 +85,7 @@
 
  private:
   const FieldDescriptor* descriptor_;
-  map<string, string> variables_;
+  std::map<string, string> variables_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageOneofFieldGenerator);
 };
@@ -108,7 +108,7 @@
 
  private:
   const FieldDescriptor* descriptor_;
-  map<string, string> variables_;
+  std::map<string, string> variables_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
 };
diff --git a/src/google/protobuf/compiler/javanano/javanano_params.h b/src/google/protobuf/compiler/javanano/javanano_params.h
index e3b4bb9..3594767 100644
--- a/src/google/protobuf/compiler/javanano/javanano_params.h
+++ b/src/google/protobuf/compiler/javanano/javanano_params.h
@@ -47,8 +47,8 @@
 // Parameters for used by the generators
 class Params {
  public:
-  typedef map<string, string> NameMap;
-  typedef set<string> NameSet;
+  typedef std::map<string, string> NameMap;
+  typedef std::set<string> NameSet;
  private:
   string empty_;
   string base_name_;
diff --git a/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc b/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
index 978abf2..66a0ff0 100644
--- a/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
@@ -166,7 +166,7 @@
 
 
 void SetPrimitiveVariables(const FieldDescriptor* descriptor, const Params params,
-                           map<string, string>* variables) {
+                           std::map<string, string>* variables) {
   (*variables)["name"] =
     RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
   (*variables)["capitalized_name"] =
diff --git a/src/google/protobuf/compiler/javanano/javanano_primitive_field.h b/src/google/protobuf/compiler/javanano/javanano_primitive_field.h
index a01981d..d7d72d5 100644
--- a/src/google/protobuf/compiler/javanano/javanano_primitive_field.h
+++ b/src/google/protobuf/compiler/javanano/javanano_primitive_field.h
@@ -65,7 +65,7 @@
   void GenerateSerializationConditional(io::Printer* printer) const;
 
   const FieldDescriptor* descriptor_;
-  map<string, string> variables_;
+  std::map<string, string> variables_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
 };
@@ -89,7 +89,7 @@
 
  private:
   const FieldDescriptor* descriptor_;
-  map<string, string> variables_;
+  std::map<string, string> variables_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AccessorPrimitiveFieldGenerator);
 };
@@ -111,7 +111,7 @@
 
  private:
   const FieldDescriptor* descriptor_;
-  map<string, string> variables_;
+  std::map<string, string> variables_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveOneofFieldGenerator);
 };
@@ -137,7 +137,7 @@
   void GenerateRepeatedDataSizeCode(io::Printer* printer) const;
 
   const FieldDescriptor* descriptor_;
-  map<string, string> variables_;
+  std::map<string, string> variables_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);
 };
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
index 7a774a0..8899a13 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
@@ -46,7 +46,7 @@
 namespace {
 
 void SetEnumVariables(const FieldDescriptor* descriptor,
-                      map<string, string>* variables) {
+                      std::map<string, string>* variables) {
   string type = EnumName(descriptor->enum_type());
   (*variables)["storage_type"] = type;
   // For non repeated fields, if it was defined in a different file, the
@@ -118,7 +118,7 @@
 }
 
 void EnumFieldGenerator::DetermineForwardDeclarations(
-    set<string>* fwd_decls) const {
+    std::set<string>* fwd_decls) const {
   SingleFieldGenerator::DetermineForwardDeclarations(fwd_decls);
   // If it is an enum defined in a different file, then we'll need a forward
   // declaration for it.  When it is in our file, all the enums are output
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h
index 946faa8..ae56c06 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h
@@ -47,7 +47,7 @@
  public:
   virtual void GenerateCFunctionDeclarations(io::Printer* printer) const;
   virtual void GenerateCFunctionImplementations(io::Printer* printer) const;
-  virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const;
+  virtual void DetermineForwardDeclarations(std::set<string>* fwd_decls) const;
 
  protected:
   EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
index 73e4b86..b788d0a 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
@@ -59,7 +59,7 @@
 ExtensionGenerator::~ExtensionGenerator() {}
 
 void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) {
-  map<string, string> vars;
+  std::map<string, string> vars;
   vars["method_name"] = method_name_;
   SourceLocation location;
   if (descriptor_->GetSourceLocation(&location)) {
@@ -77,7 +77,7 @@
 
 void ExtensionGenerator::GenerateStaticVariablesInitialization(
     io::Printer* printer) {
-  map<string, string> vars;
+  std::map<string, string> vars;
   vars["root_class_and_method_name"] = root_class_and_method_name_;
   vars["extended_type"] = ClassName(descriptor_->containing_type());
   vars["number"] = SimpleItoa(descriptor_->number());
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_field.cc
index 9f7e84f..b6123fa 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_field.cc
@@ -49,7 +49,7 @@
 namespace {
 
 void SetCommonFieldVariables(const FieldDescriptor* descriptor,
-                             map<string, string>* variables) {
+                             std::map<string, string>* variables) {
   string camel_case_name = FieldName(descriptor);
   string raw_field_name;
   if (descriptor->type() == FieldDescriptor::TYPE_GROUP) {
@@ -178,7 +178,7 @@
 }
 
 void FieldGenerator::DetermineForwardDeclarations(
-    set<string>* fwd_decls) const {
+    std::set<string>* fwd_decls) const {
   // Nothing
 }
 
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.h b/src/google/protobuf/compiler/objectivec/objectivec_field.h
index a3a4b1b..6bd5db2 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_field.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_field.h
@@ -67,7 +67,7 @@
   virtual void GenerateCFunctionImplementations(io::Printer* printer) const;
 
   // Exposed for subclasses, should always call it on the parent class also.
-  virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const;
+  virtual void DetermineForwardDeclarations(std::set<string>* fwd_decls) const;
 
   // Used during generation, not intended to be extended by subclasses.
   void GenerateFieldDescription(
@@ -100,7 +100,7 @@
   virtual bool WantsHasProperty(void) const = 0;
 
   const FieldDescriptor* descriptor_;
-  map<string, string> variables_;
+  std::map<string, string> variables_;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator);
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc
index 7ad127b..954b268 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc
@@ -89,7 +89,7 @@
 void PruneFileAndDepsMarkingAsVisited(
     const FileDescriptor* file,
     vector<const FileDescriptor*>* files,
-    set<const FileDescriptor*>* files_visited) {
+    std::set<const FileDescriptor*>* files_visited) {
   vector<const FileDescriptor*>::iterator iter =
       std::find(files->begin(), files->end(), file);
   if (iter != files->end()) {
@@ -105,7 +105,7 @@
 void CollectMinimalFileDepsContainingExtensionsWorker(
     const FileDescriptor* file,
     vector<const FileDescriptor*>* files,
-    set<const FileDescriptor*>* files_visited) {
+    std::set<const FileDescriptor*>* files_visited) {
   if (files_visited->find(file) != files_visited->end()) {
     return;
   }
@@ -138,7 +138,7 @@
 void CollectMinimalFileDepsContainingExtensions(
     const FileDescriptor* file,
     vector<const FileDescriptor*>* files) {
-  set<const FileDescriptor*> files_visited;
+  std::set<const FileDescriptor*> files_visited;
   for (int i = 0; i < file->dependency_count(); i++) {
     const FileDescriptor* dep = file->dependency(i);
     CollectMinimalFileDepsContainingExtensionsWorker(dep, files,
@@ -229,12 +229,12 @@
       "CF_EXTERN_C_BEGIN\n"
       "\n");
 
-  set<string> fwd_decls;
+  std::set<string> fwd_decls;
   for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
        iter != message_generators_.end(); ++iter) {
     (*iter)->DetermineForwardDeclarations(&fwd_decls);
   }
-  for (set<string>::const_iterator i(fwd_decls.begin());
+  for (std::set<string>::const_iterator i(fwd_decls.begin());
        i != fwd_decls.end(); ++i) {
     printer->Print("$value$;\n", "value", *i);
   }
@@ -325,7 +325,7 @@
 
     // #import the headers for anything that a plain dependency of this proto
     // file (that means they were just an include, not a "public" include).
-    set<string> public_import_names;
+    std::set<string> public_import_names;
     for (int i = 0; i < file_->public_dependency_count(); i++) {
       public_import_names.insert(file_->public_dependency(i)->name());
     }
@@ -468,7 +468,7 @@
 
   // File descriptor only needed if there are messages to use it.
   if (message_generators_.size() > 0) {
-    map<string, string> vars;
+    std::map<string, string> vars;
     vars["root_class_name"] = root_class_name_;
     vars["package"] = file_->package();
     vars["objc_prefix"] = FileClassPrefix(file_);
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
index 1ea2676..e347ef1 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
@@ -196,7 +196,7 @@
     // method declared in protos. The main cases are methods
     // that take no arguments, or setFoo:/hasFoo: type methods.
     "clear", "data", "delimitedData", "descriptor", "extensionRegistry",
-    "extensionsCurrentlySet", "isInitialized", "serializedSize",
+    "extensionsCurrentlySet", "initialized", "isInitialized", "serializedSize",
     "sortedExtensionsInUse", "unknownFields",
 
     // MacTypes.h names
@@ -980,13 +980,13 @@
 
 class ExpectedPrefixesCollector : public LineConsumer {
  public:
-  ExpectedPrefixesCollector(map<string, string>* inout_package_to_prefix_map)
+  ExpectedPrefixesCollector(std::map<string, string>* inout_package_to_prefix_map)
       : prefix_map_(inout_package_to_prefix_map) {}
 
   virtual bool ConsumeLine(const StringPiece& line, string* out_error);
 
  private:
-  map<string, string>* prefix_map_;
+  std::map<string, string>* prefix_map_;
 };
 
 bool ExpectedPrefixesCollector::ConsumeLine(
@@ -1009,7 +1009,7 @@
 }
 
 bool LoadExpectedPackagePrefixes(const Options &generation_options,
-                                 map<string, string>* prefix_map,
+                                 std::map<string, string>* prefix_map,
                                  string* out_error) {
   if (generation_options.expected_prefixes_path.empty()) {
     return true;
@@ -1023,7 +1023,7 @@
 bool ValidateObjCClassPrefix(
     const FileDescriptor* file,
     const string& expected_prefixes_path,
-    const map<string, string>& expected_package_prefixes,
+    const std::map<string, string>& expected_package_prefixes,
     string* out_error) {
   const string prefix = file->options().objc_class_prefix();
   const string package = file->package();
@@ -1033,7 +1033,7 @@
 
   // Check: Error - See if there was an expected prefix for the package and
   // report if it doesn't match (wrong or missing).
-  map<string, string>::const_iterator package_match =
+  std::map<string, string>::const_iterator package_match =
       expected_package_prefixes.find(package);
   if (package_match != expected_package_prefixes.end()) {
     // There was an entry, and...
@@ -1082,7 +1082,7 @@
 
   // Look for any other package that uses the same prefix.
   string other_package_for_prefix;
-  for (map<string, string>::const_iterator i = expected_package_prefixes.begin();
+  for (std::map<string, string>::const_iterator i = expected_package_prefixes.begin();
        i != expected_package_prefixes.end(); ++i) {
     if (i->second == prefix) {
       other_package_for_prefix = i->first;
@@ -1150,7 +1150,7 @@
                                const Options& generation_options,
                                string* out_error) {
   // Load the expected package prefixes, if available, to validate against.
-  map<string, string> expected_package_prefixes;
+  std::map<string, string> expected_package_prefixes;
   if (!LoadExpectedPackagePrefixes(generation_options,
                                    &expected_package_prefixes,
                                    out_error)) {
@@ -1519,7 +1519,7 @@
     ParseFrameworkMappings();
   }
 
-  map<string, string>::iterator proto_lookup =
+  std::map<string, string>::iterator proto_lookup =
       proto_file_to_framework_name_.find(file->name());
   if (proto_lookup != proto_file_to_framework_name_.end()) {
     other_framework_imports_.push_back(
@@ -1640,7 +1640,7 @@
     StringPiece proto_file(proto_file_list, start, offset - start);
     StringPieceTrimWhitespace(&proto_file);
     if (proto_file.size() != 0) {
-      map<string, string>::iterator existing_entry =
+      std::map<string, string>::iterator existing_entry =
           map_->find(proto_file.ToString());
       if (existing_entry != map_->end()) {
         std::cerr << "warning: duplicate proto file reference, replacing framework entry for '"
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
index c99262a..daea760 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
@@ -262,20 +262,20 @@
  private:
   class ProtoFrameworkCollector : public LineConsumer {
    public:
-    ProtoFrameworkCollector(map<string, string>* inout_proto_file_to_framework_name)
+    ProtoFrameworkCollector(std::map<string, string>* inout_proto_file_to_framework_name)
         : map_(inout_proto_file_to_framework_name) {}
 
     virtual bool ConsumeLine(const StringPiece& line, string* out_error);
 
    private:
-    map<string, string>* map_;
+    std::map<string, string>* map_;
   };
 
   void ParseFrameworkMappings();
 
   const string generate_for_named_framework_;
   const string named_framework_to_proto_path_mappings_path_;
-  map<string, string> proto_file_to_framework_name_;
+  std::map<string, string> proto_file_to_framework_name_;
   bool need_to_parse_mapping_file_;
 
   vector<string> protobuf_framework_imports_;
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
index 0bc9dc1..bcaf570 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
@@ -162,7 +162,7 @@
 }
 
 void MapFieldGenerator::DetermineForwardDeclarations(
-    set<string>* fwd_decls) const {
+    std::set<string>* fwd_decls) const {
   RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls);
   const FieldDescriptor* value_descriptor =
       descriptor_->message_type()->FindFieldByName("value");
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.h b/src/google/protobuf/compiler/objectivec/objectivec_map_field.h
index bc68a68..6664d84 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.h
@@ -51,7 +51,7 @@
   MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
   virtual ~MapFieldGenerator();
 
-  virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const;
+  virtual void DetermineForwardDeclarations(std::set<string>* fwd_decls) const;
 
  private:
   scoped_ptr<FieldGenerator> value_field_generator_;
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.cc b/src/google/protobuf/compiler/objectivec/objectivec_message.cc
index 0a554a8..4f22e29 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_message.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_message.cc
@@ -233,7 +233,7 @@
   }
 }
 
-void MessageGenerator::DetermineForwardDeclarations(set<string>* fwd_decls) {
+void MessageGenerator::DetermineForwardDeclarations(std::set<string>* fwd_decls) {
   if (!IsMapEntryMessage(descriptor_)) {
     for (int i = 0; i < descriptor_->field_count(); i++) {
       const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
@@ -514,7 +514,7 @@
           "    };\n");
     }
 
-    map<string, string> vars;
+    std::map<string, string> vars;
     vars["classname"] = class_name_;
     vars["rootclassname"] = root_classname_;
     vars["fields"] = has_fields ? "fields" : "NULL";
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.h b/src/google/protobuf/compiler/objectivec/objectivec_message.h
index 0fb78bc..8f317ac 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_message.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_message.h
@@ -64,7 +64,7 @@
   void GenerateMessageHeader(io::Printer* printer);
   void GenerateSource(io::Printer* printer);
   void GenerateExtensionRegistrationSource(io::Printer* printer);
-  void DetermineForwardDeclarations(set<string>* fwd_decls);
+  void DetermineForwardDeclarations(std::set<string>* fwd_decls);
 
   // Checks if the message or a nested message includes a oneof definition.
   bool IncludesOneOfDefinition() const;
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
index d6ccd6d..699d25b 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
@@ -45,7 +45,7 @@
 namespace {
 
 void SetMessageVariables(const FieldDescriptor* descriptor,
-                         map<string, string>* variables) {
+                         std::map<string, string>* variables) {
   const string& message_type = ClassName(descriptor->message_type());
   (*variables)["type"] = message_type;
   (*variables)["containing_class"] = ClassName(descriptor->containing_type());
@@ -67,7 +67,7 @@
 MessageFieldGenerator::~MessageFieldGenerator() {}
 
 void MessageFieldGenerator::DetermineForwardDeclarations(
-    set<string>* fwd_decls) const {
+    std::set<string>* fwd_decls) const {
   ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls);
   // Class name is already in "storage_type".
   fwd_decls->insert("@class " + variable("storage_type"));
@@ -95,7 +95,7 @@
 RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
 
 void RepeatedMessageFieldGenerator::DetermineForwardDeclarations(
-    set<string>* fwd_decls) const {
+    std::set<string>* fwd_decls) const {
   RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls);
   // Class name is already in "storage_type".
   fwd_decls->insert("@class " + variable("storage_type"));
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.h b/src/google/protobuf/compiler/objectivec/objectivec_message_field.h
index d2dba15..50f4b6d 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.h
@@ -51,7 +51,7 @@
   virtual bool WantsHasProperty(void) const;
 
  public:
-  virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const;
+  virtual void DetermineForwardDeclarations(std::set<string>* fwd_decls) const;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
@@ -67,7 +67,7 @@
   virtual ~RepeatedMessageFieldGenerator();
 
  public:
-  virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const;
+  virtual void DetermineForwardDeclarations(std::set<string>* fwd_decls) const;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_oneof.h b/src/google/protobuf/compiler/objectivec/objectivec_oneof.h
index 3d9df4d..ff353a6 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_oneof.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_oneof.h
@@ -67,7 +67,7 @@
 
  private:
   const OneofDescriptor* descriptor_;
-  map<string, string> variables_;
+  std::map<string, string> variables_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OneofGenerator);
 };
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc
index d49350f..aa8ac32 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc
@@ -118,7 +118,7 @@
 }
 
 void SetPrimitiveVariables(const FieldDescriptor* descriptor,
-                           map<string, string>* variables) {
+                           std::map<string, string>* variables) {
   std::string primitive_name = PrimitiveTypeName(descriptor);
   (*variables)["type"] = primitive_name;
   (*variables)["storage_type"] = primitive_name;
diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc
index 23e9e62..bb4a44c 100644
--- a/src/google/protobuf/compiler/parser.cc
+++ b/src/google/protobuf/compiler/parser.cc
@@ -1391,7 +1391,7 @@
           value_location.AddPath(
               UninterpretedOption::kNegativeIntValueFieldNumber);
           uninterpreted_option->set_negative_int_value(
-              -static_cast<int64>(value));
+              static_cast<int64>(-value));
         } else {
           value_location.AddPath(
               UninterpretedOption::kPositiveIntValueFieldNumber);
diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc
index ea850c0..60e6fce 100644
--- a/src/google/protobuf/compiler/php/php_generator.cc
+++ b/src/google/protobuf/compiler/php/php_generator.cc
@@ -49,8 +49,11 @@
     "GPBMetadata/Google/Protobuf/Internal/Descriptor.php";
 const std::string kDescriptorDirName = "Google/Protobuf/Internal";
 const std::string kDescriptorPackageName = "Google\\Protobuf\\Internal";
-const char* const kReservedNames[] = {"Empty", "ECHO"};
-const int kReservedNamesSize = 2;
+const char* const kReservedNames[] = {"ARRAY", "Empty", "ECHO"};
+const int kReservedNamesSize = 3;
+const int kFieldSetter = 1;
+const int kFieldGetter = 2;
+const int kFieldProperty = 3;
 
 namespace google {
 namespace protobuf {
@@ -71,12 +74,18 @@
 std::string BinaryToHex(const string& binary);
 void Indent(io::Printer* printer);
 void Outdent(io::Printer* printer);
-void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message);
-void GenerateFieldDocComment(io::Printer* printer,
-                             const FieldDescriptor* field);
-void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_);
+void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message,
+                               int is_descriptor);
+void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field,
+                             int is_descriptor, int function_type);
+void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_,
+                            int is_descriptor);
 void GenerateEnumValueDocComment(io::Printer* printer,
                                  const EnumValueDescriptor* value);
+void GenerateServiceDocComment(io::Printer* printer,
+                               const ServiceDescriptor* service);
+void GenerateServiceMethodDocComment(io::Printer* printer,
+                              const MethodDescriptor* method);
 
 std::string RenameEmpty(const std::string& name) {
   if (name == "Empty") {
@@ -134,6 +143,25 @@
   return "";
 }
 
+template <typename DescriptorType>
+std::string NamespacedName(const string& classname,
+                            const DescriptorType* desc, bool is_descriptor) {
+  if (desc->file()->options().has_php_namespace()) {
+    const string& php_namespace = desc->file()->options().php_namespace();
+    if (php_namespace != "") {
+      return php_namespace + '\\' + classname;
+    } else {
+      return classname;
+    }
+  }
+
+  if (desc->file()->package() == "") {
+    return classname;
+  } else {
+    return PhpName(desc->file()->package(), is_descriptor) + '\\' +
+           classname;
+  }
+}
 
 template <typename DescriptorType>
 std::string FullClassName(const DescriptorType* desc, bool is_descriptor) {
@@ -144,13 +172,13 @@
     containing = containing->containing_type();
   }
   classname = ClassNamePrefix(classname, desc) + classname;
+  return NamespacedName(classname, desc, is_descriptor);
+}
 
-  if (desc->file()->package() == "") {
-    return classname;
-  } else {
-    return PhpName(desc->file()->package(), is_descriptor) + '\\' +
-           classname;
-  }
+std::string FullClassName(const ServiceDescriptor* desc, bool is_descriptor) {
+  string classname = desc->name();
+  classname = ClassNamePrefix(classname, desc) + classname;
+  return NamespacedName(classname, desc, is_descriptor);
 }
 
 std::string PhpName(const std::string& full_name, bool is_descriptor) {
@@ -258,6 +286,17 @@
   return result + ".php";
 }
 
+std::string GeneratedServiceFileName(const ServiceDescriptor* service,
+                                    bool is_descriptor) {
+  std::string result = FullClassName(service, is_descriptor) + "Interface";
+  for (int i = 0; i < result.size(); i++) {
+    if (result[i] == '\\') {
+      result[i] = '/';
+    }
+  }
+  return result + ".php";
+}
+
 std::string IntToString(int32 value) {
   std::ostringstream os;
   os << value;
@@ -297,6 +336,87 @@
   }
 }
 
+std::string PhpSetterTypeName(const FieldDescriptor* field, bool is_descriptor) {
+  if (field->is_map()) {
+    return "array|\\Google\\Protobuf\\Internal\\MapField";
+  }
+  string type;
+  switch (field->type()) {
+    case FieldDescriptor::TYPE_INT32:
+    case FieldDescriptor::TYPE_UINT32:
+    case FieldDescriptor::TYPE_SINT32:
+    case FieldDescriptor::TYPE_FIXED32:
+    case FieldDescriptor::TYPE_SFIXED32:
+    case FieldDescriptor::TYPE_ENUM:
+      type = "int";
+      break;
+    case FieldDescriptor::TYPE_INT64:
+    case FieldDescriptor::TYPE_UINT64:
+    case FieldDescriptor::TYPE_SINT64:
+    case FieldDescriptor::TYPE_FIXED64:
+    case FieldDescriptor::TYPE_SFIXED64:
+      type = "int|string";
+      break;
+    case FieldDescriptor::TYPE_DOUBLE:
+    case FieldDescriptor::TYPE_FLOAT:
+      type = "float";
+      break;
+    case FieldDescriptor::TYPE_BOOL:
+      type = "bool";
+      break;
+    case FieldDescriptor::TYPE_STRING:
+    case FieldDescriptor::TYPE_BYTES:
+      type = "string";
+      break;
+    case FieldDescriptor::TYPE_MESSAGE:
+      type = "\\" + FullClassName(field->message_type(), is_descriptor);
+      break;
+    case FieldDescriptor::TYPE_GROUP:
+      return "null";
+    default: assert(false); return "";
+  }
+  if (field->is_repeated()) {
+    // accommodate for edge case with multiple types.
+    size_t start_pos = type.find("|");
+    if (start_pos != std::string::npos) {
+      type.replace(start_pos, 1, "[]|");
+    }
+    type += "[]|\\Google\\Protobuf\\Internal\\RepeatedField";
+  }
+  return type;
+}
+
+std::string PhpGetterTypeName(const FieldDescriptor* field, bool is_descriptor) {
+  if (field->is_map()) {
+    return "\\Google\\Protobuf\\Internal\\MapField";
+  }
+  if (field->is_repeated()) {
+    return "\\Google\\Protobuf\\Internal\\RepeatedField";
+  }
+  switch (field->type()) {
+    case FieldDescriptor::TYPE_INT32:
+    case FieldDescriptor::TYPE_UINT32:
+    case FieldDescriptor::TYPE_SINT32:
+    case FieldDescriptor::TYPE_FIXED32:
+    case FieldDescriptor::TYPE_SFIXED32:
+    case FieldDescriptor::TYPE_ENUM: return "int";
+    case FieldDescriptor::TYPE_INT64:
+    case FieldDescriptor::TYPE_UINT64:
+    case FieldDescriptor::TYPE_SINT64:
+    case FieldDescriptor::TYPE_FIXED64:
+    case FieldDescriptor::TYPE_SFIXED64: return "int|string";
+    case FieldDescriptor::TYPE_DOUBLE:
+    case FieldDescriptor::TYPE_FLOAT: return "float";
+    case FieldDescriptor::TYPE_BOOL: return "bool";
+    case FieldDescriptor::TYPE_STRING:
+    case FieldDescriptor::TYPE_BYTES: return "string";
+    case FieldDescriptor::TYPE_MESSAGE:
+      return "\\" + FullClassName(field->message_type(), is_descriptor);
+    case FieldDescriptor::TYPE_GROUP: return "null";
+    default: assert(false); return "";
+  }
+}
+
 std::string EnumOrMessageSuffix(
     const FieldDescriptor* field, bool is_descriptor) {
   if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
@@ -381,7 +501,7 @@
 void GenerateField(const FieldDescriptor* field, io::Printer* printer,
                    bool is_descriptor) {
   if (field->is_repeated()) {
-    GenerateFieldDocComment(printer, field);
+    GenerateFieldDocComment(printer, field, is_descriptor, kFieldProperty);
     printer->Print(
         "private $^name^;\n",
         "name", field->name());
@@ -389,7 +509,7 @@
     // Oneof fields are handled by GenerateOneofField.
     return;
   } else {
-    GenerateFieldDocComment(printer, field);
+    GenerateFieldDocComment(printer, field, is_descriptor, kFieldProperty);
     printer->Print(
         "private $^name^ = ^default^;\n",
         "name", field->name(),
@@ -417,7 +537,7 @@
 
   // Generate getter.
   if (oneof != NULL) {
-    GenerateFieldDocComment(printer, field);
+    GenerateFieldDocComment(printer, field, is_descriptor, kFieldGetter);
     printer->Print(
         "public function get^camel_name^()\n"
         "{\n"
@@ -426,7 +546,7 @@
         "camel_name", UnderscoresToCamelCase(field->name(), true),
         "number", IntToString(field->number()));
   } else {
-    GenerateFieldDocComment(printer, field);
+    GenerateFieldDocComment(printer, field, is_descriptor, kFieldGetter);
     printer->Print(
         "public function get^camel_name^()\n"
         "{\n"
@@ -437,14 +557,11 @@
   }
 
   // Generate setter.
-  GenerateFieldDocComment(printer, field);
+  GenerateFieldDocComment(printer, field, is_descriptor, kFieldSetter);
   printer->Print(
-      "public function set^camel_name^(^var^)\n"
+      "public function set^camel_name^($var)\n"
       "{\n",
-      "camel_name", UnderscoresToCamelCase(field->name(), true),
-      "var", (field->is_repeated() ||
-              field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) ?
-             "&$var": "$var");
+      "camel_name", UnderscoresToCamelCase(field->name(), true));
 
   Indent(printer);
 
@@ -530,6 +647,8 @@
         "field_name", field->name());
   }
 
+  printer->Print("\nreturn $this;\n");
+
   Outdent(printer);
 
   printer->Print(
@@ -566,6 +685,16 @@
   Outdent(printer);
 }
 
+void GenerateServiceMethod(const MethodDescriptor* method,
+                           io::Printer* printer) {
+  printer->Print(
+        "public function ^camel_name^(\\^request_name^ $request);\n\n",
+        "camel_name", UnderscoresToCamelCase(method->name(), false),
+        "request_name", FullClassName(
+          method->input_type(), false)
+  );
+}
+
 void GenerateMessageToPool(const string& name_prefix, const Descriptor* message,
                            io::Printer* printer) {
   // Don't generate MapEntry messages -- we use the PHP extension's native
@@ -747,7 +876,7 @@
         "use Google\\Protobuf\\Internal\\GPBType;\n"
         "use Google\\Protobuf\\Internal\\GPBWire;\n"
         "use Google\\Protobuf\\Internal\\RepeatedField;\n"
-        "use Google\\Protobuf\\Internal\\InputStream;\n\n"
+        "use Google\\Protobuf\\Internal\\InputStream;\n"
         "use Google\\Protobuf\\Internal\\GPBUtil;\n\n");
   }
 }
@@ -820,13 +949,20 @@
   std::string fullname = FilenameToClassname(filename);
   int lastindex = fullname.find_last_of("\\");
 
-  if (!file->package().empty()) {
+  if (file->options().has_php_namespace()) {
+    const string& php_namespace = file->options().php_namespace();
+    if (!php_namespace.empty()) {
+      printer.Print(
+          "namespace ^name^;\n\n",
+          "name", php_namespace);
+    }
+  } else if (!file->package().empty()) {
     printer.Print(
         "namespace ^name^;\n\n",
         "name", fullname.substr(0, lastindex));
   }
 
-  GenerateEnumDocComment(&printer, en);
+  GenerateEnumDocComment(&printer, en, is_descriptor);
 
   if (lastindex != string::npos) {
     printer.Print(
@@ -872,7 +1008,14 @@
   std::string fullname = FilenameToClassname(filename);
   int lastindex = fullname.find_last_of("\\");
 
-  if (!file->package().empty()) {
+  if (file->options().has_php_namespace()) {
+    const string& php_namespace = file->options().php_namespace();
+    if (!php_namespace.empty()) {
+      printer.Print(
+          "namespace ^name^;\n\n",
+          "name", php_namespace);
+    }
+  } else if (!file->package().empty()) {
     printer.Print(
         "namespace ^name^;\n\n",
         "name", fullname.substr(0, lastindex));
@@ -880,7 +1023,7 @@
 
   GenerateUseDeclaration(is_descriptor, &printer);
 
-  GenerateMessageDocComment(&printer, message);
+  GenerateMessageDocComment(&printer, message, is_descriptor);
   if (lastindex != string::npos) {
     printer.Print(
         "class ^name^ extends \\Google\\Protobuf\\Internal\\Message\n"
@@ -928,6 +1071,9 @@
   for (int i = 0; i < message->oneof_decl_count(); i++) {
     const OneofDescriptor* oneof = message->oneof_decl(i);
     printer.Print(
+      "/**\n"
+      " * @return string\n"
+      " */\n"
       "public function get^camel_name^()\n"
       "{\n"
       "    return $this->whichOneof(\"^name^\");\n"
@@ -950,6 +1096,58 @@
   }
 }
 
+void GenerateServiceFile(const FileDescriptor* file,
+  const ServiceDescriptor* service, bool is_descriptor,
+  GeneratorContext* generator_context) {
+  std::string filename = GeneratedServiceFileName(service, is_descriptor);
+  scoped_ptr<io::ZeroCopyOutputStream> output(
+      generator_context->Open(filename));
+  io::Printer printer(output.get(), '^');
+
+  GenerateHead(file, &printer);
+
+  std::string fullname = FilenameToClassname(filename);
+  int lastindex = fullname.find_last_of("\\");
+
+  if (file->options().has_php_namespace()) {
+    const string& php_namespace = file->options().php_namespace();
+    if (!php_namespace.empty()) {
+      printer.Print(
+          "namespace ^name^;\n\n",
+          "name", php_namespace);
+    }
+  } else if (!file->package().empty()) {
+    printer.Print(
+        "namespace ^name^;\n\n",
+        "name", fullname.substr(0, lastindex));
+  }
+
+  GenerateServiceDocComment(&printer, service);
+
+  if (lastindex != string::npos) {
+      printer.Print(
+        "interface ^name^\n"
+        "{\n",
+        "name", fullname.substr(lastindex + 1));
+  } else {
+      printer.Print(
+        "interface ^name^\n"
+        "{\n",
+        "name", fullname);
+  }
+
+  Indent(&printer);
+
+  for (int i = 0; i < service->method_count(); i++) {
+    const MethodDescriptor* method = service->method(i);
+    GenerateServiceMethodDocComment(&printer, method);
+    GenerateServiceMethod(method, &printer);
+  }
+
+  Outdent(&printer);
+  printer.Print("}\n\n");
+}
+
 void GenerateFile(const FileDescriptor* file, bool is_descriptor,
                   GeneratorContext* generator_context) {
   GenerateMetadataFile(file, is_descriptor, generator_context);
@@ -961,6 +1159,12 @@
     GenerateEnumFile(file, file->enum_type(i), is_descriptor,
                      generator_context);
   }
+  if (file->options().php_generic_services()) {
+    for (int i = 0; i < file->service_count(); i++) {
+      GenerateServiceFile(file, file->service(i), is_descriptor,
+                       generator_context);
+    }
+  }
 }
 
 static string EscapePhpdoc(const string& input) {
@@ -994,22 +1198,6 @@
         // does not have a corresponding @Deprecated annotation.
         result.append("&#64;");
         break;
-      case '<':
-        // Avoid interpretation as HTML.
-        result.append("&lt;");
-        break;
-      case '>':
-        // Avoid interpretation as HTML.
-        result.append("&gt;");
-        break;
-      case '&':
-        // Avoid interpretation as HTML.
-        result.append("&amp;");
-        break;
-      case '\\':
-        // Java interprets Unicode escape sequences anywhere!
-        result.append("&#92;");
-        break;
       default:
         result.push_back(c);
         break;
@@ -1028,7 +1216,7 @@
   if (!comments.empty()) {
     // TODO(teboring):  Ideally we should parse the comment text as Markdown and
     //   write it back as HTML, but this requires a Markdown parser.  For now
-    //   we just use <pre> to get fixed-width text formatting.
+    //   we just use the proto comments unchanged.
 
     // If the comment itself contains block comment start or end markers,
     // HTML-escape them so that they don't accidentally close the doc comment.
@@ -1039,7 +1227,6 @@
       lines.pop_back();
     }
 
-    printer->Print(" * <pre>\n");
     for (int i = 0; i < lines.size(); i++) {
       // Most lines should start with a space.  Watch out for lines that start
       // with a /, since putting that right after the leading asterisk will
@@ -1051,7 +1238,6 @@
       }
     }
     printer->Print(
-        " * </pre>\n"
         " *\n");
   }
 }
@@ -1077,17 +1263,28 @@
 }
 
 void GenerateMessageDocComment(io::Printer* printer,
-                               const Descriptor* message) {
+                               const Descriptor* message, int is_descriptor) {
   printer->Print("/**\n");
   GenerateDocCommentBody(printer, message);
   printer->Print(
-    " * Protobuf type <code>^fullname^</code>\n"
+    " * Generated from protobuf message <code>^messagename^</code>\n"
     " */\n",
-    "fullname", EscapePhpdoc(message->full_name()));
+    "fullname", EscapePhpdoc(PhpName(message->full_name(), is_descriptor)),
+    "messagename", EscapePhpdoc(message->full_name()));
 }
 
-void GenerateFieldDocComment(io::Printer* printer,
-                             const FieldDescriptor* field) {
+void GenerateServiceDocComment(io::Printer* printer,
+                               const ServiceDescriptor* service) {
+  printer->Print("/**\n");
+  GenerateDocCommentBody(printer, service);
+  printer->Print(
+    " * Protobuf type <code>^fullname^</code>\n"
+    " */\n",
+    "fullname", EscapePhpdoc(service->full_name()));
+}
+
+void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field,
+                             int is_descriptor, int function_type) {
   // In theory we should have slightly different comments for setters, getters,
   // etc., but in practice everyone already knows the difference between these
   // so it's redundant information.
@@ -1099,18 +1296,27 @@
   printer->Print("/**\n");
   GenerateDocCommentBody(printer, field);
   printer->Print(
-    " * <code>^def^</code>\n",
+    " * Generated from protobuf field <code>^def^</code>\n",
     "def", EscapePhpdoc(FirstLineOf(field->DebugString())));
+  if (function_type == kFieldSetter) {
+    printer->Print(" * @param ^php_type^ $var\n",
+      "php_type", PhpSetterTypeName(field, is_descriptor));
+    printer->Print(" * @return $this\n");
+  } else if (function_type == kFieldGetter) {
+    printer->Print(" * @return ^php_type^\n",
+      "php_type", PhpGetterTypeName(field, is_descriptor));
+  }
   printer->Print(" */\n");
 }
 
-void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_) {
+void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_,
+                            int is_descriptor) {
   printer->Print("/**\n");
   GenerateDocCommentBody(printer, enum_);
   printer->Print(
     " * Protobuf enum <code>^fullname^</code>\n"
     " */\n",
-    "fullname", EscapePhpdoc(enum_->full_name()));
+    "fullname", EscapePhpdoc(PhpName(enum_->full_name(), is_descriptor)));
 }
 
 void GenerateEnumValueDocComment(io::Printer* printer,
@@ -1118,11 +1324,28 @@
   printer->Print("/**\n");
   GenerateDocCommentBody(printer, value);
   printer->Print(
-    " * <code>^def^</code>\n"
+    " * Generated from protobuf enum <code>^def^</code>\n"
     " */\n",
     "def", EscapePhpdoc(FirstLineOf(value->DebugString())));
 }
 
+void GenerateServiceMethodDocComment(io::Printer* printer,
+                              const MethodDescriptor* method) {
+  printer->Print("/**\n");
+  GenerateDocCommentBody(printer, method);
+  printer->Print(
+    " * Method <code>^method_name^</code>\n"
+    " *\n",
+    "method_name", EscapePhpdoc(UnderscoresToCamelCase(method->name(), false)));
+  printer->Print(
+    " * @param \\^input_type^ $request\n",
+    "input_type", EscapePhpdoc(FullClassName(method->input_type(), false)));
+  printer->Print(
+    " * @return \\^return_type^\n"
+    " */\n",
+    "return_type", EscapePhpdoc(FullClassName(method->output_type(), false)));
+}
+
 bool Generator::Generate(const FileDescriptor* file, const string& parameter,
                          GeneratorContext* generator_context,
                          string* error) const {
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index 6cc96b3..170148d 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -225,16 +225,17 @@
     suffix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.suffix_);
   }
   ::memcpy(&major_, &from.major_,
-    reinterpret_cast<char*>(&patch_) -
-    reinterpret_cast<char*>(&major_) + sizeof(patch_));
+    static_cast<size_t>(reinterpret_cast<char*>(&patch_) -
+    reinterpret_cast<char*>(&major_)) + sizeof(patch_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.Version)
 }
 
 void Version::SharedCtor() {
   _cached_size_ = 0;
   suffix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  ::memset(&major_, 0, reinterpret_cast<char*>(&patch_) -
-    reinterpret_cast<char*>(&major_) + sizeof(patch_));
+  ::memset(&major_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&patch_) -
+      reinterpret_cast<char*>(&major_)) + sizeof(patch_));
 }
 
 Version::~Version() {
@@ -281,8 +282,9 @@
   }
   cached_has_bits = _has_bits_[0];
   if (cached_has_bits & 14u) {
-    ::memset(&major_, 0, reinterpret_cast<char*>(&patch_) -
-      reinterpret_cast<char*>(&major_) + sizeof(patch_));
+    ::memset(&major_, 0, static_cast<size_t>(
+        reinterpret_cast<char*>(&patch_) -
+        reinterpret_cast<char*>(&major_)) + sizeof(patch_));
   }
   _has_bits_.Clear();
   _internal_metadata_.Clear();
@@ -347,7 +349,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_suffix()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->suffix().data(), this->suffix().length(),
+            this->suffix().data(), static_cast<int>(this->suffix().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.compiler.Version.suffix");
         } else {
@@ -401,7 +403,7 @@
   // optional string suffix = 4;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->suffix().data(), this->suffix().length(),
+      this->suffix().data(), static_cast<int>(this->suffix().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.compiler.Version.suffix");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -440,7 +442,7 @@
   // optional string suffix = 4;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->suffix().data(), this->suffix().length(),
+      this->suffix().data(), static_cast<int>(this->suffix().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.compiler.Version.suffix");
     target =
@@ -838,7 +840,7 @@
                 input, this->add_file_to_generate()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
             this->file_to_generate(this->file_to_generate_size() - 1).data(),
-            this->file_to_generate(this->file_to_generate_size() - 1).length(),
+            static_cast<int>(this->file_to_generate(this->file_to_generate_size() - 1).length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate");
         } else {
@@ -854,7 +856,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_parameter()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->parameter().data(), this->parameter().length(),
+            this->parameter().data(), static_cast<int>(this->parameter().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.compiler.CodeGeneratorRequest.parameter");
         } else {
@@ -916,7 +918,7 @@
   // repeated string file_to_generate = 1;
   for (int i = 0, n = this->file_to_generate_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->file_to_generate(i).data(), this->file_to_generate(i).length(),
+      this->file_to_generate(i).data(), static_cast<int>(this->file_to_generate(i).length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate");
     ::google::protobuf::internal::WireFormatLite::WriteString(
@@ -927,7 +929,7 @@
   // optional string parameter = 2;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->parameter().data(), this->parameter().length(),
+      this->parameter().data(), static_cast<int>(this->parameter().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.compiler.CodeGeneratorRequest.parameter");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -941,9 +943,10 @@
   }
 
   // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
-  for (unsigned int i = 0, n = this->proto_file_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->proto_file_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      15, this->proto_file(i), output);
+      15, this->proto_file(static_cast<int>(i)), output);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -962,7 +965,7 @@
   // repeated string file_to_generate = 1;
   for (int i = 0, n = this->file_to_generate_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->file_to_generate(i).data(), this->file_to_generate(i).length(),
+      this->file_to_generate(i).data(), static_cast<int>(this->file_to_generate(i).length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate");
     target = ::google::protobuf::internal::WireFormatLite::
@@ -973,7 +976,7 @@
   // optional string parameter = 2;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->parameter().data(), this->parameter().length(),
+      this->parameter().data(), static_cast<int>(this->parameter().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.compiler.CodeGeneratorRequest.parameter");
     target =
@@ -989,10 +992,11 @@
   }
 
   // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
-  for (unsigned int i = 0, n = this->proto_file_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->proto_file_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        15, this->proto_file(i), deterministic, target);
+        15, this->proto_file(static_cast<int>(i)), deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -1022,12 +1026,12 @@
 
   // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
   {
-    unsigned int count = this->proto_file_size();
+    unsigned int count = static_cast<unsigned int>(this->proto_file_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->proto_file(i));
+          this->proto_file(static_cast<int>(i)));
     }
   }
 
@@ -1462,7 +1466,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.compiler.CodeGeneratorResponse.File.name");
         } else {
@@ -1478,7 +1482,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_insertion_point()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->insertion_point().data(), this->insertion_point().length(),
+            this->insertion_point().data(), static_cast<int>(this->insertion_point().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point");
         } else {
@@ -1494,7 +1498,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_content()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->content().data(), this->content().length(),
+            this->content().data(), static_cast<int>(this->content().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.compiler.CodeGeneratorResponse.File.content");
         } else {
@@ -1533,7 +1537,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.compiler.CodeGeneratorResponse.File.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -1543,7 +1547,7 @@
   // optional string insertion_point = 2;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->insertion_point().data(), this->insertion_point().length(),
+      this->insertion_point().data(), static_cast<int>(this->insertion_point().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -1553,7 +1557,7 @@
   // optional string content = 15;
   if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->content().data(), this->content().length(),
+      this->content().data(), static_cast<int>(this->content().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.compiler.CodeGeneratorResponse.File.content");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -1577,7 +1581,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.compiler.CodeGeneratorResponse.File.name");
     target =
@@ -1588,7 +1592,7 @@
   // optional string insertion_point = 2;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->insertion_point().data(), this->insertion_point().length(),
+      this->insertion_point().data(), static_cast<int>(this->insertion_point().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point");
     target =
@@ -1599,7 +1603,7 @@
   // optional string content = 15;
   if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->content().data(), this->content().length(),
+      this->content().data(), static_cast<int>(this->content().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.compiler.CodeGeneratorResponse.File.content");
     target =
@@ -2022,7 +2026,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_error()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->error().data(), this->error().length(),
+            this->error().data(), static_cast<int>(this->error().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.compiler.CodeGeneratorResponse.error");
         } else {
@@ -2073,7 +2077,7 @@
   // optional string error = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->error().data(), this->error().length(),
+      this->error().data(), static_cast<int>(this->error().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.compiler.CodeGeneratorResponse.error");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -2081,9 +2085,10 @@
   }
 
   // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
-  for (unsigned int i = 0, n = this->file_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->file_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      15, this->file(i), output);
+      15, this->file(static_cast<int>(i)), output);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -2103,7 +2108,7 @@
   // optional string error = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->error().data(), this->error().length(),
+      this->error().data(), static_cast<int>(this->error().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.compiler.CodeGeneratorResponse.error");
     target =
@@ -2112,10 +2117,11 @@
   }
 
   // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
-  for (unsigned int i = 0, n = this->file_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->file_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        15, this->file(i), deterministic, target);
+        15, this->file(static_cast<int>(i)), deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -2137,12 +2143,12 @@
   }
   // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
   {
-    unsigned int count = this->file_size();
+    unsigned int count = static_cast<unsigned int>(this->file_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->file(i));
+          this->file(static_cast<int>(i)));
     }
   }
 
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index 6a3f5f8..92e28f6 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -309,29 +309,33 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_generic_services_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generic_services_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, py_generic_services_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, php_generic_services_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, deprecated_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_enable_arenas_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, objc_class_prefix_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_namespace_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, swift_prefix_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, php_class_prefix_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, php_namespace_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, uninterpreted_option_),
   0,
   1,
-  7,
   8,
   9,
-  15,
-  2,
   10,
+  17,
+  2,
   11,
   12,
   13,
   14,
+  15,
+  16,
   3,
   4,
   5,
   6,
+  7,
   ~0u,
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _has_bits_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _internal_metadata_),
@@ -498,20 +502,20 @@
   { 133, 141, sizeof(EnumValueDescriptorProto)},
   { 144, 152, sizeof(ServiceDescriptorProto)},
   { 155, 166, sizeof(MethodDescriptorProto)},
-  { 172, 194, sizeof(FileOptions)},
-  { 211, 221, sizeof(MessageOptions)},
-  { 226, 238, sizeof(FieldOptions)},
-  { 245, 251, sizeof(OneofOptions)},
-  { 252, 260, sizeof(EnumOptions)},
-  { 263, 270, sizeof(EnumValueOptions)},
-  { 272, 279, sizeof(ServiceOptions)},
-  { 281, 289, sizeof(MethodOptions)},
-  { 292, 299, sizeof(UninterpretedOption_NamePart)},
-  { 301, 313, sizeof(UninterpretedOption)},
-  { 320, 330, sizeof(SourceCodeInfo_Location)},
-  { 335, 341, sizeof(SourceCodeInfo)},
-  { 342, 351, sizeof(GeneratedCodeInfo_Annotation)},
-  { 355, 361, sizeof(GeneratedCodeInfo)},
+  { 172, 196, sizeof(FileOptions)},
+  { 215, 225, sizeof(MessageOptions)},
+  { 230, 242, sizeof(FieldOptions)},
+  { 249, 255, sizeof(OneofOptions)},
+  { 256, 264, sizeof(EnumOptions)},
+  { 267, 274, sizeof(EnumValueOptions)},
+  { 276, 283, sizeof(ServiceOptions)},
+  { 285, 293, sizeof(MethodOptions)},
+  { 296, 303, sizeof(UninterpretedOption_NamePart)},
+  { 305, 317, sizeof(UninterpretedOption)},
+  { 324, 334, sizeof(SourceCodeInfo_Location)},
+  { 339, 345, sizeof(SourceCodeInfo)},
+  { 346, 355, sizeof(GeneratedCodeInfo_Annotation)},
+  { 359, 365, sizeof(GeneratedCodeInfo)},
 };
 
 static ::google::protobuf::Message const * const file_default_instances[] = {
@@ -693,7 +697,7 @@
       "\022\023\n\013output_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036"
       ".google.protobuf.MethodOptions\022\037\n\020client"
       "_streaming\030\005 \001(\010:\005false\022\037\n\020server_stream"
-      "ing\030\006 \001(\010:\005false\"\264\005\n\013FileOptions\022\024\n\014java"
+      "ing\030\006 \001(\010:\005false\"\360\005\n\013FileOptions\022\024\n\014java"
       "_package\030\001 \001(\t\022\034\n\024java_outer_classname\030\010"
       " \001(\t\022\"\n\023java_multiple_files\030\n \001(\010:\005false"
       "\022)\n\035java_generate_equals_and_hash\030\024 \001(\010B"
@@ -703,74 +707,76 @@
       "_package\030\013 \001(\t\022\"\n\023cc_generic_services\030\020 "
       "\001(\010:\005false\022$\n\025java_generic_services\030\021 \001("
       "\010:\005false\022\"\n\023py_generic_services\030\022 \001(\010:\005f"
-      "alse\022\031\n\ndeprecated\030\027 \001(\010:\005false\022\037\n\020cc_en"
-      "able_arenas\030\037 \001(\010:\005false\022\031\n\021objc_class_p"
-      "refix\030$ \001(\t\022\030\n\020csharp_namespace\030% \001(\t\022\024\n"
-      "\014swift_prefix\030\' \001(\t\022\030\n\020php_class_prefix\030"
-      "( \001(\t\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.g"
-      "oogle.protobuf.UninterpretedOption\":\n\014Op"
-      "timizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014"
-      "LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002J\004\010&\020\'\"\362\001\n\016Mess"
-      "ageOptions\022&\n\027message_set_wire_format\030\001 "
-      "\001(\010:\005false\022.\n\037no_standard_descriptor_acc"
-      "essor\030\002 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005"
-      "false\022\021\n\tmap_entry\030\007 \001(\010\022C\n\024uninterprete"
-      "d_option\030\347\007 \003(\0132$.google.protobuf.Uninte"
-      "rpretedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\010\020\tJ\004\010\t\020\n\"\236\003\n"
-      "\014FieldOptions\022:\n\005ctype\030\001 \001(\0162#.google.pr"
-      "otobuf.FieldOptions.CType:\006STRING\022\016\n\006pac"
-      "ked\030\002 \001(\010\022\?\n\006jstype\030\006 \001(\0162$.google.proto"
-      "buf.FieldOptions.JSType:\tJS_NORMAL\022\023\n\004la"
-      "zy\030\005 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005fal"
-      "se\022\023\n\004weak\030\n \001(\010:\005false\022C\n\024uninterpreted"
-      "_option\030\347\007 \003(\0132$.google.protobuf.Uninter"
-      "pretedOption\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004COR"
-      "D\020\001\022\020\n\014STRING_PIECE\020\002\"5\n\006JSType\022\r\n\tJS_NO"
-      "RMAL\020\000\022\r\n\tJS_STRING\020\001\022\r\n\tJS_NUMBER\020\002*\t\010\350"
-      "\007\020\200\200\200\200\002J\004\010\004\020\005\"^\n\014OneofOptions\022C\n\024uninter"
-      "preted_option\030\347\007 \003(\0132$.google.protobuf.U"
-      "ninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\223\001\n\013EnumOp"
-      "tions\022\023\n\013allow_alias\030\002 \001(\010\022\031\n\ndeprecated"
-      "\030\003 \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007"
-      " \003(\0132$.google.protobuf.UninterpretedOpti"
-      "on*\t\010\350\007\020\200\200\200\200\002J\004\010\005\020\006\"}\n\020EnumValueOptions\022"
-      "\031\n\ndeprecated\030\001 \001(\010:\005false\022C\n\024uninterpre"
-      "ted_option\030\347\007 \003(\0132$.google.protobuf.Unin"
-      "terpretedOption*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOpt"
-      "ions\022\031\n\ndeprecated\030! \001(\010:\005false\022C\n\024unint"
-      "erpreted_option\030\347\007 \003(\0132$.google.protobuf"
-      ".UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\255\002\n\rMeth"
-      "odOptions\022\031\n\ndeprecated\030! \001(\010:\005false\022_\n\021"
-      "idempotency_level\030\" \001(\0162/.google.protobu"
-      "f.MethodOptions.IdempotencyLevel:\023IDEMPO"
-      "TENCY_UNKNOWN\022C\n\024uninterpreted_option\030\347\007"
-      " \003(\0132$.google.protobuf.UninterpretedOpti"
-      "on\"P\n\020IdempotencyLevel\022\027\n\023IDEMPOTENCY_UN"
-      "KNOWN\020\000\022\023\n\017NO_SIDE_EFFECTS\020\001\022\016\n\nIDEMPOTE"
-      "NT\020\002*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023UninterpretedOption\022"
-      ";\n\004name\030\002 \003(\0132-.google.protobuf.Uninterp"
-      "retedOption.NamePart\022\030\n\020identifier_value"
-      "\030\003 \001(\t\022\032\n\022positive_int_value\030\004 \001(\004\022\032\n\022ne"
-      "gative_int_value\030\005 \001(\003\022\024\n\014double_value\030\006"
-      " \001(\001\022\024\n\014string_value\030\007 \001(\014\022\027\n\017aggregate_"
-      "value\030\010 \001(\t\0323\n\010NamePart\022\021\n\tname_part\030\001 \002"
-      "(\t\022\024\n\014is_extension\030\002 \002(\010\"\325\001\n\016SourceCodeI"
-      "nfo\022:\n\010location\030\001 \003(\0132(.google.protobuf."
-      "SourceCodeInfo.Location\032\206\001\n\010Location\022\020\n\004"
-      "path\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020lead"
-      "ing_comments\030\003 \001(\t\022\031\n\021trailing_comments\030"
-      "\004 \001(\t\022!\n\031leading_detached_comments\030\006 \003(\t"
-      "\"\247\001\n\021GeneratedCodeInfo\022A\n\nannotation\030\001 \003"
-      "(\0132-.google.protobuf.GeneratedCodeInfo.A"
-      "nnotation\032O\n\nAnnotation\022\020\n\004path\030\001 \003(\005B\002\020"
-      "\001\022\023\n\013source_file\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n"
-      "\003end\030\004 \001(\005B\214\001\n\023com.google.protobufB\020Desc"
-      "riptorProtosH\001Z>github.com/golang/protob"
-      "uf/protoc-gen-go/descriptor;descriptor\242\002"
-      "\003GPB\252\002\032Google.Protobuf.Reflection"
+      "alse\022#\n\024php_generic_services\030\023 \001(\010:\005fals"
+      "e\022\031\n\ndeprecated\030\027 \001(\010:\005false\022\037\n\020cc_enabl"
+      "e_arenas\030\037 \001(\010:\005false\022\031\n\021objc_class_pref"
+      "ix\030$ \001(\t\022\030\n\020csharp_namespace\030% \001(\t\022\024\n\014sw"
+      "ift_prefix\030\' \001(\t\022\030\n\020php_class_prefix\030( \001"
+      "(\t\022\025\n\rphp_namespace\030) \001(\t\022C\n\024uninterpret"
+      "ed_option\030\347\007 \003(\0132$.google.protobuf.Unint"
+      "erpretedOption\":\n\014OptimizeMode\022\t\n\005SPEED\020"
+      "\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020"
+      "\200\200\200\200\002J\004\010&\020\'\"\362\001\n\016MessageOptions\022&\n\027messag"
+      "e_set_wire_format\030\001 \001(\010:\005false\022.\n\037no_sta"
+      "ndard_descriptor_accessor\030\002 \001(\010:\005false\022\031"
+      "\n\ndeprecated\030\003 \001(\010:\005false\022\021\n\tmap_entry\030\007"
+      " \001(\010\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.go"
+      "ogle.protobuf.UninterpretedOption*\t\010\350\007\020\200"
+      "\200\200\200\002J\004\010\010\020\tJ\004\010\t\020\n\"\236\003\n\014FieldOptions\022:\n\005cty"
+      "pe\030\001 \001(\0162#.google.protobuf.FieldOptions."
+      "CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\?\n\006jstype\030"
+      "\006 \001(\0162$.google.protobuf.FieldOptions.JST"
+      "ype:\tJS_NORMAL\022\023\n\004lazy\030\005 \001(\010:\005false\022\031\n\nd"
+      "eprecated\030\003 \001(\010:\005false\022\023\n\004weak\030\n \001(\010:\005fa"
+      "lse\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goo"
+      "gle.protobuf.UninterpretedOption\"/\n\005CTyp"
+      "e\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_PIECE\020"
+      "\002\"5\n\006JSType\022\r\n\tJS_NORMAL\020\000\022\r\n\tJS_STRING\020"
+      "\001\022\r\n\tJS_NUMBER\020\002*\t\010\350\007\020\200\200\200\200\002J\004\010\004\020\005\"^\n\014One"
+      "ofOptions\022C\n\024uninterpreted_option\030\347\007 \003(\013"
+      "2$.google.protobuf.UninterpretedOption*\t"
+      "\010\350\007\020\200\200\200\200\002\"\223\001\n\013EnumOptions\022\023\n\013allow_alias"
+      "\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005false\022C\n\024uni"
+      "nterpreted_option\030\347\007 \003(\0132$.google.protob"
+      "uf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\005\020\006\""
+      "}\n\020EnumValueOptions\022\031\n\ndeprecated\030\001 \001(\010:"
+      "\005false\022C\n\024uninterpreted_option\030\347\007 \003(\0132$."
+      "google.protobuf.UninterpretedOption*\t\010\350\007"
+      "\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndeprecated\030!"
+      " \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003"
+      "(\0132$.google.protobuf.UninterpretedOption"
+      "*\t\010\350\007\020\200\200\200\200\002\"\255\002\n\rMethodOptions\022\031\n\ndepreca"
+      "ted\030! \001(\010:\005false\022_\n\021idempotency_level\030\" "
+      "\001(\0162/.google.protobuf.MethodOptions.Idem"
+      "potencyLevel:\023IDEMPOTENCY_UNKNOWN\022C\n\024uni"
+      "nterpreted_option\030\347\007 \003(\0132$.google.protob"
+      "uf.UninterpretedOption\"P\n\020IdempotencyLev"
+      "el\022\027\n\023IDEMPOTENCY_UNKNOWN\020\000\022\023\n\017NO_SIDE_E"
+      "FFECTS\020\001\022\016\n\nIDEMPOTENT\020\002*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023"
+      "UninterpretedOption\022;\n\004name\030\002 \003(\0132-.goog"
+      "le.protobuf.UninterpretedOption.NamePart"
+      "\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022positive_i"
+      "nt_value\030\004 \001(\004\022\032\n\022negative_int_value\030\005 \001"
+      "(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014string_value"
+      "\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323\n\010NameP"
+      "art\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_extension\030\002"
+      " \002(\010\"\325\001\n\016SourceCodeInfo\022:\n\010location\030\001 \003("
+      "\0132(.google.protobuf.SourceCodeInfo.Locat"
+      "ion\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004sp"
+      "an\030\002 \003(\005B\002\020\001\022\030\n\020leading_comments\030\003 \001(\t\022\031"
+      "\n\021trailing_comments\030\004 \001(\t\022!\n\031leading_det"
+      "ached_comments\030\006 \003(\t\"\247\001\n\021GeneratedCodeIn"
+      "fo\022A\n\nannotation\030\001 \003(\0132-.google.protobuf"
+      ".GeneratedCodeInfo.Annotation\032O\n\nAnnotat"
+      "ion\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source_file\030\002 \001"
+      "(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B\214\001\n\023com.g"
+      "oogle.protobufB\020DescriptorProtosH\001Z>gith"
+      "ub.com/golang/protobuf/protoc-gen-go/des"
+      "criptor;descriptor\242\002\003GPB\252\002\032Google.Protob"
+      "uf.Reflection"
   };
   ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 5753);
+      descriptor, 5813);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
 }
@@ -1076,9 +1082,10 @@
   (void) cached_has_bits;
 
   // repeated .google.protobuf.FileDescriptorProto file = 1;
-  for (unsigned int i = 0, n = this->file_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->file_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      1, this->file(i), output);
+      1, this->file(static_cast<int>(i)), output);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -1095,10 +1102,11 @@
   (void) cached_has_bits;
 
   // repeated .google.protobuf.FileDescriptorProto file = 1;
-  for (unsigned int i = 0, n = this->file_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->file_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        1, this->file(i), deterministic, target);
+        1, this->file(static_cast<int>(i)), deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -1120,12 +1128,12 @@
   }
   // repeated .google.protobuf.FileDescriptorProto file = 1;
   {
-    unsigned int count = this->file_size();
+    unsigned int count = static_cast<unsigned int>(this->file_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->file(i));
+          this->file(static_cast<int>(i)));
     }
   }
 
@@ -1300,8 +1308,9 @@
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   package_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   syntax_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  ::memset(&options_, 0, reinterpret_cast<char*>(&source_code_info_) -
-    reinterpret_cast<char*>(&options_) + sizeof(source_code_info_));
+  ::memset(&options_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&source_code_info_) -
+      reinterpret_cast<char*>(&options_)) + sizeof(source_code_info_));
 }
 
 FileDescriptorProto::~FileDescriptorProto() {
@@ -1397,7 +1406,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.FileDescriptorProto.name");
         } else {
@@ -1413,7 +1422,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_package()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->package().data(), this->package().length(),
+            this->package().data(), static_cast<int>(this->package().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.FileDescriptorProto.package");
         } else {
@@ -1430,7 +1439,7 @@
                 input, this->add_dependency()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
             this->dependency(this->dependency_size() - 1).data(),
-            this->dependency(this->dependency_size() - 1).length(),
+            static_cast<int>(this->dependency(this->dependency_size() - 1).length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.FileDescriptorProto.dependency");
         } else {
@@ -1556,7 +1565,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_syntax()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->syntax().data(), this->syntax().length(),
+            this->syntax().data(), static_cast<int>(this->syntax().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.FileDescriptorProto.syntax");
         } else {
@@ -1595,7 +1604,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileDescriptorProto.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -1605,7 +1614,7 @@
   // optional string package = 2;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->package().data(), this->package().length(),
+      this->package().data(), static_cast<int>(this->package().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileDescriptorProto.package");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -1615,7 +1624,7 @@
   // repeated string dependency = 3;
   for (int i = 0, n = this->dependency_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->dependency(i).data(), this->dependency(i).length(),
+      this->dependency(i).data(), static_cast<int>(this->dependency(i).length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileDescriptorProto.dependency");
     ::google::protobuf::internal::WireFormatLite::WriteString(
@@ -1623,27 +1632,31 @@
   }
 
   // repeated .google.protobuf.DescriptorProto message_type = 4;
-  for (unsigned int i = 0, n = this->message_type_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->message_type_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      4, this->message_type(i), output);
+      4, this->message_type(static_cast<int>(i)), output);
   }
 
   // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
-  for (unsigned int i = 0, n = this->enum_type_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->enum_type_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      5, this->enum_type(i), output);
+      5, this->enum_type(static_cast<int>(i)), output);
   }
 
   // repeated .google.protobuf.ServiceDescriptorProto service = 6;
-  for (unsigned int i = 0, n = this->service_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->service_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      6, this->service(i), output);
+      6, this->service(static_cast<int>(i)), output);
   }
 
   // repeated .google.protobuf.FieldDescriptorProto extension = 7;
-  for (unsigned int i = 0, n = this->extension_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->extension_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      7, this->extension(i), output);
+      7, this->extension(static_cast<int>(i)), output);
   }
 
   // optional .google.protobuf.FileOptions options = 8;
@@ -1673,7 +1686,7 @@
   // optional string syntax = 12;
   if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->syntax().data(), this->syntax().length(),
+      this->syntax().data(), static_cast<int>(this->syntax().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileDescriptorProto.syntax");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -1697,7 +1710,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileDescriptorProto.name");
     target =
@@ -1708,7 +1721,7 @@
   // optional string package = 2;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->package().data(), this->package().length(),
+      this->package().data(), static_cast<int>(this->package().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileDescriptorProto.package");
     target =
@@ -1719,7 +1732,7 @@
   // repeated string dependency = 3;
   for (int i = 0, n = this->dependency_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->dependency(i).data(), this->dependency(i).length(),
+      this->dependency(i).data(), static_cast<int>(this->dependency(i).length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileDescriptorProto.dependency");
     target = ::google::protobuf::internal::WireFormatLite::
@@ -1727,31 +1740,35 @@
   }
 
   // repeated .google.protobuf.DescriptorProto message_type = 4;
-  for (unsigned int i = 0, n = this->message_type_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->message_type_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        4, this->message_type(i), deterministic, target);
+        4, this->message_type(static_cast<int>(i)), deterministic, target);
   }
 
   // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
-  for (unsigned int i = 0, n = this->enum_type_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->enum_type_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        5, this->enum_type(i), deterministic, target);
+        5, this->enum_type(static_cast<int>(i)), deterministic, target);
   }
 
   // repeated .google.protobuf.ServiceDescriptorProto service = 6;
-  for (unsigned int i = 0, n = this->service_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->service_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        6, this->service(i), deterministic, target);
+        6, this->service(static_cast<int>(i)), deterministic, target);
   }
 
   // repeated .google.protobuf.FieldDescriptorProto extension = 7;
-  for (unsigned int i = 0, n = this->extension_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->extension_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        7, this->extension(i), deterministic, target);
+        7, this->extension(static_cast<int>(i)), deterministic, target);
   }
 
   // optional .google.protobuf.FileOptions options = 8;
@@ -1779,7 +1796,7 @@
   // optional string syntax = 12;
   if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->syntax().data(), this->syntax().length(),
+      this->syntax().data(), static_cast<int>(this->syntax().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileDescriptorProto.syntax");
     target =
@@ -1814,45 +1831,45 @@
 
   // repeated .google.protobuf.DescriptorProto message_type = 4;
   {
-    unsigned int count = this->message_type_size();
+    unsigned int count = static_cast<unsigned int>(this->message_type_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->message_type(i));
+          this->message_type(static_cast<int>(i)));
     }
   }
 
   // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
   {
-    unsigned int count = this->enum_type_size();
+    unsigned int count = static_cast<unsigned int>(this->enum_type_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->enum_type(i));
+          this->enum_type(static_cast<int>(i)));
     }
   }
 
   // repeated .google.protobuf.ServiceDescriptorProto service = 6;
   {
-    unsigned int count = this->service_size();
+    unsigned int count = static_cast<unsigned int>(this->service_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->service(i));
+          this->service(static_cast<int>(i)));
     }
   }
 
   // repeated .google.protobuf.FieldDescriptorProto extension = 7;
   {
-    unsigned int count = this->extension_size();
+    unsigned int count = static_cast<unsigned int>(this->extension_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->extension(i));
+          this->extension(static_cast<int>(i)));
     }
   }
 
@@ -2586,15 +2603,16 @@
     options_ = NULL;
   }
   ::memcpy(&start_, &from.start_,
-    reinterpret_cast<char*>(&end_) -
-    reinterpret_cast<char*>(&start_) + sizeof(end_));
+    static_cast<size_t>(reinterpret_cast<char*>(&end_) -
+    reinterpret_cast<char*>(&start_)) + sizeof(end_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ExtensionRange)
 }
 
 void DescriptorProto_ExtensionRange::SharedCtor() {
   _cached_size_ = 0;
-  ::memset(&options_, 0, reinterpret_cast<char*>(&end_) -
-    reinterpret_cast<char*>(&options_) + sizeof(end_));
+  ::memset(&options_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&end_) -
+      reinterpret_cast<char*>(&options_)) + sizeof(end_));
 }
 
 DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() {
@@ -2641,8 +2659,9 @@
   }
   cached_has_bits = _has_bits_[0];
   if (cached_has_bits & 6u) {
-    ::memset(&start_, 0, reinterpret_cast<char*>(&end_) -
-      reinterpret_cast<char*>(&start_) + sizeof(end_));
+    ::memset(&start_, 0, static_cast<size_t>(
+        reinterpret_cast<char*>(&end_) -
+        reinterpret_cast<char*>(&start_)) + sizeof(end_));
   }
   _has_bits_.Clear();
   _internal_metadata_.Clear();
@@ -3017,15 +3036,16 @@
       _cached_size_(0) {
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   ::memcpy(&start_, &from.start_,
-    reinterpret_cast<char*>(&end_) -
-    reinterpret_cast<char*>(&start_) + sizeof(end_));
+    static_cast<size_t>(reinterpret_cast<char*>(&end_) -
+    reinterpret_cast<char*>(&start_)) + sizeof(end_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ReservedRange)
 }
 
 void DescriptorProto_ReservedRange::SharedCtor() {
   _cached_size_ = 0;
-  ::memset(&start_, 0, reinterpret_cast<char*>(&end_) -
-    reinterpret_cast<char*>(&start_) + sizeof(end_));
+  ::memset(&start_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&end_) -
+      reinterpret_cast<char*>(&start_)) + sizeof(end_));
 }
 
 DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() {
@@ -3067,8 +3087,9 @@
 
   cached_has_bits = _has_bits_[0];
   if (cached_has_bits & 3u) {
-    ::memset(&start_, 0, reinterpret_cast<char*>(&end_) -
-      reinterpret_cast<char*>(&start_) + sizeof(end_));
+    ::memset(&start_, 0, static_cast<size_t>(
+        reinterpret_cast<char*>(&end_) -
+        reinterpret_cast<char*>(&start_)) + sizeof(end_));
   }
   _has_bits_.Clear();
   _internal_metadata_.Clear();
@@ -3470,7 +3491,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.DescriptorProto.name");
         } else {
@@ -3583,7 +3604,7 @@
                 input, this->add_reserved_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
             this->reserved_name(this->reserved_name_size() - 1).data(),
-            this->reserved_name(this->reserved_name_size() - 1).length(),
+            static_cast<int>(this->reserved_name(this->reserved_name_size() - 1).length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.DescriptorProto.reserved_name");
         } else {
@@ -3622,7 +3643,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.DescriptorProto.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -3630,33 +3651,38 @@
   }
 
   // repeated .google.protobuf.FieldDescriptorProto field = 2;
-  for (unsigned int i = 0, n = this->field_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->field_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      2, this->field(i), output);
+      2, this->field(static_cast<int>(i)), output);
   }
 
   // repeated .google.protobuf.DescriptorProto nested_type = 3;
-  for (unsigned int i = 0, n = this->nested_type_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->nested_type_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      3, this->nested_type(i), output);
+      3, this->nested_type(static_cast<int>(i)), output);
   }
 
   // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
-  for (unsigned int i = 0, n = this->enum_type_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->enum_type_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      4, this->enum_type(i), output);
+      4, this->enum_type(static_cast<int>(i)), output);
   }
 
   // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
-  for (unsigned int i = 0, n = this->extension_range_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->extension_range_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      5, this->extension_range(i), output);
+      5, this->extension_range(static_cast<int>(i)), output);
   }
 
   // repeated .google.protobuf.FieldDescriptorProto extension = 6;
-  for (unsigned int i = 0, n = this->extension_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->extension_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      6, this->extension(i), output);
+      6, this->extension(static_cast<int>(i)), output);
   }
 
   // optional .google.protobuf.MessageOptions options = 7;
@@ -3666,21 +3692,23 @@
   }
 
   // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
-  for (unsigned int i = 0, n = this->oneof_decl_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->oneof_decl_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      8, this->oneof_decl(i), output);
+      8, this->oneof_decl(static_cast<int>(i)), output);
   }
 
   // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
-  for (unsigned int i = 0, n = this->reserved_range_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->reserved_range_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      9, this->reserved_range(i), output);
+      9, this->reserved_range(static_cast<int>(i)), output);
   }
 
   // repeated string reserved_name = 10;
   for (int i = 0, n = this->reserved_name_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->reserved_name(i).data(), this->reserved_name(i).length(),
+      this->reserved_name(i).data(), static_cast<int>(this->reserved_name(i).length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.DescriptorProto.reserved_name");
     ::google::protobuf::internal::WireFormatLite::WriteString(
@@ -3704,7 +3732,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.DescriptorProto.name");
     target =
@@ -3713,38 +3741,43 @@
   }
 
   // repeated .google.protobuf.FieldDescriptorProto field = 2;
-  for (unsigned int i = 0, n = this->field_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->field_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        2, this->field(i), deterministic, target);
+        2, this->field(static_cast<int>(i)), deterministic, target);
   }
 
   // repeated .google.protobuf.DescriptorProto nested_type = 3;
-  for (unsigned int i = 0, n = this->nested_type_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->nested_type_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        3, this->nested_type(i), deterministic, target);
+        3, this->nested_type(static_cast<int>(i)), deterministic, target);
   }
 
   // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
-  for (unsigned int i = 0, n = this->enum_type_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->enum_type_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        4, this->enum_type(i), deterministic, target);
+        4, this->enum_type(static_cast<int>(i)), deterministic, target);
   }
 
   // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
-  for (unsigned int i = 0, n = this->extension_range_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->extension_range_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        5, this->extension_range(i), deterministic, target);
+        5, this->extension_range(static_cast<int>(i)), deterministic, target);
   }
 
   // repeated .google.protobuf.FieldDescriptorProto extension = 6;
-  for (unsigned int i = 0, n = this->extension_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->extension_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        6, this->extension(i), deterministic, target);
+        6, this->extension(static_cast<int>(i)), deterministic, target);
   }
 
   // optional .google.protobuf.MessageOptions options = 7;
@@ -3755,23 +3788,25 @@
   }
 
   // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
-  for (unsigned int i = 0, n = this->oneof_decl_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->oneof_decl_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        8, this->oneof_decl(i), deterministic, target);
+        8, this->oneof_decl(static_cast<int>(i)), deterministic, target);
   }
 
   // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
-  for (unsigned int i = 0, n = this->reserved_range_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->reserved_range_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        9, this->reserved_range(i), deterministic, target);
+        9, this->reserved_range(static_cast<int>(i)), deterministic, target);
   }
 
   // repeated string reserved_name = 10;
   for (int i = 0, n = this->reserved_name_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->reserved_name(i).data(), this->reserved_name(i).length(),
+      this->reserved_name(i).data(), static_cast<int>(this->reserved_name(i).length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.DescriptorProto.reserved_name");
     target = ::google::protobuf::internal::WireFormatLite::
@@ -3797,78 +3832,78 @@
   }
   // repeated .google.protobuf.FieldDescriptorProto field = 2;
   {
-    unsigned int count = this->field_size();
+    unsigned int count = static_cast<unsigned int>(this->field_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->field(i));
+          this->field(static_cast<int>(i)));
     }
   }
 
   // repeated .google.protobuf.DescriptorProto nested_type = 3;
   {
-    unsigned int count = this->nested_type_size();
+    unsigned int count = static_cast<unsigned int>(this->nested_type_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->nested_type(i));
+          this->nested_type(static_cast<int>(i)));
     }
   }
 
   // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
   {
-    unsigned int count = this->enum_type_size();
+    unsigned int count = static_cast<unsigned int>(this->enum_type_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->enum_type(i));
+          this->enum_type(static_cast<int>(i)));
     }
   }
 
   // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
   {
-    unsigned int count = this->extension_range_size();
+    unsigned int count = static_cast<unsigned int>(this->extension_range_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->extension_range(i));
+          this->extension_range(static_cast<int>(i)));
     }
   }
 
   // repeated .google.protobuf.FieldDescriptorProto extension = 6;
   {
-    unsigned int count = this->extension_size();
+    unsigned int count = static_cast<unsigned int>(this->extension_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->extension(i));
+          this->extension(static_cast<int>(i)));
     }
   }
 
   // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
   {
-    unsigned int count = this->oneof_decl_size();
+    unsigned int count = static_cast<unsigned int>(this->oneof_decl_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->oneof_decl(i));
+          this->oneof_decl(static_cast<int>(i)));
     }
   }
 
   // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
   {
-    unsigned int count = this->reserved_range_size();
+    unsigned int count = static_cast<unsigned int>(this->reserved_range_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->reserved_range(i));
+          this->reserved_range(static_cast<int>(i)));
     }
   }
 
@@ -4518,9 +4553,10 @@
   (void) cached_has_bits;
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      999, this->uninterpreted_option(i), output);
+      999, this->uninterpreted_option(static_cast<int>(i)), output);
   }
 
   // Extension range [1000, 536870912)
@@ -4541,10 +4577,11 @@
   (void) cached_has_bits;
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), deterministic, target);
+        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -4572,12 +4609,12 @@
   }
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
-    unsigned int count = this->uninterpreted_option_size();
+    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
     total_size += 2UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->uninterpreted_option(i));
+          this->uninterpreted_option(static_cast<int>(i)));
     }
   }
 
@@ -4745,8 +4782,8 @@
     options_ = NULL;
   }
   ::memcpy(&number_, &from.number_,
-    reinterpret_cast<char*>(&type_) -
-    reinterpret_cast<char*>(&number_) + sizeof(type_));
+    static_cast<size_t>(reinterpret_cast<char*>(&type_) -
+    reinterpret_cast<char*>(&number_)) + sizeof(type_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldDescriptorProto)
 }
 
@@ -4757,8 +4794,9 @@
   type_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   default_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   json_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  ::memset(&options_, 0, reinterpret_cast<char*>(&oneof_index_) -
-    reinterpret_cast<char*>(&options_) + sizeof(oneof_index_));
+  ::memset(&options_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&oneof_index_) -
+      reinterpret_cast<char*>(&options_)) + sizeof(oneof_index_));
   label_ = 1;
   type_ = 1;
 }
@@ -4834,8 +4872,9 @@
     }
   }
   if (cached_has_bits & 192u) {
-    ::memset(&number_, 0, reinterpret_cast<char*>(&oneof_index_) -
-      reinterpret_cast<char*>(&number_) + sizeof(oneof_index_));
+    ::memset(&number_, 0, static_cast<size_t>(
+        reinterpret_cast<char*>(&oneof_index_) -
+        reinterpret_cast<char*>(&number_)) + sizeof(oneof_index_));
   }
   if (cached_has_bits & 768u) {
     label_ = 1;
@@ -4862,7 +4901,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.FieldDescriptorProto.name");
         } else {
@@ -4878,7 +4917,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_extendee()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->extendee().data(), this->extendee().length(),
+            this->extendee().data(), static_cast<int>(this->extendee().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.FieldDescriptorProto.extendee");
         } else {
@@ -4912,7 +4951,8 @@
           if (::google::protobuf::FieldDescriptorProto_Label_IsValid(value)) {
             set_label(static_cast< ::google::protobuf::FieldDescriptorProto_Label >(value));
           } else {
-            mutable_unknown_fields()->AddVarint(4, value);
+            mutable_unknown_fields()->AddVarint(
+                4, static_cast< ::google::protobuf::uint64>(value));
           }
         } else {
           goto handle_unusual;
@@ -4931,7 +4971,8 @@
           if (::google::protobuf::FieldDescriptorProto_Type_IsValid(value)) {
             set_type(static_cast< ::google::protobuf::FieldDescriptorProto_Type >(value));
           } else {
-            mutable_unknown_fields()->AddVarint(5, value);
+            mutable_unknown_fields()->AddVarint(
+                5, static_cast< ::google::protobuf::uint64>(value));
           }
         } else {
           goto handle_unusual;
@@ -4946,7 +4987,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_type_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->type_name().data(), this->type_name().length(),
+            this->type_name().data(), static_cast<int>(this->type_name().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.FieldDescriptorProto.type_name");
         } else {
@@ -4962,7 +5003,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_default_value()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->default_value().data(), this->default_value().length(),
+            this->default_value().data(), static_cast<int>(this->default_value().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.FieldDescriptorProto.default_value");
         } else {
@@ -5004,7 +5045,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_json_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->json_name().data(), this->json_name().length(),
+            this->json_name().data(), static_cast<int>(this->json_name().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.FieldDescriptorProto.json_name");
         } else {
@@ -5043,7 +5084,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FieldDescriptorProto.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -5053,7 +5094,7 @@
   // optional string extendee = 2;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->extendee().data(), this->extendee().length(),
+      this->extendee().data(), static_cast<int>(this->extendee().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FieldDescriptorProto.extendee");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -5080,7 +5121,7 @@
   // optional string type_name = 6;
   if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->type_name().data(), this->type_name().length(),
+      this->type_name().data(), static_cast<int>(this->type_name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FieldDescriptorProto.type_name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -5090,7 +5131,7 @@
   // optional string default_value = 7;
   if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->default_value().data(), this->default_value().length(),
+      this->default_value().data(), static_cast<int>(this->default_value().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FieldDescriptorProto.default_value");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -5111,7 +5152,7 @@
   // optional string json_name = 10;
   if (cached_has_bits & 0x00000010u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->json_name().data(), this->json_name().length(),
+      this->json_name().data(), static_cast<int>(this->json_name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FieldDescriptorProto.json_name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -5135,7 +5176,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FieldDescriptorProto.name");
     target =
@@ -5146,7 +5187,7 @@
   // optional string extendee = 2;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->extendee().data(), this->extendee().length(),
+      this->extendee().data(), static_cast<int>(this->extendee().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FieldDescriptorProto.extendee");
     target =
@@ -5174,7 +5215,7 @@
   // optional string type_name = 6;
   if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->type_name().data(), this->type_name().length(),
+      this->type_name().data(), static_cast<int>(this->type_name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FieldDescriptorProto.type_name");
     target =
@@ -5185,7 +5226,7 @@
   // optional string default_value = 7;
   if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->default_value().data(), this->default_value().length(),
+      this->default_value().data(), static_cast<int>(this->default_value().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FieldDescriptorProto.default_value");
     target =
@@ -5208,7 +5249,7 @@
   // optional string json_name = 10;
   if (cached_has_bits & 0x00000010u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->json_name().data(), this->json_name().length(),
+      this->json_name().data(), static_cast<int>(this->json_name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FieldDescriptorProto.json_name");
     target =
@@ -5999,7 +6040,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.OneofDescriptorProto.name");
         } else {
@@ -6050,7 +6091,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.OneofDescriptorProto.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -6080,7 +6121,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.OneofDescriptorProto.name");
     target =
@@ -6435,7 +6476,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.EnumDescriptorProto.name");
         } else {
@@ -6498,7 +6539,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.EnumDescriptorProto.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -6506,9 +6547,10 @@
   }
 
   // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
-  for (unsigned int i = 0, n = this->value_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->value_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      2, this->value(i), output);
+      2, this->value(static_cast<int>(i)), output);
   }
 
   // optional .google.protobuf.EnumOptions options = 3;
@@ -6534,7 +6576,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.EnumDescriptorProto.name");
     target =
@@ -6543,10 +6585,11 @@
   }
 
   // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
-  for (unsigned int i = 0, n = this->value_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->value_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        2, this->value(i), deterministic, target);
+        2, this->value(static_cast<int>(i)), deterministic, target);
   }
 
   // optional .google.protobuf.EnumOptions options = 3;
@@ -6575,12 +6618,12 @@
   }
   // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
   {
-    unsigned int count = this->value_size();
+    unsigned int count = static_cast<unsigned int>(this->value_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->value(i));
+          this->value(static_cast<int>(i)));
     }
   }
 
@@ -6865,8 +6908,9 @@
 void EnumValueDescriptorProto::SharedCtor() {
   _cached_size_ = 0;
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  ::memset(&options_, 0, reinterpret_cast<char*>(&number_) -
-    reinterpret_cast<char*>(&options_) + sizeof(number_));
+  ::memset(&options_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&number_) -
+      reinterpret_cast<char*>(&options_)) + sizeof(number_));
 }
 
 EnumValueDescriptorProto::~EnumValueDescriptorProto() {
@@ -6941,7 +6985,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.EnumValueDescriptorProto.name");
         } else {
@@ -7006,7 +7050,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.EnumValueDescriptorProto.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -7041,7 +7085,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.EnumValueDescriptorProto.name");
     target =
@@ -7437,7 +7481,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.ServiceDescriptorProto.name");
         } else {
@@ -7500,7 +7544,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.ServiceDescriptorProto.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -7508,9 +7552,10 @@
   }
 
   // repeated .google.protobuf.MethodDescriptorProto method = 2;
-  for (unsigned int i = 0, n = this->method_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->method_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      2, this->method(i), output);
+      2, this->method(static_cast<int>(i)), output);
   }
 
   // optional .google.protobuf.ServiceOptions options = 3;
@@ -7536,7 +7581,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.ServiceDescriptorProto.name");
     target =
@@ -7545,10 +7590,11 @@
   }
 
   // repeated .google.protobuf.MethodDescriptorProto method = 2;
-  for (unsigned int i = 0, n = this->method_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->method_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        2, this->method(i), deterministic, target);
+        2, this->method(static_cast<int>(i)), deterministic, target);
   }
 
   // optional .google.protobuf.ServiceOptions options = 3;
@@ -7577,12 +7623,12 @@
   }
   // repeated .google.protobuf.MethodDescriptorProto method = 2;
   {
-    unsigned int count = this->method_size();
+    unsigned int count = static_cast<unsigned int>(this->method_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->method(i));
+          this->method(static_cast<int>(i)));
     }
   }
 
@@ -7872,8 +7918,8 @@
     options_ = NULL;
   }
   ::memcpy(&client_streaming_, &from.client_streaming_,
-    reinterpret_cast<char*>(&server_streaming_) -
-    reinterpret_cast<char*>(&client_streaming_) + sizeof(server_streaming_));
+    static_cast<size_t>(reinterpret_cast<char*>(&server_streaming_) -
+    reinterpret_cast<char*>(&client_streaming_)) + sizeof(server_streaming_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodDescriptorProto)
 }
 
@@ -7882,8 +7928,9 @@
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   input_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   output_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  ::memset(&options_, 0, reinterpret_cast<char*>(&server_streaming_) -
-    reinterpret_cast<char*>(&options_) + sizeof(server_streaming_));
+  ::memset(&options_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&server_streaming_) -
+      reinterpret_cast<char*>(&options_)) + sizeof(server_streaming_));
 }
 
 MethodDescriptorProto::~MethodDescriptorProto() {
@@ -7947,8 +7994,9 @@
     }
   }
   if (cached_has_bits & 48u) {
-    ::memset(&client_streaming_, 0, reinterpret_cast<char*>(&server_streaming_) -
-      reinterpret_cast<char*>(&client_streaming_) + sizeof(server_streaming_));
+    ::memset(&client_streaming_, 0, static_cast<size_t>(
+        reinterpret_cast<char*>(&server_streaming_) -
+        reinterpret_cast<char*>(&client_streaming_)) + sizeof(server_streaming_));
   }
   _has_bits_.Clear();
   _internal_metadata_.Clear();
@@ -7971,7 +8019,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.MethodDescriptorProto.name");
         } else {
@@ -7987,7 +8035,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_input_type()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->input_type().data(), this->input_type().length(),
+            this->input_type().data(), static_cast<int>(this->input_type().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.MethodDescriptorProto.input_type");
         } else {
@@ -8003,7 +8051,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_output_type()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->output_type().data(), this->output_type().length(),
+            this->output_type().data(), static_cast<int>(this->output_type().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.MethodDescriptorProto.output_type");
         } else {
@@ -8082,7 +8130,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.MethodDescriptorProto.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -8092,7 +8140,7 @@
   // optional string input_type = 2;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->input_type().data(), this->input_type().length(),
+      this->input_type().data(), static_cast<int>(this->input_type().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.MethodDescriptorProto.input_type");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -8102,7 +8150,7 @@
   // optional string output_type = 3;
   if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->output_type().data(), this->output_type().length(),
+      this->output_type().data(), static_cast<int>(this->output_type().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.MethodDescriptorProto.output_type");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -8142,7 +8190,7 @@
   // optional string name = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.MethodDescriptorProto.name");
     target =
@@ -8153,7 +8201,7 @@
   // optional string input_type = 2;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->input_type().data(), this->input_type().length(),
+      this->input_type().data(), static_cast<int>(this->input_type().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.MethodDescriptorProto.input_type");
     target =
@@ -8164,7 +8212,7 @@
   // optional string output_type = 3;
   if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->output_type().data(), this->output_type().length(),
+      this->output_type().data(), static_cast<int>(this->output_type().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.MethodDescriptorProto.output_type");
     target =
@@ -8646,12 +8694,14 @@
 const int FileOptions::kCcGenericServicesFieldNumber;
 const int FileOptions::kJavaGenericServicesFieldNumber;
 const int FileOptions::kPyGenericServicesFieldNumber;
+const int FileOptions::kPhpGenericServicesFieldNumber;
 const int FileOptions::kDeprecatedFieldNumber;
 const int FileOptions::kCcEnableArenasFieldNumber;
 const int FileOptions::kObjcClassPrefixFieldNumber;
 const int FileOptions::kCsharpNamespaceFieldNumber;
 const int FileOptions::kSwiftPrefixFieldNumber;
 const int FileOptions::kPhpClassPrefixFieldNumber;
+const int FileOptions::kPhpNamespaceFieldNumber;
 const int FileOptions::kUninterpretedOptionFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
@@ -8699,9 +8749,13 @@
   if (from.has_php_class_prefix()) {
     php_class_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.php_class_prefix_);
   }
+  php_namespace_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.has_php_namespace()) {
+    php_namespace_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.php_namespace_);
+  }
   ::memcpy(&java_multiple_files_, &from.java_multiple_files_,
-    reinterpret_cast<char*>(&optimize_for_) -
-    reinterpret_cast<char*>(&java_multiple_files_) + sizeof(optimize_for_));
+    static_cast<size_t>(reinterpret_cast<char*>(&optimize_for_) -
+    reinterpret_cast<char*>(&java_multiple_files_)) + sizeof(optimize_for_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.FileOptions)
 }
 
@@ -8714,8 +8768,10 @@
   csharp_namespace_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   swift_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   php_class_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  ::memset(&java_multiple_files_, 0, reinterpret_cast<char*>(&cc_enable_arenas_) -
-    reinterpret_cast<char*>(&java_multiple_files_) + sizeof(cc_enable_arenas_));
+  php_namespace_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&java_multiple_files_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&cc_enable_arenas_) -
+      reinterpret_cast<char*>(&java_multiple_files_)) + sizeof(cc_enable_arenas_));
   optimize_for_ = 1;
 }
 
@@ -8732,6 +8788,7 @@
   csharp_namespace_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   swift_prefix_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   php_class_prefix_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  php_namespace_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 
 void FileOptions::SetCachedSize(int size) const {
@@ -8766,7 +8823,7 @@
   _extensions_.Clear();
   uninterpreted_option_.Clear();
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 127u) {
+  if (cached_has_bits & 255u) {
     if (cached_has_bits & 0x00000001u) {
       GOOGLE_DCHECK(!java_package_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
       (*java_package_.UnsafeRawStringPointer())->clear();
@@ -8795,11 +8852,18 @@
       GOOGLE_DCHECK(!php_class_prefix_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
       (*php_class_prefix_.UnsafeRawStringPointer())->clear();
     }
+    if (cached_has_bits & 0x00000080u) {
+      GOOGLE_DCHECK(!php_namespace_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
+      (*php_namespace_.UnsafeRawStringPointer())->clear();
+    }
   }
-  java_multiple_files_ = false;
   if (cached_has_bits & 65280u) {
-    ::memset(&java_generate_equals_and_hash_, 0, reinterpret_cast<char*>(&cc_enable_arenas_) -
-      reinterpret_cast<char*>(&java_generate_equals_and_hash_) + sizeof(cc_enable_arenas_));
+    ::memset(&java_multiple_files_, 0, static_cast<size_t>(
+        reinterpret_cast<char*>(&deprecated_) -
+        reinterpret_cast<char*>(&java_multiple_files_)) + sizeof(deprecated_));
+  }
+  if (cached_has_bits & 196608u) {
+    cc_enable_arenas_ = false;
     optimize_for_ = 1;
   }
   _has_bits_.Clear();
@@ -8823,7 +8887,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_java_package()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->java_package().data(), this->java_package().length(),
+            this->java_package().data(), static_cast<int>(this->java_package().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.FileOptions.java_package");
         } else {
@@ -8839,7 +8903,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_java_outer_classname()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->java_outer_classname().data(), this->java_outer_classname().length(),
+            this->java_outer_classname().data(), static_cast<int>(this->java_outer_classname().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.FileOptions.java_outer_classname");
         } else {
@@ -8859,7 +8923,8 @@
           if (::google::protobuf::FileOptions_OptimizeMode_IsValid(value)) {
             set_optimize_for(static_cast< ::google::protobuf::FileOptions_OptimizeMode >(value));
           } else {
-            mutable_unknown_fields()->AddVarint(9, value);
+            mutable_unknown_fields()->AddVarint(
+                9, static_cast< ::google::protobuf::uint64>(value));
           }
         } else {
           goto handle_unusual;
@@ -8888,7 +8953,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_go_package()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->go_package().data(), this->go_package().length(),
+            this->go_package().data(), static_cast<int>(this->go_package().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.FileOptions.go_package");
         } else {
@@ -8939,6 +9004,20 @@
         break;
       }
 
+      // optional bool php_generic_services = 19 [default = false];
+      case 19: {
+        if (static_cast< ::google::protobuf::uint8>(tag) ==
+            static_cast< ::google::protobuf::uint8>(152u /* 152 & 0xFF */)) {
+          set_has_php_generic_services();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &php_generic_services_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
       // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
       case 20: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
@@ -9002,7 +9081,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_objc_class_prefix()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->objc_class_prefix().data(), this->objc_class_prefix().length(),
+            this->objc_class_prefix().data(), static_cast<int>(this->objc_class_prefix().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.FileOptions.objc_class_prefix");
         } else {
@@ -9018,7 +9097,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_csharp_namespace()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->csharp_namespace().data(), this->csharp_namespace().length(),
+            this->csharp_namespace().data(), static_cast<int>(this->csharp_namespace().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.FileOptions.csharp_namespace");
         } else {
@@ -9034,7 +9113,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_swift_prefix()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->swift_prefix().data(), this->swift_prefix().length(),
+            this->swift_prefix().data(), static_cast<int>(this->swift_prefix().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.FileOptions.swift_prefix");
         } else {
@@ -9050,7 +9129,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_php_class_prefix()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->php_class_prefix().data(), this->php_class_prefix().length(),
+            this->php_class_prefix().data(), static_cast<int>(this->php_class_prefix().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.FileOptions.php_class_prefix");
         } else {
@@ -9059,6 +9138,22 @@
         break;
       }
 
+      // optional string php_namespace = 41;
+      case 41: {
+        if (static_cast< ::google::protobuf::uint8>(tag) ==
+            static_cast< ::google::protobuf::uint8>(74u /* 330 & 0xFF */)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_php_namespace()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->php_namespace().data(), static_cast<int>(this->php_namespace().length()),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "google.protobuf.FileOptions.php_namespace");
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
       // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
       case 999: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
@@ -9107,7 +9202,7 @@
   // optional string java_package = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->java_package().data(), this->java_package().length(),
+      this->java_package().data(), static_cast<int>(this->java_package().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileOptions.java_package");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -9117,7 +9212,7 @@
   // optional string java_outer_classname = 8;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->java_outer_classname().data(), this->java_outer_classname().length(),
+      this->java_outer_classname().data(), static_cast<int>(this->java_outer_classname().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileOptions.java_outer_classname");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -9125,20 +9220,20 @@
   }
 
   // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
-  if (cached_has_bits & 0x00008000u) {
+  if (cached_has_bits & 0x00020000u) {
     ::google::protobuf::internal::WireFormatLite::WriteEnum(
       9, this->optimize_for(), output);
   }
 
   // optional bool java_multiple_files = 10 [default = false];
-  if (cached_has_bits & 0x00000080u) {
+  if (cached_has_bits & 0x00000100u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->java_multiple_files(), output);
   }
 
   // optional string go_package = 11;
   if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->go_package().data(), this->go_package().length(),
+      this->go_package().data(), static_cast<int>(this->go_package().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileOptions.go_package");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -9146,44 +9241,49 @@
   }
 
   // optional bool cc_generic_services = 16 [default = false];
-  if (cached_has_bits & 0x00000400u) {
+  if (cached_has_bits & 0x00000800u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(16, this->cc_generic_services(), output);
   }
 
   // optional bool java_generic_services = 17 [default = false];
-  if (cached_has_bits & 0x00000800u) {
+  if (cached_has_bits & 0x00001000u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(17, this->java_generic_services(), output);
   }
 
   // optional bool py_generic_services = 18 [default = false];
-  if (cached_has_bits & 0x00001000u) {
+  if (cached_has_bits & 0x00002000u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(18, this->py_generic_services(), output);
   }
 
+  // optional bool php_generic_services = 19 [default = false];
+  if (cached_has_bits & 0x00004000u) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(19, this->php_generic_services(), output);
+  }
+
   // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
-  if (cached_has_bits & 0x00000100u) {
+  if (cached_has_bits & 0x00000200u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(20, this->java_generate_equals_and_hash(), output);
   }
 
   // optional bool deprecated = 23 [default = false];
-  if (cached_has_bits & 0x00002000u) {
+  if (cached_has_bits & 0x00008000u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(23, this->deprecated(), output);
   }
 
   // optional bool java_string_check_utf8 = 27 [default = false];
-  if (cached_has_bits & 0x00000200u) {
+  if (cached_has_bits & 0x00000400u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(27, this->java_string_check_utf8(), output);
   }
 
   // optional bool cc_enable_arenas = 31 [default = false];
-  if (cached_has_bits & 0x00004000u) {
+  if (cached_has_bits & 0x00010000u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(31, this->cc_enable_arenas(), output);
   }
 
   // optional string objc_class_prefix = 36;
   if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->objc_class_prefix().data(), this->objc_class_prefix().length(),
+      this->objc_class_prefix().data(), static_cast<int>(this->objc_class_prefix().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileOptions.objc_class_prefix");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -9193,7 +9293,7 @@
   // optional string csharp_namespace = 37;
   if (cached_has_bits & 0x00000010u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->csharp_namespace().data(), this->csharp_namespace().length(),
+      this->csharp_namespace().data(), static_cast<int>(this->csharp_namespace().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileOptions.csharp_namespace");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -9203,7 +9303,7 @@
   // optional string swift_prefix = 39;
   if (cached_has_bits & 0x00000020u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->swift_prefix().data(), this->swift_prefix().length(),
+      this->swift_prefix().data(), static_cast<int>(this->swift_prefix().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileOptions.swift_prefix");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -9213,17 +9313,28 @@
   // optional string php_class_prefix = 40;
   if (cached_has_bits & 0x00000040u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->php_class_prefix().data(), this->php_class_prefix().length(),
+      this->php_class_prefix().data(), static_cast<int>(this->php_class_prefix().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileOptions.php_class_prefix");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
       40, this->php_class_prefix(), output);
   }
 
+  // optional string php_namespace = 41;
+  if (cached_has_bits & 0x00000080u) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->php_namespace().data(), static_cast<int>(this->php_namespace().length()),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.FileOptions.php_namespace");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      41, this->php_namespace(), output);
+  }
+
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      999, this->uninterpreted_option(i), output);
+      999, this->uninterpreted_option(static_cast<int>(i)), output);
   }
 
   // Extension range [1000, 536870912)
@@ -9247,7 +9358,7 @@
   // optional string java_package = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->java_package().data(), this->java_package().length(),
+      this->java_package().data(), static_cast<int>(this->java_package().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileOptions.java_package");
     target =
@@ -9258,7 +9369,7 @@
   // optional string java_outer_classname = 8;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->java_outer_classname().data(), this->java_outer_classname().length(),
+      this->java_outer_classname().data(), static_cast<int>(this->java_outer_classname().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileOptions.java_outer_classname");
     target =
@@ -9267,20 +9378,20 @@
   }
 
   // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
-  if (cached_has_bits & 0x00008000u) {
+  if (cached_has_bits & 0x00020000u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
       9, this->optimize_for(), target);
   }
 
   // optional bool java_multiple_files = 10 [default = false];
-  if (cached_has_bits & 0x00000080u) {
+  if (cached_has_bits & 0x00000100u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->java_multiple_files(), target);
   }
 
   // optional string go_package = 11;
   if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->go_package().data(), this->go_package().length(),
+      this->go_package().data(), static_cast<int>(this->go_package().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileOptions.go_package");
     target =
@@ -9289,44 +9400,49 @@
   }
 
   // optional bool cc_generic_services = 16 [default = false];
-  if (cached_has_bits & 0x00000400u) {
+  if (cached_has_bits & 0x00000800u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(16, this->cc_generic_services(), target);
   }
 
   // optional bool java_generic_services = 17 [default = false];
-  if (cached_has_bits & 0x00000800u) {
+  if (cached_has_bits & 0x00001000u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(17, this->java_generic_services(), target);
   }
 
   // optional bool py_generic_services = 18 [default = false];
-  if (cached_has_bits & 0x00001000u) {
+  if (cached_has_bits & 0x00002000u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(18, this->py_generic_services(), target);
   }
 
+  // optional bool php_generic_services = 19 [default = false];
+  if (cached_has_bits & 0x00004000u) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(19, this->php_generic_services(), target);
+  }
+
   // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
-  if (cached_has_bits & 0x00000100u) {
+  if (cached_has_bits & 0x00000200u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(20, this->java_generate_equals_and_hash(), target);
   }
 
   // optional bool deprecated = 23 [default = false];
-  if (cached_has_bits & 0x00002000u) {
+  if (cached_has_bits & 0x00008000u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(23, this->deprecated(), target);
   }
 
   // optional bool java_string_check_utf8 = 27 [default = false];
-  if (cached_has_bits & 0x00000200u) {
+  if (cached_has_bits & 0x00000400u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(27, this->java_string_check_utf8(), target);
   }
 
   // optional bool cc_enable_arenas = 31 [default = false];
-  if (cached_has_bits & 0x00004000u) {
+  if (cached_has_bits & 0x00010000u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(31, this->cc_enable_arenas(), target);
   }
 
   // optional string objc_class_prefix = 36;
   if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->objc_class_prefix().data(), this->objc_class_prefix().length(),
+      this->objc_class_prefix().data(), static_cast<int>(this->objc_class_prefix().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileOptions.objc_class_prefix");
     target =
@@ -9337,7 +9453,7 @@
   // optional string csharp_namespace = 37;
   if (cached_has_bits & 0x00000010u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->csharp_namespace().data(), this->csharp_namespace().length(),
+      this->csharp_namespace().data(), static_cast<int>(this->csharp_namespace().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileOptions.csharp_namespace");
     target =
@@ -9348,7 +9464,7 @@
   // optional string swift_prefix = 39;
   if (cached_has_bits & 0x00000020u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->swift_prefix().data(), this->swift_prefix().length(),
+      this->swift_prefix().data(), static_cast<int>(this->swift_prefix().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileOptions.swift_prefix");
     target =
@@ -9359,7 +9475,7 @@
   // optional string php_class_prefix = 40;
   if (cached_has_bits & 0x00000040u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->php_class_prefix().data(), this->php_class_prefix().length(),
+      this->php_class_prefix().data(), static_cast<int>(this->php_class_prefix().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.FileOptions.php_class_prefix");
     target =
@@ -9367,11 +9483,23 @@
         40, this->php_class_prefix(), target);
   }
 
+  // optional string php_namespace = 41;
+  if (cached_has_bits & 0x00000080u) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->php_namespace().data(), static_cast<int>(this->php_namespace().length()),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.FileOptions.php_namespace");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        41, this->php_namespace(), target);
+  }
+
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), deterministic, target);
+        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -9399,12 +9527,12 @@
   }
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
-    unsigned int count = this->uninterpreted_option_size();
+    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
     total_size += 2UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->uninterpreted_option(i));
+          this->uninterpreted_option(static_cast<int>(i)));
     }
   }
 
@@ -9458,13 +9586,20 @@
           this->php_class_prefix());
     }
 
+    // optional string php_namespace = 41;
+    if (has_php_namespace()) {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->php_namespace());
+    }
+
+  }
+  if (_has_bits_[8 / 32] & 65280u) {
     // optional bool java_multiple_files = 10 [default = false];
     if (has_java_multiple_files()) {
       total_size += 1 + 1;
     }
 
-  }
-  if (_has_bits_[8 / 32] & 65280u) {
     // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
     if (has_java_generate_equals_and_hash()) {
       total_size += 2 + 1;
@@ -9490,11 +9625,18 @@
       total_size += 2 + 1;
     }
 
+    // optional bool php_generic_services = 19 [default = false];
+    if (has_php_generic_services()) {
+      total_size += 2 + 1;
+    }
+
     // optional bool deprecated = 23 [default = false];
     if (has_deprecated()) {
       total_size += 2 + 1;
     }
 
+  }
+  if (_has_bits_[16 / 32] & 196608u) {
     // optional bool cc_enable_arenas = 31 [default = false];
     if (has_cc_enable_arenas()) {
       total_size += 2 + 1;
@@ -9569,33 +9711,42 @@
       php_class_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.php_class_prefix_);
     }
     if (cached_has_bits & 0x00000080u) {
-      java_multiple_files_ = from.java_multiple_files_;
+      set_has_php_namespace();
+      php_namespace_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.php_namespace_);
     }
-    _has_bits_[0] |= cached_has_bits;
   }
   if (cached_has_bits & 65280u) {
     if (cached_has_bits & 0x00000100u) {
-      java_generate_equals_and_hash_ = from.java_generate_equals_and_hash_;
+      java_multiple_files_ = from.java_multiple_files_;
     }
     if (cached_has_bits & 0x00000200u) {
-      java_string_check_utf8_ = from.java_string_check_utf8_;
+      java_generate_equals_and_hash_ = from.java_generate_equals_and_hash_;
     }
     if (cached_has_bits & 0x00000400u) {
-      cc_generic_services_ = from.cc_generic_services_;
+      java_string_check_utf8_ = from.java_string_check_utf8_;
     }
     if (cached_has_bits & 0x00000800u) {
-      java_generic_services_ = from.java_generic_services_;
+      cc_generic_services_ = from.cc_generic_services_;
     }
     if (cached_has_bits & 0x00001000u) {
-      py_generic_services_ = from.py_generic_services_;
+      java_generic_services_ = from.java_generic_services_;
     }
     if (cached_has_bits & 0x00002000u) {
-      deprecated_ = from.deprecated_;
+      py_generic_services_ = from.py_generic_services_;
     }
     if (cached_has_bits & 0x00004000u) {
-      cc_enable_arenas_ = from.cc_enable_arenas_;
+      php_generic_services_ = from.php_generic_services_;
     }
     if (cached_has_bits & 0x00008000u) {
+      deprecated_ = from.deprecated_;
+    }
+    _has_bits_[0] |= cached_has_bits;
+  }
+  if (cached_has_bits & 196608u) {
+    if (cached_has_bits & 0x00010000u) {
+      cc_enable_arenas_ = from.cc_enable_arenas_;
+    }
+    if (cached_has_bits & 0x00020000u) {
       optimize_for_ = from.optimize_for_;
     }
     _has_bits_[0] |= cached_has_bits;
@@ -9639,12 +9790,14 @@
   csharp_namespace_.Swap(&other->csharp_namespace_);
   swift_prefix_.Swap(&other->swift_prefix_);
   php_class_prefix_.Swap(&other->php_class_prefix_);
+  php_namespace_.Swap(&other->php_namespace_);
   swap(java_multiple_files_, other->java_multiple_files_);
   swap(java_generate_equals_and_hash_, other->java_generate_equals_and_hash_);
   swap(java_string_check_utf8_, other->java_string_check_utf8_);
   swap(cc_generic_services_, other->cc_generic_services_);
   swap(java_generic_services_, other->java_generic_services_);
   swap(py_generic_services_, other->py_generic_services_);
+  swap(php_generic_services_, other->php_generic_services_);
   swap(deprecated_, other->deprecated_);
   swap(cc_enable_arenas_, other->cc_enable_arenas_);
   swap(optimize_for_, other->optimize_for_);
@@ -9790,13 +9943,13 @@
 
 // optional bool java_multiple_files = 10 [default = false];
 bool FileOptions::has_java_multiple_files() const {
-  return (_has_bits_[0] & 0x00000080u) != 0;
+  return (_has_bits_[0] & 0x00000100u) != 0;
 }
 void FileOptions::set_has_java_multiple_files() {
-  _has_bits_[0] |= 0x00000080u;
+  _has_bits_[0] |= 0x00000100u;
 }
 void FileOptions::clear_has_java_multiple_files() {
-  _has_bits_[0] &= ~0x00000080u;
+  _has_bits_[0] &= ~0x00000100u;
 }
 void FileOptions::clear_java_multiple_files() {
   java_multiple_files_ = false;
@@ -9814,13 +9967,13 @@
 
 // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
 bool FileOptions::has_java_generate_equals_and_hash() const {
-  return (_has_bits_[0] & 0x00000100u) != 0;
+  return (_has_bits_[0] & 0x00000200u) != 0;
 }
 void FileOptions::set_has_java_generate_equals_and_hash() {
-  _has_bits_[0] |= 0x00000100u;
+  _has_bits_[0] |= 0x00000200u;
 }
 void FileOptions::clear_has_java_generate_equals_and_hash() {
-  _has_bits_[0] &= ~0x00000100u;
+  _has_bits_[0] &= ~0x00000200u;
 }
 void FileOptions::clear_java_generate_equals_and_hash() {
   java_generate_equals_and_hash_ = false;
@@ -9838,13 +9991,13 @@
 
 // optional bool java_string_check_utf8 = 27 [default = false];
 bool FileOptions::has_java_string_check_utf8() const {
-  return (_has_bits_[0] & 0x00000200u) != 0;
+  return (_has_bits_[0] & 0x00000400u) != 0;
 }
 void FileOptions::set_has_java_string_check_utf8() {
-  _has_bits_[0] |= 0x00000200u;
+  _has_bits_[0] |= 0x00000400u;
 }
 void FileOptions::clear_has_java_string_check_utf8() {
-  _has_bits_[0] &= ~0x00000200u;
+  _has_bits_[0] &= ~0x00000400u;
 }
 void FileOptions::clear_java_string_check_utf8() {
   java_string_check_utf8_ = false;
@@ -9862,13 +10015,13 @@
 
 // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
 bool FileOptions::has_optimize_for() const {
-  return (_has_bits_[0] & 0x00008000u) != 0;
+  return (_has_bits_[0] & 0x00020000u) != 0;
 }
 void FileOptions::set_has_optimize_for() {
-  _has_bits_[0] |= 0x00008000u;
+  _has_bits_[0] |= 0x00020000u;
 }
 void FileOptions::clear_has_optimize_for() {
-  _has_bits_[0] &= ~0x00008000u;
+  _has_bits_[0] &= ~0x00020000u;
 }
 void FileOptions::clear_optimize_for() {
   optimize_for_ = 1;
@@ -9950,13 +10103,13 @@
 
 // optional bool cc_generic_services = 16 [default = false];
 bool FileOptions::has_cc_generic_services() const {
-  return (_has_bits_[0] & 0x00000400u) != 0;
+  return (_has_bits_[0] & 0x00000800u) != 0;
 }
 void FileOptions::set_has_cc_generic_services() {
-  _has_bits_[0] |= 0x00000400u;
+  _has_bits_[0] |= 0x00000800u;
 }
 void FileOptions::clear_has_cc_generic_services() {
-  _has_bits_[0] &= ~0x00000400u;
+  _has_bits_[0] &= ~0x00000800u;
 }
 void FileOptions::clear_cc_generic_services() {
   cc_generic_services_ = false;
@@ -9974,13 +10127,13 @@
 
 // optional bool java_generic_services = 17 [default = false];
 bool FileOptions::has_java_generic_services() const {
-  return (_has_bits_[0] & 0x00000800u) != 0;
+  return (_has_bits_[0] & 0x00001000u) != 0;
 }
 void FileOptions::set_has_java_generic_services() {
-  _has_bits_[0] |= 0x00000800u;
+  _has_bits_[0] |= 0x00001000u;
 }
 void FileOptions::clear_has_java_generic_services() {
-  _has_bits_[0] &= ~0x00000800u;
+  _has_bits_[0] &= ~0x00001000u;
 }
 void FileOptions::clear_java_generic_services() {
   java_generic_services_ = false;
@@ -9998,13 +10151,13 @@
 
 // optional bool py_generic_services = 18 [default = false];
 bool FileOptions::has_py_generic_services() const {
-  return (_has_bits_[0] & 0x00001000u) != 0;
+  return (_has_bits_[0] & 0x00002000u) != 0;
 }
 void FileOptions::set_has_py_generic_services() {
-  _has_bits_[0] |= 0x00001000u;
+  _has_bits_[0] |= 0x00002000u;
 }
 void FileOptions::clear_has_py_generic_services() {
-  _has_bits_[0] &= ~0x00001000u;
+  _has_bits_[0] &= ~0x00002000u;
 }
 void FileOptions::clear_py_generic_services() {
   py_generic_services_ = false;
@@ -10020,15 +10173,39 @@
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.py_generic_services)
 }
 
+// optional bool php_generic_services = 19 [default = false];
+bool FileOptions::has_php_generic_services() const {
+  return (_has_bits_[0] & 0x00004000u) != 0;
+}
+void FileOptions::set_has_php_generic_services() {
+  _has_bits_[0] |= 0x00004000u;
+}
+void FileOptions::clear_has_php_generic_services() {
+  _has_bits_[0] &= ~0x00004000u;
+}
+void FileOptions::clear_php_generic_services() {
+  php_generic_services_ = false;
+  clear_has_php_generic_services();
+}
+bool FileOptions::php_generic_services() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_generic_services)
+  return php_generic_services_;
+}
+void FileOptions::set_php_generic_services(bool value) {
+  set_has_php_generic_services();
+  php_generic_services_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_generic_services)
+}
+
 // optional bool deprecated = 23 [default = false];
 bool FileOptions::has_deprecated() const {
-  return (_has_bits_[0] & 0x00002000u) != 0;
+  return (_has_bits_[0] & 0x00008000u) != 0;
 }
 void FileOptions::set_has_deprecated() {
-  _has_bits_[0] |= 0x00002000u;
+  _has_bits_[0] |= 0x00008000u;
 }
 void FileOptions::clear_has_deprecated() {
-  _has_bits_[0] &= ~0x00002000u;
+  _has_bits_[0] &= ~0x00008000u;
 }
 void FileOptions::clear_deprecated() {
   deprecated_ = false;
@@ -10046,13 +10223,13 @@
 
 // optional bool cc_enable_arenas = 31 [default = false];
 bool FileOptions::has_cc_enable_arenas() const {
-  return (_has_bits_[0] & 0x00004000u) != 0;
+  return (_has_bits_[0] & 0x00010000u) != 0;
 }
 void FileOptions::set_has_cc_enable_arenas() {
-  _has_bits_[0] |= 0x00004000u;
+  _has_bits_[0] |= 0x00010000u;
 }
 void FileOptions::clear_has_cc_enable_arenas() {
-  _has_bits_[0] &= ~0x00004000u;
+  _has_bits_[0] &= ~0x00010000u;
 }
 void FileOptions::clear_cc_enable_arenas() {
   cc_enable_arenas_ = false;
@@ -10320,6 +10497,69 @@
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_class_prefix)
 }
 
+// optional string php_namespace = 41;
+bool FileOptions::has_php_namespace() const {
+  return (_has_bits_[0] & 0x00000080u) != 0;
+}
+void FileOptions::set_has_php_namespace() {
+  _has_bits_[0] |= 0x00000080u;
+}
+void FileOptions::clear_has_php_namespace() {
+  _has_bits_[0] &= ~0x00000080u;
+}
+void FileOptions::clear_php_namespace() {
+  php_namespace_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_php_namespace();
+}
+const ::std::string& FileOptions::php_namespace() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_namespace)
+  return php_namespace_.GetNoArena();
+}
+void FileOptions::set_php_namespace(const ::std::string& value) {
+  set_has_php_namespace();
+  php_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_namespace)
+}
+#if LANG_CXX11
+void FileOptions::set_php_namespace(::std::string&& value) {
+  set_has_php_namespace();
+  php_namespace_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.php_namespace)
+}
+#endif
+void FileOptions::set_php_namespace(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
+  set_has_php_namespace();
+  php_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_namespace)
+}
+void FileOptions::set_php_namespace(const char* value, size_t size) {
+  set_has_php_namespace();
+  php_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.php_namespace)
+}
+::std::string* FileOptions::mutable_php_namespace() {
+  set_has_php_namespace();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.php_namespace)
+  return php_namespace_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+::std::string* FileOptions::release_php_namespace() {
+  // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_namespace)
+  clear_has_php_namespace();
+  return php_namespace_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void FileOptions::set_allocated_php_namespace(::std::string* php_namespace) {
+  if (php_namespace != NULL) {
+    set_has_php_namespace();
+  } else {
+    clear_has_php_namespace();
+  }
+  php_namespace_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), php_namespace);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_namespace)
+}
+
 // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
 int FileOptions::uninterpreted_option_size() const {
   return uninterpreted_option_.size();
@@ -10379,15 +10619,16 @@
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   _extensions_.MergeFrom(from._extensions_);
   ::memcpy(&message_set_wire_format_, &from.message_set_wire_format_,
-    reinterpret_cast<char*>(&map_entry_) -
-    reinterpret_cast<char*>(&message_set_wire_format_) + sizeof(map_entry_));
+    static_cast<size_t>(reinterpret_cast<char*>(&map_entry_) -
+    reinterpret_cast<char*>(&message_set_wire_format_)) + sizeof(map_entry_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.MessageOptions)
 }
 
 void MessageOptions::SharedCtor() {
   _cached_size_ = 0;
-  ::memset(&message_set_wire_format_, 0, reinterpret_cast<char*>(&map_entry_) -
-    reinterpret_cast<char*>(&message_set_wire_format_) + sizeof(map_entry_));
+  ::memset(&message_set_wire_format_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&map_entry_) -
+      reinterpret_cast<char*>(&message_set_wire_format_)) + sizeof(map_entry_));
 }
 
 MessageOptions::~MessageOptions() {
@@ -10431,8 +10672,9 @@
   uninterpreted_option_.Clear();
   cached_has_bits = _has_bits_[0];
   if (cached_has_bits & 15u) {
-    ::memset(&message_set_wire_format_, 0, reinterpret_cast<char*>(&map_entry_) -
-      reinterpret_cast<char*>(&message_set_wire_format_) + sizeof(map_entry_));
+    ::memset(&message_set_wire_format_, 0, static_cast<size_t>(
+        reinterpret_cast<char*>(&map_entry_) -
+        reinterpret_cast<char*>(&message_set_wire_format_)) + sizeof(map_entry_));
   }
   _has_bits_.Clear();
   _internal_metadata_.Clear();
@@ -10570,9 +10812,10 @@
   }
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      999, this->uninterpreted_option(i), output);
+      999, this->uninterpreted_option(static_cast<int>(i)), output);
   }
 
   // Extension range [1000, 536870912)
@@ -10614,10 +10857,11 @@
   }
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), deterministic, target);
+        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -10645,12 +10889,12 @@
   }
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
-    unsigned int count = this->uninterpreted_option_size();
+    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
     total_size += 2UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->uninterpreted_option(i));
+          this->uninterpreted_option(static_cast<int>(i)));
     }
   }
 
@@ -10930,15 +11174,16 @@
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   _extensions_.MergeFrom(from._extensions_);
   ::memcpy(&ctype_, &from.ctype_,
-    reinterpret_cast<char*>(&jstype_) -
-    reinterpret_cast<char*>(&ctype_) + sizeof(jstype_));
+    static_cast<size_t>(reinterpret_cast<char*>(&jstype_) -
+    reinterpret_cast<char*>(&ctype_)) + sizeof(jstype_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldOptions)
 }
 
 void FieldOptions::SharedCtor() {
   _cached_size_ = 0;
-  ::memset(&ctype_, 0, reinterpret_cast<char*>(&jstype_) -
-    reinterpret_cast<char*>(&ctype_) + sizeof(jstype_));
+  ::memset(&ctype_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&jstype_) -
+      reinterpret_cast<char*>(&ctype_)) + sizeof(jstype_));
 }
 
 FieldOptions::~FieldOptions() {
@@ -10982,8 +11227,9 @@
   uninterpreted_option_.Clear();
   cached_has_bits = _has_bits_[0];
   if (cached_has_bits & 63u) {
-    ::memset(&ctype_, 0, reinterpret_cast<char*>(&jstype_) -
-      reinterpret_cast<char*>(&ctype_) + sizeof(jstype_));
+    ::memset(&ctype_, 0, static_cast<size_t>(
+        reinterpret_cast<char*>(&jstype_) -
+        reinterpret_cast<char*>(&ctype_)) + sizeof(jstype_));
   }
   _has_bits_.Clear();
   _internal_metadata_.Clear();
@@ -11010,7 +11256,8 @@
           if (::google::protobuf::FieldOptions_CType_IsValid(value)) {
             set_ctype(static_cast< ::google::protobuf::FieldOptions_CType >(value));
           } else {
-            mutable_unknown_fields()->AddVarint(1, value);
+            mutable_unknown_fields()->AddVarint(
+                1, static_cast< ::google::protobuf::uint64>(value));
           }
         } else {
           goto handle_unusual;
@@ -11071,7 +11318,8 @@
           if (::google::protobuf::FieldOptions_JSType_IsValid(value)) {
             set_jstype(static_cast< ::google::protobuf::FieldOptions_JSType >(value));
           } else {
-            mutable_unknown_fields()->AddVarint(6, value);
+            mutable_unknown_fields()->AddVarint(
+                6, static_cast< ::google::protobuf::uint64>(value));
           }
         } else {
           goto handle_unusual;
@@ -11171,9 +11419,10 @@
   }
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      999, this->uninterpreted_option(i), output);
+      999, this->uninterpreted_option(static_cast<int>(i)), output);
   }
 
   // Extension range [1000, 536870912)
@@ -11227,10 +11476,11 @@
   }
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), deterministic, target);
+        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -11258,12 +11508,12 @@
   }
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
-    unsigned int count = this->uninterpreted_option_size();
+    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
     total_size += 2UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->uninterpreted_option(i));
+          this->uninterpreted_option(static_cast<int>(i)));
     }
   }
 
@@ -11711,9 +11961,10 @@
   (void) cached_has_bits;
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      999, this->uninterpreted_option(i), output);
+      999, this->uninterpreted_option(static_cast<int>(i)), output);
   }
 
   // Extension range [1000, 536870912)
@@ -11734,10 +11985,11 @@
   (void) cached_has_bits;
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), deterministic, target);
+        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -11765,12 +12017,12 @@
   }
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
-    unsigned int count = this->uninterpreted_option_size();
+    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
     total_size += 2UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->uninterpreted_option(i));
+          this->uninterpreted_option(static_cast<int>(i)));
     }
   }
 
@@ -11908,15 +12160,16 @@
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   _extensions_.MergeFrom(from._extensions_);
   ::memcpy(&allow_alias_, &from.allow_alias_,
-    reinterpret_cast<char*>(&deprecated_) -
-    reinterpret_cast<char*>(&allow_alias_) + sizeof(deprecated_));
+    static_cast<size_t>(reinterpret_cast<char*>(&deprecated_) -
+    reinterpret_cast<char*>(&allow_alias_)) + sizeof(deprecated_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumOptions)
 }
 
 void EnumOptions::SharedCtor() {
   _cached_size_ = 0;
-  ::memset(&allow_alias_, 0, reinterpret_cast<char*>(&deprecated_) -
-    reinterpret_cast<char*>(&allow_alias_) + sizeof(deprecated_));
+  ::memset(&allow_alias_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&deprecated_) -
+      reinterpret_cast<char*>(&allow_alias_)) + sizeof(deprecated_));
 }
 
 EnumOptions::~EnumOptions() {
@@ -11960,8 +12213,9 @@
   uninterpreted_option_.Clear();
   cached_has_bits = _has_bits_[0];
   if (cached_has_bits & 3u) {
-    ::memset(&allow_alias_, 0, reinterpret_cast<char*>(&deprecated_) -
-      reinterpret_cast<char*>(&allow_alias_) + sizeof(deprecated_));
+    ::memset(&allow_alias_, 0, static_cast<size_t>(
+        reinterpret_cast<char*>(&deprecated_) -
+        reinterpret_cast<char*>(&allow_alias_)) + sizeof(deprecated_));
   }
   _has_bits_.Clear();
   _internal_metadata_.Clear();
@@ -12061,9 +12315,10 @@
   }
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      999, this->uninterpreted_option(i), output);
+      999, this->uninterpreted_option(static_cast<int>(i)), output);
   }
 
   // Extension range [1000, 536870912)
@@ -12095,10 +12350,11 @@
   }
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), deterministic, target);
+        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -12126,12 +12382,12 @@
   }
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
-    unsigned int count = this->uninterpreted_option_size();
+    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
     total_size += 2UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->uninterpreted_option(i));
+          this->uninterpreted_option(static_cast<int>(i)));
     }
   }
 
@@ -12467,9 +12723,10 @@
   }
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      999, this->uninterpreted_option(i), output);
+      999, this->uninterpreted_option(static_cast<int>(i)), output);
   }
 
   // Extension range [1000, 536870912)
@@ -12496,10 +12753,11 @@
   }
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), deterministic, target);
+        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -12527,12 +12785,12 @@
   }
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
-    unsigned int count = this->uninterpreted_option_size();
+    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
     total_size += 2UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->uninterpreted_option(i));
+          this->uninterpreted_option(static_cast<int>(i)));
     }
   }
 
@@ -12829,9 +13087,10 @@
   }
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      999, this->uninterpreted_option(i), output);
+      999, this->uninterpreted_option(static_cast<int>(i)), output);
   }
 
   // Extension range [1000, 536870912)
@@ -12858,10 +13117,11 @@
   }
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), deterministic, target);
+        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -12889,12 +13149,12 @@
   }
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
-    unsigned int count = this->uninterpreted_option_size();
+    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
     total_size += 2UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->uninterpreted_option(i));
+          this->uninterpreted_option(static_cast<int>(i)));
     }
   }
 
@@ -13065,15 +13325,16 @@
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   _extensions_.MergeFrom(from._extensions_);
   ::memcpy(&deprecated_, &from.deprecated_,
-    reinterpret_cast<char*>(&idempotency_level_) -
-    reinterpret_cast<char*>(&deprecated_) + sizeof(idempotency_level_));
+    static_cast<size_t>(reinterpret_cast<char*>(&idempotency_level_) -
+    reinterpret_cast<char*>(&deprecated_)) + sizeof(idempotency_level_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodOptions)
 }
 
 void MethodOptions::SharedCtor() {
   _cached_size_ = 0;
-  ::memset(&deprecated_, 0, reinterpret_cast<char*>(&idempotency_level_) -
-    reinterpret_cast<char*>(&deprecated_) + sizeof(idempotency_level_));
+  ::memset(&deprecated_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&idempotency_level_) -
+      reinterpret_cast<char*>(&deprecated_)) + sizeof(idempotency_level_));
 }
 
 MethodOptions::~MethodOptions() {
@@ -13117,8 +13378,9 @@
   uninterpreted_option_.Clear();
   cached_has_bits = _has_bits_[0];
   if (cached_has_bits & 3u) {
-    ::memset(&deprecated_, 0, reinterpret_cast<char*>(&idempotency_level_) -
-      reinterpret_cast<char*>(&deprecated_) + sizeof(idempotency_level_));
+    ::memset(&deprecated_, 0, static_cast<size_t>(
+        reinterpret_cast<char*>(&idempotency_level_) -
+        reinterpret_cast<char*>(&deprecated_)) + sizeof(idempotency_level_));
   }
   _has_bits_.Clear();
   _internal_metadata_.Clear();
@@ -13159,7 +13421,8 @@
           if (::google::protobuf::MethodOptions_IdempotencyLevel_IsValid(value)) {
             set_idempotency_level(static_cast< ::google::protobuf::MethodOptions_IdempotencyLevel >(value));
           } else {
-            mutable_unknown_fields()->AddVarint(34, value);
+            mutable_unknown_fields()->AddVarint(
+                34, static_cast< ::google::protobuf::uint64>(value));
           }
         } else {
           goto handle_unusual;
@@ -13224,9 +13487,10 @@
   }
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      999, this->uninterpreted_option(i), output);
+      999, this->uninterpreted_option(static_cast<int>(i)), output);
   }
 
   // Extension range [1000, 536870912)
@@ -13259,10 +13523,11 @@
   }
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), deterministic, target);
+        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -13290,12 +13555,12 @@
   }
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
-    unsigned int count = this->uninterpreted_option_size();
+    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
     total_size += 2UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->uninterpreted_option(i));
+          this->uninterpreted_option(static_cast<int>(i)));
     }
   }
 
@@ -13581,7 +13846,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name_part()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->name_part().data(), this->name_part().length(),
+            this->name_part().data(), static_cast<int>(this->name_part().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.UninterpretedOption.NamePart.name_part");
         } else {
@@ -13634,7 +13899,7 @@
   // required string name_part = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name_part().data(), this->name_part().length(),
+      this->name_part().data(), static_cast<int>(this->name_part().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.UninterpretedOption.NamePart.name_part");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -13663,7 +13928,7 @@
   // required string name_part = 1;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->name_part().data(), this->name_part().length(),
+      this->name_part().data(), static_cast<int>(this->name_part().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.UninterpretedOption.NamePart.name_part");
     target =
@@ -13934,8 +14199,8 @@
     aggregate_value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.aggregate_value_);
   }
   ::memcpy(&positive_int_value_, &from.positive_int_value_,
-    reinterpret_cast<char*>(&double_value_) -
-    reinterpret_cast<char*>(&positive_int_value_) + sizeof(double_value_));
+    static_cast<size_t>(reinterpret_cast<char*>(&double_value_) -
+    reinterpret_cast<char*>(&positive_int_value_)) + sizeof(double_value_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption)
 }
 
@@ -13944,8 +14209,9 @@
   identifier_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   aggregate_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  ::memset(&positive_int_value_, 0, reinterpret_cast<char*>(&double_value_) -
-    reinterpret_cast<char*>(&positive_int_value_) + sizeof(double_value_));
+  ::memset(&positive_int_value_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&double_value_) -
+      reinterpret_cast<char*>(&positive_int_value_)) + sizeof(double_value_));
 }
 
 UninterpretedOption::~UninterpretedOption() {
@@ -14005,8 +14271,9 @@
     }
   }
   if (cached_has_bits & 56u) {
-    ::memset(&positive_int_value_, 0, reinterpret_cast<char*>(&double_value_) -
-      reinterpret_cast<char*>(&positive_int_value_) + sizeof(double_value_));
+    ::memset(&positive_int_value_, 0, static_cast<size_t>(
+        reinterpret_cast<char*>(&double_value_) -
+        reinterpret_cast<char*>(&positive_int_value_)) + sizeof(double_value_));
   }
   _has_bits_.Clear();
   _internal_metadata_.Clear();
@@ -14041,7 +14308,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_identifier_value()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->identifier_value().data(), this->identifier_value().length(),
+            this->identifier_value().data(), static_cast<int>(this->identifier_value().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.UninterpretedOption.identifier_value");
         } else {
@@ -14111,7 +14378,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_aggregate_value()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->aggregate_value().data(), this->aggregate_value().length(),
+            this->aggregate_value().data(), static_cast<int>(this->aggregate_value().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.UninterpretedOption.aggregate_value");
         } else {
@@ -14147,16 +14414,17 @@
   (void) cached_has_bits;
 
   // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
-  for (unsigned int i = 0, n = this->name_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->name_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      2, this->name(i), output);
+      2, this->name(static_cast<int>(i)), output);
   }
 
   cached_has_bits = _has_bits_[0];
   // optional string identifier_value = 3;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->identifier_value().data(), this->identifier_value().length(),
+      this->identifier_value().data(), static_cast<int>(this->identifier_value().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.UninterpretedOption.identifier_value");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -14187,7 +14455,7 @@
   // optional string aggregate_value = 8;
   if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->aggregate_value().data(), this->aggregate_value().length(),
+      this->aggregate_value().data(), static_cast<int>(this->aggregate_value().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.UninterpretedOption.aggregate_value");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -14208,17 +14476,18 @@
   (void) cached_has_bits;
 
   // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
-  for (unsigned int i = 0, n = this->name_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->name_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        2, this->name(i), deterministic, target);
+        2, this->name(static_cast<int>(i)), deterministic, target);
   }
 
   cached_has_bits = _has_bits_[0];
   // optional string identifier_value = 3;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->identifier_value().data(), this->identifier_value().length(),
+      this->identifier_value().data(), static_cast<int>(this->identifier_value().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.UninterpretedOption.identifier_value");
     target =
@@ -14251,7 +14520,7 @@
   // optional string aggregate_value = 8;
   if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->aggregate_value().data(), this->aggregate_value().length(),
+      this->aggregate_value().data(), static_cast<int>(this->aggregate_value().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.UninterpretedOption.aggregate_value");
     target =
@@ -14278,12 +14547,12 @@
   }
   // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
   {
-    unsigned int count = this->name_size();
+    unsigned int count = static_cast<unsigned int>(this->name_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->name(i));
+          this->name(static_cast<int>(i)));
     }
   }
 
@@ -14880,7 +15149,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_leading_comments()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->leading_comments().data(), this->leading_comments().length(),
+            this->leading_comments().data(), static_cast<int>(this->leading_comments().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.SourceCodeInfo.Location.leading_comments");
         } else {
@@ -14896,7 +15165,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_trailing_comments()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->trailing_comments().data(), this->trailing_comments().length(),
+            this->trailing_comments().data(), static_cast<int>(this->trailing_comments().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.SourceCodeInfo.Location.trailing_comments");
         } else {
@@ -14913,7 +15182,7 @@
                 input, this->add_leading_detached_comments()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
             this->leading_detached_comments(this->leading_detached_comments_size() - 1).data(),
-            this->leading_detached_comments(this->leading_detached_comments_size() - 1).length(),
+            static_cast<int>(this->leading_detached_comments(this->leading_detached_comments_size() - 1).length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
         } else {
@@ -14951,7 +15220,8 @@
   // repeated int32 path = 1 [packed = true];
   if (this->path_size() > 0) {
     ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
-    output->WriteVarint32(_path_cached_byte_size_);
+    output->WriteVarint32(static_cast< ::google::protobuf::uint32>(
+        _path_cached_byte_size_));
   }
   for (int i = 0, n = this->path_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
@@ -14961,7 +15231,8 @@
   // repeated int32 span = 2 [packed = true];
   if (this->span_size() > 0) {
     ::google::protobuf::internal::WireFormatLite::WriteTag(2, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
-    output->WriteVarint32(_span_cached_byte_size_);
+    output->WriteVarint32(static_cast< ::google::protobuf::uint32>(
+        _span_cached_byte_size_));
   }
   for (int i = 0, n = this->span_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
@@ -14972,7 +15243,7 @@
   // optional string leading_comments = 3;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->leading_comments().data(), this->leading_comments().length(),
+      this->leading_comments().data(), static_cast<int>(this->leading_comments().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.SourceCodeInfo.Location.leading_comments");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -14982,7 +15253,7 @@
   // optional string trailing_comments = 4;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->trailing_comments().data(), this->trailing_comments().length(),
+      this->trailing_comments().data(), static_cast<int>(this->trailing_comments().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.SourceCodeInfo.Location.trailing_comments");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -14992,7 +15263,7 @@
   // repeated string leading_detached_comments = 6;
   for (int i = 0, n = this->leading_detached_comments_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->leading_detached_comments(i).data(), this->leading_detached_comments(i).length(),
+      this->leading_detached_comments(i).data(), static_cast<int>(this->leading_detached_comments(i).length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
     ::google::protobuf::internal::WireFormatLite::WriteString(
@@ -15019,7 +15290,8 @@
       ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
       target);
     target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
-      _path_cached_byte_size_, target);
+        static_cast< ::google::protobuf::uint32>(
+            _path_cached_byte_size_), target);
     target = ::google::protobuf::internal::WireFormatLite::
       WriteInt32NoTagToArray(this->path_, target);
   }
@@ -15031,7 +15303,8 @@
       ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
       target);
     target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
-      _span_cached_byte_size_, target);
+        static_cast< ::google::protobuf::uint32>(
+            _span_cached_byte_size_), target);
     target = ::google::protobuf::internal::WireFormatLite::
       WriteInt32NoTagToArray(this->span_, target);
   }
@@ -15040,7 +15313,7 @@
   // optional string leading_comments = 3;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->leading_comments().data(), this->leading_comments().length(),
+      this->leading_comments().data(), static_cast<int>(this->leading_comments().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.SourceCodeInfo.Location.leading_comments");
     target =
@@ -15051,7 +15324,7 @@
   // optional string trailing_comments = 4;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->trailing_comments().data(), this->trailing_comments().length(),
+      this->trailing_comments().data(), static_cast<int>(this->trailing_comments().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.SourceCodeInfo.Location.trailing_comments");
     target =
@@ -15062,7 +15335,7 @@
   // repeated string leading_detached_comments = 6;
   for (int i = 0, n = this->leading_detached_comments_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->leading_detached_comments(i).data(), this->leading_detached_comments(i).length(),
+      this->leading_detached_comments(i).data(), static_cast<int>(this->leading_detached_comments(i).length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
     target = ::google::protobuf::internal::WireFormatLite::
@@ -15092,7 +15365,8 @@
       Int32Size(this->path_);
     if (data_size > 0) {
       total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+            static_cast< ::google::protobuf::int32>(data_size));
     }
     int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);
     GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
@@ -15107,7 +15381,8 @@
       Int32Size(this->span_);
     if (data_size > 0) {
       total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+            static_cast< ::google::protobuf::int32>(data_size));
     }
     int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);
     GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
@@ -15603,9 +15878,10 @@
   (void) cached_has_bits;
 
   // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
-  for (unsigned int i = 0, n = this->location_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->location_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      1, this->location(i), output);
+      1, this->location(static_cast<int>(i)), output);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -15622,10 +15898,11 @@
   (void) cached_has_bits;
 
   // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
-  for (unsigned int i = 0, n = this->location_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->location_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        1, this->location(i), deterministic, target);
+        1, this->location(static_cast<int>(i)), deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -15647,12 +15924,12 @@
   }
   // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
   {
-    unsigned int count = this->location_size();
+    unsigned int count = static_cast<unsigned int>(this->location_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->location(i));
+          this->location(static_cast<int>(i)));
     }
   }
 
@@ -15787,16 +16064,17 @@
     source_file_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.source_file_);
   }
   ::memcpy(&begin_, &from.begin_,
-    reinterpret_cast<char*>(&end_) -
-    reinterpret_cast<char*>(&begin_) + sizeof(end_));
+    static_cast<size_t>(reinterpret_cast<char*>(&end_) -
+    reinterpret_cast<char*>(&begin_)) + sizeof(end_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo.Annotation)
 }
 
 void GeneratedCodeInfo_Annotation::SharedCtor() {
   _cached_size_ = 0;
   source_file_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  ::memset(&begin_, 0, reinterpret_cast<char*>(&end_) -
-    reinterpret_cast<char*>(&begin_) + sizeof(end_));
+  ::memset(&begin_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&end_) -
+      reinterpret_cast<char*>(&begin_)) + sizeof(end_));
 }
 
 GeneratedCodeInfo_Annotation::~GeneratedCodeInfo_Annotation() {
@@ -15844,8 +16122,9 @@
   }
   cached_has_bits = _has_bits_[0];
   if (cached_has_bits & 6u) {
-    ::memset(&begin_, 0, reinterpret_cast<char*>(&end_) -
-      reinterpret_cast<char*>(&begin_) + sizeof(end_));
+    ::memset(&begin_, 0, static_cast<size_t>(
+        reinterpret_cast<char*>(&end_) -
+        reinterpret_cast<char*>(&begin_)) + sizeof(end_));
   }
   _has_bits_.Clear();
   _internal_metadata_.Clear();
@@ -15887,7 +16166,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_source_file()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-            this->source_file().data(), this->source_file().length(),
+            this->source_file().data(), static_cast<int>(this->source_file().length()),
             ::google::protobuf::internal::WireFormat::PARSE,
             "google.protobuf.GeneratedCodeInfo.Annotation.source_file");
         } else {
@@ -15953,7 +16232,8 @@
   // repeated int32 path = 1 [packed = true];
   if (this->path_size() > 0) {
     ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
-    output->WriteVarint32(_path_cached_byte_size_);
+    output->WriteVarint32(static_cast< ::google::protobuf::uint32>(
+        _path_cached_byte_size_));
   }
   for (int i = 0, n = this->path_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
@@ -15964,7 +16244,7 @@
   // optional string source_file = 2;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->source_file().data(), this->source_file().length(),
+      this->source_file().data(), static_cast<int>(this->source_file().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.GeneratedCodeInfo.Annotation.source_file");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -16001,7 +16281,8 @@
       ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
       target);
     target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
-      _path_cached_byte_size_, target);
+        static_cast< ::google::protobuf::uint32>(
+            _path_cached_byte_size_), target);
     target = ::google::protobuf::internal::WireFormatLite::
       WriteInt32NoTagToArray(this->path_, target);
   }
@@ -16010,7 +16291,7 @@
   // optional string source_file = 2;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
-      this->source_file().data(), this->source_file().length(),
+      this->source_file().data(), static_cast<int>(this->source_file().length()),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
       "google.protobuf.GeneratedCodeInfo.Annotation.source_file");
     target =
@@ -16051,7 +16332,8 @@
       Int32Size(this->path_);
     if (data_size > 0) {
       total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+            static_cast< ::google::protobuf::int32>(data_size));
     }
     int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);
     GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
@@ -16432,9 +16714,10 @@
   (void) cached_has_bits;
 
   // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
-  for (unsigned int i = 0, n = this->annotation_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->annotation_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      1, this->annotation(i), output);
+      1, this->annotation(static_cast<int>(i)), output);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -16451,10 +16734,11 @@
   (void) cached_has_bits;
 
   // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
-  for (unsigned int i = 0, n = this->annotation_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->annotation_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        1, this->annotation(i), deterministic, target);
+        1, this->annotation(static_cast<int>(i)), deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -16476,12 +16760,12 @@
   }
   // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
   {
-    unsigned int count = this->annotation_size();
+    unsigned int count = static_cast<unsigned int>(this->annotation_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->annotation(i));
+          this->annotation(static_cast<int>(i)));
     }
   }
 
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index 9c11ccf..cbc7458 100644
--- a/src/google/protobuf/descriptor.pb.h
+++ b/src/google/protobuf/descriptor.pb.h
@@ -2555,6 +2555,21 @@
   ::std::string* release_php_class_prefix();
   void set_allocated_php_class_prefix(::std::string* php_class_prefix);
 
+  // optional string php_namespace = 41;
+  bool has_php_namespace() const;
+  void clear_php_namespace();
+  static const int kPhpNamespaceFieldNumber = 41;
+  const ::std::string& php_namespace() const;
+  void set_php_namespace(const ::std::string& value);
+  #if LANG_CXX11
+  void set_php_namespace(::std::string&& value);
+  #endif
+  void set_php_namespace(const char* value);
+  void set_php_namespace(const char* value, size_t size);
+  ::std::string* mutable_php_namespace();
+  ::std::string* release_php_namespace();
+  void set_allocated_php_namespace(::std::string* php_namespace);
+
   // optional bool java_multiple_files = 10 [default = false];
   bool has_java_multiple_files() const;
   void clear_java_multiple_files();
@@ -2597,6 +2612,13 @@
   bool py_generic_services() const;
   void set_py_generic_services(bool value);
 
+  // optional bool php_generic_services = 19 [default = false];
+  bool has_php_generic_services() const;
+  void clear_php_generic_services();
+  static const int kPhpGenericServicesFieldNumber = 19;
+  bool php_generic_services() const;
+  void set_php_generic_services(bool value);
+
   // optional bool deprecated = 23 [default = false];
   bool has_deprecated() const;
   void clear_deprecated();
@@ -2641,6 +2663,8 @@
   void clear_has_java_generic_services();
   void set_has_py_generic_services();
   void clear_has_py_generic_services();
+  void set_has_php_generic_services();
+  void clear_has_php_generic_services();
   void set_has_deprecated();
   void clear_has_deprecated();
   void set_has_cc_enable_arenas();
@@ -2653,6 +2677,8 @@
   void clear_has_swift_prefix();
   void set_has_php_class_prefix();
   void clear_has_php_class_prefix();
+  void set_has_php_namespace();
+  void clear_has_php_namespace();
 
   ::google::protobuf::internal::ExtensionSet _extensions_;
 
@@ -2667,12 +2693,14 @@
   ::google::protobuf::internal::ArenaStringPtr csharp_namespace_;
   ::google::protobuf::internal::ArenaStringPtr swift_prefix_;
   ::google::protobuf::internal::ArenaStringPtr php_class_prefix_;
+  ::google::protobuf::internal::ArenaStringPtr php_namespace_;
   bool java_multiple_files_;
   bool java_generate_equals_and_hash_;
   bool java_string_check_utf8_;
   bool cc_generic_services_;
   bool java_generic_services_;
   bool py_generic_services_;
+  bool php_generic_services_;
   bool deprecated_;
   bool cc_enable_arenas_;
   int optimize_for_;
@@ -7177,13 +7205,13 @@
 
 // optional bool java_multiple_files = 10 [default = false];
 inline bool FileOptions::has_java_multiple_files() const {
-  return (_has_bits_[0] & 0x00000080u) != 0;
+  return (_has_bits_[0] & 0x00000100u) != 0;
 }
 inline void FileOptions::set_has_java_multiple_files() {
-  _has_bits_[0] |= 0x00000080u;
+  _has_bits_[0] |= 0x00000100u;
 }
 inline void FileOptions::clear_has_java_multiple_files() {
-  _has_bits_[0] &= ~0x00000080u;
+  _has_bits_[0] &= ~0x00000100u;
 }
 inline void FileOptions::clear_java_multiple_files() {
   java_multiple_files_ = false;
@@ -7201,13 +7229,13 @@
 
 // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
 inline bool FileOptions::has_java_generate_equals_and_hash() const {
-  return (_has_bits_[0] & 0x00000100u) != 0;
+  return (_has_bits_[0] & 0x00000200u) != 0;
 }
 inline void FileOptions::set_has_java_generate_equals_and_hash() {
-  _has_bits_[0] |= 0x00000100u;
+  _has_bits_[0] |= 0x00000200u;
 }
 inline void FileOptions::clear_has_java_generate_equals_and_hash() {
-  _has_bits_[0] &= ~0x00000100u;
+  _has_bits_[0] &= ~0x00000200u;
 }
 inline void FileOptions::clear_java_generate_equals_and_hash() {
   java_generate_equals_and_hash_ = false;
@@ -7225,13 +7253,13 @@
 
 // optional bool java_string_check_utf8 = 27 [default = false];
 inline bool FileOptions::has_java_string_check_utf8() const {
-  return (_has_bits_[0] & 0x00000200u) != 0;
+  return (_has_bits_[0] & 0x00000400u) != 0;
 }
 inline void FileOptions::set_has_java_string_check_utf8() {
-  _has_bits_[0] |= 0x00000200u;
+  _has_bits_[0] |= 0x00000400u;
 }
 inline void FileOptions::clear_has_java_string_check_utf8() {
-  _has_bits_[0] &= ~0x00000200u;
+  _has_bits_[0] &= ~0x00000400u;
 }
 inline void FileOptions::clear_java_string_check_utf8() {
   java_string_check_utf8_ = false;
@@ -7249,13 +7277,13 @@
 
 // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
 inline bool FileOptions::has_optimize_for() const {
-  return (_has_bits_[0] & 0x00008000u) != 0;
+  return (_has_bits_[0] & 0x00020000u) != 0;
 }
 inline void FileOptions::set_has_optimize_for() {
-  _has_bits_[0] |= 0x00008000u;
+  _has_bits_[0] |= 0x00020000u;
 }
 inline void FileOptions::clear_has_optimize_for() {
-  _has_bits_[0] &= ~0x00008000u;
+  _has_bits_[0] &= ~0x00020000u;
 }
 inline void FileOptions::clear_optimize_for() {
   optimize_for_ = 1;
@@ -7337,13 +7365,13 @@
 
 // optional bool cc_generic_services = 16 [default = false];
 inline bool FileOptions::has_cc_generic_services() const {
-  return (_has_bits_[0] & 0x00000400u) != 0;
+  return (_has_bits_[0] & 0x00000800u) != 0;
 }
 inline void FileOptions::set_has_cc_generic_services() {
-  _has_bits_[0] |= 0x00000400u;
+  _has_bits_[0] |= 0x00000800u;
 }
 inline void FileOptions::clear_has_cc_generic_services() {
-  _has_bits_[0] &= ~0x00000400u;
+  _has_bits_[0] &= ~0x00000800u;
 }
 inline void FileOptions::clear_cc_generic_services() {
   cc_generic_services_ = false;
@@ -7361,13 +7389,13 @@
 
 // optional bool java_generic_services = 17 [default = false];
 inline bool FileOptions::has_java_generic_services() const {
-  return (_has_bits_[0] & 0x00000800u) != 0;
+  return (_has_bits_[0] & 0x00001000u) != 0;
 }
 inline void FileOptions::set_has_java_generic_services() {
-  _has_bits_[0] |= 0x00000800u;
+  _has_bits_[0] |= 0x00001000u;
 }
 inline void FileOptions::clear_has_java_generic_services() {
-  _has_bits_[0] &= ~0x00000800u;
+  _has_bits_[0] &= ~0x00001000u;
 }
 inline void FileOptions::clear_java_generic_services() {
   java_generic_services_ = false;
@@ -7385,13 +7413,13 @@
 
 // optional bool py_generic_services = 18 [default = false];
 inline bool FileOptions::has_py_generic_services() const {
-  return (_has_bits_[0] & 0x00001000u) != 0;
+  return (_has_bits_[0] & 0x00002000u) != 0;
 }
 inline void FileOptions::set_has_py_generic_services() {
-  _has_bits_[0] |= 0x00001000u;
+  _has_bits_[0] |= 0x00002000u;
 }
 inline void FileOptions::clear_has_py_generic_services() {
-  _has_bits_[0] &= ~0x00001000u;
+  _has_bits_[0] &= ~0x00002000u;
 }
 inline void FileOptions::clear_py_generic_services() {
   py_generic_services_ = false;
@@ -7407,15 +7435,39 @@
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.py_generic_services)
 }
 
+// optional bool php_generic_services = 19 [default = false];
+inline bool FileOptions::has_php_generic_services() const {
+  return (_has_bits_[0] & 0x00004000u) != 0;
+}
+inline void FileOptions::set_has_php_generic_services() {
+  _has_bits_[0] |= 0x00004000u;
+}
+inline void FileOptions::clear_has_php_generic_services() {
+  _has_bits_[0] &= ~0x00004000u;
+}
+inline void FileOptions::clear_php_generic_services() {
+  php_generic_services_ = false;
+  clear_has_php_generic_services();
+}
+inline bool FileOptions::php_generic_services() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_generic_services)
+  return php_generic_services_;
+}
+inline void FileOptions::set_php_generic_services(bool value) {
+  set_has_php_generic_services();
+  php_generic_services_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_generic_services)
+}
+
 // optional bool deprecated = 23 [default = false];
 inline bool FileOptions::has_deprecated() const {
-  return (_has_bits_[0] & 0x00002000u) != 0;
+  return (_has_bits_[0] & 0x00008000u) != 0;
 }
 inline void FileOptions::set_has_deprecated() {
-  _has_bits_[0] |= 0x00002000u;
+  _has_bits_[0] |= 0x00008000u;
 }
 inline void FileOptions::clear_has_deprecated() {
-  _has_bits_[0] &= ~0x00002000u;
+  _has_bits_[0] &= ~0x00008000u;
 }
 inline void FileOptions::clear_deprecated() {
   deprecated_ = false;
@@ -7433,13 +7485,13 @@
 
 // optional bool cc_enable_arenas = 31 [default = false];
 inline bool FileOptions::has_cc_enable_arenas() const {
-  return (_has_bits_[0] & 0x00004000u) != 0;
+  return (_has_bits_[0] & 0x00010000u) != 0;
 }
 inline void FileOptions::set_has_cc_enable_arenas() {
-  _has_bits_[0] |= 0x00004000u;
+  _has_bits_[0] |= 0x00010000u;
 }
 inline void FileOptions::clear_has_cc_enable_arenas() {
-  _has_bits_[0] &= ~0x00004000u;
+  _has_bits_[0] &= ~0x00010000u;
 }
 inline void FileOptions::clear_cc_enable_arenas() {
   cc_enable_arenas_ = false;
@@ -7707,6 +7759,69 @@
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_class_prefix)
 }
 
+// optional string php_namespace = 41;
+inline bool FileOptions::has_php_namespace() const {
+  return (_has_bits_[0] & 0x00000080u) != 0;
+}
+inline void FileOptions::set_has_php_namespace() {
+  _has_bits_[0] |= 0x00000080u;
+}
+inline void FileOptions::clear_has_php_namespace() {
+  _has_bits_[0] &= ~0x00000080u;
+}
+inline void FileOptions::clear_php_namespace() {
+  php_namespace_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_php_namespace();
+}
+inline const ::std::string& FileOptions::php_namespace() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_namespace)
+  return php_namespace_.GetNoArena();
+}
+inline void FileOptions::set_php_namespace(const ::std::string& value) {
+  set_has_php_namespace();
+  php_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_namespace)
+}
+#if LANG_CXX11
+inline void FileOptions::set_php_namespace(::std::string&& value) {
+  set_has_php_namespace();
+  php_namespace_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.php_namespace)
+}
+#endif
+inline void FileOptions::set_php_namespace(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
+  set_has_php_namespace();
+  php_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_namespace)
+}
+inline void FileOptions::set_php_namespace(const char* value, size_t size) {
+  set_has_php_namespace();
+  php_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.php_namespace)
+}
+inline ::std::string* FileOptions::mutable_php_namespace() {
+  set_has_php_namespace();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.php_namespace)
+  return php_namespace_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* FileOptions::release_php_namespace() {
+  // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_namespace)
+  clear_has_php_namespace();
+  return php_namespace_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void FileOptions::set_allocated_php_namespace(::std::string* php_namespace) {
+  if (php_namespace != NULL) {
+    set_has_php_namespace();
+  } else {
+    clear_has_php_namespace();
+  }
+  php_namespace_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), php_namespace);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_namespace)
+}
+
 // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
 inline int FileOptions::uninterpreted_option_size() const {
   return uninterpreted_option_.size();
diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto
index 0502878..f1ec573 100644
--- a/src/google/protobuf/descriptor.proto
+++ b/src/google/protobuf/descriptor.proto
@@ -361,6 +361,7 @@
   optional bool cc_generic_services = 16 [default=false];
   optional bool java_generic_services = 17 [default=false];
   optional bool py_generic_services = 18 [default=false];
+  optional bool php_generic_services = 19 [default=false];
 
   // Is this file deprecated?
   // Depending on the target platform, this can emit Deprecated annotations
@@ -390,6 +391,11 @@
   // from this .proto. Default is empty.
   optional string php_class_prefix = 40;
 
+  // Use this option to change the namespace of php generated classes. Default
+  // is empty. When this option is empty, the package name will be used for
+  // determining the namespace.
+  optional string php_namespace = 41;
+
   // The parser stores options it doesn't recognize here. See above.
   repeated UninterpretedOption uninterpreted_option = 999;
 
diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc
index 46812a0..6e1f747 100644
--- a/src/google/protobuf/duration.pb.cc
+++ b/src/google/protobuf/duration.pb.cc
@@ -154,14 +154,15 @@
       _cached_size_(0) {
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   ::memcpy(&seconds_, &from.seconds_,
-    reinterpret_cast<char*>(&nanos_) -
-    reinterpret_cast<char*>(&seconds_) + sizeof(nanos_));
+    static_cast<size_t>(reinterpret_cast<char*>(&nanos_) -
+    reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Duration)
 }
 
 void Duration::SharedCtor() {
-  ::memset(&seconds_, 0, reinterpret_cast<char*>(&nanos_) -
-    reinterpret_cast<char*>(&seconds_) + sizeof(nanos_));
+  ::memset(&seconds_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&nanos_) -
+      reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_));
   _cached_size_ = 0;
 }
 
@@ -210,8 +211,9 @@
   // Prevent compiler warnings about cached_has_bits being unused
   (void) cached_has_bits;
 
-  ::memset(&seconds_, 0, reinterpret_cast<char*>(&nanos_) -
-    reinterpret_cast<char*>(&seconds_) + sizeof(nanos_));
+  ::memset(&seconds_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&nanos_) -
+      reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_));
   _internal_metadata_.Clear();
 }
 
diff --git a/src/google/protobuf/dynamic_message.h b/src/google/protobuf/dynamic_message.h
index 0572217..e29b148 100644
--- a/src/google/protobuf/dynamic_message.h
+++ b/src/google/protobuf/dynamic_message.h
@@ -156,20 +156,20 @@
                                           int map_size,
                                           const Reflection* reflection,
                                           const FieldDescriptor* field) {
-    std::vector<const Message*> result(map_size);
+    std::vector<const Message*> result(static_cast<size_t>(map_size));
     const RepeatedPtrField<Message>& map_field =
         reflection->GetRepeatedPtrField<Message>(message, field);
-    int i = 0;
+    size_t i = 0;
     for (RepeatedPtrField<Message>::const_pointer_iterator it =
              map_field.pointer_begin(); it != map_field.pointer_end(); ) {
       result[i++] = *it++;
     }
-    GOOGLE_DCHECK_EQ(result.size(), static_cast<size_t>(i));
+    GOOGLE_DCHECK_EQ(result.size(), i);
     MapEntryMessageComparator comparator(field->message_type());
     std::stable_sort(result.begin(), result.end(), comparator);
     // Complain if the keys aren't in ascending order.
 #ifndef NDEBUG
-    for (int j = 1; j < map_size; j++) {
+    for (size_t j = 1; j < static_cast<size_t>(map_size); j++) {
       if (!comparator(result[j - 1], result[j])) {
         GOOGLE_LOG(ERROR) << (comparator(result[j], result[j - 1]) ?
                       "internal error in map key sorting" :
diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc
index a3ec2d2..43495a9 100644
--- a/src/google/protobuf/field_mask.pb.cc
+++ b/src/google/protobuf/field_mask.pb.cc
@@ -210,7 +210,7 @@
                 input, this->add_paths()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
             this->paths(this->paths_size() - 1).data(),
-            this->paths(this->paths_size() - 1).length(),
+            static_cast<int>(this->paths(this->paths_size() - 1).length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.FieldMask.paths"));
         } else {
@@ -248,7 +248,7 @@
   // repeated string paths = 1;
   for (int i = 0, n = this->paths_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->paths(i).data(), this->paths(i).length(),
+      this->paths(i).data(), static_cast<int>(this->paths(i).length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.FieldMask.paths");
     ::google::protobuf::internal::WireFormatLite::WriteString(
@@ -271,7 +271,7 @@
   // repeated string paths = 1;
   for (int i = 0, n = this->paths_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->paths(i).data(), this->paths(i).length(),
+      this->paths(i).data(), static_cast<int>(this->paths(i).length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.FieldMask.paths");
     target = ::google::protobuf::internal::WireFormatLite::
diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h
index 911c3a5..f6ce16a 100644
--- a/src/google/protobuf/generated_message_reflection.h
+++ b/src/google/protobuf/generated_message_reflection.h
@@ -129,7 +129,7 @@
 struct ReflectionSchema {
  public:
   // Size of a google::protobuf::Message object of this type.
-  uint32 GetObjectSize() const { return object_size_; }
+  uint32 GetObjectSize() const { return static_cast<uint32>(object_size_); }
 
   // Offset of a non-oneof field.  Getting a field offset is slightly more
   // efficient when we know statically that it is not a oneof field.
@@ -141,8 +141,9 @@
   // Offset of any field.
   uint32 GetFieldOffset(const FieldDescriptor* field) const {
     if (field->containing_oneof()) {
-      size_t offset = field->containing_type()->field_count() +
-                      field->containing_oneof()->index();
+      size_t offset =
+          static_cast<size_t>(field->containing_type()->field_count() +
+          field->containing_oneof()->index());
       return offsets_[offset];
     } else {
       return GetFieldOffsetNonOneof(field);
@@ -150,7 +151,9 @@
   }
 
   uint32 GetOneofCaseOffset(const OneofDescriptor* oneof_descriptor) const {
-    return oneof_case_offset_ + (oneof_descriptor->index() * sizeof(uint32));
+    return static_cast<uint32>(oneof_case_offset_) +
+           static_cast<uint32>(
+               static_cast<size_t>(oneof_descriptor->index()) * sizeof(uint32));
   }
 
   bool HasHasbits() const { return has_bits_offset_ != -1; }
@@ -164,7 +167,7 @@
   // Byte offset of the hasbits array.
   uint32 HasBitsOffset() const {
     GOOGLE_DCHECK(HasHasbits());
-    return has_bits_offset_;
+    return static_cast<uint32>(has_bits_offset_);
   }
 
   // The offset of the InternalMetadataWithArena member.
@@ -172,7 +175,7 @@
   // The schema doesn't contain enough information to distinguish between
   // these two cases.
   uint32 GetMetadataOffset() const {
-    return metadata_offset_;
+    return static_cast<uint32>(metadata_offset_);
   }
 
   // Whether this message has an ExtensionSet.
@@ -181,7 +184,7 @@
   // The offset of the ExtensionSet in this message.
   uint32 GetExtensionSetOffset() const {
     GOOGLE_DCHECK(HasExtensionSet());
-    return extensions_offset_;
+    return static_cast<uint32>(extensions_offset_);
   }
 
   // The off set of WeakFieldMap when the message contains weak fields.
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h
index bce05a3..6d2599f 100644
--- a/src/google/protobuf/io/coded_stream.h
+++ b/src/google/protobuf/io/coded_stream.h
@@ -1418,7 +1418,7 @@
 }  // namespace protobuf
 
 
-#if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
+#if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
   #pragma runtime_checks("c", restore)
 #endif  // _MSC_VER && !defined(__INTEL_COMPILER)
 
diff --git a/src/google/protobuf/io/tokenizer_unittest.cc b/src/google/protobuf/io/tokenizer_unittest.cc
index cadeb69..e55288e 100644
--- a/src/google/protobuf/io/tokenizer_unittest.cc
+++ b/src/google/protobuf/io/tokenizer_unittest.cc
@@ -341,7 +341,7 @@
 MultiTokenCase kMultiTokenCases[] = {
   // Test empty input.
   { "", {
-    { Tokenizer::TYPE_END       , ""     , 0,  0 },
+    { Tokenizer::TYPE_END       , ""     , 0,  0,  0 },
   }},
 
   // Test all token types at the same time.
diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h
index 2d561c2..6514a0c 100644
--- a/src/google/protobuf/map.h
+++ b/src/google/protobuf/map.h
@@ -47,9 +47,6 @@
 #include <google/protobuf/generated_enum_util.h>
 #include <google/protobuf/map_type_handler.h>
 #include <google/protobuf/stubs/hash.h>
-#if __cpp_exceptions && LANG_CXX11
-#include <random>
-#endif
 
 namespace google {
 namespace protobuf {
@@ -161,7 +158,7 @@
 
  private:
   void Init() {
-    elements_ = Arena::Create<InnerMap>(arena_, 0, hasher(), Allocator(arena_));
+    elements_ = Arena::Create<InnerMap>(arena_, 0u, hasher(), Allocator(arena_));
   }
 
   // re-implement std::allocator to use arena allocator for memory allocation.
@@ -915,16 +912,6 @@
 
     // Return a randomish value.
     size_type Seed() const {
-      // random_device can throw, so avoid it unless we are compiling with
-      // exceptions enabled.
-#if __cpp_exceptions && LANG_CXX11
-      try {
-        std::random_device rd;
-        std::knuth_b knuth(rd());
-        std::uniform_int_distribution<size_type> u;
-        return u(knuth);
-      } catch (...) { }
-#endif
       size_type s = static_cast<size_type>(reinterpret_cast<uintptr_t>(this));
 #if defined(__x86_64__) && defined(__GNUC__)
       uint32 hi, lo;
diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h
index d245cfc..0bccf4d 100644
--- a/src/google/protobuf/map_entry_lite.h
+++ b/src/google/protobuf/map_entry_lite.h
@@ -227,8 +227,10 @@
 
   size_t ByteSizeLong() const {
     size_t size = 0;
-    size += has_key() ? kTagSize + KeyTypeHandler::ByteSize(key()) : 0;
-    size += has_value() ? kTagSize + ValueTypeHandler::ByteSize(value()) : 0;
+    size += has_key() ?
+        kTagSize + static_cast<size_t>(KeyTypeHandler::ByteSize(key())) : 0;
+    size += has_value() ?
+        kTagSize + static_cast<size_t>(ValueTypeHandler::ByteSize(value())) : 0;
     return size;
   }
 
@@ -251,11 +253,10 @@
   int GetCachedSize() const {
     int size = 0;
     size += has_key()
-        ? kTagSize + KeyTypeHandler::GetCachedSize(key())
+        ? static_cast<int>(kTagSize) + KeyTypeHandler::GetCachedSize(key())
         : 0;
     size += has_value()
-        ? kTagSize + ValueTypeHandler::GetCachedSize(
-            value())
+        ? static_cast<int>(kTagSize) + ValueTypeHandler::GetCachedSize(value())
         : 0;
     return size;
   }
diff --git a/src/google/protobuf/map_field_inl.h b/src/google/protobuf/map_field_inl.h
index 8c5da3c..e317b5e 100644
--- a/src/google/protobuf/map_field_inl.h
+++ b/src/google/protobuf/map_field_inl.h
@@ -168,7 +168,7 @@
 int MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
              default_enum_value>::size() const {
   MapFieldBase::SyncMapWithRepeatedField();
-  return impl_.GetMap().size();
+  return static_cast<int>(impl_.GetMap().size());
 }
 
 template <typename Derived, typename Key, typename T,
@@ -252,9 +252,9 @@
           WireFormatLite::FieldType kValueFieldType, int default_enum_value>
 void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
               default_enum_value>::Swap(MapField* other) {
-  std::swap(MapFieldBase::repeated_field_, other->repeated_field_);
+  std::swap(this->MapFieldBase::repeated_field_, other->repeated_field_);
   impl_.Swap(&other->impl_);
-  std::swap(MapFieldBase::state_, other->state_);
+  std::swap(this->MapFieldBase::state_, other->state_);
 }
 
 template <typename Derived, typename Key, typename T,
diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h
index 0ac7aee..12d4e6b 100644
--- a/src/google/protobuf/map_field_lite.h
+++ b/src/google/protobuf/map_field_lite.h
@@ -64,7 +64,7 @@
   Map<Key, T>* MutableMap() { return &map_; }
 
   // Convenient methods for generated message implementation.
-  int size() const { return map_.size(); }
+  int size() const { return static_cast<int>(map_.size()); }
   void Clear() { return map_.clear(); }
   void MergeFrom(const MapFieldLite& other) {
     for (typename Map<Key, T>::const_iterator it = other.map_.begin();
diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h
index a10a720..423c98f 100644
--- a/src/google/protobuf/map_type_handler.h
+++ b/src/google/protobuf/map_type_handler.h
@@ -283,7 +283,7 @@
   template <typename Type>                                                     \
   inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::ByteSize( \
       const MapEntryAccessorType& value) {                                     \
-    return WireFormatLite::DeclaredType##Size(value);                          \
+    return static_cast<int>(WireFormatLite::DeclaredType##Size(value));        \
   }
 
 GOOGLE_PROTOBUF_BYTE_SIZE(STRING, String)
@@ -319,7 +319,9 @@
 inline int
 MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::GetCachedSize(
     const MapEntryAccessorType& value) {
-  return WireFormatLite::LengthDelimitedSize(value.GetCachedSize());
+  return static_cast<int>(
+      WireFormatLite::LengthDelimitedSize(
+          static_cast<size_t>(value.GetCachedSize())));
 }
 
 #define GET_CACHED_SIZE(FieldType, DeclaredType)                         \
@@ -327,7 +329,7 @@
   inline int                                                             \
   MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::GetCachedSize( \
       const MapEntryAccessorType& value) {                               \
-    return WireFormatLite::DeclaredType##Size(value);                    \
+    return static_cast<int>(WireFormatLite::DeclaredType##Size(value));  \
   }
 
 GET_CACHED_SIZE(STRING, String)
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index c65ff62..44fe0fd 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -963,7 +963,7 @@
   // TODO(jieluo) - make the map APIs pure virtual after updating
   // all the subclasses.
   // Returns true if key is in map. Returns false if key is not in map field.
-  virtual bool ContainsMapKey(const Message& /* message*/,
+  virtual bool ContainsMapKey(const Message& /* message */,
                               const FieldDescriptor* /* field */,
                               const MapKey& /* key */) const {
     return false;
@@ -981,7 +981,7 @@
 
   // Delete and returns true if key is in the map field. Returns false
   // otherwise.
-  virtual bool DeleteMapValue(Message* /* mesage */,
+  virtual bool DeleteMapValue(Message* /* message */,
                               const FieldDescriptor* /* field */,
                               const MapKey& /* key */) const {
     return false;
diff --git a/src/google/protobuf/metadata_lite.h b/src/google/protobuf/metadata_lite.h
index 840c02e..64fde0c 100644
--- a/src/google/protobuf/metadata_lite.h
+++ b/src/google/protobuf/metadata_lite.h
@@ -167,7 +167,8 @@
   InternalMetadataWithArenaLite() {}
 
   explicit InternalMetadataWithArenaLite(Arena* arena)
-      : InternalMetadataWithArenaBase(arena) {}
+      : InternalMetadataWithArenaBase<string,
+                                      InternalMetadataWithArenaLite>(arena) {}
 
   void DoSwap(string* other) {
     mutable_unknown_fields()->swap(*other);
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index 20743fa..d8003b8 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -1331,7 +1331,7 @@
       static_cast<size_t>(new_size),
       (std::numeric_limits<size_t>::max() - kRepHeaderSize) / sizeof(Element))
       << "Requested size is too large to fit into size_t.";
-  size_t bytes = kRepHeaderSize + sizeof(Element) * new_size;
+  size_t bytes = kRepHeaderSize + sizeof(Element) * static_cast<size_t>(new_size);
   if (arena == NULL) {
     rep_ = static_cast<Rep*>(::operator new(bytes));
   } else {
@@ -1395,7 +1395,7 @@
 template <typename Element>
 struct ElementCopier<Element, true> {
   void operator()(Element* to, const Element* from, int array_size) {
-    memcpy(to, from, array_size * sizeof(Element));
+    memcpy(to, from, static_cast<size_t>(array_size) * sizeof(Element));
   }
 };
 
@@ -1647,7 +1647,7 @@
 
 template <typename TypeHandler>
 inline size_t RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong() const {
-  size_t allocated_bytes = total_size_ * sizeof(void*);
+  size_t allocated_bytes = static_cast<size_t>(total_size_) * sizeof(void*);
   if (rep_ != NULL) {
     for (int i = 0; i < rep_->allocated_size; ++i) {
       allocated_bytes += TypeHandler::SpaceUsedLong(
diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc
index 3a7c5b5..130eb2a 100644
--- a/src/google/protobuf/source_context.pb.cc
+++ b/src/google/protobuf/source_context.pb.cc
@@ -215,7 +215,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_file_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->file_name().data(), this->file_name().length(),
+            this->file_name().data(), static_cast<int>(this->file_name().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.SourceContext.file_name"));
         } else {
@@ -253,7 +253,7 @@
   // string file_name = 1;
   if (this->file_name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->file_name().data(), this->file_name().length(),
+      this->file_name().data(), static_cast<int>(this->file_name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.SourceContext.file_name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -276,7 +276,7 @@
   // string file_name = 1;
   if (this->file_name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->file_name().data(), this->file_name().length(),
+      this->file_name().data(), static_cast<int>(this->file_name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.SourceContext.file_name");
     target =
diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc
index bb33a55..08029a4 100644
--- a/src/google/protobuf/struct.pb.cc
+++ b/src/google/protobuf/struct.pb.cc
@@ -331,7 +331,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
               input, &parser));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            parser.key().data(), parser.key().length(),
+            parser.key().data(), static_cast<int>(parser.key().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Struct.FieldsEntry.key"));
         } else {
@@ -375,7 +375,7 @@
     struct Utf8Check {
       static void Check(ConstPtr p) {
         ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-          p->first.data(), p->first.length(),
+          p->first.data(), static_cast<int>(p->first.length()),
           ::google::protobuf::internal::WireFormatLite::SERIALIZE,
           "google.protobuf.Struct.FieldsEntry.key");
       }
@@ -390,19 +390,19 @@
       for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
           it = this->fields().begin();
           it != this->fields().end(); ++it, ++n) {
-        items[n] = SortItem(&*it);
+        items[static_cast<ptrdiff_t>(n)] = SortItem(&*it);
       }
-      ::std::sort(&items[0], &items[n], Less());
+      ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());
       ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
       for (size_type i = 0; i < n; i++) {
         entry.reset(fields_.NewEntryWrapper(
-            items[i]->first, items[i]->second));
+            items[static_cast<ptrdiff_t>(i)]->first, items[static_cast<ptrdiff_t>(i)]->second));
         ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
             1, *entry, output);
         if (entry->GetArena() != NULL) {
           entry.release();
         }
-        Utf8Check::Check(items[i]);
+        Utf8Check::Check(items[static_cast<ptrdiff_t>(i)]);
       }
     } else {
       ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
@@ -443,7 +443,7 @@
     struct Utf8Check {
       static void Check(ConstPtr p) {
         ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-          p->first.data(), p->first.length(),
+          p->first.data(), static_cast<int>(p->first.length()),
           ::google::protobuf::internal::WireFormatLite::SERIALIZE,
           "google.protobuf.Struct.FieldsEntry.key");
       }
@@ -458,13 +458,13 @@
       for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
           it = this->fields().begin();
           it != this->fields().end(); ++it, ++n) {
-        items[n] = SortItem(&*it);
+        items[static_cast<ptrdiff_t>(n)] = SortItem(&*it);
       }
-      ::std::sort(&items[0], &items[n], Less());
+      ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());
       ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
       for (size_type i = 0; i < n; i++) {
         entry.reset(fields_.NewEntryWrapper(
-            items[i]->first, items[i]->second));
+            items[static_cast<ptrdiff_t>(i)]->first, items[static_cast<ptrdiff_t>(i)]->second));
         target = ::google::protobuf::internal::WireFormatLite::
                    InternalWriteMessageNoVirtualToArray(
                        1, *entry, deterministic, target);
@@ -472,7 +472,7 @@
         if (entry->GetArena() != NULL) {
           entry.release();
         }
-        Utf8Check::Check(items[i]);
+        Utf8Check::Check(items[static_cast<ptrdiff_t>(i)]);
       }
     } else {
       ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
@@ -843,7 +843,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_string_value()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->string_value().data(), this->string_value().length(),
+            this->string_value().data(), static_cast<int>(this->string_value().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Value.string_value"));
         } else {
@@ -931,7 +931,7 @@
   // string string_value = 3;
   if (has_string_value()) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->string_value().data(), this->string_value().length(),
+      this->string_value().data(), static_cast<int>(this->string_value().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Value.string_value");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -982,7 +982,7 @@
   // string string_value = 3;
   if (has_string_value()) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->string_value().data(), this->string_value().length(),
+      this->string_value().data(), static_cast<int>(this->string_value().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Value.string_value");
     target =
@@ -1712,9 +1712,10 @@
   (void) cached_has_bits;
 
   // repeated .google.protobuf.Value values = 1;
-  for (unsigned int i = 0, n = this->values_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->values_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      1, this->values(i), output);
+      1, this->values(static_cast<int>(i)), output);
   }
 
   if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
@@ -1731,10 +1732,11 @@
   (void) cached_has_bits;
 
   // repeated .google.protobuf.Value values = 1;
-  for (unsigned int i = 0, n = this->values_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->values_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        1, this->values(i), deterministic, target);
+        1, this->values(static_cast<int>(i)), deterministic, target);
   }
 
   if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
@@ -1756,12 +1758,12 @@
   }
   // repeated .google.protobuf.Value values = 1;
   {
-    unsigned int count = this->values_size();
+    unsigned int count = static_cast<unsigned int>(this->values_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->values(i));
+          this->values(static_cast<int>(i)));
     }
   }
 
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h
index 79d615d..f32fd22 100644
--- a/src/google/protobuf/stubs/common.h
+++ b/src/google/protobuf/stubs/common.h
@@ -228,10 +228,8 @@
 // in some versions of MSVC.
 // TODO(acozzette): remove these using statements
 using std::istream;
-using std::map;
 using std::ostream;
 using std::pair;
-using std::set;
 using std::string;
 using std::vector;
 
diff --git a/src/google/protobuf/stubs/fastmem.h b/src/google/protobuf/stubs/fastmem.h
index 763a6e6..1f1f6ed 100644
--- a/src/google/protobuf/stubs/fastmem.h
+++ b/src/google/protobuf/stubs/fastmem.h
@@ -111,7 +111,8 @@
     b += sizeof(uint32);
   }
   while (a < a_limit) {
-    int d = static_cast<uint32>(*a++) - static_cast<uint32>(*b++);
+    int d =
+        static_cast<int>(static_cast<uint32>(*a++) - static_cast<uint32>(*b++));
     if (d) return d;
   }
   return 0;
diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h
index be998b2..612b586 100644
--- a/src/google/protobuf/stubs/hash.h
+++ b/src/google/protobuf/stubs/hash.h
@@ -40,10 +40,9 @@
 
 #define GOOGLE_PROTOBUF_HAVE_HASH_MAP 1
 #define GOOGLE_PROTOBUF_HAVE_HASH_SET 1
-#define GOOGLE_PROTOBUF_HAVE_64BIT_HASH 1
 
 // Use C++11 unordered_{map|set} if available.
-#if ((_LIBCPP_STD_VER >= 11) || \
+#if ((defined(_LIBCPP_STD_VER) && _LIBCPP_STD_VER >= 11) || \
     (((__cplusplus >= 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X)) && \
     (__GLIBCXX__ > 20090421)))
 # define GOOGLE_PROTOBUF_HAS_CXX11_HASH
@@ -93,8 +92,11 @@
 #  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
 # endif
 
+// GCC <= 4.1 does not define std::tr1::hash for `long long int` or `long long unsigned int`
 # if __GNUC__ == 4 && __GNUC__MINOR__ <= 1
-#  undef GOOGLE_PROTOBUF_HAVE_64BIT_HASH
+#  define GOOGLE_PROTOBUF_MISSING_HASH
+#  include <map>
+#  include <set>
 # endif
 
 // Version checks for MSC.
@@ -348,7 +350,7 @@
   inline size_t operator()(const char* str) const {
     size_t result = 0;
     for (; *str != '\0'; str++) {
-      result = 5 * result + *str;
+      result = 5 * result + static_cast<size_t>(*str);
     }
     return result;
   }
diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h
index ca9a150..dbc2986 100644
--- a/src/google/protobuf/stubs/port.h
+++ b/src/google/protobuf/stubs/port.h
@@ -252,9 +252,15 @@
 #define GOOGLE_GUARDED_BY(x)
 #define GOOGLE_ATTRIBUTE_COLD
 
+#ifdef GOOGLE_PROTOBUF_DONT_USE_UNALIGNED
+# define GOOGLE_PROTOBUF_USE_UNALIGNED 0
+#else
 // x86 and x86-64 can perform unaligned loads/stores directly.
-#if defined(_M_X64) || defined(__x86_64__) || \
-    defined(_M_IX86) || defined(__i386__)
+# define GOOGLE_PROTOBUF_USE_UNALIGNED defined(_M_X64) || \
+     defined(__x86_64__) || defined(_M_IX86) || defined(__i386__)
+#endif
+
+#if GOOGLE_PROTOBUF_USE_UNALIGNED
 
 #define GOOGLE_UNALIGNED_LOAD16(_p) (*reinterpret_cast<const uint16 *>(_p))
 #define GOOGLE_UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32 *>(_p))
@@ -348,7 +354,7 @@
  public:
   static uint32 Log2FloorNonZero(uint32 n) {
 #if defined(__GNUC__)
-  return 31 ^ __builtin_clz(n);
+  return 31 ^ static_cast<uint32>(__builtin_clz(n));
 #elif defined(COMPILER_MSVC) && defined(_M_IX86)
   _asm {
     bsr ebx, n
@@ -367,7 +373,7 @@
     // To work around this, when we build for NaCl we use the portable
     // implementation instead.
 #if defined(__GNUC__) && !defined(GOOGLE_PROTOBUF_OS_NACL)
-  return 63 ^ __builtin_clzll(n);
+  return 63 ^ static_cast<uint32>(__builtin_clzll(n));
 #else
   return Log2FloorNonZero64_Portable(n);
 #endif
@@ -394,9 +400,9 @@
     const uint32 topbits = static_cast<uint32>(n >> 32);
     if (topbits == 0) {
       // Top bits are zero, so scan in bottom bits
-      return Log2FloorNonZero(static_cast<uint32>(n));
+      return static_cast<int>(Log2FloorNonZero(static_cast<uint32>(n)));
     } else {
-      return 32 + Log2FloorNonZero(topbits);
+      return 32 + static_cast<int>(Log2FloorNonZero(topbits));
     }
   }
 };
diff --git a/src/google/protobuf/stubs/stringpiece.h b/src/google/protobuf/stubs/stringpiece.h
index 8910688..563ff75 100644
--- a/src/google/protobuf/stubs/stringpiece.h
+++ b/src/google/protobuf/stubs/stringpiece.h
@@ -292,7 +292,7 @@
   int compare(StringPiece x) const {
     const stringpiece_ssize_type min_size =
         length_ < x.length_ ? length_ : x.length_;
-    int r = memcmp(ptr_, x.ptr_, min_size);
+    int r = memcmp(ptr_, x.ptr_, static_cast<size_t>(min_size));
     if (r < 0) return -1;
     if (r > 0) return 1;
     if (length_ < x.length_) return -1;
@@ -310,7 +310,7 @@
   // "as_string()" method defined here for existing code.
   string ToString() const {
     if (ptr_ == NULL) return string();
-    return string(data(), size());
+    return string(data(), static_cast<size_type>(size()));
   }
 
   operator string() const {
@@ -321,12 +321,14 @@
   void AppendToString(string* target) const;
 
   bool starts_with(StringPiece x) const {
-    return (length_ >= x.length_) && (memcmp(ptr_, x.ptr_, x.length_) == 0);
+    return (length_ >= x.length_) &&
+           (memcmp(ptr_, x.ptr_, static_cast<size_t>(x.length_)) == 0);
   }
 
   bool ends_with(StringPiece x) const {
     return ((length_ >= x.length_) &&
-            (memcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0));
+            (memcmp(ptr_ + (length_-x.length_), x.ptr_,
+                 static_cast<size_t>(x.length_)) == 0));
   }
 
   // Checks whether StringPiece starts with x and if so advances the beginning
@@ -398,7 +400,7 @@
   }
 
   return x.data() == y.data() || len <= 0 ||
-      memcmp(x.data(), y.data(), len) == 0;
+      memcmp(x.data(), y.data(), static_cast<size_t>(len)) == 0;
 }
 
 inline bool operator!=(StringPiece x, StringPiece y) {
@@ -408,7 +410,7 @@
 inline bool operator<(StringPiece x, StringPiece y) {
   const stringpiece_ssize_type min_size =
       x.size() < y.size() ? x.size() : y.size();
-  const int r = memcmp(x.data(), y.data(), min_size);
+  const int r = memcmp(x.data(), y.data(), static_cast<size_t>(min_size));
   return (r < 0) || (r == 0 && x.size() < y.size());
 }
 
@@ -458,7 +460,9 @@
     return size_;
   }
 
-  std::string ToString() const { return std::string(data_, size_); }
+  std::string ToString() const {
+    return std::string(data_, static_cast<size_t>(size_));
+  }
  private:
   const char* data_;
   stringpiece_ssize_type size_;
@@ -473,7 +477,7 @@
   size_t operator()(const StringPiece& s) const {
     size_t result = 0;
     for (const char *str = s.data(), *end = str + s.size(); str < end; str++) {  
-      result = 5 * result + *str;
+      result = 5 * result + static_cast<size_t>(*str);
     }
     return result;
   }
diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc
index 336894b..1a4d71c 100644
--- a/src/google/protobuf/stubs/strutil.cc
+++ b/src/google/protobuf/stubs/strutil.cc
@@ -1401,7 +1401,7 @@
   float parsed_value;
   if (!safe_strtof(buffer, &parsed_value) || parsed_value != value) {
     int snprintf_result =
-      snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG+2, value);
+      snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG+3, value);
 
     // Should never overflow; see above.
     GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize);
diff --git a/src/google/protobuf/testing/googletest.h b/src/google/protobuf/testing/googletest.h
index 04b3019..dc4401d 100644
--- a/src/google/protobuf/testing/googletest.h
+++ b/src/google/protobuf/testing/googletest.h
@@ -85,7 +85,7 @@
   const vector<string>& GetMessages(LogLevel error);
 
  private:
-  map<LogLevel, vector<string> > messages_;
+  std::map<LogLevel, vector<string> > messages_;
   LogHandler* old_handler_;
 
   static void HandleLog(LogLevel level, const char* filename, int line,
diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc
index 54f022a..52ceec7 100644
--- a/src/google/protobuf/timestamp.pb.cc
+++ b/src/google/protobuf/timestamp.pb.cc
@@ -154,14 +154,15 @@
       _cached_size_(0) {
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   ::memcpy(&seconds_, &from.seconds_,
-    reinterpret_cast<char*>(&nanos_) -
-    reinterpret_cast<char*>(&seconds_) + sizeof(nanos_));
+    static_cast<size_t>(reinterpret_cast<char*>(&nanos_) -
+    reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Timestamp)
 }
 
 void Timestamp::SharedCtor() {
-  ::memset(&seconds_, 0, reinterpret_cast<char*>(&nanos_) -
-    reinterpret_cast<char*>(&seconds_) + sizeof(nanos_));
+  ::memset(&seconds_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&nanos_) -
+      reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_));
   _cached_size_ = 0;
 }
 
@@ -210,8 +211,9 @@
   // Prevent compiler warnings about cached_has_bits being unused
   (void) cached_has_bits;
 
-  ::memset(&seconds_, 0, reinterpret_cast<char*>(&nanos_) -
-    reinterpret_cast<char*>(&seconds_) + sizeof(nanos_));
+  ::memset(&seconds_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&nanos_) -
+      reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_));
   _internal_metadata_.Clear();
 }
 
diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc
index e28cec2..4e6d0f8 100644
--- a/src/google/protobuf/type.pb.cc
+++ b/src/google/protobuf/type.pb.cc
@@ -419,8 +419,9 @@
 
 void Type::SharedCtor() {
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  ::memset(&source_context_, 0, reinterpret_cast<char*>(&syntax_) -
-    reinterpret_cast<char*>(&source_context_) + sizeof(syntax_));
+  ::memset(&source_context_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&syntax_) -
+      reinterpret_cast<char*>(&source_context_)) + sizeof(syntax_));
   _cached_size_ = 0;
 }
 
@@ -500,7 +501,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Type.name"));
         } else {
@@ -529,7 +530,7 @@
                 input, this->add_oneofs()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
             this->oneofs(this->oneofs_size() - 1).data(),
-            this->oneofs(this->oneofs_size() - 1).length(),
+            static_cast<int>(this->oneofs(this->oneofs_size() - 1).length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Type.oneofs"));
         } else {
@@ -606,7 +607,7 @@
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Type.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -614,15 +615,16 @@
   }
 
   // repeated .google.protobuf.Field fields = 2;
-  for (unsigned int i = 0, n = this->fields_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->fields_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      2, this->fields(i), output);
+      2, this->fields(static_cast<int>(i)), output);
   }
 
   // repeated string oneofs = 3;
   for (int i = 0, n = this->oneofs_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->oneofs(i).data(), this->oneofs(i).length(),
+      this->oneofs(i).data(), static_cast<int>(this->oneofs(i).length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Type.oneofs");
     ::google::protobuf::internal::WireFormatLite::WriteString(
@@ -630,9 +632,10 @@
   }
 
   // repeated .google.protobuf.Option options = 4;
-  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->options_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      4, this->options(i), output);
+      4, this->options(static_cast<int>(i)), output);
   }
 
   // .google.protobuf.SourceContext source_context = 5;
@@ -663,7 +666,7 @@
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Type.name");
     target =
@@ -672,16 +675,17 @@
   }
 
   // repeated .google.protobuf.Field fields = 2;
-  for (unsigned int i = 0, n = this->fields_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->fields_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        2, this->fields(i), deterministic, target);
+        2, this->fields(static_cast<int>(i)), deterministic, target);
   }
 
   // repeated string oneofs = 3;
   for (int i = 0, n = this->oneofs_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->oneofs(i).data(), this->oneofs(i).length(),
+      this->oneofs(i).data(), static_cast<int>(this->oneofs(i).length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Type.oneofs");
     target = ::google::protobuf::internal::WireFormatLite::
@@ -689,10 +693,11 @@
   }
 
   // repeated .google.protobuf.Option options = 4;
-  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->options_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        4, this->options(i), deterministic, target);
+        4, this->options(static_cast<int>(i)), deterministic, target);
   }
 
   // .google.protobuf.SourceContext source_context = 5;
@@ -727,12 +732,12 @@
   }
   // repeated .google.protobuf.Field fields = 2;
   {
-    unsigned int count = this->fields_size();
+    unsigned int count = static_cast<unsigned int>(this->fields_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->fields(i));
+          this->fields(static_cast<int>(i)));
     }
   }
 
@@ -746,12 +751,12 @@
 
   // repeated .google.protobuf.Option options = 4;
   {
-    unsigned int count = this->options_size();
+    unsigned int count = static_cast<unsigned int>(this->options_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->options(i));
+          this->options(static_cast<int>(i)));
     }
   }
 
@@ -1206,8 +1211,8 @@
       GetArenaNoVirtual());
   }
   ::memcpy(&kind_, &from.kind_,
-    reinterpret_cast<char*>(&packed_) -
-    reinterpret_cast<char*>(&kind_) + sizeof(packed_));
+    static_cast<size_t>(reinterpret_cast<char*>(&packed_) -
+    reinterpret_cast<char*>(&kind_)) + sizeof(packed_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Field)
 }
 
@@ -1216,8 +1221,9 @@
   type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   json_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   default_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  ::memset(&kind_, 0, reinterpret_cast<char*>(&packed_) -
-    reinterpret_cast<char*>(&kind_) + sizeof(packed_));
+  ::memset(&kind_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&packed_) -
+      reinterpret_cast<char*>(&kind_)) + sizeof(packed_));
   _cached_size_ = 0;
 }
 
@@ -1275,8 +1281,9 @@
   type_url_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
   json_name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
   default_value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  ::memset(&kind_, 0, reinterpret_cast<char*>(&packed_) -
-    reinterpret_cast<char*>(&kind_) + sizeof(packed_));
+  ::memset(&kind_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&packed_) -
+      reinterpret_cast<char*>(&kind_)) + sizeof(packed_));
   _internal_metadata_.Clear();
 }
 
@@ -1341,7 +1348,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Field.name"));
         } else {
@@ -1357,7 +1364,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_type_url()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->type_url().data(), this->type_url().length(),
+            this->type_url().data(), static_cast<int>(this->type_url().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Field.type_url"));
         } else {
@@ -1413,7 +1420,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_json_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->json_name().data(), this->json_name().length(),
+            this->json_name().data(), static_cast<int>(this->json_name().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Field.json_name"));
         } else {
@@ -1429,7 +1436,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_default_value()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->default_value().data(), this->default_value().length(),
+            this->default_value().data(), static_cast<int>(this->default_value().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Field.default_value"));
         } else {
@@ -1484,7 +1491,7 @@
   // string name = 4;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Field.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -1494,7 +1501,7 @@
   // string type_url = 6;
   if (this->type_url().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->type_url().data(), this->type_url().length(),
+      this->type_url().data(), static_cast<int>(this->type_url().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Field.type_url");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -1512,15 +1519,16 @@
   }
 
   // repeated .google.protobuf.Option options = 9;
-  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->options_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      9, this->options(i), output);
+      9, this->options(static_cast<int>(i)), output);
   }
 
   // string json_name = 10;
   if (this->json_name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->json_name().data(), this->json_name().length(),
+      this->json_name().data(), static_cast<int>(this->json_name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Field.json_name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -1530,7 +1538,7 @@
   // string default_value = 11;
   if (this->default_value().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->default_value().data(), this->default_value().length(),
+      this->default_value().data(), static_cast<int>(this->default_value().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Field.default_value");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -1570,7 +1578,7 @@
   // string name = 4;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Field.name");
     target =
@@ -1581,7 +1589,7 @@
   // string type_url = 6;
   if (this->type_url().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->type_url().data(), this->type_url().length(),
+      this->type_url().data(), static_cast<int>(this->type_url().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Field.type_url");
     target =
@@ -1600,16 +1608,17 @@
   }
 
   // repeated .google.protobuf.Option options = 9;
-  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->options_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        9, this->options(i), deterministic, target);
+        9, this->options(static_cast<int>(i)), deterministic, target);
   }
 
   // string json_name = 10;
   if (this->json_name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->json_name().data(), this->json_name().length(),
+      this->json_name().data(), static_cast<int>(this->json_name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Field.json_name");
     target =
@@ -1620,7 +1629,7 @@
   // string default_value = 11;
   if (this->default_value().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->default_value().data(), this->default_value().length(),
+      this->default_value().data(), static_cast<int>(this->default_value().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Field.default_value");
     target =
@@ -1647,12 +1656,12 @@
   }
   // repeated .google.protobuf.Option options = 9;
   {
-    unsigned int count = this->options_size();
+    unsigned int count = static_cast<unsigned int>(this->options_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->options(i));
+          this->options(static_cast<int>(i)));
     }
   }
 
@@ -2321,8 +2330,9 @@
 
 void Enum::SharedCtor() {
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  ::memset(&source_context_, 0, reinterpret_cast<char*>(&syntax_) -
-    reinterpret_cast<char*>(&source_context_) + sizeof(syntax_));
+  ::memset(&source_context_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&syntax_) -
+      reinterpret_cast<char*>(&source_context_)) + sizeof(syntax_));
   _cached_size_ = 0;
 }
 
@@ -2401,7 +2411,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Enum.name"));
         } else {
@@ -2490,7 +2500,7 @@
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Enum.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -2498,15 +2508,17 @@
   }
 
   // repeated .google.protobuf.EnumValue enumvalue = 2;
-  for (unsigned int i = 0, n = this->enumvalue_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->enumvalue_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      2, this->enumvalue(i), output);
+      2, this->enumvalue(static_cast<int>(i)), output);
   }
 
   // repeated .google.protobuf.Option options = 3;
-  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->options_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      3, this->options(i), output);
+      3, this->options(static_cast<int>(i)), output);
   }
 
   // .google.protobuf.SourceContext source_context = 4;
@@ -2537,7 +2549,7 @@
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Enum.name");
     target =
@@ -2546,17 +2558,19 @@
   }
 
   // repeated .google.protobuf.EnumValue enumvalue = 2;
-  for (unsigned int i = 0, n = this->enumvalue_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->enumvalue_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        2, this->enumvalue(i), deterministic, target);
+        2, this->enumvalue(static_cast<int>(i)), deterministic, target);
   }
 
   // repeated .google.protobuf.Option options = 3;
-  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->options_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        3, this->options(i), deterministic, target);
+        3, this->options(static_cast<int>(i)), deterministic, target);
   }
 
   // .google.protobuf.SourceContext source_context = 4;
@@ -2591,23 +2605,23 @@
   }
   // repeated .google.protobuf.EnumValue enumvalue = 2;
   {
-    unsigned int count = this->enumvalue_size();
+    unsigned int count = static_cast<unsigned int>(this->enumvalue_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->enumvalue(i));
+          this->enumvalue(static_cast<int>(i)));
     }
   }
 
   // repeated .google.protobuf.Option options = 3;
   {
-    unsigned int count = this->options_size();
+    unsigned int count = static_cast<unsigned int>(this->options_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->options(i));
+          this->options(static_cast<int>(i)));
     }
   }
 
@@ -3047,7 +3061,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.EnumValue.name"));
         } else {
@@ -3111,7 +3125,7 @@
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.EnumValue.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -3124,9 +3138,10 @@
   }
 
   // repeated .google.protobuf.Option options = 3;
-  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->options_size()); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      3, this->options(i), output);
+      3, this->options(static_cast<int>(i)), output);
   }
 
   if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
@@ -3145,7 +3160,7 @@
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.EnumValue.name");
     target =
@@ -3159,10 +3174,11 @@
   }
 
   // repeated .google.protobuf.Option options = 3;
-  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->options_size()); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        3, this->options(i), deterministic, target);
+        3, this->options(static_cast<int>(i)), deterministic, target);
   }
 
   if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
@@ -3184,12 +3200,12 @@
   }
   // repeated .google.protobuf.Option options = 3;
   {
-    unsigned int count = this->options_size();
+    unsigned int count = static_cast<unsigned int>(this->options_size());
     total_size += 1UL * count;
     for (unsigned int i = 0; i < count; i++) {
       total_size +=
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->options(i));
+          this->options(static_cast<int>(i)));
     }
   }
 
@@ -3572,7 +3588,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->name().data(), this->name().length(),
+            this->name().data(), static_cast<int>(this->name().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.Option.name"));
         } else {
@@ -3622,7 +3638,7 @@
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Option.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -3651,7 +3667,7 @@
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->name().data(), this->name().length(),
+      this->name().data(), static_cast<int>(this->name().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.Option.name");
     target =
diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h
index 002ea8e..beb4c9e 100644
--- a/src/google/protobuf/unknown_field_set.h
+++ b/src/google/protobuf/unknown_field_set.h
@@ -282,10 +282,10 @@
 }
 inline const UnknownField& UnknownFieldSet::field(int index) const {
   GOOGLE_DCHECK(fields_ != NULL);
-  return (*fields_)[index];
+  return (*fields_)[static_cast<size_t>(index)];
 }
 inline UnknownField* UnknownFieldSet::mutable_field(int index) {
-  return &(*fields_)[index];
+  return &(*fields_)[static_cast<size_t>(index)];
 }
 
 inline void UnknownFieldSet::AddLengthDelimited(
@@ -296,7 +296,7 @@
 
 
 
-inline int UnknownField::number() const { return number_; }
+inline int UnknownField::number() const { return static_cast<int>(number_); }
 inline UnknownField::Type UnknownField::type() const {
   return static_cast<Type>(type_);
 }
diff --git a/src/google/protobuf/util/message_differencer.h b/src/google/protobuf/util/message_differencer.h
index fdbf04e..b7d4de0 100644
--- a/src/google/protobuf/util/message_differencer.h
+++ b/src/google/protobuf/util/message_differencer.h
@@ -241,18 +241,18 @@
     // mutually exclusive. If a field has been both moved and modified, then
     // only ReportModified will be called.
     virtual void ReportMoved(
-        const Message& message1,
-        const Message& message2,
-        const std::vector<SpecificField>& field_path) { }
+        const Message& /* message1 */,
+        const Message& /* message2 */,
+        const std::vector<SpecificField>& /* field_path */) { }
 
     // Reports that two fields match. Useful for doing side-by-side diffs.
     // This function is mutually exclusive with ReportModified and ReportMoved.
     // Note that you must call set_report_matches(true) before calling Compare
     // to make use of this function.
     virtual void ReportMatched(
-        const Message& message1,
-        const Message& message2,
-        const std::vector<SpecificField>& field_path) { }
+        const Message& /* message1 */,
+        const Message& /* message2 */,
+        const std::vector<SpecificField>& /* field_path */) { }
 
     // Reports that two fields would have been compared, but the
     // comparison has been skipped because the field was marked as
@@ -274,16 +274,16 @@
     // the fields are equal or not (perhaps with a second call to
     // Compare()), if it cares.
     virtual void ReportIgnored(
-        const Message& message1,
-        const Message& message2,
-        const std::vector<SpecificField>& field_path) { }
+        const Message& /* message1 */,
+        const Message& /* message2 */,
+        const std::vector<SpecificField>& /* field_path */) { }
 
     // Report that an unknown field is ignored. (see comment above).
     // Note this is a different function since the last SpecificField in field
     // path has a null field.  This could break existing Reporter.
     virtual void ReportUnknownFieldIgnored(
-        const Message& message1, const Message& message2,
-        const std::vector<SpecificField>& field_path) {}
+        const Message& /* message1 */, const Message& /* message2 */,
+        const std::vector<SpecificField>& /* field_path */) {}
 
    private:
     GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reporter);
@@ -297,9 +297,9 @@
     virtual ~MapKeyComparator();
 
     virtual bool IsMatch(
-        const Message& message1,
-        const Message& message2,
-        const std::vector<SpecificField>& parent_fields) const {
+        const Message& /* message1 */,
+        const Message& /* message2 */,
+        const std::vector<SpecificField>& /* parent_fields */) const {
       GOOGLE_CHECK(false) << "IsMatch() is not implemented.";
       return false;
     }
@@ -321,18 +321,18 @@
 
     // Returns true if the field should be ignored.
     virtual bool IsIgnored(
-        const Message& message1,
-        const Message& message2,
-        const FieldDescriptor* field,
-        const std::vector<SpecificField>& parent_fields) = 0;
+        const Message& /* message1 */,
+        const Message& /* message2 */,
+        const FieldDescriptor* /* field */,
+        const std::vector<SpecificField>& /* parent_fields */) = 0;
 
     // Returns true if the unknown field should be ignored.
     // Note: This will be called for unknown fields as well in which case
     //       field.field will be null.
     virtual bool IsUnknownFieldIgnored(
-        const Message& message1, const Message& message2,
-        const SpecificField& field,
-        const std::vector<SpecificField>& parent_fields) {
+        const Message& /* message1 */, const Message& /* message2 */,
+        const SpecificField& /* field */,
+        const std::vector<SpecificField>& /* parent_fields */) {
       return false;
     }
   };
diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h
index 346d5b2..3e079ea 100644
--- a/src/google/protobuf/wire_format_lite.h
+++ b/src/google/protobuf/wire_format_lite.h
@@ -202,7 +202,7 @@
 // type-safe, though, so prefer it if possible.
 #define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE)                  \
   static_cast<uint32>(                                                   \
-    ((FIELD_NUMBER) << ::google::protobuf::internal::WireFormatLite::kTagTypeBits) \
+    (static_cast<uint32>(FIELD_NUMBER) << ::google::protobuf::internal::WireFormatLite::kTagTypeBits) \
       | (TYPE))
 
   // These are the tags for the old MessageSet format, which was defined as:
@@ -792,7 +792,7 @@
 inline size_t WireFormatLite::TagSize(int field_number,
                                       WireFormatLite::FieldType type) {
   size_t result = io::CodedOutputStream::VarintSize32(
-    field_number << kTagTypeBits);
+    static_cast<uint32>(field_number << kTagTypeBits));
   if (type == TYPE_GROUP) {
     // Groups have both a start and an end tag.
     return result * 2;
@@ -851,20 +851,20 @@
 
 inline uint32 WireFormatLite::ZigZagEncode32(int32 n) {
   // Note:  the right-shift must be arithmetic
-  return (static_cast<uint32>(n) << 1) ^ (n >> 31);
+  return static_cast<uint32>((n << 1) ^ (n >> 31));
 }
 
 inline int32 WireFormatLite::ZigZagDecode32(uint32 n) {
-  return (n >> 1) ^ -static_cast<int32>(n & 1);
+  return static_cast<int32>(n >> 1) ^ -static_cast<int32>(n & 1);
 }
 
 inline uint64 WireFormatLite::ZigZagEncode64(int64 n) {
   // Note:  the right-shift must be arithmetic
-  return (static_cast<uint64>(n) << 1) ^ (n >> 63);
+  return static_cast<uint64>((n << 1) ^ (n >> 63));
 }
 
 inline int64 WireFormatLite::ZigZagDecode64(uint64 n) {
-  return (n >> 1) ^ -static_cast<int64>(n & 1);
+  return static_cast<int64>(n >> 1) ^ -static_cast<int64>(n & 1);
 }
 
 // String is for UTF-8 text only, but, even so, ReadString() can simply
diff --git a/src/google/protobuf/wire_format_lite_inl.h b/src/google/protobuf/wire_format_lite_inl.h
index 0504901..c044def 100644
--- a/src/google/protobuf/wire_format_lite_inl.h
+++ b/src/google/protobuf/wire_format_lite_inl.h
@@ -268,7 +268,7 @@
   if (size > 0) {
     const uint8* buffer = reinterpret_cast<const uint8*>(void_pointer);
     // The number of bytes each type occupies on the wire.
-    const int per_value_size = tag_size + sizeof(value);
+    const int per_value_size = tag_size + static_cast<int>(sizeof(value));
 
     // parentheses around (std::min) prevents macro expansion of min(...)
     int elements_available =
@@ -344,8 +344,8 @@
   int length;
   if (!input->ReadVarintSizeAsInt(&length)) return false;
   const int old_entries = values->size();
-  const int new_entries = length / sizeof(CType);
-  const int new_bytes = new_entries * sizeof(CType);
+  const int new_entries = length / static_cast<int>(sizeof(CType));
+  const int new_bytes = new_entries * static_cast<int>(sizeof(CType));
   if (new_bytes != length) return false;
   // We would *like* to pre-allocate the buffer to write into (for
   // speed), but *must* avoid performing a very large allocation due
@@ -695,8 +695,8 @@
   GOOGLE_DCHECK_GT(n, 0);
 
   const T* ii = value.unsafe_data();
-  const int bytes = n * sizeof(ii[0]);
-  memcpy(target, ii, bytes);
+  const int bytes = n * static_cast<int>(sizeof(ii[0]));
+  memcpy(target, ii, static_cast<size_t>(bytes));
   return target + bytes;
 #else
   return WritePrimitiveNoTagToArray(value, Writer, target);
@@ -954,7 +954,7 @@
     uint8* target) {
   target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
   target = io::CodedOutputStream::WriteVarint32ToArray(
-    value.GetCachedSize(), target);
+    static_cast<uint32>(value.GetCachedSize()), target);
   return value.InternalSerializeWithCachedSizesToArray(deterministic, target);
 }
 
@@ -975,7 +975,9 @@
     bool deterministic, uint8* target) {
   target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
   target = io::CodedOutputStream::WriteVarint32ToArray(
-    value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target);
+        static_cast<uint32>(
+            value.MessageType_WorkAroundCppLookupDefect::GetCachedSize()),
+        target);
   return value.MessageType_WorkAroundCppLookupDefect::
       InternalSerializeWithCachedSizesToArray(deterministic, target);
 }
diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc
index 67d0440..b1db6e9 100644
--- a/src/google/protobuf/wrappers.pb.cc
+++ b/src/google/protobuf/wrappers.pb.cc
@@ -2315,7 +2315,7 @@
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_value()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-            this->value().data(), this->value().length(),
+            this->value().data(), static_cast<int>(this->value().length()),
             ::google::protobuf::internal::WireFormatLite::PARSE,
             "google.protobuf.StringValue.value"));
         } else {
@@ -2353,7 +2353,7 @@
   // string value = 1;
   if (this->value().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->value().data(), this->value().length(),
+      this->value().data(), static_cast<int>(this->value().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.StringValue.value");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
@@ -2376,7 +2376,7 @@
   // string value = 1;
   if (this->value().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
-      this->value().data(), this->value().length(),
+      this->value().data(), static_cast<int>(this->value().length()),
       ::google::protobuf::internal::WireFormatLite::SERIALIZE,
       "google.protobuf.StringValue.value");
     target =
diff --git a/tests.sh b/tests.sh
index edb37da..c458584 100755
--- a/tests.sh
+++ b/tests.sh
@@ -93,30 +93,17 @@
   internal_build_cpp
   NUGET=/usr/local/bin/nuget.exe
 
-  if [ "$TRAVIS" == "true" ]; then
-    # Install latest version of Mono
-    sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
-    sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1397BC53640DB551
-    echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list
-    sudo apt-get update -qq
-    sudo apt-get install -qq mono-devel referenceassemblies-pcl nunit
-
-    # Then install the dotnet SDK as per Ubuntu 14.04 instructions on dot.net.
-    sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list'
-    sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893
-    sudo apt-get update -qq
-    sudo apt-get install -qq dotnet-dev-1.0.0-preview2-003121
-  fi
-
   # Perform "dotnet new" once to get the setup preprocessing out of the
   # way. That spews a lot of output (including backspaces) into logs
   # otherwise, and can cause problems. It doesn't matter if this step
   # is performed multiple times; it's cheap after the first time anyway.
+  # (It also doesn't matter if it's unnecessary, which it will be on some
+  # systems. It's necessary on Jenkins in order to avoid unprintable
+  # characters appearing in the JUnit output.)
   mkdir dotnettmp
   (cd dotnettmp; dotnet new > /dev/null)
   rm -rf dotnettmp
 
-  (cd csharp/src; dotnet restore)
   csharp/buildall.sh
   cd conformance && make test_csharp && cd ..
 
@@ -359,7 +346,7 @@
   # Generate test file
   rm -rf generated
   mkdir generated
-  ../../src/protoc --php_out=generated proto/test.proto proto/test_include.proto proto/test_no_namespace.proto proto/test_prefix.proto
+  ../../src/protoc --php_out=generated proto/test.proto proto/test_include.proto proto/test_no_namespace.proto proto/test_prefix.proto proto/test_php_namespace.proto proto/test_empty_php_namespace.proto proto/test_service.proto proto/test_service_namespace.proto
   pushd ../../src
   ./protoc --php_out=../php/tests/generated google/protobuf/empty.proto
   ./protoc --php_out=../php/tests/generated -I../php/tests -I. ../php/tests/proto/test_import_descriptor_proto.proto
@@ -410,27 +397,30 @@
   phpunit
   popd
   pushd conformance
-  # TODO(teboring): Add it back
-  # make test_php
+  make test_php
   popd
 }
 
 build_php5.5_c() {
   use_php 5.5
   wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit
-  cd php/tests && /bin/bash ./test.sh && cd ../..
-  pushd conformance
-  # make test_php_c
+  pushd php/tests
+  /bin/bash ./test.sh
   popd
+  # TODO(teboring): Add it back
+  # pushd conformance
+  # make test_php_c
+  # popd
 }
 
 build_php5.5_zts_c() {
   use_php_zts 5.5
   wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh && cd ../..
-  pushd conformance
-  # make test_php_c
-  popd
+  # TODO(teboring): Add it back
+  # pushd conformance
+  # make test_php_zts_c
+  # popd
 }
 
 build_php5.6() {
@@ -442,8 +432,7 @@
   phpunit
   popd
   pushd conformance
-  # TODO(teboring): Add it back
-  # make test_php
+  make test_php
   popd
 }
 
@@ -451,18 +440,20 @@
   use_php 5.6
   wget https://phar.phpunit.de/phpunit-5.7.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh && cd ../..
-  pushd conformance
+  # TODO(teboring): Add it back
+  # pushd conformance
   # make test_php_c
-  popd
+  # popd
 }
 
 build_php5.6_zts_c() {
   use_php_zts 5.6
   wget https://phar.phpunit.de/phpunit-5.7.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh && cd ../..
-  pushd conformance
-  # make test_php_c
-  popd
+  # TODO(teboring): Add it back
+  # pushd conformance
+  # make test_php_zts_c
+  # popd
 }
 
 build_php5.6_mac() {
@@ -484,9 +475,10 @@
 
   # Test
   cd php/tests && /bin/bash ./test.sh && cd ../..
-  pushd conformance
+  # TODO(teboring): Add it back
+  # pushd conformance
   # make test_php_c
-  popd
+  # popd
 }
 
 build_php7.0() {
@@ -498,8 +490,7 @@
   phpunit
   popd
   pushd conformance
-  # TODO(teboring): Add it back
-  # make test_php
+  make test_php
   popd
 }
 
@@ -507,18 +498,20 @@
   use_php 7.0
   wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh && cd ../..
-  pushd conformance
+  # TODO(teboring): Add it back
+  # pushd conformance
   # make test_php_c
-  popd
+  # popd
 }
 
 build_php7.0_zts_c() {
   use_php_zts 7.0
   wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh && cd ../..
-  pushd conformance
-  # make test_php_c
-  popd
+  # TODO(teboring): Add it back.
+  # pushd conformance
+  # make test_php_zts_c
+  # popd
 }
 
 build_php7.0_mac() {
@@ -540,12 +533,18 @@
 
   # Test
   cd php/tests && /bin/bash ./test.sh && cd ../..
-  pushd conformance
+  # TODO(teboring): Add it back
+  # pushd conformance
   # make test_php_c
-  popd
+  # popd
 }
 
-build_php_all() {
+build_php_compatibility() {
+  internal_build_cpp
+  php/tests/compatibility_test.sh
+}
+
+build_php_all_32() {
   build_php5.5
   build_php5.6
   build_php7.0
@@ -557,6 +556,11 @@
   build_php7.0_zts_c
 }
 
+build_php_all() {
+  build_php_all_32
+  build_php_compatibility
+}
+
 # Note: travis currently does not support testing more than one language so the
 # .travis.yml cheats and claims to only be cpp.  If they add multiple language
 # support, this should probably get updated to install steps and/or
@@ -595,6 +599,7 @@
             php5.6_c |
             php7.0   |
             php7.0_c |
+            php_compatibility |
             php_all)
 "
   exit 1