Sync from Piper @327110949

PROTOBUF_SYNC_PIPER
diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml
new file mode 100644
index 0000000..d853702
--- /dev/null
+++ b/.github/workflows/codespell.yml
@@ -0,0 +1,16 @@
+# GitHub Action to automate the identification of common misspellings in text files.
+# https://github.com/codespell-project/actions-codespell
+# https://github.com/codespell-project/codespell
+name: codespell
+on: [push, pull_request]
+jobs:
+  codespell:
+    name: Check for spelling errors
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: codespell-project/actions-codespell@master
+        with:
+          check_filenames: true
+          skip: ./.git,./conformance/third_party,*.snk,*.pb,./src/google/protobuf/testdata,./objectivec/Tests,./python/compatibility_tests/v2.5.0/tests/google/protobuf/internal
+          ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,fo,fundementals,hel,importd,inout,leapyear,nd,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od"
diff --git a/.gitignore b/.gitignore
index a7349c2..e06aede 100644
--- a/.gitignore
+++ b/.gitignore
@@ -104,7 +104,7 @@
 # needed to trigger "pod install" to rerun the preinstall commands.
 Pods/
 
-# Comformance test output
+# Conformance test output
 conformance/.libs/
 conformance/com/
 conformance/conformance-cpp
@@ -137,19 +137,24 @@
 
 # php test output
 composer.lock
+php/tests/.phpunit.result.cache
 php/tests/generated/
 php/tests/old_protoc
+php/tests/phpunit-9.phar
 php/tests/protobuf/
 php/tests/core
 php/tests/vgcore*
 php/tests/multirequest.result
 php/tests/nohup.out
+php/tests/.phpunit.result.cache
+php/tests/phpunit-*
 php/ext/google/protobuf/.libs/
 php/ext/google/protobuf/Makefile.fragments
 php/ext/google/protobuf/Makefile.global
 php/ext/google/protobuf/Makefile.objects
 php/ext/google/protobuf/acinclude.m4
 php/ext/google/protobuf/build/
+php/ext/google/protobuf/bundled_php.c
 php/ext/google/protobuf/config.h
 php/ext/google/protobuf/config.h.in~
 php/ext/google/protobuf/config.nice
diff --git a/BUILD b/BUILD
index 224c8fc..f3fd3f4 100644
--- a/BUILD
+++ b/BUILD
@@ -954,96 +954,13 @@
 
 alias(
     name = "objectivec",
-    actual = ":protobuf_objc",
+    actual = "//objectivec",
     visibility = ["//visibility:public"],
 )
 
-objc_library(
+alias(
     name = "protobuf_objc",
-    hdrs = [
-        "objectivec/GPBAny.pbobjc.h",
-        "objectivec/GPBApi.pbobjc.h",
-        "objectivec/GPBDuration.pbobjc.h",
-        "objectivec/GPBEmpty.pbobjc.h",
-        "objectivec/GPBFieldMask.pbobjc.h",
-        "objectivec/GPBSourceContext.pbobjc.h",
-        "objectivec/GPBStruct.pbobjc.h",
-        "objectivec/GPBTimestamp.pbobjc.h",
-        "objectivec/GPBType.pbobjc.h",
-        "objectivec/GPBWrappers.pbobjc.h",
-        "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",
-        # Package private headers, but exposed because the generated sources
-        # need to use them.
-        "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",
-    ],
-    copts = [
-        "-Wno-vla",
-    ],
-    includes = [
-        "objectivec",
-    ],
-    non_arc_srcs = [
-        "objectivec/GPBAny.pbobjc.m",
-        "objectivec/GPBApi.pbobjc.m",
-        "objectivec/GPBDuration.pbobjc.m",
-        "objectivec/GPBEmpty.pbobjc.m",
-        "objectivec/GPBFieldMask.pbobjc.m",
-        "objectivec/GPBSourceContext.pbobjc.m",
-        "objectivec/GPBStruct.pbobjc.m",
-        "objectivec/GPBTimestamp.pbobjc.m",
-        "objectivec/GPBType.pbobjc.m",
-        "objectivec/GPBWrappers.pbobjc.m",
-        "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",
-    ],
+    actual = "//objectivec",
     visibility = ["//visibility:public"],
 )
 
diff --git a/CHANGES.txt b/CHANGES.txt
index 6d77428..76910c4 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,4 @@
-Unreleased Changes
+2020-07-14 version 3.13.0-rc1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
 
   C++:
   * Removed deprecated unsafe arena string accessors
@@ -37,10 +37,19 @@
     type internally. (#7351)
   * Add `ParseFrom(ReadOnlySequence<byte>)` method to enable GC friendly
     parsing with reduced allocations and buffer copies. (#7351)
+  * Add support for serialization directly to a `IBufferWriter<byte>` or
+    to a `Span<byte>` to enable GC friendly serialization.
+    The new API is available as extension methods on the `IMessage` type. (#7576)
   * Add `GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE` define to make
     generated code compatible with old C# compilers (pre-roslyn compilers
     from .NET framework and old versions of mono) that do not support
-    ref structs. (#7490)
+    ref structs. Users that are still on a legacy stack that does
+    not support C# 7.2 compiler might need to use the new define
+    in their projects to be able to build the newly generated code. (#7490)
+  * Due to the major overhaul of parsing and serialization internals (#7351 and #7576),
+    it is recommended to regenerate your generated code to achieve the best
+    performance (the legacy generated code will still work, but might incur
+    a slight performance penalty).
 
 2020-06-01 version 3.12.3 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
 
diff --git a/Protobuf.podspec b/Protobuf.podspec
index 3b7a716..22e7ce3 100644
--- a/Protobuf.podspec
+++ b/Protobuf.podspec
@@ -5,7 +5,7 @@
 # dependent projects use the :git notation to refer to the library.
 Pod::Spec.new do |s|
   s.name     = 'Protobuf'
-  s.version  = '3.12.3'
+  s.version  = '3.13.0'
   s.summary  = 'Protocol Buffers v.3 runtime library for Objective-C.'
   s.homepage = 'https://github.com/protocolbuffers/protobuf'
   s.license  = '3-Clause BSD License'
diff --git a/cmake/libprotobuf-lite.cmake b/cmake/libprotobuf-lite.cmake
index 6bf86a2..bbba607 100644
--- a/cmake/libprotobuf-lite.cmake
+++ b/cmake/libprotobuf-lite.cmake
@@ -12,6 +12,7 @@
   ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream.cc
   ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_impl.cc
   ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
+  ${protobuf_source_dir}/src/google/protobuf/map.cc
   ${protobuf_source_dir}/src/google/protobuf/message_lite.cc
   ${protobuf_source_dir}/src/google/protobuf/parse_context.cc
   ${protobuf_source_dir}/src/google/protobuf/repeated_field.cc
diff --git a/conformance/failure_list_php.txt b/conformance/failure_list_php.txt
index 1c7f92b..d51a75d 100644
--- a/conformance/failure_list_php.txt
+++ b/conformance/failure_list_php.txt
@@ -6,62 +6,6 @@
 Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput
 Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
 Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.Merge.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput
 Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator
 Required.Proto3.JsonInput.DoubleFieldTooSmall
 Required.Proto3.JsonInput.FloatFieldTooLarge
diff --git a/conformance/failure_list_php_c.txt b/conformance/failure_list_php_c.txt
index cfed9f6..63c7e8a 100644
--- a/conformance/failure_list_php_c.txt
+++ b/conformance/failure_list_php_c.txt
@@ -1,58 +1,2 @@
 Recommended.Proto2.JsonInput.FieldNameExtension.Validator
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput
 Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator
diff --git a/conformance/failure_list_php_c_32.txt b/conformance/failure_list_php_c_32.txt
index cfed9f6..63c7e8a 100644
--- a/conformance/failure_list_php_c_32.txt
+++ b/conformance/failure_list_php_c_32.txt
@@ -1,58 +1,2 @@
 Recommended.Proto2.JsonInput.FieldNameExtension.Validator
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput
-Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput
 Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator
diff --git a/conformance/third_party/jsoncpp/json.h b/conformance/third_party/jsoncpp/json.h
index 5639c92..373ec98 100644
--- a/conformance/third_party/jsoncpp/json.h
+++ b/conformance/third_party/jsoncpp/json.h
@@ -1371,7 +1371,7 @@
    */
   std::string getFormattedErrorMessages() const;
 
-  /** \brief Returns a vector of structured errors encounted while parsing.
+  /** \brief Returns a vector of structured errors encountered while parsing.
    * \return A (possibly empty) vector of StructuredError objects. Currently
    *         only one error can be returned, but the caller should tolerate
    * multiple
@@ -1867,7 +1867,7 @@
  *     - otherwise, it the values do not fit on one line, or the array contains
  *       object or non empty array, then print one value per line.
  *
- * If the Value have comments then they are outputed according to their
+ * If the Value have comments then they are outputted according to their
  *#CommentPlacement.
  *
  * \sa Reader, Value, Value::setComment()
@@ -1928,7 +1928,7 @@
  *     - otherwise, it the values do not fit on one line, or the array contains
  *       object or non empty array, then print one value per line.
  *
- * If the Value have comments then they are outputed according to their
+ * If the Value have comments then they are outputted according to their
  #CommentPlacement.
  *
  * \param indentation Each level will be indented by this amount extra.
diff --git a/conformance/third_party/jsoncpp/jsoncpp.cpp b/conformance/third_party/jsoncpp/jsoncpp.cpp
index d313d05..78919ea 100644
--- a/conformance/third_party/jsoncpp/jsoncpp.cpp
+++ b/conformance/third_party/jsoncpp/jsoncpp.cpp
@@ -142,7 +142,7 @@
 typedef char UIntToStringBuffer[uintToStringBufferSize];
 
 /** Converts an unsigned integer to string.
- * @param value Unsigned interger to convert to string
+ * @param value Unsigned integer to convert to string
  * @param current Input/Output string buffer.
  *        Must have at least uintToStringBufferSize chars free.
  */
diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec
index d0c088f..019f054 100644
--- a/csharp/Google.Protobuf.Tools.nuspec
+++ b/csharp/Google.Protobuf.Tools.nuspec
@@ -5,7 +5,7 @@
     <title>Google Protocol Buffers tools</title>
     <summary>Tools for Protocol Buffers - Google's data interchange format.</summary>
     <description>See project site for more info.</description>
-    <version>3.12.3</version>
+    <version>3.13.0</version>
     <authors>Google Inc.</authors>
     <owners>protobuf-packages</owners>
     <licenseUrl>https://github.com/protocolbuffers/protobuf/blob/master/LICENSE</licenseUrl>
diff --git a/csharp/generate_protos.sh b/csharp/generate_protos.sh
index 49a5a42..b663138 100755
--- a/csharp/generate_protos.sh
+++ b/csharp/generate_protos.sh
@@ -45,6 +45,7 @@
 # and old_extensions2.proto, which are generated with an older version
 # of protoc.
 $PROTOC -Isrc -Icsharp/protos \
+    --experimental_allow_proto3_optional \
     --csharp_out=csharp/src/Google.Protobuf.Test.TestProtos \
     --descriptor_set_out=csharp/src/Google.Protobuf.Test/testprotos.pb \
     --include_source_info \
diff --git a/csharp/protos/unittest_issues.proto b/csharp/protos/unittest_issues.proto
index ef40d75..388998f 100644
--- a/csharp/protos/unittest_issues.proto
+++ b/csharp/protos/unittest_issues.proto
@@ -151,3 +151,8 @@
 message NullValueNotInOneof {
   google.protobuf.NullValue null_value = 2;
 }
+
+message MixedRegularAndOptional {
+  string regular_field = 1;
+  optional string optional_field = 2;
+}
diff --git a/csharp/src/AddressBook/Program.cs b/csharp/src/AddressBook/Program.cs
index ff7b9c0..de4867a 100644
--- a/csharp/src/AddressBook/Program.cs
+++ b/csharp/src/AddressBook/Program.cs
@@ -37,7 +37,7 @@
     /// <summary>

     /// Entry point. Repeatedly prompts user for an action to take, delegating actual behaviour

     /// to individual actions. Each action has its own Main method, so that it can be used as an

-    /// invidual complete program.

+    /// individual complete program.

     /// </summary>

     internal class Program

     {

diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssues.cs b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssues.cs
index e09191a..4377cf3 100644
--- a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssues.cs
+++ b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssues.cs
@@ -52,11 +52,13 @@
             "bmdfdmFsdWUYASABKAlIABIwCgpudWxsX3ZhbHVlGAIgASgOMhouZ29vZ2xl",
             "LnByb3RvYnVmLk51bGxWYWx1ZUgAQgcKBXZhbHVlIkUKE051bGxWYWx1ZU5v",
             "dEluT25lb2YSLgoKbnVsbF92YWx1ZRgCIAEoDjIaLmdvb2dsZS5wcm90b2J1",
-            "Zi5OdWxsVmFsdWUqVQoMTmVnYXRpdmVFbnVtEhYKEk5FR0FUSVZFX0VOVU1f",
-            "WkVSTxAAEhYKCUZpdmVCZWxvdxD7//////////8BEhUKCE1pbnVzT25lEP//",
-            "/////////wEqLgoORGVwcmVjYXRlZEVudW0SEwoPREVQUkVDQVRFRF9aRVJP",
-            "EAASBwoDb25lEAFCHaoCGlVuaXRUZXN0Lklzc3Vlcy5UZXN0UHJvdG9zYgZw",
-            "cm90bzM="));
+            "Zi5OdWxsVmFsdWUiYAoXTWl4ZWRSZWd1bGFyQW5kT3B0aW9uYWwSFQoNcmVn",
+            "dWxhcl9maWVsZBgBIAEoCRIbCg5vcHRpb25hbF9maWVsZBgCIAEoCUgAiAEB",
+            "QhEKD19vcHRpb25hbF9maWVsZCpVCgxOZWdhdGl2ZUVudW0SFgoSTkVHQVRJ",
+            "VkVfRU5VTV9aRVJPEAASFgoJRml2ZUJlbG93EPv//////////wESFQoITWlu",
+            "dXNPbmUQ////////////ASouCg5EZXByZWNhdGVkRW51bRITCg9ERVBSRUNB",
+            "VEVEX1pFUk8QABIHCgNvbmUQAUIdqgIaVW5pdFRlc3QuSXNzdWVzLlRlc3RQ",
+            "cm90b3NiBnByb3RvMw=="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, },
           new pbr::GeneratedClrTypeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.NegativeEnum), typeof(global::UnitTest.Issues.TestProtos.DeprecatedEnum), }, null, new pbr::GeneratedClrTypeInfo[] {
@@ -70,7 +72,8 @@
             new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonName), global::UnitTest.Issues.TestProtos.TestJsonName.Parser, new[]{ "Name", "Description", "Guid" }, null, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging), global::UnitTest.Issues.TestProtos.OneofMerging.Parser, new[]{ "Text", "Nested" }, new[]{ "Value" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested), global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested.Parser, new[]{ "X", "Y" }, null, null, null, null)}),
             new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NullValueOutsideStruct), global::UnitTest.Issues.TestProtos.NullValueOutsideStruct.Parser, new[]{ "StringValue", "NullValue" }, new[]{ "Value" }, null, null, null),
-            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NullValueNotInOneof), global::UnitTest.Issues.TestProtos.NullValueNotInOneof.Parser, new[]{ "NullValue" }, null, null, null, null)
+            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NullValueNotInOneof), global::UnitTest.Issues.TestProtos.NullValueNotInOneof.Parser, new[]{ "NullValue" }, null, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.MixedRegularAndOptional), global::UnitTest.Issues.TestProtos.MixedRegularAndOptional.Parser, new[]{ "RegularField", "OptionalField" }, new[]{ "OptionalField" }, null, null, null)
           }));
     }
     #endregion
@@ -3304,6 +3307,224 @@
 
   }
 
+  public sealed partial class MixedRegularAndOptional : pb::IMessage<MixedRegularAndOptional>
+  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+      , pb::IBufferMessage
+  #endif
+  {
+    private static readonly pb::MessageParser<MixedRegularAndOptional> _parser = new pb::MessageParser<MixedRegularAndOptional>(() => new MixedRegularAndOptional());
+    private pb::UnknownFieldSet _unknownFields;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<MixedRegularAndOptional> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[11]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public MixedRegularAndOptional() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public MixedRegularAndOptional(MixedRegularAndOptional other) : this() {
+      regularField_ = other.regularField_;
+      optionalField_ = other.optionalField_;
+      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public MixedRegularAndOptional Clone() {
+      return new MixedRegularAndOptional(this);
+    }
+
+    /// <summary>Field number for the "regular_field" field.</summary>
+    public const int RegularFieldFieldNumber = 1;
+    private string regularField_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string RegularField {
+      get { return regularField_; }
+      set {
+        regularField_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "optional_field" field.</summary>
+    public const int OptionalFieldFieldNumber = 2;
+    private string optionalField_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string OptionalField {
+      get { return optionalField_ ?? ""; }
+      set {
+        optionalField_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+    /// <summary>Gets whether the "optional_field" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalField {
+      get { return optionalField_ != null; }
+    }
+    /// <summary>Clears the value of the "optional_field" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalField() {
+      optionalField_ = null;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as MixedRegularAndOptional);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(MixedRegularAndOptional other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (RegularField != other.RegularField) return false;
+      if (OptionalField != other.OptionalField) return false;
+      return Equals(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (RegularField.Length != 0) hash ^= RegularField.GetHashCode();
+      if (HasOptionalField) hash ^= OptionalField.GetHashCode();
+      if (_unknownFields != null) {
+        hash ^= _unknownFields.GetHashCode();
+      }
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+      output.WriteRawMessage(this);
+    #else
+      if (RegularField.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(RegularField);
+      }
+      if (HasOptionalField) {
+        output.WriteRawTag(18);
+        output.WriteString(OptionalField);
+      }
+      if (_unknownFields != null) {
+        _unknownFields.WriteTo(output);
+      }
+    #endif
+    }
+
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
+      if (RegularField.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(RegularField);
+      }
+      if (HasOptionalField) {
+        output.WriteRawTag(18);
+        output.WriteString(OptionalField);
+      }
+      if (_unknownFields != null) {
+        _unknownFields.WriteTo(ref output);
+      }
+    }
+    #endif
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (RegularField.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(RegularField);
+      }
+      if (HasOptionalField) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(OptionalField);
+      }
+      if (_unknownFields != null) {
+        size += _unknownFields.CalculateSize();
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(MixedRegularAndOptional other) {
+      if (other == null) {
+        return;
+      }
+      if (other.RegularField.Length != 0) {
+        RegularField = other.RegularField;
+      }
+      if (other.HasOptionalField) {
+        OptionalField = other.OptionalField;
+      }
+      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+      input.ReadRawMessage(this);
+    #else
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+            break;
+          case 10: {
+            RegularField = input.ReadString();
+            break;
+          }
+          case 18: {
+            OptionalField = input.ReadString();
+            break;
+          }
+        }
+      }
+    #endif
+    }
+
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
+            break;
+          case 10: {
+            RegularField = input.ReadString();
+            break;
+          }
+          case 18: {
+            OptionalField = input.ReadString();
+            break;
+          }
+        }
+      }
+    }
+    #endif
+
+  }
+
   #endregion
 
 }
diff --git a/csharp/src/Google.Protobuf.Test/Buffers/ArrayBufferWriter.cs b/csharp/src/Google.Protobuf.Test/Buffers/ArrayBufferWriter.cs
index 8e42d13..5b9913b 100644
--- a/csharp/src/Google.Protobuf.Test/Buffers/ArrayBufferWriter.cs
+++ b/csharp/src/Google.Protobuf.Test/Buffers/ArrayBufferWriter.cs
@@ -60,7 +60,7 @@
         }
 
         /// <summary>
-        /// Userful for testing writing to buffer writer with a lot of small segments.
+        /// Useful for testing writing to buffer writer with a lot of small segments.
         /// If set, it limits the max number of bytes by which the buffer grows by at once.
         /// </summary>
         public int? MaxGrowBy { get; set; }
diff --git a/csharp/src/Google.Protobuf.Test/IssuesTest.cs b/csharp/src/Google.Protobuf.Test/IssuesTest.cs
index 941bce0..2904c46 100644
--- a/csharp/src/Google.Protobuf.Test/IssuesTest.cs
+++ b/csharp/src/Google.Protobuf.Test/IssuesTest.cs
@@ -108,7 +108,7 @@
 

             // we still must read the tag correctly, even though the tag is at the very end of our limited input

             // (which is a corner case and will most likely result in an error when trying to read value of the field

-            // decribed by this tag, but it would be a logical error not to read the tag that's actually present).

+            // described by this tag, but it would be a logical error not to read the tag that's actually present).

             // See https://github.com/protocolbuffers/protobuf/pull/7289

             cis.AssertNextTag(WireFormat.MakeTag(11, WireFormat.WireType.Varint));

         }

diff --git a/csharp/src/Google.Protobuf.Test/Proto3OptionalTest.cs b/csharp/src/Google.Protobuf.Test/Proto3OptionalTest.cs
index 20c1846..46a8c57 100644
--- a/csharp/src/Google.Protobuf.Test/Proto3OptionalTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Proto3OptionalTest.cs
@@ -34,6 +34,7 @@
 using ProtobufUnittest;
 using System;
 using System.IO;
+using UnitTest.Issues.TestProtos;
 
 namespace Google.Protobuf.Test
 {
@@ -139,5 +140,14 @@
             Assert.IsTrue(message1.Equals(message2));
             message1.ClearOptionalInt32();
         }
+
+        [Test]
+        public void MixedFields()
+        {
+            var descriptor = MixedRegularAndOptional.Descriptor;
+            Assert.AreEqual(1, descriptor.Oneofs.Count);
+            Assert.AreEqual(0, descriptor.RealOneofCount);
+            Assert.True(descriptor.Oneofs[0].IsSynthetic);
+        }
     }
 }
diff --git a/csharp/src/Google.Protobuf.Test/testprotos.pb b/csharp/src/Google.Protobuf.Test/testprotos.pb
index bde0dae..bae05e0 100644
--- a/csharp/src/Google.Protobuf.Test/testprotos.pb
+++ b/csharp/src/Google.Protobuf.Test/testprotos.pb
Binary files differ
diff --git a/csharp/src/Google.Protobuf/ByteString.cs b/csharp/src/Google.Protobuf/ByteString.cs
index 74dc865..2a52ae5 100644
--- a/csharp/src/Google.Protobuf/ByteString.cs
+++ b/csharp/src/Google.Protobuf/ByteString.cs
@@ -269,7 +269,7 @@
         }

 

         /// <summary>

-        /// Retuns the byte at the given index.

+        /// Returns the byte at the given index.

         /// </summary>

         public byte this[int index]

         {

diff --git a/csharp/src/Google.Protobuf/CodedInputStream.cs b/csharp/src/Google.Protobuf/CodedInputStream.cs
index 4050cbe..b09f96c 100644
--- a/csharp/src/Google.Protobuf/CodedInputStream.cs
+++ b/csharp/src/Google.Protobuf/CodedInputStream.cs
@@ -652,7 +652,7 @@
 

         /// <summary>

         /// Called when buffer is empty to read more bytes from the

-        /// input.  If <paramref name="mustSucceed"/> is true, RefillBuffer() gurantees that

+        /// input.  If <paramref name="mustSucceed"/> is true, RefillBuffer() guarantees that

         /// either there will be at least one byte in the buffer when it returns

         /// or it will throw an exception.  If <paramref name="mustSucceed"/> is false,

         /// RefillBuffer() returns false if no more bytes were available.

diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
index db86da5..082a398 100644
--- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj
+++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
@@ -4,8 +4,7 @@
     <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.12.2</VersionPrefix>
-    <VersionPrefix>3.12.3</VersionPrefix>
+    <VersionPrefix>3.13.0</VersionPrefix>
     <!-- C# 7.2 is required for Span/BufferWriter/ReadOnlySequence -->
     <LangVersion>7.2</LangVersion>
     <Authors>Google Inc.</Authors>
diff --git a/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs b/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs
index 4e040c1..7523426 100644
--- a/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs
@@ -63,7 +63,7 @@
         internal static OneofAccessor ForSyntheticOneof(OneofDescriptor descriptor)
         {
             // Note: descriptor.Fields will be null when this method is called, because we haven't
-            // cross-linked yet. But by the time the delgates are called by user code, all will be
+            // cross-linked yet. But by the time the delegates are called by user code, all will be
             // well. (That's why we capture the descriptor itself rather than a field.)
             return new OneofAccessor(descriptor,
                 message => descriptor.Fields[0].Accessor.HasValue(message) ? descriptor.Fields[0].FieldNumber : 0,
diff --git a/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs
index 0df4f53..b41d520 100644
--- a/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs
@@ -59,7 +59,7 @@
 
             // It's useful to determine whether or not this is a synthetic oneof before cross-linking. That means
             // diving into the proto directly rather than using FieldDescriptor, but that's okay.
-            var firstFieldInOneof = parent.Proto.Field.FirstOrDefault(fieldProto => fieldProto.OneofIndex == index);
+            var firstFieldInOneof = parent.Proto.Field.FirstOrDefault(fieldProto => fieldProto.HasOneofIndex && fieldProto.OneofIndex == index);
             IsSynthetic = firstFieldInOneof?.Proto3Optional ?? false;
 
             accessor = CreateAccessor(clrName);
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
index c75ef0f..2fb1b4d 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
@@ -91,7 +91,15 @@
   ///     Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
   ///         .setNanos((int) ((millis % 1000) * 1000000)).build();
   ///
-  /// Example 5: Compute Timestamp from current time in Python.
+  /// Example 5: Compute Timestamp from Java `Instant.now()`.
+  ///
+  ///     Instant now = Instant.now();
+  ///
+  ///     Timestamp timestamp =
+  ///         Timestamp.newBuilder().setSeconds(now.getEpochSecond())
+  ///             .setNanos(now.getNano()).build();
+  ///
+  /// Example 6: Compute Timestamp from current time in Python.
   ///
   ///     timestamp = Timestamp()
   ///     timestamp.GetCurrentTime()
diff --git a/docs/csharp/proto2.md b/docs/csharp/proto2.md
index 0d9159d..53fc43c 100644
--- a/docs/csharp/proto2.md
+++ b/docs/csharp/proto2.md
@@ -97,7 +97,7 @@
 
 ### Message initialization
 
-Initialization refers to checking the status of required fields in a proto2 message. If a message is uninitialized, not all required fields are set in either the message itself or any of its submessages. In other languages, missing required fields throw errors depending on the merge method used. This could cause unforseen errors at runtime if the incorrect method is used. 
+Initialization refers to checking the status of required fields in a proto2 message. If a message is uninitialized, not all required fields are set in either the message itself or any of its submessages. In other languages, missing required fields throw errors depending on the merge method used. This could cause unforeseen errors at runtime if the incorrect method is used. 
 However, in this implementation, parsers and input streams don't check messages for initialization on their own and throw errors. Instead it's up to you to handle messages with missing required fields in whatever way you see fit.
 Checking message initialization can be done manually via the `IsInitialized` extension method in `MessageExtensions`.
 
diff --git a/docs/field_presence.md b/docs/field_presence.md
index 4ce7785..dc16292 100644
--- a/docs/field_presence.md
+++ b/docs/field_presence.md
@@ -127,7 +127,7 @@
 
 ### Considerations for merging
 
-Under the _no presence_ rules, it is effectively impossible for a target field to merge-from its default value (using the protobuf's API merging functions). This is because default values are skipped, simliar to the _no presence_ serialization discipline. Merging only updates the target (merged-to) message using the non-skipped values from the update (merged-from) message.
+Under the _no presence_ rules, it is effectively impossible for a target field to merge-from its default value (using the protobuf's API merging functions). This is because default values are skipped, similar to the _no presence_ serialization discipline. Merging only updates the target (merged-to) message using the non-skipped values from the update (merged-from) message.
 
 The difference in merging behavior has further implications for protocols which rely on partial "patch" updates. If field presence is not tracked, then an update patch alone cannot represent an update to the default value, because only non-default values are merged-from.
 
diff --git a/docs/implementing_proto3_presence.md b/docs/implementing_proto3_presence.md
index fae2eb5..73f21a3 100644
--- a/docs/implementing_proto3_presence.md
+++ b/docs/implementing_proto3_presence.md
@@ -13,7 +13,7 @@
 updated already. However third-party code generators will need to be updated
 independently by their authors. This includes:
 
-- implementations of Protocol Buffers for other languges.
+- implementations of Protocol Buffers for other languages.
 - alternate implementations of Protocol Buffers that target specialized use
   cases.
 - RPC code generators that create generated APIs for service calls.
diff --git a/docs/options.md b/docs/options.md
index df6b88c..fd1e813 100644
--- a/docs/options.md
+++ b/docs/options.md
@@ -244,3 +244,7 @@
 1. ADLINK EdgeSDK
    * Website: https://www.adlinktech.com/en/Edge-SDK-IoT
    * Extensions: 1086
+
+1. Wire wire_package
+   * Website: https://square.github.io/wire/
+   * Extensions: 1087
diff --git a/docs/third_party.md b/docs/third_party.md
index c1726a0..b9c66c0 100644
--- a/docs/third_party.md
+++ b/docs/third_party.md
@@ -26,8 +26,8 @@
 * Clojure: http://github.com/ninjudd/clojure-protobuf
 * Clojure: https://github.com/clojusc/protobuf
 * Clojure: https://protojure.github.io
-* Common Lisp: http://github.com/ndantam/s-protobuf
 * Common Lisp: http://github.com/brown/protobuf
+* Common Lisp: http://github.com/qitab/cl-protobuf
 * D: https://github.com/dcarp/protobuf-d
 * D: https://github.com/msoucy/dproto
 * D: https://github.com/opticron/ProtocolBuffer
@@ -62,6 +62,8 @@
 * Javascript: https://github.com/dcodeIO/ProtoBuf.js
 * Javascript: http://code.google.com/p/protobuf-for-node/
 * Javascript: http://code.google.com/p/protostuff/
+* Javascript: https://github.com/seishun/node-protoc-plugin (Node.js port of plugin.h)
+* Javascript: https://github.com/seishun/node-protoc-gen-javascript (Node.js port of the Google-official implementation)
 * Julia: https://github.com/tanmaykm/ProtoBuf.jl
 * Kotlin: https://github.com/marcoferrer/kroto-plus
 * Kotlin: https://github.com/Kotlin/kotlinx.serialization
@@ -154,7 +156,7 @@
 * [Alternate encodings (JSON, XML, HTML) for Java protobufs](http://code.google.com/p/protobuf-java-format/)
 * [Another JSON encoder/decoder for Java](https://github.com/sijuv/protobuf-codec)
 * [Editor for serialized protobufs](http://code.google.com/p/protobufeditor/)
-* [Intellij IDEA plugin](http://github.com/nnmatveev/idea-plugin-protobuf)
+* [IntelliJ IDEA plugin](http://github.com/jvolkman/intellij-protobuf-editor)
 * [TextMate syntax highlighting](http://github.com/michaeledgar/protobuf-tmbundle)
 * [Oracle PL SQL plugin](http://code.google.com/p/protocol-buffer-plsql/)
 * [Eclipse editor for protobuf (from Google)](http://code.google.com/p/protobuf-dt/)
@@ -184,3 +186,9 @@
 * [Protocol Buffer property-based testing utility and example message generator (Python / Hypothesis)](https://github.com/CurataEng/hypothesis-protobuf)
 * [Protolock - CLI utility to prevent backward-incompatible changes to .proto files](https://github.com/nilslice/protolock)
 * [Optional GRPC - GRPC for testable microservices (Python)](https://github.com/mattpaletta/optional-grpc.git)
+* [Protobuf Parser - Yet another Go package which parses a Protocol Buffer file (proto2+proto3)](https://github.com/yoheimuta/go-protoparser)
+* [Protolint - A tool to enforce Protocol Buffer style and conventions.](https://github.com/yoheimuta/protolint)
+    * [vscode-protolint: A protobuf linter for visual studio code](https://github.com/plexsystems/vscode-protolint)
+    * [intellij-protolint: A protobuf linter for JetBrains IDEs](https://github.com/yoheimuta/intellij-protolint)
+    * [vim-protolint: A protobuf linter for Vim](https://github.com/yoheimuta/vim-protolint)
+* [super-linter: Protocol Buffer lint as GitHub Action](https://github.com/github/super-linter)
diff --git a/java/README.md b/java/README.md
index c4e8e20..dea9e76 100644
--- a/java/README.md
+++ b/java/README.md
@@ -47,7 +47,7 @@
 ```
     compile 'com.google.protobuf:protobuf-java:3.11.0'
 ```
-Again, be sure to check that the version number maches (or is newer than) the version number of protoc that you are using.
+Again, be sure to check that the version number matches (or is newer than) the version number of protoc that you are using.
 
 ### Use Java Protocol Buffers on Android
 
@@ -68,7 +68,7 @@
 
 Most users should follow the instructions above to use protobuf Java runtime.
 If you are contributing code to protobuf or want to use a protobuf version
-that hasn't been officially released yet, you can folllow the instructions
+that hasn't been officially released yet, you can follow the instructions
 below to build protobuf from source code.
 
 ### Build from Source - With Maven
diff --git a/java/bom/pom.xml b/java/bom/pom.xml
index ff2d106..3642783 100644
--- a/java/bom/pom.xml
+++ b/java/bom/pom.xml
@@ -4,7 +4,7 @@
 
   <groupId>com.google.protobuf</groupId>
   <artifactId>protobuf-bom</artifactId>
-  <version>3.12.3</version>
+  <version>3.13.0</version>
   <packaging>pom</packaging>
 
   <name>Protocol Buffers [BOM]</name>
diff --git a/java/core/pom.xml b/java/core/pom.xml
index b2b0b03..3509163 100644
--- a/java/core/pom.xml
+++ b/java/core/pom.xml
@@ -4,7 +4,7 @@
   <parent>
     <groupId>com.google.protobuf</groupId>
     <artifactId>protobuf-parent</artifactId>
-    <version>3.12.3</version>
+    <version>3.13.0</version>
   </parent>
 
   <artifactId>protobuf-java</artifactId>
diff --git a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
index 63dda6b..8beebba 100644
--- a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
+++ b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
@@ -328,20 +328,6 @@
       this.fields = FieldSet.newFieldSet();
       this.unknownFields = UnknownFieldSet.getDefaultInstance();
       this.oneofCases = new FieldDescriptor[type.toProto().getOneofDeclCount()];
-      // A MapEntry has all of its fields present at all times.
-      if (type.getOptions().getMapEntry()) {
-        populateMapEntry();
-      }
-    }
-
-    private void populateMapEntry() {
-      for (FieldDescriptor field : type.getFields()) {
-        if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
-          fields.setField(field, getDefaultInstance(field.getMessageType()));
-        } else {
-          fields.setField(field, field.getDefaultValue());
-        }
-      }
     }
 
     // ---------------------------------------------------------------
@@ -354,10 +340,6 @@
       } else {
         fields.clear();
       }
-      // A MapEntry has all of its fields present at all times.
-      if (type.getOptions().getMapEntry()) {
-        populateMapEntry();
-      }
       unknownFields = UnknownFieldSet.getDefaultInstance();
       return this;
     }
@@ -423,6 +405,19 @@
 
     @Override
     public DynamicMessage buildPartial() {
+      // Set default values for all fields in a MapEntry.
+      if (type.getOptions().getMapEntry()) {
+        for (FieldDescriptor field : type.getFields()) {
+          if (field.isOptional() && !fields.hasField(field)) {
+            if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+              fields.setField(field, getDefaultInstance(field.getMessageType()));
+            } else {
+              fields.setField(field, field.getDefaultValue());
+            }
+          }
+        }
+      }
+
       fields.makeImmutable();
       DynamicMessage result =
           new DynamicMessage(
diff --git a/java/core/src/main/java/com/google/protobuf/MessageSchema.java b/java/core/src/main/java/com/google/protobuf/MessageSchema.java
index 139e55a..28879d7 100644
--- a/java/core/src/main/java/com/google/protobuf/MessageSchema.java
+++ b/java/core/src/main/java/com/google/protobuf/MessageSchema.java
@@ -1402,8 +1402,10 @@
     if (!isOneofPresent(other, number, pos)) {
       return;
     }
-
-    Object mine = UnsafeUtil.getObject(message, offset);
+    Object mine = null;
+    if (isOneofPresent(message, number, pos)) {
+      mine = UnsafeUtil.getObject(message, offset);
+    }
     Object theirs = UnsafeUtil.getObject(other, offset);
     if (mine != null && theirs != null) {
       Object merged = Internal.mergeMessage(mine, theirs);
diff --git a/java/core/src/main/java/com/google/protobuf/TextFormat.java b/java/core/src/main/java/com/google/protobuf/TextFormat.java
index bec9623..7f744dd 100644
--- a/java/core/src/main/java/com/google/protobuf/TextFormat.java
+++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java
@@ -1661,7 +1661,7 @@
         throws IOException {
       // Read the entire input to a String then parse that.
 
-      // If StreamTokenizer were not quite so crippled, or if there were a kind
+      // If StreamTokenizer was not so limited, or if there were a kind
       // of Reader that could read in chunks that match some particular regex,
       // or if we wanted to write a custom Reader to tokenize our stream, then
       // we would not have to read to one big String.  Alas, none of these is
diff --git a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
index a9a884e..e229fac 100644
--- a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
+++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
@@ -1478,11 +1478,23 @@
       // With overwrite forbidden, same behavior.
       // TODO(b/29122459): Expect parse exception here.
       TestMap.Builder builder = TestMap.newBuilder();
-      defaultParser.merge(text, builder);
+      parserWithOverwriteForbidden.merge(text, builder);
       TestMap map = builder.build();
       assertEquals(2, map.getInt32ToInt32Field().size());
       assertEquals(30, map.getInt32ToInt32Field().get(1).intValue());
     }
+
+    {
+      // With overwrite forbidden and a dynamic message, same behavior.
+      // TODO(b/29122459): Expect parse exception here.
+      Message.Builder builder = DynamicMessage.newBuilder(TestMap.getDescriptor());
+      parserWithOverwriteForbidden.merge(text, builder);
+      TestMap map =
+          TestMap.parseFrom(
+              builder.build().toByteString(), ExtensionRegistryLite.getEmptyRegistry());
+      assertEquals(2, map.getInt32ToInt32Field().size());
+      assertEquals(30, map.getInt32ToInt32Field().get(1).intValue());
+    }
   }
 
   // =======================================================================
diff --git a/java/lite/pom.xml b/java/lite/pom.xml
index 49686cd..779eacc 100644
--- a/java/lite/pom.xml
+++ b/java/lite/pom.xml
@@ -4,7 +4,7 @@
   <parent>
     <groupId>com.google.protobuf</groupId>
     <artifactId>protobuf-parent</artifactId>
-    <version>3.12.3</version>
+    <version>3.13.0</version>
   </parent>
 
   <artifactId>protobuf-javalite</artifactId>
@@ -52,6 +52,7 @@
         <includes>
           <include>google/protobuf/any.proto</include>
           <include>google/protobuf/api.proto</include>
+          <include>google/protobuf/duration.proto</include>
           <include>google/protobuf/empty.proto</include>
           <include>google/protobuf/field_mask.proto</include>
           <include>google/protobuf/source_context.proto</include>
diff --git a/java/lite/src/test/java/com/google/protobuf/LiteTest.java b/java/lite/src/test/java/com/google/protobuf/LiteTest.java
index 3e39bc7..140df72 100644
--- a/java/lite/src/test/java/com/google/protobuf/LiteTest.java
+++ b/java/lite/src/test/java/com/google/protobuf/LiteTest.java
@@ -42,6 +42,7 @@
 import com.google.protobuf.UnittestLite.TestAllTypesLite;
 import com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum;
 import com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage;
+import com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2;
 import com.google.protobuf.UnittestLite.TestAllTypesLite.OneofFieldCase;
 import com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup;
 import com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup;
@@ -1354,6 +1355,45 @@
     assertEquals(message.getSerializedSize() * 2, result.getSerializedSize());
   }
 
+  public void testMergeFrom_differentFieldsSetWithinOneField() throws Exception {
+    TestAllTypesLite result =
+        TestAllTypesLite.newBuilder()
+            .setOneofNestedMessage(NestedMessage.newBuilder().setBb(2))
+            .mergeFrom(
+                TestAllTypesLite.newBuilder()
+                    .setOneofNestedMessage2(NestedMessage2.newBuilder().setDd(3))
+                    .build())
+            .build();
+
+    assertToStringEquals("oneof_nested_message2 {\n  dd: 3\n}", result);
+  }
+
+  public void testMergeFrom_differentFieldsOfSameTypeSetWithinOneField() throws Exception {
+    TestAllTypesLite result =
+        TestAllTypesLite.newBuilder()
+            .setOneofNestedMessage(NestedMessage.newBuilder().setBb(2))
+            .mergeFrom(
+                TestAllTypesLite.newBuilder()
+                    .setOneofLazyNestedMessage(NestedMessage.newBuilder().setCc(3))
+                    .build())
+            .build();
+
+    assertToStringEquals("oneof_lazy_nested_message {\n  cc: 3\n}", result);
+  }
+
+  public void testMergeFrom_sameFieldSetWithinOneofField() throws Exception {
+    TestAllTypesLite result =
+        TestAllTypesLite.newBuilder()
+            .setOneofNestedMessage(NestedMessage.newBuilder().setBb(2))
+            .mergeFrom(
+                TestAllTypesLite.newBuilder()
+                    .setOneofNestedMessage(NestedMessage.newBuilder().setCc(4))
+                    .build())
+            .build();
+
+    assertToStringEquals("oneof_nested_message {\n  bb: 2\n  cc: 4\n}", result);
+  }
+
   public void testToStringDefaultInstance() throws Exception {
     assertToStringEquals("", TestAllTypesLite.getDefaultInstance());
   }
diff --git a/java/pom.xml b/java/pom.xml
index 0a813e0..bb91146 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -4,7 +4,7 @@
 
   <groupId>com.google.protobuf</groupId>
   <artifactId>protobuf-parent</artifactId>
-  <version>3.12.3</version>
+  <version>3.13.0</version>
   <packaging>pom</packaging>
 
   <name>Protocol Buffers [Parent]</name>
diff --git a/java/util/BUILD b/java/util/BUILD
index cfdb28e..71f73ba 100644
--- a/java/util/BUILD
+++ b/java/util/BUILD
@@ -5,10 +5,6 @@
     srcs = glob([
         "src/main/java/com/google/protobuf/util/*.java",
     ]),
-    javacopts = [
-        "-source 7",
-        "-target 7",
-    ],
     visibility = ["//visibility:public"],
     deps = [
         "//external:error_prone_annotations",
diff --git a/java/util/pom.xml b/java/util/pom.xml
index daa123a..54dcc86 100644
--- a/java/util/pom.xml
+++ b/java/util/pom.xml
@@ -4,7 +4,7 @@
   <parent>
     <groupId>com.google.protobuf</groupId>
     <artifactId>protobuf-parent</artifactId>
-    <version>3.12.3</version>
+    <version>3.13.0</version>
   </parent>
 
   <artifactId>protobuf-java-util</artifactId>
diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
index 6798143..cc3f5f6 100644
--- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
+++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
@@ -328,14 +328,13 @@
     /**
      * Create a new {@link Printer} that will sort the map keys in the JSON output.
      *
-     * Use of this modifier is discouraged, the generated JSON messages are equivalent
-     * with and without this option set, but there are some corner caseuse cases that
-     * demand a stable output, while order of map keys is otherwise arbitrary.
+     * <p>Use of this modifier is discouraged, the generated JSON messages are equivalent with and
+     * without this option set, but there are some corner use cases that demand a stable output,
+     * while order of map keys is otherwise arbitrary.
      *
-     * The generated order is not well-defined and should not be depended on, but
-     * it's stable.
+     * <p>The generated order is not well-defined and should not be depended on, but it's stable.
      *
-     * This new Printer clones all other configurations from the current {@link Printer}.
+     * <p>This new Printer clones all other configurations from the current {@link Printer}.
      */
     public Printer sortingMapKeys() {
       return new Printer(
diff --git a/js/experimental/runtime/kernel/kernel_test.js b/js/experimental/runtime/kernel/kernel_test.js
index e72be4f..eba7c4a 100644
--- a/js/experimental/runtime/kernel/kernel_test.js
+++ b/js/experimental/runtime/kernel/kernel_test.js
@@ -699,7 +699,7 @@
     expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString);
   });
 
-  it('decodes value from wire with multple values being present', () => {
+  it('decodes value from wire with multiple values being present', () => {
     const accessor = Kernel.fromArrayBuffer(
         createArrayBuffer(0x0A, 0x01, 0x00, 0x0A, 0x01, 0x01));
     expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString);
@@ -801,7 +801,7 @@
     expect(accessor.getFixed32WithDefault(1)).toEqual(1);
   });
 
-  it('decodes value from wire with multple values being present', () => {
+  it('decodes value from wire with multiple values being present', () => {
     const accessor = Kernel.fromArrayBuffer(createArrayBuffer(
         0x0D, 0x01, 0x00, 0x80, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00));
     expect(accessor.getFixed32WithDefault(1)).toEqual(2);
@@ -909,7 +909,7 @@
     expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(1));
   });
 
-  it('decodes value from wire with multple values being present', () => {
+  it('decodes value from wire with multiple values being present', () => {
     const accessor = Kernel.fromArrayBuffer(createArrayBuffer(
         0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00));
@@ -1008,7 +1008,7 @@
     expect(accessor.getFloatWithDefault(1)).toEqual(1);
   });
 
-  it('decodes value from wire with multple values being present', () => {
+  it('decodes value from wire with multiple values being present', () => {
     const accessor = Kernel.fromArrayBuffer(createArrayBuffer(
         0x0D, 0x00, 0x00, 0x80, 0x3F, 0x0D, 0x00, 0x00, 0x80, 0xBF));
     expect(accessor.getFloatWithDefault(1)).toEqual(-1);
@@ -1110,7 +1110,7 @@
     expect(accessor.getInt32WithDefault(1)).toEqual(1);
   });
 
-  it('decodes value from wire with multple values being present', () => {
+  it('decodes value from wire with multiple values being present', () => {
     const accessor =
         Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02));
     expect(accessor.getInt32WithDefault(1)).toEqual(2);
@@ -1207,7 +1207,7 @@
     expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(1));
   });
 
-  it('decodes value from wire with multple values being present', () => {
+  it('decodes value from wire with multiple values being present', () => {
     const accessor =
         Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02));
     expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(2));
@@ -1306,7 +1306,7 @@
     expect(accessor.getSfixed32WithDefault(1)).toEqual(1);
   });
 
-  it('decodes value from wire with multple values being present', () => {
+  it('decodes value from wire with multiple values being present', () => {
     const accessor = Kernel.fromArrayBuffer(createArrayBuffer(
         0x0D, 0x01, 0x00, 0x80, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00));
     expect(accessor.getSfixed32WithDefault(1)).toEqual(2);
@@ -1404,7 +1404,7 @@
     expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(1));
   });
 
-  it('decodes value from wire with multple values being present', () => {
+  it('decodes value from wire with multiple values being present', () => {
     const accessor = Kernel.fromArrayBuffer(createArrayBuffer(
         0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00));
@@ -1502,7 +1502,7 @@
     expect(accessor.getSint32WithDefault(1)).toEqual(1);
   });
 
-  it('decodes value from wire with multple values being present', () => {
+  it('decodes value from wire with multiple values being present', () => {
     const accessor =
         Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x03, 0x08, 0x02));
     expect(accessor.getSint32WithDefault(1)).toEqual(1);
@@ -1599,7 +1599,7 @@
     expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1));
   });
 
-  it('decodes value from wire with multple values being present', () => {
+  it('decodes value from wire with multiple values being present', () => {
     const accessor =
         Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02));
     expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1));
@@ -1698,7 +1698,7 @@
     expect(accessor.getStringWithDefault(1)).toEqual('a');
   });
 
-  it('decodes value from wire with multple values being present', () => {
+  it('decodes value from wire with multiple values being present', () => {
     const accessor = Kernel.fromArrayBuffer(
         createArrayBuffer(0x0A, 0x01, 0x60, 0x0A, 0x01, 0x61));
     expect(accessor.getStringWithDefault(1)).toEqual('a');
@@ -1789,7 +1789,7 @@
     expect(accessor.getUint32WithDefault(1)).toEqual(1);
   });
 
-  it('decodes value from wire with multple values being present', () => {
+  it('decodes value from wire with multiple values being present', () => {
     const accessor =
         Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02));
     expect(accessor.getUint32WithDefault(1)).toEqual(2);
@@ -1896,7 +1896,7 @@
     expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(1));
   });
 
-  it('decodes value from wire with multple values being present', () => {
+  it('decodes value from wire with multiple values being present', () => {
     const accessor =
         Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02));
     expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(2));
@@ -1996,7 +1996,7 @@
   });
 
 
-  it('decodes value from wire with multple values being present', () => {
+  it('decodes value from wire with multiple values being present', () => {
     const accessor = Kernel.fromArrayBuffer(createArrayBuffer(
         0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x09, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0xF0, 0xBF));
diff --git a/js/experimental/runtime/kernel/tag_test.js b/js/experimental/runtime/kernel/tag_test.js
index 04a6cb6..35137bb 100644
--- a/js/experimental/runtime/kernel/tag_test.js
+++ b/js/experimental/runtime/kernel/tag_test.js
@@ -95,12 +95,12 @@
 
   it('skips group in group', () => {
     const buffer = createArrayBuffer(
-        0x0B,        // start outter
+        0x0B,        // start outer
         0x10, 0x01,  // field: 2, value: 1
         0x0B,        // start inner group
         0x10, 0x01,  // payload inner group
         0x0C,        // stop inner group
-        0x0C         // end outter
+        0x0C         // end outer
     );
     const bufferDecoder = BufferDecoder.fromArrayBuffer(buffer);
     bufferDecoder.setCursor(1);
diff --git a/kokoro/linux/dockerfile/test/php80/Dockerfile b/kokoro/linux/dockerfile/test/php80/Dockerfile
new file mode 100644
index 0000000..d6c9b4d
--- /dev/null
+++ b/kokoro/linux/dockerfile/test/php80/Dockerfile
@@ -0,0 +1,96 @@
+FROM debian:jessie
+
+# Install dependencies.  We start with the basic ones require to build protoc
+# and the C++ build
+RUN apt-get update && apt-get install -y \
+  autoconf \
+  autotools-dev \
+  build-essential \
+  bzip2 \
+  ccache \
+  curl \
+  gcc \
+  git \
+  libc6 \
+  libc6-dbg \
+  libc6-dev \
+  libgtest-dev \
+  libtool \
+  make \
+  parallel \
+  time \
+  wget \
+  re2c \
+  sqlite3 \
+  vim \
+  libonig-dev \
+  libsqlite3-dev \
+  && apt-get clean
+
+# Install php dependencies
+RUN apt-get clean && apt-get update && apt-get install -y --force-yes \
+  php5 \
+  libcurl4-openssl-dev \
+  libgmp-dev \
+  libgmp3-dev \
+  libssl-dev \
+  libxml2-dev \
+  unzip \
+  zlib1g-dev \
+  pkg-config \
+  && apt-get clean
+
+# Install other dependencies
+RUN ln -sf /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h
+RUN wget https://ftp.gnu.org/gnu/bison/bison-3.0.1.tar.gz -O /var/local/bison-3.0.1.tar.gz
+RUN cd /var/local \
+  && tar -zxvf bison-3.0.1.tar.gz \
+  && cd /var/local/bison-3.0.1 \
+  && ./configure \
+  && make \
+  && make install
+
+# Install composer
+RUN curl -sS https://getcomposer.org/installer | php
+RUN mv composer.phar /usr/local/bin/composer
+
+# Download php source code
+RUN git clone https://github.com/php/php-src
+
+# php 8.0
+RUN cd php-src \
+  && git checkout php-8.0.0alpha3 \
+  && ./buildconf --force
+RUN cd php-src \
+  && ./configure \
+  --enable-bcmath \
+  --enable-mbstring \
+  --with-gmp \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-8.0 \
+  && make \
+  && make install \
+  && make clean
+RUN cd php-src \
+  && ./configure \
+  --enable-bcmath \
+  --enable-mbstring \
+  --enable-maintainer-zts \
+  --with-gmp \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-8.0-zts \
+  && make \
+  && make install \
+  && make clean
+
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-9.phar \
+  && chmod +x phpunit \
+  && cp phpunit /usr/local/php-8.0/bin \
+  && mv phpunit /usr/local/php-8.0-zts/bin
+
+# Install php dependencies
+RUN apt-get clean && apt-get update && apt-get install -y --force-yes \
+  valgrind \
+  && apt-get clean
diff --git a/kokoro/linux/php80/build.sh b/kokoro/linux/php80/build.sh
new file mode 100755
index 0000000..6499b39
--- /dev/null
+++ b/kokoro/linux/php80/build.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+# This is the top-level script we give to Kokoro as the entry point for
+# running the "pull request" project:
+#
+# This script selects a specific Dockerfile (for building a Docker image) and
+# a script to run inside that image.  Then we delegate to the general
+# build_and_run_docker.sh script.
+
+# Change to repo root
+cd $(dirname $0)/../../..
+
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/php
+export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
+export OUTPUT_DIR=testoutput
+export TEST_SET="php8.0_all"
+./kokoro/linux/build_and_run_docker.sh
diff --git a/kokoro/linux/php80/continuous.cfg b/kokoro/linux/php80/continuous.cfg
new file mode 100644
index 0000000..8426318
--- /dev/null
+++ b/kokoro/linux/php80/continuous.cfg
@@ -0,0 +1,11 @@
+# Config file for running tests in Kokoro
+
+# Location of the build script in repository
+build_file: "protobuf/kokoro/linux/php80/build.sh"
+timeout_mins: 120
+
+action {
+  define_artifacts {
+    regex: "**/sponge_log.xml"
+  }
+}
diff --git a/kokoro/linux/php80/presubmit.cfg b/kokoro/linux/php80/presubmit.cfg
new file mode 100644
index 0000000..8426318
--- /dev/null
+++ b/kokoro/linux/php80/presubmit.cfg
@@ -0,0 +1,11 @@
+# Config file for running tests in Kokoro
+
+# Location of the build script in repository
+build_file: "protobuf/kokoro/linux/php80/build.sh"
+timeout_mins: 120
+
+action {
+  define_artifacts {
+    regex: "**/sponge_log.xml"
+  }
+}
diff --git a/kokoro/macos/prepare_build_macos_rc b/kokoro/macos/prepare_build_macos_rc
index 18ce60b..830e7ee 100755
--- a/kokoro/macos/prepare_build_macos_rc
+++ b/kokoro/macos/prepare_build_macos_rc
@@ -66,7 +66,7 @@
 # Install Tox
 
 if [[ "${KOKORO_INSTALL_TOX:-}" == "yes" ]] ; then
-  sudo pip install tox==2.4.1
+  sudo python3 -m pip install --upgrade pip tox
 fi
 
 ##
diff --git a/kokoro/release/collect_all_artifacts.sh b/kokoro/release/collect_all_artifacts.sh
index 3b7d7d4..8f6e9db 100755
--- a/kokoro/release/collect_all_artifacts.sh
+++ b/kokoro/release/collect_all_artifacts.sh
@@ -39,7 +39,7 @@
 mkdir -p protoc/linux_x86
 mkdir -p protoc/linux_x64
 # Because of maven unrelated reasonse the linux protoc binaries have a dummy .exe extension.
-# For the Google.Protobuf.Tools nuget, we don't want that expection, so we just remove it.
+# For the Google.Protobuf.Tools nuget, we don't want that exception, so we just remove it.
 cp ${INPUT_ARTIFACTS_DIR}/protoc-artifacts/target/linux/x86_32/protoc.exe protoc/linux_x86/protoc
 cp ${INPUT_ARTIFACTS_DIR}/protoc-artifacts/target/linux/x86_64/protoc.exe protoc/linux_x64/protoc
 
diff --git a/kokoro/release/python/macos/config.sh b/kokoro/release/python/macos/config.sh
index 741988a..1b0a302 100644
--- a/kokoro/release/python/macos/config.sh
+++ b/kokoro/release/python/macos/config.sh
@@ -1,6 +1,25 @@
 # Define custom utilities
 # Test for OSX with [ -n "$IS_OSX" ]
 
+function remove_travis_ve_pip {
+    # Removing the system virtualenv or pip can be very problematic for
+    # macOS on Kokoro, so just leave them be.
+    :;
+}
+
+function install_pip {
+    check_python
+    PIP_CMD="sudo $PYTHON_EXE -m pip${pip_args:+ $pip_args}"
+    $PIP_CMD install --upgrade pip
+}
+
+function install_virtualenv {
+    check_python
+    check_pip
+    $PIP_CMD install --upgrade virtualenv
+    VIRTUALENV_CMD="$PYTHON_EXE -m virtualenv"
+}
+
 function pre_build {
     # Any stuff that you need to do before you start building the wheels
     # Runs in the root directory of this repository.
diff --git a/objectivec/BUILD b/objectivec/BUILD
new file mode 100644
index 0000000..9f702ec
--- /dev/null
+++ b/objectivec/BUILD
@@ -0,0 +1,90 @@
+load("@rules_cc//cc:defs.bzl", "objc_library")
+
+objc_library(
+    name = "objectivec",
+    hdrs = [
+        "GPBAny.pbobjc.h",
+        "GPBApi.pbobjc.h",
+        "GPBDuration.pbobjc.h",
+        "GPBEmpty.pbobjc.h",
+        "GPBFieldMask.pbobjc.h",
+        "GPBSourceContext.pbobjc.h",
+        "GPBStruct.pbobjc.h",
+        "GPBTimestamp.pbobjc.h",
+        "GPBType.pbobjc.h",
+        "GPBWrappers.pbobjc.h",
+        "GPBArray.h",
+        "GPBBootstrap.h",
+        "GPBCodedInputStream.h",
+        "GPBCodedOutputStream.h",
+        "GPBDescriptor.h",
+        "GPBDictionary.h",
+        "GPBExtensionInternals.h",
+        "GPBExtensionRegistry.h",
+        "GPBMessage.h",
+        "GPBProtocolBuffers.h",
+        "GPBProtocolBuffers_RuntimeSupport.h",
+        "GPBRootObject.h",
+        "GPBRuntimeTypes.h",
+        "GPBUnknownField.h",
+        "GPBUnknownFieldSet.h",
+        "GPBUtilities.h",
+        "GPBWellKnownTypes.h",
+        "GPBWireFormat.h",
+        "google/protobuf/Any.pbobjc.h",
+        "google/protobuf/Api.pbobjc.h",
+        "google/protobuf/Duration.pbobjc.h",
+        "google/protobuf/Empty.pbobjc.h",
+        "google/protobuf/FieldMask.pbobjc.h",
+        "google/protobuf/SourceContext.pbobjc.h",
+        "google/protobuf/Struct.pbobjc.h",
+        "google/protobuf/Timestamp.pbobjc.h",
+        "google/protobuf/Type.pbobjc.h",
+        "google/protobuf/Wrappers.pbobjc.h",
+        # Package private headers, but exposed because the generated sources
+        # need to use them.
+        "GPBArray_PackagePrivate.h",
+        "GPBCodedInputStream_PackagePrivate.h",
+        "GPBCodedOutputStream_PackagePrivate.h",
+        "GPBDescriptor_PackagePrivate.h",
+        "GPBDictionary_PackagePrivate.h",
+        "GPBMessage_PackagePrivate.h",
+        "GPBRootObject_PackagePrivate.h",
+        "GPBUnknownFieldSet_PackagePrivate.h",
+        "GPBUnknownField_PackagePrivate.h",
+        "GPBUtilities_PackagePrivate.h",
+    ],
+    copts = [
+        "-Wno-vla",
+    ],
+    includes = [
+        ".",
+    ],
+    non_arc_srcs = [
+        "GPBAny.pbobjc.m",
+        "GPBApi.pbobjc.m",
+        "GPBDuration.pbobjc.m",
+        "GPBEmpty.pbobjc.m",
+        "GPBFieldMask.pbobjc.m",
+        "GPBSourceContext.pbobjc.m",
+        "GPBStruct.pbobjc.m",
+        "GPBTimestamp.pbobjc.m",
+        "GPBType.pbobjc.m",
+        "GPBWrappers.pbobjc.m",
+        "GPBArray.m",
+        "GPBCodedInputStream.m",
+        "GPBCodedOutputStream.m",
+        "GPBDescriptor.m",
+        "GPBDictionary.m",
+        "GPBExtensionInternals.m",
+        "GPBExtensionRegistry.m",
+        "GPBMessage.m",
+        "GPBRootObject.m",
+        "GPBUnknownField.m",
+        "GPBUnknownFieldSet.m",
+        "GPBUtilities.m",
+        "GPBWellKnownTypes.m",
+        "GPBWireFormat.m",
+    ],
+    visibility = ["//visibility:public"],
+)
diff --git a/objectivec/DevTools/compile_testing_protos.sh b/objectivec/DevTools/compile_testing_protos.sh
index 021e03d..69c32f9 100755
--- a/objectivec/DevTools/compile_testing_protos.sh
+++ b/objectivec/DevTools/compile_testing_protos.sh
@@ -95,7 +95,7 @@
 # -----------------------------------------------------------------------------
 RUN_PROTOC=no
 
-# Check to if all the output files exist (incase a new one got added).
+# Check to if all the output files exist (in case a new one got added).
 
 for PROTO_FILE in "${CORE_PROTO_FILES[@]}" "${OBJC_TEST_PROTO_FILES[@]}"; do
   DIR=${PROTO_FILE%/*}
diff --git a/objectivec/DevTools/full_mac_build.sh b/objectivec/DevTools/full_mac_build.sh
index 84ed8e9..4df1314 100755
--- a/objectivec/DevTools/full_mac_build.sh
+++ b/objectivec/DevTools/full_mac_build.sh
@@ -285,7 +285,7 @@
           -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
           -destination "platform=iOS Simulator,name=iPhone 7,OS=latest" # 64bit
           # 10.x also seems to often fail running destinations in parallel (with
-          # 32bit one include atleast)
+          # 32bit one include at least)
           -disable-concurrent-destination-testing
       )
       ;;
diff --git a/objectivec/DevTools/pddm.py b/objectivec/DevTools/pddm.py
index dacf7bb..b572cc7 100755
--- a/objectivec/DevTools/pddm.py
+++ b/objectivec/DevTools/pddm.py
@@ -645,7 +645,7 @@
   opts, extra_args = parser.parse_args(args)
 
   if not extra_args:
-    parser.error('Need atleast one file to process')
+    parser.error('Need at least one file to process')
 
   result = 0
   for a_path in extra_args:
diff --git a/objectivec/GPBExtensionInternals.m b/objectivec/GPBExtensionInternals.m
index 290c82a..bacec57 100644
--- a/objectivec/GPBExtensionInternals.m
+++ b/objectivec/GPBExtensionInternals.m
@@ -361,8 +361,8 @@
       if (existingValue) {
         message = [existingValue retain];
       } else {
-        GPBDescriptor *decriptor = [extension.msgClass descriptor];
-        message = [[decriptor.messageClass alloc] init];
+        GPBDescriptor *descriptor = [extension.msgClass descriptor];
+        message = [[descriptor.messageClass alloc] init];
       }
 
       if (description->dataType == GPBDataTypeGroup) {
diff --git a/objectivec/GPBMessage.m b/objectivec/GPBMessage.m
index 8e6aaf1..7b1263f 100644
--- a/objectivec/GPBMessage.m
+++ b/objectivec/GPBMessage.m
@@ -3286,7 +3286,7 @@
     // if a sub message in a field has extensions, the issue still exists. A
     // recursive check could be done here (like the work in
     // GPBMessageDropUnknownFieldsRecursively()), but that has the potential to
-    // be expensive and could slow down serialization in DEBUG enought to cause
+    // be expensive and could slow down serialization in DEBUG enough to cause
     // developers other problems.
     NSLog(@"Warning: writing out a GPBMessage (%@) via NSCoding and it"
           @" has %ld extensions; when read back in, those fields will be"
diff --git a/objectivec/GPBTimestamp.pbobjc.h b/objectivec/GPBTimestamp.pbobjc.h
index 92f0bac..a328afc 100644
--- a/objectivec/GPBTimestamp.pbobjc.h
+++ b/objectivec/GPBTimestamp.pbobjc.h
@@ -107,7 +107,16 @@
  *         .setNanos((int) ((millis % 1000) * 1000000)).build();
  *
  *
- * Example 5: Compute Timestamp from current time in Python.
+ * Example 5: Compute Timestamp from Java `Instant.now()`.
+ *
+ *     Instant now = Instant.now();
+ *
+ *     Timestamp timestamp =
+ *         Timestamp.newBuilder().setSeconds(now.getEpochSecond())
+ *             .setNanos(now.getNano()).build();
+ *
+ *
+ * Example 6: Compute Timestamp from current time in Python.
  *
  *     timestamp = Timestamp()
  *     timestamp.GetCurrentTime()
diff --git a/objectivec/GPBUtilities.m b/objectivec/GPBUtilities.m
index ee79d00..e132102 100644
--- a/objectivec/GPBUtilities.m
+++ b/objectivec/GPBUtilities.m
@@ -219,7 +219,7 @@
     // Library is too old for headers.
     [NSException raise:NSInternalInconsistencyException
                 format:@"Linked to ProtocolBuffer runtime version %d,"
-                       @" but code compiled needing atleast %d!",
+                       @" but code compiled needing at least %d!",
                        GOOGLE_PROTOBUF_OBJC_VERSION, objcRuntimeVersion];
   }
   if (objcRuntimeVersion < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION) {
diff --git a/objectivec/GPBUtilities_PackagePrivate.h b/objectivec/GPBUtilities_PackagePrivate.h
index 9c29c39..a620288 100644
--- a/objectivec/GPBUtilities_PackagePrivate.h
+++ b/objectivec/GPBUtilities_PackagePrivate.h
@@ -304,7 +304,7 @@
 const char *GPBMessageEncodingForSelector(SEL selector, BOOL instanceSel);
 
 // Helper for text format name encoding.
-// decodeData is the data describing the sepecial decodes.
+// decodeData is the data describing the special decodes.
 // key and inputString are the input that needs decoding.
 NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key,
                                   NSString *inputString);
diff --git a/objectivec/README.md b/objectivec/README.md
index 5982939..2583779 100644
--- a/objectivec/README.md
+++ b/objectivec/README.md
@@ -168,7 +168,7 @@
     Any number of files can be listed for a framework, just separate them with
     commas.
 
-    There can be multiple lines listing the same frameworkName incase it has a
+    There can be multiple lines listing the same frameworkName in case it has a
     lot of proto files included in it; and having multiple lines makes things
     easier to read.
 
diff --git a/objectivec/Tests/CocoaPods/run_tests.sh b/objectivec/Tests/CocoaPods/run_tests.sh
index 6d3e12b..35bcc18 100755
--- a/objectivec/Tests/CocoaPods/run_tests.sh
+++ b/objectivec/Tests/CocoaPods/run_tests.sh
@@ -90,7 +90,7 @@
   echo "Cleaning up..."
 
   # Generally don't let things fail, and eat common stdout, but let stderr show
-  # incase something does hiccup.
+  # in case something does hiccup.
   xcodebuild -workspace "${TEST_NAME}.xcworkspace" -scheme "${TEST_NAME}" clean > /dev/null || true
   pod deintegrate > /dev/null || true
   # Flush the cache so nothing is left behind.
diff --git a/objectivec/Tests/GPBCodedInputStreamTests.m b/objectivec/Tests/GPBCodedInputStreamTests.m
index f5aa690..6cd5a1f 100644
--- a/objectivec/Tests/GPBCodedInputStreamTests.m
+++ b/objectivec/Tests/GPBCodedInputStreamTests.m
@@ -422,7 +422,7 @@
 - (void)testBOMWithinStrings {
   // We've seen servers that end up with BOMs within strings (not always at the
   // start, and sometimes in multiple places), make sure they always parse
-  // correctly. (Again, this is inpart incase a custom string class is ever
+  // correctly. (Again, this is inpart in case a custom string class is ever
   // used again.)
   const char* strs[] = {
     "\xEF\xBB\xBF String with BOM",
diff --git a/objectivec/Tests/GPBCodedOuputStreamTests.m b/objectivec/Tests/GPBCodedOuputStreamTests.m
index 6c9144f..a9934ac 100644
--- a/objectivec/Tests/GPBCodedOuputStreamTests.m
+++ b/objectivec/Tests/GPBCodedOuputStreamTests.m
@@ -400,7 +400,7 @@
 
 - (void)testWriteStringsWithZeroChar {
   // Unicode allows `\0` as a character, and NSString is a class cluster, so
-  // there are a few different classes that could end up beind a given string.
+  // there are a few different classes that could end up behind a given string.
   // Historically, we've seen differences based on constant strings in code and
   // strings built via the NSString apis. So this round trips them to ensure
   // they are acting as expected.
diff --git a/php/ext/google/protobuf/array.c b/php/ext/google/protobuf/array.c
index 571d3e4..4615ed3 100644
--- a/php/ext/google/protobuf/array.c
+++ b/php/ext/google/protobuf/array.c
@@ -94,11 +94,12 @@
   zend_object_std_dtor(&intern->std);
 }
 
-static HashTable *RepeatedField_GetProperties(zval *object TSRMLS_DC) {
+static HashTable *RepeatedField_GetProperties(PROTO_VAL *object) {
   return NULL;  // We do not have a properties table.
 }
 
-static zval *RepeatedField_GetPropertyPtrPtr(zval *object, zval *member,
+static zval *RepeatedField_GetPropertyPtrPtr(PROTO_VAL *object,
+                                             PROTO_STR *member,
                                              int type, void **cache_slot) {
   return NULL;  // We don't offer direct references to our properties.
 }
@@ -392,6 +393,15 @@
   RETURN_ZVAL(&ret, 0, 1);
 }
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 1)
+  ZEND_ARG_INFO(0, type)
+  ZEND_ARG_INFO(0, class)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_append, 0, 0, 1)
+  ZEND_ARG_INFO(0, newval)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1)
   ZEND_ARG_INFO(0, index)
 ZEND_END_ARG_INFO()
@@ -405,8 +415,8 @@
 ZEND_END_ARG_INFO()
 
 static zend_function_entry repeated_field_methods[] = {
-  PHP_ME(RepeatedField, __construct,  NULL,              ZEND_ACC_PUBLIC)
-  PHP_ME(RepeatedField, append,       NULL,              ZEND_ACC_PUBLIC)
+  PHP_ME(RepeatedField, __construct,  arginfo_construct, ZEND_ACC_PUBLIC)
+  PHP_ME(RepeatedField, append,       arginfo_append,    ZEND_ACC_PUBLIC)
   PHP_ME(RepeatedField, offsetExists, arginfo_offsetGet, ZEND_ACC_PUBLIC)
   PHP_ME(RepeatedField, offsetGet,    arginfo_offsetGet, ZEND_ACC_PUBLIC)
   PHP_ME(RepeatedField, offsetSet,    arginfo_offsetSet, ZEND_ACC_PUBLIC)
diff --git a/php/ext/google/protobuf/convert.c b/php/ext/google/protobuf/convert.c
index dd076c5..1c2f628 100644
--- a/php/ext/google/protobuf/convert.c
+++ b/php/ext/google/protobuf/convert.c
@@ -92,20 +92,55 @@
   RETURN_ZVAL(val, 1, 0);
 }
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_checkPrimitive, 0, 0, 1)
+  ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_checkMessage, 0, 0, 2)
+  ZEND_ARG_INFO(0, value)
+  ZEND_ARG_INFO(0, class)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_checkMapField, 0, 0, 3)
+  ZEND_ARG_INFO(0, value)
+  ZEND_ARG_INFO(0, key_type)
+  ZEND_ARG_INFO(0, value_type)
+  ZEND_ARG_INFO(0, value_class)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_checkRepeatedField, 0, 0, 2)
+  ZEND_ARG_INFO(0, value)
+  ZEND_ARG_INFO(0, type)
+  ZEND_ARG_INFO(0, class)
+ZEND_END_ARG_INFO()
+
 static zend_function_entry util_methods[] = {
-  PHP_ME(Util, checkInt32,  NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-  PHP_ME(Util, checkUint32, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-  PHP_ME(Util, checkInt64,  NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-  PHP_ME(Util, checkUint64, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-  PHP_ME(Util, checkEnum,   NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-  PHP_ME(Util, checkFloat,  NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-  PHP_ME(Util, checkDouble, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-  PHP_ME(Util, checkBool,   NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-  PHP_ME(Util, checkString, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-  PHP_ME(Util, checkBytes,  NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-  PHP_ME(Util, checkMessage, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-  PHP_ME(Util, checkMapField, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-  PHP_ME(Util, checkRepeatedField, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+  PHP_ME(Util, checkInt32,  arginfo_checkPrimitive,
+         ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+  PHP_ME(Util, checkUint32, arginfo_checkPrimitive,
+         ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+  PHP_ME(Util, checkInt64,  arginfo_checkPrimitive,
+         ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+  PHP_ME(Util, checkUint64, arginfo_checkPrimitive,
+         ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+  PHP_ME(Util, checkEnum,   arginfo_checkPrimitive,
+         ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+  PHP_ME(Util, checkFloat,  arginfo_checkPrimitive,
+         ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+  PHP_ME(Util, checkDouble, arginfo_checkPrimitive,
+         ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+  PHP_ME(Util, checkBool,   arginfo_checkPrimitive,
+         ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+  PHP_ME(Util, checkString, arginfo_checkPrimitive,
+         ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+  PHP_ME(Util, checkBytes,  arginfo_checkPrimitive,
+         ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+  PHP_ME(Util, checkMessage, arginfo_checkMessage,
+         ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+  PHP_ME(Util, checkMapField, arginfo_checkMapField,
+         ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+  PHP_ME(Util, checkRepeatedField, arginfo_checkRepeatedField,
+         ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
   ZEND_FE_END
 };
 
diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c
index c76134d..37dd50c 100644
--- a/php/ext/google/protobuf/def.c
+++ b/php/ext/google/protobuf/def.c
@@ -180,8 +180,7 @@
   zend_long index;
   zval ret;
 
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) ==
-      FAILURE) {
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
     zend_error(E_USER_ERROR, "Expect integer for index.\n");
     return;
   }
@@ -284,8 +283,7 @@
   zend_long index;
   zval ret;
 
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) ==
-      FAILURE) {
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
     zend_error(E_USER_ERROR, "Expect integer for index.\n");
     return;
   }
@@ -615,8 +613,7 @@
   zval ret;
   zend_long index;
 
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) ==
-      FAILURE) {
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
     zend_error(E_USER_ERROR, "Expect integer for index.\n");
     return;
   }
@@ -658,8 +655,7 @@
   zend_long index;
   zval ret;
 
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) ==
-      FAILURE) {
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
     zend_error(E_USER_ERROR, "Expect integer for index.\n");
     return;
   }
@@ -799,8 +795,8 @@
   zend_string *str;
   zval ret;
 
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &classname,
-                            &classname_len) == FAILURE) {
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &classname, &classname_len) ==
+      FAILURE) {
     return;
   }
 
@@ -828,8 +824,8 @@
   zend_string *str;
   zval ret;
 
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &classname,
-                            &classname_len) == FAILURE) {
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &classname, &classname_len) ==
+      FAILURE) {
     return;
   }
 
@@ -856,8 +852,8 @@
   zend_long protoname_len;
   const upb_msgdef *m;
 
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &protoname,
-                            &protoname_len) == FAILURE) {
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &protoname, &protoname_len) ==
+      FAILURE) {
     return;
   }
 
diff --git a/php/ext/google/protobuf/map.c b/php/ext/google/protobuf/map.c
index 0217c64..f29c18c 100644
--- a/php/ext/google/protobuf/map.c
+++ b/php/ext/google/protobuf/map.c
@@ -90,12 +90,12 @@
   zend_object_std_dtor(&intern->std);
 }
 
-static zval *Map_GetPropertyPtrPtr(zval *object, zval *member, int type,
-                                      void **cache_slot) {
+static zval *Map_GetPropertyPtrPtr(PROTO_VAL *object, PROTO_STR *member,
+                                   int type, void **cache_slot) {
   return NULL;  // We don't offer direct references to our properties.
 }
 
-static HashTable *map_get_properties(zval *object TSRMLS_DC) {
+static HashTable *Map_GetProperties(PROTO_VAL *object) {
   return NULL;  // We do not have a properties table.
 }
 
@@ -378,6 +378,12 @@
   RETURN_ZVAL(&ret, 0, 1);
 }
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 2)
+  ZEND_ARG_INFO(0, key_type)
+  ZEND_ARG_INFO(0, value_type)
+  ZEND_ARG_INFO(0, value_class)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1)
   ZEND_ARG_INFO(0, index)
 ZEND_END_ARG_INFO()
@@ -391,7 +397,7 @@
 ZEND_END_ARG_INFO()
 
 static zend_function_entry MapField_methods[] = {
-  PHP_ME(MapField, __construct,  NULL,              ZEND_ACC_PUBLIC)
+  PHP_ME(MapField, __construct,  arginfo_construct, ZEND_ACC_PUBLIC)
   PHP_ME(MapField, offsetExists, arginfo_offsetGet, ZEND_ACC_PUBLIC)
   PHP_ME(MapField, offsetGet,    arginfo_offsetGet, ZEND_ACC_PUBLIC)
   PHP_ME(MapField, offsetSet,    arginfo_offsetSet, ZEND_ACC_PUBLIC)
@@ -572,7 +578,7 @@
   h = &MapField_object_handlers;
   memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
   h->dtor_obj = MapField_destructor;
-  h->get_properties = map_get_properties;
+  h->get_properties = Map_GetProperties;
   h->get_property_ptr_ptr = Map_GetPropertyPtrPtr;
 
   INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\MapFieldIter",
diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c
index 20dd37a..63d2b08 100644
--- a/php/ext/google/protobuf/message.c
+++ b/php/ext/google/protobuf/message.c
@@ -95,10 +95,10 @@
  *
  * Helper function to look up a field given a member name (as a string).
  */
-static const upb_fielddef *get_field(Message *msg, zval *member) {
+static const upb_fielddef *get_field(Message *msg, PROTO_STR *member) {
   const upb_msgdef *m = msg->desc->msgdef;
   const upb_fielddef *f =
-      upb_msgdef_ntof(m, Z_STRVAL_P(member), Z_STRLEN_P(member));
+      upb_msgdef_ntof(m, PROTO_STRVAL_P(member), PROTO_STRLEN_P(member));
 
   if (!f) {
     zend_throw_exception_ex(NULL, 0, "No such property %s.",
@@ -109,6 +109,78 @@
 }
 
 /**
+ * Message_has_property()
+ *
+ * Object handler for testing whether a property exists. Called when PHP code
+ * does any of:
+ *
+ *   isset($message->foobar);
+ *   property_exists($message->foobar);
+ *
+ * Note that all properties of generated messages are private, so this should
+ * only be possible to invoke from generated code, which has accessors like this
+ * (if the field has presence):
+ *
+ *   public function hasOptionalInt32()
+ *   {
+ *       return isset($this->optional_int32);
+ *   }
+ */
+static int Message_has_property(PROTO_VAL *obj, PROTO_STR *member,
+                                int has_set_exists,
+                                void **cache_slot) {
+  Message* intern = PROTO_MSG_P(obj);
+  const upb_fielddef *f = get_field(intern, member);
+
+  if (!f) return 0;
+
+  if (!upb_fielddef_haspresence(f)) {
+    zend_throw_exception_ex(
+        NULL, 0,
+        "Cannot call isset() on field %s which does not have presence.",
+        ZSTR_VAL(intern->desc->class_entry->name));
+    return 0;
+  }
+
+  return upb_msg_has(intern->msg, f);
+}
+
+/**
+ * Message_unset_property()
+ *
+ * Object handler for unsetting a property. Called when PHP code calls:
+ * does any of:
+ *
+ *   unset($message->foobar);
+ *
+ * Note that all properties of generated messages are private, so this should
+ * only be possible to invoke from generated code, which has accessors like this
+ * (if the field has presence):
+ *
+ *   public function clearOptionalInt32()
+ *   {
+ *       unset($this->optional_int32);
+ *   }
+ */
+static void Message_unset_property(PROTO_VAL *obj, PROTO_STR *member,
+                                   void **cache_slot) {
+  Message* intern = PROTO_MSG_P(obj);
+  const upb_fielddef *f = get_field(intern, member);
+
+  if (!f) return;
+
+  if (!upb_fielddef_haspresence(f)) {
+    zend_throw_exception_ex(
+        NULL, 0,
+        "Cannot call unset() on field %s which does not have presence.",
+        ZSTR_VAL(intern->desc->class_entry->name));
+    return;
+  }
+
+  upb_msg_clearfield(intern->msg, f);
+}
+
+/**
  * Message_read_property()
  *
  * Object handler for reading a property in PHP. Called when PHP code does:
@@ -126,9 +198,9 @@
  * We lookup the field and return the scalar, RepeatedField, or MapField for
  * this field.
  */
-static zval *Message_read_property(zval *obj, zval *member, int type,
-                                   void **cache_slot, zval *rv) {
-  Message* intern = (Message*)Z_OBJ_P(obj);
+static zval *Message_read_property(PROTO_VAL *obj, PROTO_STR *member,
+                                   int type, void **cache_slot, zval *rv) {
+  Message* intern = PROTO_MSG_P(obj);
   const upb_fielddef *f = get_field(intern, member);
   upb_arena *arena = Arena_Get(&intern->arena);
 
@@ -170,29 +242,41 @@
  * The C extension version of checkInt32() doesn't actually check anything, so
  * we perform all checking and conversion in this function.
  */
-static void Message_write_property(zval *obj, zval *member, zval *val,
-                                   void **cache_slot) {
-  Message* intern = (Message*)Z_OBJ_P(obj);
+static PROTO_RETURN_VAL Message_write_property(
+    PROTO_VAL *obj, PROTO_STR *member, zval *val, void **cache_slot) {
+  Message* intern = PROTO_MSG_P(obj);
   const upb_fielddef *f = get_field(intern, member);
   upb_arena *arena = Arena_Get(&intern->arena);
   upb_msgval msgval;
 
-  if (!f) return;
+  if (!f) goto error;
 
   if (upb_fielddef_ismap(f)) {
     msgval.map_val = MapField_GetUpbMap(val, f, arena);
-    if (!msgval.map_val) return;
+    if (!msgval.map_val) goto error;
   } else if (upb_fielddef_isseq(f)) {
     msgval.array_val = RepeatedField_GetUpbArray(val, f, arena);
-    if (!msgval.array_val) return;
+    if (!msgval.array_val) goto error;
   } else {
     upb_fieldtype_t type = upb_fielddef_type(f);
     const Descriptor *subdesc = Descriptor_GetFromFieldDef(f);
     bool ok = Convert_PhpToUpb(val, &msgval, type, subdesc, arena);
-    if (!ok) return;
+    if (!ok) goto error;
   }
 
   upb_msg_set(intern->msg, f, msgval, arena);
+#if PHP_VERSION_ID < 704000
+  return;
+#else
+  return val;
+#endif
+
+error:
+#if PHP_VERSION_ID < 704000
+  return;
+#else
+  return &EG(error_zval);
+#endif
 }
 
 /**
@@ -202,7 +286,8 @@
  * reference to our internal properties. We don't support this, so we return
  * NULL.
  */
-static zval *Message_get_property_ptr_ptr(zval *object, zval *member, int type,
+static zval *Message_get_property_ptr_ptr(PROTO_VAL *object, PROTO_STR *member,
+                                          int type,
                                           void **cache_slot) {
   return NULL;  // We do not have a properties table.
 }
@@ -213,7 +298,7 @@
  * Object handler for the get_properties event in PHP. This returns a HashTable
  * of our internal properties. We don't support this, so we return NULL.
  */
-static HashTable* Message_get_properties(zval* object TSRMLS_DC) {
+static HashTable *Message_get_properties(PROTO_VAL *object) {
   return NULL;  // We don't offer direct references to our properties.
 }
 
@@ -549,7 +634,7 @@
   zend_bool preserve_proto_fieldnames = false;
   upb_status status;
 
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b",
+  if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b",
                             &preserve_proto_fieldnames) == FAILURE) {
     return;
   }
@@ -800,20 +885,36 @@
   upb_msg_set(intern->msg, f, msgval, arena);
 }
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_void, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mergeFrom, 0, 0, 1)
+  ZEND_ARG_INFO(0, data)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_read, 0, 0, 1)
+  ZEND_ARG_INFO(0, field)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_write, 0, 0, 2)
+  ZEND_ARG_INFO(0, field)
+  ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
 static zend_function_entry Message_methods[] = {
-  PHP_ME(Message, clear, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Message, discardUnknownFields, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Message, serializeToString, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Message, mergeFromString, 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, readWrapperValue, NULL, ZEND_ACC_PROTECTED)
-  PHP_ME(Message, writeWrapperValue, NULL, ZEND_ACC_PROTECTED)
-  PHP_ME(Message, readOneof, NULL, ZEND_ACC_PROTECTED)
-  PHP_ME(Message, writeOneof, NULL, ZEND_ACC_PROTECTED)
-  PHP_ME(Message, whichOneof, NULL, ZEND_ACC_PROTECTED)
-  PHP_ME(Message, __construct, NULL, ZEND_ACC_PROTECTED)
+  PHP_ME(Message, clear,                 arginfo_void,      ZEND_ACC_PUBLIC)
+  PHP_ME(Message, discardUnknownFields,  arginfo_void,      ZEND_ACC_PUBLIC)
+  PHP_ME(Message, serializeToString,     arginfo_void,      ZEND_ACC_PUBLIC)
+  PHP_ME(Message, mergeFromString,       arginfo_mergeFrom, ZEND_ACC_PUBLIC)
+  PHP_ME(Message, serializeToJsonString, arginfo_void,      ZEND_ACC_PUBLIC)
+  PHP_ME(Message, mergeFromJsonString,   arginfo_mergeFrom, ZEND_ACC_PUBLIC)
+  PHP_ME(Message, mergeFrom,             arginfo_mergeFrom, ZEND_ACC_PUBLIC)
+  PHP_ME(Message, readWrapperValue,      arginfo_read,      ZEND_ACC_PROTECTED)
+  PHP_ME(Message, writeWrapperValue,     arginfo_write,     ZEND_ACC_PROTECTED)
+  PHP_ME(Message, readOneof,             arginfo_read,      ZEND_ACC_PROTECTED)
+  PHP_ME(Message, writeOneof,            arginfo_write,     ZEND_ACC_PROTECTED)
+  PHP_ME(Message, whichOneof,            arginfo_read,      ZEND_ACC_PROTECTED)
+  PHP_ME(Message, __construct,           arginfo_void,      ZEND_ACC_PROTECTED)
   ZEND_FE_END
 };
 
@@ -836,6 +937,8 @@
   h->dtor_obj = Message_dtor;
   h->read_property = Message_read_property;
   h->write_property = Message_write_property;
+  h->has_property = Message_has_property;
+  h->unset_property = Message_unset_property;
   h->get_properties = Message_get_properties;
   h->get_property_ptr_ptr = Message_get_property_ptr_ptr;
 }
diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml
index b8ae8ba..037fa90 100644
--- a/php/ext/google/protobuf/package.xml
+++ b/php/ext/google/protobuf/package.xml
@@ -10,11 +10,11 @@
   <email>[email protected]</email>
   <active>yes</active>
  </lead>
- <date>2020-06-01</date>
- <time>01:14:10</time>
+ <date>2020-08-14</date>
+ <time>14:07:59</time>
  <version>
-  <release>3.12.3</release>
-  <api>3.12.3</api>
+  <release>3.13.0</release>
+  <api>3.13.0</api>
  </version>
  <stability>
   <release>stable</release>
@@ -51,7 +51,7 @@
  <dependencies>
   <required>
    <php>
-    <min>5.5.9</min>
+    <min>7.0.0</min>
    </php>
    <pearinstaller>
     <min>1.4.0</min>
@@ -619,5 +619,61 @@
    <license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
    <notes>GA release.</notes>
   </release>
+  <release>
+   <version>
+    <release>3.13.0RC1</release>
+    <api>3.13.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2020-08-05</date>
+   <time>11:21:41</time>
+   <license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
+   <notes>GA release.</notes>
+  </release>
+  <release>
+   <version>
+    <release>3.13.0RC2</release>
+    <api>3.13.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2020-08-05</date>
+   <time>11:22:52</time>
+   <license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
+   <notes>GA release.</notes>
+  </release>
+  <release>
+   <version>
+    <release>3.13.0RC3</release>
+    <api>3.13.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2020-08-12</date>
+   <time>13:46:54</time>
+   <license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
+   <notes>GA release.</notes>
+  </release>
+  <release>
+   <version>
+    <release>3.13.0</release>
+    <api>3.13.0</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2020-08-14</date>
+   <time>14:07:59</time>
+   <license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
+   <notes>GA release.</notes>
+  </release>
  </changelog>
 </package>
diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c
index f5ea2ef..6ce85f1 100644
--- a/php/ext/google/protobuf/php-upb.c
+++ b/php/ext/google/protobuf/php-upb.c
@@ -174,6 +174,11 @@
 #else
 #define UPB_INFINITY (1.0 / 0.0)
 #endif
+#ifdef NAN
+#define UPB_NAN NAN
+#else
+#define UPB_NAN (0.0 / 0.0)
+#endif
 
 #include <setjmp.h>
 #include <string.h>
@@ -235,11 +240,13 @@
                                    (1 << UPB_DTYPE_SFIXED64);
 
 /* Op: an action to be performed for a wire-type/field-type combination. */
-#define OP_SCALAR_LG2(n) (n)
-#define OP_FIXPCK_LG2(n) (n + 4)
-#define OP_VARPCK_LG2(n) (n + 8)
+#define OP_SCALAR_LG2(n) (n)      /* n in [0, 2, 3] => op in [0, 2, 3] */
 #define OP_STRING 4
-#define OP_SUBMSG 5
+#define OP_BYTES 5
+#define OP_SUBMSG 6
+/* Ops above are scalar-only. Repeated fields can use any op.  */
+#define OP_FIXPCK_LG2(n) (n + 5)  /* n in [2, 3] => op in [7, 8] */
+#define OP_VARPCK_LG2(n) (n + 9)  /* n in [0, 2, 3] => op in [9, 11, 12] */
 
 static const int8_t varint_ops[19] = {
     -1,               /* field not found */
@@ -277,7 +284,7 @@
     OP_STRING, /* STRING */
     -1,        /* GROUP */
     OP_SUBMSG, /* MESSAGE */
-    OP_STRING, /* BYTES */
+    OP_BYTES,  /* BYTES */
     -1,        /* UINT32 */
     -1,        /* ENUM */
     -1,        /* SFIXED32 */
@@ -296,7 +303,7 @@
     OP_STRING,        /* REPEATED STRING */
     OP_SUBMSG,        /* REPEATED GROUP */
     OP_SUBMSG,        /* REPEATED MESSAGE */
-    OP_STRING,        /* REPEATED BYTES */
+    OP_BYTES,         /* REPEATED BYTES */
     OP_VARPCK_LG2(2), /* REPEATED UINT32 */
     OP_VARPCK_LG2(2), /* REPEATED ENUM */
     OP_FIXPCK_LG2(2), /* REPEATED SFIXED32 */
@@ -328,6 +335,40 @@
 
 UPB_NORETURN static void decode_err(upb_decstate *d) { longjmp(d->err, 1); }
 
+void decode_verifyutf8(upb_decstate *d, const char *buf, int len) {
+  static const uint8_t utf8_offset[] = {
+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+      1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+      2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+      4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0,
+  };
+
+  int i, j;
+  uint8_t offset;
+
+  i = 0;
+  while (i < len) {
+    offset = utf8_offset[(uint8_t)buf[i]];
+    if (offset == 0 || i + offset > len) {
+      decode_err(d);
+    }
+    for (j = i + 1; j < i + offset; j++) {
+      if ((buf[j] & 0xc0) != 0x80) {
+        decode_err(d);
+      }
+    }
+    i += offset;
+  }
+  if (i != len) decode_err(d);
+}
+
 static bool decode_reserve(upb_decstate *d, upb_array *arr, size_t elem) {
   bool need_realloc = arr->size - arr->len < elem;
   if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, d->arena)) {
@@ -395,7 +436,7 @@
 
 static const upb_msglayout_field *upb_find_field(const upb_msglayout *l,
                                                  uint32_t field_number) {
-  static upb_msglayout_field none = {0};
+  static upb_msglayout_field none = {0, 0, 0, 0, 0, 0};
 
   /* Lots of optimization opportunities here. */
   int i;
@@ -473,7 +514,10 @@
       memcpy(mem, &val, 1 << op);
       return ptr;
     case OP_STRING:
-      /* Append string. */
+      decode_verifyutf8(d, val.str_val.data, val.str_val.size);
+      /* Fallthrough. */
+    case OP_BYTES:
+      /* Append bytes. */
       mem =
           UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(upb_strview), void);
       arr->len++;
@@ -607,6 +651,9 @@
       break;
     }
     case OP_STRING:
+      decode_verifyutf8(d, val.str_val.data, val.str_val.size);
+      /* Fallthrough. */
+    case OP_BYTES:
       memcpy(mem, &val, sizeof(upb_strview));
       break;
     case OP_SCALAR_LG2(3):
@@ -1892,17 +1939,6 @@
   return success;
 }
 
-bool upb_inttable_push2(upb_inttable *t, upb_value val, upb_alloc *a) {
-  return upb_inttable_insert2(t, upb_inttable_count(t), val, a);
-}
-
-upb_value upb_inttable_pop(upb_inttable *t) {
-  upb_value val;
-  bool ok = upb_inttable_remove(t, upb_inttable_count(t) - 1, &val);
-  UPB_ASSERT(ok);
-  return val;
-}
-
 bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val,
                              upb_alloc *a) {
   return upb_inttable_insert2(t, (uintptr_t)key, val, a);
@@ -2328,15 +2364,28 @@
 
 static const size_t memblock_reserve = UPB_ALIGN_UP(sizeof(mem_block), 16);
 
+static upb_arena *arena_findroot(upb_arena *a) {
+  /* Path splitting keeps time complexity down, see:
+   *   https://en.wikipedia.org/wiki/Disjoint-set_data_structure */
+  while (a->parent != a) {
+    upb_arena *next = a->parent;
+    a->parent = next->parent;
+    a = next;
+  }
+  return a;
+}
+
 static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size) {
   mem_block *block = ptr;
+  upb_arena *root = arena_findroot(a);
 
-  block->next = a->freelist;
+  /* The block is for arena |a|, but should appear in the freelist of |root|. */
+  block->next = root->freelist;
   block->size = (uint32_t)size;
   block->cleanups = 0;
-  a->freelist = block;
+  root->freelist = block;
   a->last_size = block->size;
-  if (!a->freelist_tail) a->freelist_tail = block;
+  if (!root->freelist_tail) root->freelist_tail = block;
 
   a->head.ptr = UPB_PTR_AT(block, memblock_reserve, char);
   a->head.end = UPB_PTR_AT(block, size, char);
@@ -2371,17 +2420,6 @@
   return upb_arena_realloc(a, ptr, oldsize, size);
 }
 
-static upb_arena *arena_findroot(upb_arena *a) {
-  /* Path splitting keeps time complexity down, see:
-   *   https://en.wikipedia.org/wiki/Disjoint-set_data_structure */
-  while (a->parent != a) {
-    upb_arena *next = a->parent;
-    a->parent = next->parent;
-    a = next;
-  }
-  return a;
-}
-
 /* Public Arena API ***********************************************************/
 
 upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) {
@@ -2540,9 +2578,9 @@
 };
 
 static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12] = {
-  {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
-  {2, UPB_SIZE(12, 24), 2, 0, 9, 1},
-  {3, UPB_SIZE(36, 72), 0, 0, 9, 3},
+  {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
+  {2, UPB_SIZE(12, 24), 2, 0, 12, 1},
+  {3, UPB_SIZE(36, 72), 0, 0, 12, 3},
   {4, UPB_SIZE(40, 80), 0, 0, 11, 3},
   {5, UPB_SIZE(44, 88), 0, 1, 11, 3},
   {6, UPB_SIZE(48, 96), 0, 4, 11, 3},
@@ -2551,7 +2589,7 @@
   {9, UPB_SIZE(32, 64), 5, 5, 11, 1},
   {10, UPB_SIZE(56, 112), 0, 0, 5, 3},
   {11, UPB_SIZE(60, 120), 0, 0, 5, 3},
-  {12, UPB_SIZE(20, 40), 3, 0, 9, 1},
+  {12, UPB_SIZE(20, 40), 3, 0, 12, 1},
 };
 
 const upb_msglayout google_protobuf_FileDescriptorProto_msginit = {
@@ -2571,7 +2609,7 @@
 };
 
 static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = {
-  {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
   {2, UPB_SIZE(16, 32), 0, 4, 11, 3},
   {3, UPB_SIZE(20, 40), 0, 0, 11, 3},
   {4, UPB_SIZE(24, 48), 0, 3, 11, 3},
@@ -2580,7 +2618,7 @@
   {7, UPB_SIZE(12, 24), 2, 5, 11, 1},
   {8, UPB_SIZE(36, 72), 0, 6, 11, 3},
   {9, UPB_SIZE(40, 80), 0, 2, 11, 3},
-  {10, UPB_SIZE(44, 88), 0, 0, 9, 3},
+  {10, UPB_SIZE(44, 88), 0, 0, 12, 3},
 };
 
 const upb_msglayout google_protobuf_DescriptorProto_msginit = {
@@ -2635,16 +2673,16 @@
 };
 
 static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11] = {
-  {1, UPB_SIZE(36, 40), 6, 0, 9, 1},
-  {2, UPB_SIZE(44, 56), 7, 0, 9, 1},
+  {1, UPB_SIZE(36, 40), 6, 0, 12, 1},
+  {2, UPB_SIZE(44, 56), 7, 0, 12, 1},
   {3, UPB_SIZE(24, 24), 3, 0, 5, 1},
   {4, UPB_SIZE(8, 8), 1, 0, 14, 1},
   {5, UPB_SIZE(16, 16), 2, 0, 14, 1},
-  {6, UPB_SIZE(52, 72), 8, 0, 9, 1},
-  {7, UPB_SIZE(60, 88), 9, 0, 9, 1},
+  {6, UPB_SIZE(52, 72), 8, 0, 12, 1},
+  {7, UPB_SIZE(60, 88), 9, 0, 12, 1},
   {8, UPB_SIZE(76, 120), 11, 0, 11, 1},
   {9, UPB_SIZE(28, 28), 4, 0, 5, 1},
-  {10, UPB_SIZE(68, 104), 10, 0, 9, 1},
+  {10, UPB_SIZE(68, 104), 10, 0, 12, 1},
   {17, UPB_SIZE(32, 32), 5, 0, 8, 1},
 };
 
@@ -2659,7 +2697,7 @@
 };
 
 static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2] = {
-  {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
   {2, UPB_SIZE(12, 24), 2, 0, 11, 1},
 };
 
@@ -2676,11 +2714,11 @@
 };
 
 static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5] = {
-  {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
   {2, UPB_SIZE(16, 32), 0, 2, 11, 3},
   {3, UPB_SIZE(12, 24), 2, 1, 11, 1},
   {4, UPB_SIZE(20, 40), 0, 0, 11, 3},
-  {5, UPB_SIZE(24, 48), 0, 0, 9, 3},
+  {5, UPB_SIZE(24, 48), 0, 0, 12, 3},
 };
 
 const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = {
@@ -2705,7 +2743,7 @@
 };
 
 static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = {
-  {1, UPB_SIZE(8, 8), 2, 0, 9, 1},
+  {1, UPB_SIZE(8, 8), 2, 0, 12, 1},
   {2, UPB_SIZE(4, 4), 1, 0, 5, 1},
   {3, UPB_SIZE(16, 24), 3, 0, 11, 1},
 };
@@ -2722,7 +2760,7 @@
 };
 
 static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[3] = {
-  {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
   {2, UPB_SIZE(16, 32), 0, 0, 11, 3},
   {3, UPB_SIZE(12, 24), 2, 1, 11, 1},
 };
@@ -2738,9 +2776,9 @@
 };
 
 static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = {
-  {1, UPB_SIZE(4, 8), 3, 0, 9, 1},
-  {2, UPB_SIZE(12, 24), 4, 0, 9, 1},
-  {3, UPB_SIZE(20, 40), 5, 0, 9, 1},
+  {1, UPB_SIZE(4, 8), 3, 0, 12, 1},
+  {2, UPB_SIZE(12, 24), 4, 0, 12, 1},
+  {3, UPB_SIZE(20, 40), 5, 0, 12, 1},
   {4, UPB_SIZE(28, 56), 6, 0, 11, 1},
   {5, UPB_SIZE(1, 1), 1, 0, 8, 1},
   {6, UPB_SIZE(2, 2), 2, 0, 8, 1},
@@ -2757,11 +2795,11 @@
 };
 
 static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = {
-  {1, UPB_SIZE(28, 32), 11, 0, 9, 1},
-  {8, UPB_SIZE(36, 48), 12, 0, 9, 1},
+  {1, UPB_SIZE(28, 32), 11, 0, 12, 1},
+  {8, UPB_SIZE(36, 48), 12, 0, 12, 1},
   {9, UPB_SIZE(8, 8), 1, 0, 14, 1},
   {10, UPB_SIZE(16, 16), 2, 0, 8, 1},
-  {11, UPB_SIZE(44, 64), 13, 0, 9, 1},
+  {11, UPB_SIZE(44, 64), 13, 0, 12, 1},
   {16, UPB_SIZE(17, 17), 3, 0, 8, 1},
   {17, UPB_SIZE(18, 18), 4, 0, 8, 1},
   {18, UPB_SIZE(19, 19), 5, 0, 8, 1},
@@ -2769,14 +2807,14 @@
   {23, UPB_SIZE(21, 21), 7, 0, 8, 1},
   {27, UPB_SIZE(22, 22), 8, 0, 8, 1},
   {31, UPB_SIZE(23, 23), 9, 0, 8, 1},
-  {36, UPB_SIZE(52, 80), 14, 0, 9, 1},
-  {37, UPB_SIZE(60, 96), 15, 0, 9, 1},
-  {39, UPB_SIZE(68, 112), 16, 0, 9, 1},
-  {40, UPB_SIZE(76, 128), 17, 0, 9, 1},
-  {41, UPB_SIZE(84, 144), 18, 0, 9, 1},
+  {36, UPB_SIZE(52, 80), 14, 0, 12, 1},
+  {37, UPB_SIZE(60, 96), 15, 0, 12, 1},
+  {39, UPB_SIZE(68, 112), 16, 0, 12, 1},
+  {40, UPB_SIZE(76, 128), 17, 0, 12, 1},
+  {41, UPB_SIZE(84, 144), 18, 0, 12, 1},
   {42, UPB_SIZE(24, 24), 10, 0, 8, 1},
-  {44, UPB_SIZE(92, 160), 19, 0, 9, 1},
-  {45, UPB_SIZE(100, 176), 20, 0, 9, 1},
+  {44, UPB_SIZE(92, 160), 19, 0, 12, 1},
+  {45, UPB_SIZE(100, 176), 20, 0, 12, 1},
   {999, UPB_SIZE(108, 192), 0, 0, 11, 3},
 };
 
@@ -2906,12 +2944,12 @@
 
 static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = {
   {2, UPB_SIZE(56, 80), 0, 0, 11, 3},
-  {3, UPB_SIZE(32, 32), 4, 0, 9, 1},
+  {3, UPB_SIZE(32, 32), 4, 0, 12, 1},
   {4, UPB_SIZE(8, 8), 1, 0, 4, 1},
   {5, UPB_SIZE(16, 16), 2, 0, 3, 1},
   {6, UPB_SIZE(24, 24), 3, 0, 1, 1},
   {7, UPB_SIZE(40, 48), 5, 0, 12, 1},
-  {8, UPB_SIZE(48, 64), 6, 0, 9, 1},
+  {8, UPB_SIZE(48, 64), 6, 0, 12, 1},
 };
 
 const upb_msglayout google_protobuf_UninterpretedOption_msginit = {
@@ -2921,7 +2959,7 @@
 };
 
 static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = {
-  {1, UPB_SIZE(4, 8), 2, 0, 9, 2},
+  {1, UPB_SIZE(4, 8), 2, 0, 12, 2},
   {2, UPB_SIZE(1, 1), 1, 0, 8, 2},
 };
 
@@ -2948,9 +2986,9 @@
 static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = {
   {1, UPB_SIZE(20, 40), 0, 0, 5, _UPB_LABEL_PACKED},
   {2, UPB_SIZE(24, 48), 0, 0, 5, _UPB_LABEL_PACKED},
-  {3, UPB_SIZE(4, 8), 1, 0, 9, 1},
-  {4, UPB_SIZE(12, 24), 2, 0, 9, 1},
-  {6, UPB_SIZE(28, 56), 0, 0, 9, 3},
+  {3, UPB_SIZE(4, 8), 1, 0, 12, 1},
+  {4, UPB_SIZE(12, 24), 2, 0, 12, 1},
+  {6, UPB_SIZE(28, 56), 0, 0, 12, 3},
 };
 
 const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = {
@@ -2975,7 +3013,7 @@
 
 static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = {
   {1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_LABEL_PACKED},
-  {2, UPB_SIZE(12, 16), 3, 0, 9, 1},
+  {2, UPB_SIZE(12, 16), 3, 0, 12, 1},
   {3, UPB_SIZE(4, 4), 1, 0, 5, 1},
   {4, UPB_SIZE(8, 8), 2, 0, 5, 1},
 };
@@ -4383,6 +4421,13 @@
     field->descriptortype = upb_fielddef_descriptortype(f);
     field->label = upb_fielddef_label(f);
 
+    if (field->descriptortype == UPB_DTYPE_STRING &&
+        f->file->syntax == UPB_SYNTAX_PROTO2) {
+      /* See TableDescriptorType() in upbc/generator.cc for details and
+       * rationale. */
+      field->descriptortype = UPB_DTYPE_BYTES;
+    }
+
     if (upb_fielddef_ismap(f)) {
       field->label = _UPB_LABEL_MAP;
     } else if (upb_fielddef_packed(f)) {
@@ -4918,13 +4963,21 @@
     f->oneof = NULL;
   }
 
-  if (google_protobuf_FieldDescriptorProto_has_options(field_proto)) {
-    options = google_protobuf_FieldDescriptorProto_options(field_proto);
-    f->lazy_ = google_protobuf_FieldOptions_lazy(options);
+  options = google_protobuf_FieldDescriptorProto_has_options(field_proto) ?
+    google_protobuf_FieldDescriptorProto_options(field_proto) : NULL;
+
+  if (options && google_protobuf_FieldOptions_has_packed(options)) {
     f->packed_ = google_protobuf_FieldOptions_packed(options);
   } else {
+    /* Repeated fields default to packed for proto3 only. */
+    f->packed_ = upb_fielddef_isprimitive(f) &&
+        f->label_ == UPB_LABEL_REPEATED && f->file->syntax == UPB_SYNTAX_PROTO3;
+  }
+
+  if (options) {
+    f->lazy_ = google_protobuf_FieldOptions_lazy(options);
+  } else {
     f->lazy_ = false;
-    f->packed_ = false;
   }
 
   return true;
@@ -5188,7 +5241,7 @@
   const google_protobuf_FieldDescriptorProto *const *exts;
   const upb_strview* strs;
   size_t i, n;
-  decl_counts counts = {0};
+  decl_counts counts = {0, 0, 0};
 
   count_types_in_file(file_proto, &counts);
 
@@ -5612,7 +5665,11 @@
   if (upb_oneof_done(&i)) return false;
   f = upb_oneof_iter_field(&i);
   field = upb_fielddef_layout(f);
-  oneof_case = _upb_getoneofcase_field(msg, field);
+  if (in_oneof(field)) {
+    oneof_case = _upb_getoneofcase_field(msg, field);
+  } else {
+    return _upb_hasbit_field(msg, field) ? f : NULL;
+  }
 
   return oneof_case ? upb_msgdef_itof(m, oneof_case) : NULL;
 }
@@ -6341,6 +6398,7 @@
         upb_strview ret;
         ret.data = buf;
         ret.size = end - buf;
+        *end = '\0';  /* Needed for possible strtod(). */
         return ret;
       }
       case '\\':
@@ -6665,7 +6723,7 @@
     case JD_STRING:
       str = jsondec_string(d);
       if (jsondec_streql(str, "NaN")) {
-        val.double_val = 0.0 / 0.0;
+        val.double_val = UPB_NAN;
       } else if (jsondec_streql(str, "Infinity")) {
         val.double_val = UPB_INFINITY;
       } else if (jsondec_streql(str, "-Infinity")) {
@@ -6822,7 +6880,7 @@
     return;
   }
 
-  if (upb_fielddef_containingoneof(f) &&
+  if (upb_fielddef_realcontainingoneof(f) &&
       upb_msg_whichoneof(msg, upb_fielddef_containingoneof(f))) {
     jsondec_err(d, "More than one field for this oneof.");
   }
@@ -7655,7 +7713,7 @@
   ret = upb_symtab_lookupmsg2(e->ext_pool, ptr, end - ptr);
 
   if (!ret) {
-    jsonenc_errf(e, "Couldn't find Any type: %.*s (full URL: " UPB_STRVIEW_FORMAT ")", (int)(end - ptr), ptr, UPB_STRVIEW_ARGS(type_url));
+    jsonenc_errf(e, "Couldn't find Any type: %.*s", (int)(end - ptr), ptr);
   }
 
   return ret;
@@ -8071,6 +8129,7 @@
 #undef UPB_ASSERT_DEBUGVAR
 #undef UPB_UNREACHABLE
 #undef UPB_INFINITY
+#undef UPB_NAN
 #undef UPB_MSVC_VSNPRINTF
 #undef _upb_snprintf
 #undef _upb_vsnprintf
diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h
index a07885f..666ec76 100644
--- a/php/ext/google/protobuf/php-upb.h
+++ b/php/ext/google/protobuf/php-upb.h
@@ -173,6 +173,11 @@
 #else
 #define UPB_INFINITY (1.0 / 0.0)
 #endif
+#ifdef NAN
+#define UPB_NAN NAN
+#else
+#define UPB_NAN (0.0 / 0.0)
+#endif
 /*
 ** upb_decode: parsing into a upb_msg using a upb_msglayout.
 */
@@ -208,7 +213,7 @@
 ** store pointers or integers of at least 32 bits (upb isn't really useful on
 ** systems where sizeof(void*) < 4).
 **
-** The table must be homogenous (all values of the same type).  In debug
+** The table must be homogeneous (all values of the same type).  In debug
 ** mode, we check this on insert and lookup.
 */
 
@@ -799,15 +804,6 @@
  * invalidate iterators. */
 bool upb_inttable_replace(upb_inttable *t, uintptr_t key, upb_value val);
 
-/* Handy routines for treating an inttable like a stack.  May not be mixed with
- * other insert/remove calls. */
-bool upb_inttable_push2(upb_inttable *t, upb_value val, upb_alloc *a);
-upb_value upb_inttable_pop(upb_inttable *t);
-
-UPB_INLINE bool upb_inttable_push(upb_inttable *t, upb_value val) {
-  return upb_inttable_push2(t, val, &upb_alloc_global);
-}
-
 /* Convenience routines for inttables with pointer keys. */
 bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val,
                              upb_alloc *a);
@@ -1072,7 +1068,7 @@
 
 UPB_INLINE size_t _upb_oneofcase_ofs(const upb_msglayout_field *f) {
   UPB_ASSERT(f->presence < 0);
-  return ~(int64_t)f->presence;
+  return ~(ptrdiff_t)f->presence;
 }
 
 UPB_INLINE uint32_t *_upb_oneofcase_field(upb_msg *msg,
@@ -3831,7 +3827,7 @@
 #endif
 
 enum {
-  /* When set, emits 0/default values.  TOOD(haberman): proto3 only? */
+  /* When set, emits 0/default values.  TODO(haberman): proto3 only? */
   UPB_JSONENC_EMITDEFAULTS = 1,
 
   /* When set, use normal (snake_caes) field names instead of JSON (camelCase)
@@ -3879,6 +3875,7 @@
 #undef UPB_ASSERT_DEBUGVAR
 #undef UPB_UNREACHABLE
 #undef UPB_INFINITY
+#undef UPB_NAN
 #undef UPB_MSVC_VSNPRINTF
 #undef _upb_snprintf
 #undef _upb_vsnprintf
diff --git a/php/ext/google/protobuf/protobuf.c b/php/ext/google/protobuf/protobuf.c
index 15c8f9b..fa1cc11 100644
--- a/php/ext/google/protobuf/protobuf.c
+++ b/php/ext/google/protobuf/protobuf.c
@@ -273,11 +273,18 @@
       zend_hash_find_ptr(&PROTOBUF_G(name_msg_cache), ce->name);
 
   if (!ret && ce->create_object) {
+#if PHP_VERSION_ID < 80000
     zval tmp;
     zval zv;
     ZVAL_OBJ(&tmp, ce->create_object(ce));
     zend_call_method_with_0_params(&tmp, ce, NULL, "__construct", &zv);
     zval_ptr_dtor(&tmp);
+#else
+    zval zv;
+    zend_object *tmp = ce->create_object(ce);
+    zend_call_method_with_0_params(tmp, ce, NULL, "__construct", &zv);
+    OBJ_RELEASE(tmp);
+#endif
     zval_ptr_dtor(&zv);
     ret = zend_hash_find_ptr(&PROTOBUF_G(name_msg_cache), ce->name);
   }
diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h
index 6a7afae..3188fe7 100644
--- a/php/ext/google/protobuf/protobuf.h
+++ b/php/ext/google/protobuf/protobuf.h
@@ -43,6 +43,34 @@
 #define GC_DELREF(h) --GC_REFCOUNT(h)
 #endif
 
+// Since php 7.4, the write_property() object handler now returns the assigned
+// value (after possible type coercions) rather than void.
+// https://github.com/php/php-src/blob/PHP-7.4.0/UPGRADING.INTERNALS#L171-L173
+#if PHP_VERSION_ID < 70400
+#define PROTO_RETURN_VAL void
+#else
+#define PROTO_RETURN_VAL zval*
+#endif
+
+// Sine php 8.0, the Object Handlers API was changed to receive zend_object*
+// instead of zval* and zend_string* instead of zval* for property names.
+// https://github.com/php/php-src/blob/php-8.0.0beta1/UPGRADING.INTERNALS#L37-L39
+#if PHP_VERSION_ID < 80000
+#define PROTO_VAL zval 
+#define PROTO_STR zval
+#define PROTO_MSG_P(obj) (Message*)Z_OBJ_P(obj)
+#define PROTO_STRVAL_P(obj) Z_STRVAL_P(obj)
+#define PROTO_STRLEN_P(obj) Z_STRLEN_P(obj)
+#else
+#define PROTO_VAL zend_object
+#define PROTO_STR zend_string
+#define PROTO_MSG_P(obj) (Message*)(obj)
+#define PROTO_STRVAL_P(obj) ZSTR_VAL(obj)
+#define PROTO_STRLEN_P(obj) ZSTR_LEN(obj)
+#endif
+
+#define PHP_PROTOBUF_VERSION "3.13.0"
+
 // ptr -> PHP object cache. This is a weak map that caches lazily-created
 // wrapper objects around upb types:
 //  * upb_msg* -> Message
diff --git a/php/phpunit.xml b/php/phpunit.xml
index 769037c..8e75835 100644
--- a/php/phpunit.xml
+++ b/php/phpunit.xml
@@ -3,16 +3,16 @@
          colors="true">
   <testsuites>
     <testsuite name="protobuf-tests">
-      <file>tests/php_implementation_test.php</file>
-      <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/descriptors_test.php</file>
-      <file>tests/generated_service_test.php</file>
-      <file>tests/wrapper_type_setters_test.php</file>
+      <file>tests/PhpImplementationTest.php</file>
+      <file>tests/ArrayTest.php</file>
+      <file>tests/EncodeDecodeTest.php</file>
+      <file>tests/GeneratedClassTest.php</file>
+      <file>tests/GeneratedPhpdocTest.php</file>
+      <file>tests/MapFieldTest.php</file>
+      <file>tests/WellKnownTest.php</file>
+      <file>tests/DescriptorsTest.php</file>
+      <file>tests/GeneratedServiceTest.php</file>
+      <file>tests/WrapperTypeSettersTest.php</file>
     </testsuite>
   </testsuites>
 </phpunit>
diff --git a/php/src/GPBMetadata/Google/Protobuf/Struct.php b/php/src/GPBMetadata/Google/Protobuf/Struct.php
index 96b42af..8e6191d 100644
--- a/php/src/GPBMetadata/Google/Protobuf/Struct.php
+++ b/php/src/GPBMetadata/Google/Protobuf/Struct.php
@@ -15,29 +15,8 @@
           return;
         }
         $pool->internalAddGeneratedFile(hex2bin(
-            "0a81050a1c676f6f676c652f70726f746f6275662f7374727563742e7072" .
-            "6f746f120f676f6f676c652e70726f746f6275662284010a065374727563" .
-            "7412330a066669656c647318012003280b32232e676f6f676c652e70726f" .
-            "746f6275662e5374727563742e4669656c6473456e7472791a450a0b4669" .
-            "656c6473456e747279120b0a036b657918012001280912250a0576616c75" .
-            "6518022001280b32162e676f6f676c652e70726f746f6275662e56616c75" .
-            "653a02380122ea010a0556616c756512300a0a6e756c6c5f76616c756518" .
-            "012001280e321a2e676f6f676c652e70726f746f6275662e4e756c6c5661" .
-            "6c7565480012160a0c6e756d6265725f76616c7565180220012801480012" .
-            "160a0c737472696e675f76616c7565180320012809480012140a0a626f6f" .
-            "6c5f76616c75651804200128084800122f0a0c7374727563745f76616c75" .
-            "6518052001280b32172e676f6f676c652e70726f746f6275662e53747275" .
-            "6374480012300a0a6c6973745f76616c756518062001280b321a2e676f6f" .
-            "676c652e70726f746f6275662e4c69737456616c7565480042060a046b69" .
-            "6e6422330a094c69737456616c756512260a0676616c7565731801200328" .
-            "0b32162e676f6f676c652e70726f746f6275662e56616c75652a1b0a094e" .
-            "756c6c56616c7565120e0a0a4e554c4c5f56414c554510004281010a1363" .
-            "6f6d2e676f6f676c652e70726f746f627566420b53747275637450726f74" .
-            "6f50015a316769746875622e636f6d2f676f6c616e672f70726f746f6275" .
-            "662f7074797065732f7374727563743b7374727563747062f80101a20203" .
-            "475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f77" .
-            "6e5479706573620670726f746f33"
-        ));
+            "0a81050a1c676f6f676c652f70726f746f6275662f7374727563742e70726f746f120f676f6f676c652e70726f746f6275662284010a0653747275637412330a066669656c647318012003280b32232e676f6f676c652e70726f746f6275662e5374727563742e4669656c6473456e7472791a450a0b4669656c6473456e747279120b0a036b657918012001280912250a0576616c756518022001280b32162e676f6f676c652e70726f746f6275662e56616c75653a02380122ea010a0556616c756512300a0a6e756c6c5f76616c756518012001280e321a2e676f6f676c652e70726f746f6275662e4e756c6c56616c7565480012160a0c6e756d6265725f76616c7565180220012801480012160a0c737472696e675f76616c7565180320012809480012140a0a626f6f6c5f76616c75651804200128084800122f0a0c7374727563745f76616c756518052001280b32172e676f6f676c652e70726f746f6275662e537472756374480012300a0a6c6973745f76616c756518062001280b321a2e676f6f676c652e70726f746f6275662e4c69737456616c7565480042060a046b696e6422330a094c69737456616c756512260a0676616c75657318012003280b32162e676f6f676c652e70726f746f6275662e56616c75652a1b0a094e756c6c56616c7565120e0a0a4e554c4c5f56414c554510004281010a13636f6d2e676f6f676c652e70726f746f627566420b53747275637450726f746f50015a316769746875622e636f6d2f676f6c616e672f70726f746f6275662f7074797065732f7374727563743b7374727563747062f80101a20203475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33"
+        ), true);
 
         static::$is_initialized = true;
     }
diff --git a/php/src/Google/Protobuf/Descriptor.php b/php/src/Google/Protobuf/Descriptor.php
index 986b81e..36436e2 100644
--- a/php/src/Google/Protobuf/Descriptor.php
+++ b/php/src/Google/Protobuf/Descriptor.php
@@ -97,4 +97,12 @@
     {
         return count($this->internal_desc->getOneofDecl());
     }
+
+    /**
+     * @return int Number of real oneofs in message
+     */
+    public function getRealOneofDeclCount()
+    {
+        return $this->internal_desc->getRealOneofDeclCount();
+    }
 }
diff --git a/php/src/Google/Protobuf/FieldDescriptor.php b/php/src/Google/Protobuf/FieldDescriptor.php
index ac9271f..6d08cea 100644
--- a/php/src/Google/Protobuf/FieldDescriptor.php
+++ b/php/src/Google/Protobuf/FieldDescriptor.php
@@ -114,4 +114,12 @@
     {
         return $this->internal_desc->isMap();
     }
+
+    /**
+     * @return boolean
+     */
+    public function hasOptionalKeyword()
+    {
+        return $this->internal_desc->hasOptionalKeyword();
+    }
 }
diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto.php b/php/src/Google/Protobuf/Internal/DescriptorProto.php
index 7cc689d..e0822d7 100644
--- a/php/src/Google/Protobuf/Internal/DescriptorProto.php
+++ b/php/src/Google/Protobuf/Internal/DescriptorProto.php
@@ -20,48 +20,39 @@
     /**
      * Generated from protobuf field <code>optional string name = 1;</code>
      */
-    protected $name = '';
-    private $has_name = false;
+    protected $name = null;
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.FieldDescriptorProto field = 2;</code>
      */
     private $field;
-    private $has_field = false;
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.FieldDescriptorProto extension = 6;</code>
      */
     private $extension;
-    private $has_extension = false;
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto nested_type = 3;</code>
      */
     private $nested_type;
-    private $has_nested_type = false;
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.EnumDescriptorProto enum_type = 4;</code>
      */
     private $enum_type;
-    private $has_enum_type = false;
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;</code>
      */
     private $extension_range;
-    private $has_extension_range = false;
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;</code>
      */
     private $oneof_decl;
-    private $has_oneof_decl = false;
     /**
      * Generated from protobuf field <code>optional .google.protobuf.MessageOptions options = 7;</code>
      */
     protected $options = null;
-    private $has_options = false;
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;</code>
      */
     private $reserved_range;
-    private $has_reserved_range = false;
     /**
      * Reserved field names, which may not be used by fields in the same message.
      * A given name may only be reserved once.
@@ -69,7 +60,6 @@
      * Generated from protobuf field <code>repeated string reserved_name = 10;</code>
      */
     private $reserved_name;
-    private $has_reserved_name = false;
 
     /**
      * Constructor.
@@ -102,7 +92,17 @@
      */
     public function getName()
     {
-        return $this->name;
+        return isset($this->name) ? $this->name : '';
+    }
+
+    public function hasName()
+    {
+        return isset($this->name);
+    }
+
+    public function clearName()
+    {
+        unset($this->name);
     }
 
     /**
@@ -114,16 +114,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->name = $var;
-        $this->has_name = true;
 
         return $this;
     }
 
-    public function hasName()
-    {
-        return $this->has_name;
-    }
-
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.FieldDescriptorProto field = 2;</code>
      * @return \Google\Protobuf\Internal\RepeatedField
@@ -142,16 +136,10 @@
     {
         $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()
-    {
-        return $this->has_field;
-    }
-
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.FieldDescriptorProto extension = 6;</code>
      * @return \Google\Protobuf\Internal\RepeatedField
@@ -170,16 +158,10 @@
     {
         $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()
-    {
-        return $this->has_extension;
-    }
-
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto nested_type = 3;</code>
      * @return \Google\Protobuf\Internal\RepeatedField
@@ -198,16 +180,10 @@
     {
         $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()
-    {
-        return $this->has_nested_type;
-    }
-
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.EnumDescriptorProto enum_type = 4;</code>
      * @return \Google\Protobuf\Internal\RepeatedField
@@ -226,16 +202,10 @@
     {
         $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()
-    {
-        return $this->has_enum_type;
-    }
-
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;</code>
      * @return \Google\Protobuf\Internal\RepeatedField
@@ -254,16 +224,10 @@
     {
         $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()
-    {
-        return $this->has_extension_range;
-    }
-
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;</code>
      * @return \Google\Protobuf\Internal\RepeatedField
@@ -282,23 +246,27 @@
     {
         $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()
-    {
-        return $this->has_oneof_decl;
-    }
-
     /**
      * Generated from protobuf field <code>optional .google.protobuf.MessageOptions options = 7;</code>
      * @return \Google\Protobuf\Internal\MessageOptions
      */
     public function getOptions()
     {
-        return $this->options;
+        return isset($this->options) ? $this->options : null;
+    }
+
+    public function hasOptions()
+    {
+        return isset($this->options);
+    }
+
+    public function clearOptions()
+    {
+        unset($this->options);
     }
 
     /**
@@ -310,16 +278,10 @@
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\MessageOptions::class);
         $this->options = $var;
-        $this->has_options = true;
 
         return $this;
     }
 
-    public function hasOptions()
-    {
-        return $this->has_options;
-    }
-
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;</code>
      * @return \Google\Protobuf\Internal\RepeatedField
@@ -338,16 +300,10 @@
     {
         $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()
-    {
-        return $this->has_reserved_range;
-    }
-
     /**
      * Reserved field names, which may not be used by fields in the same message.
      * A given name may only be reserved once.
@@ -372,15 +328,9 @@
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING);
         $this->reserved_name = $arr;
-        $this->has_reserved_name = true;
 
         return $this;
     }
 
-    public function hasReservedName()
-    {
-        return $this->has_reserved_name;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php b/php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php
index 82b5695..1594913 100644
--- a/php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php
+++ b/php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php
@@ -20,20 +20,17 @@
      *
      * Generated from protobuf field <code>optional int32 start = 1;</code>
      */
-    protected $start = 0;
-    private $has_start = false;
+    protected $start = null;
     /**
      * Exclusive.
      *
      * Generated from protobuf field <code>optional int32 end = 2;</code>
      */
-    protected $end = 0;
-    private $has_end = false;
+    protected $end = null;
     /**
      * Generated from protobuf field <code>optional .google.protobuf.ExtensionRangeOptions options = 3;</code>
      */
     protected $options = null;
-    private $has_options = false;
 
     /**
      * Constructor.
@@ -61,7 +58,17 @@
      */
     public function getStart()
     {
-        return $this->start;
+        return isset($this->start) ? $this->start : 0;
+    }
+
+    public function hasStart()
+    {
+        return isset($this->start);
+    }
+
+    public function clearStart()
+    {
+        unset($this->start);
     }
 
     /**
@@ -75,16 +82,10 @@
     {
         GPBUtil::checkInt32($var);
         $this->start = $var;
-        $this->has_start = true;
 
         return $this;
     }
 
-    public function hasStart()
-    {
-        return $this->has_start;
-    }
-
     /**
      * Exclusive.
      *
@@ -93,7 +94,17 @@
      */
     public function getEnd()
     {
-        return $this->end;
+        return isset($this->end) ? $this->end : 0;
+    }
+
+    public function hasEnd()
+    {
+        return isset($this->end);
+    }
+
+    public function clearEnd()
+    {
+        unset($this->end);
     }
 
     /**
@@ -107,23 +118,27 @@
     {
         GPBUtil::checkInt32($var);
         $this->end = $var;
-        $this->has_end = true;
 
         return $this;
     }
 
-    public function hasEnd()
-    {
-        return $this->has_end;
-    }
-
     /**
      * Generated from protobuf field <code>optional .google.protobuf.ExtensionRangeOptions options = 3;</code>
      * @return \Google\Protobuf\Internal\ExtensionRangeOptions
      */
     public function getOptions()
     {
-        return $this->options;
+        return isset($this->options) ? $this->options : null;
+    }
+
+    public function hasOptions()
+    {
+        return isset($this->options);
+    }
+
+    public function clearOptions()
+    {
+        unset($this->options);
     }
 
     /**
@@ -135,16 +150,10 @@
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\ExtensionRangeOptions::class);
         $this->options = $var;
-        $this->has_options = true;
 
         return $this;
     }
 
-    public function hasOptions()
-    {
-        return $this->has_options;
-    }
-
 }
 
 // Adding a class alias for backwards compatibility with the previous class name.
diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php b/php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php
index 8022151..f099cc3 100644
--- a/php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php
+++ b/php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php
@@ -24,15 +24,13 @@
      *
      * Generated from protobuf field <code>optional int32 start = 1;</code>
      */
-    protected $start = 0;
-    private $has_start = false;
+    protected $start = null;
     /**
      * Exclusive.
      *
      * Generated from protobuf field <code>optional int32 end = 2;</code>
      */
-    protected $end = 0;
-    private $has_end = false;
+    protected $end = null;
 
     /**
      * Constructor.
@@ -59,7 +57,17 @@
      */
     public function getStart()
     {
-        return $this->start;
+        return isset($this->start) ? $this->start : 0;
+    }
+
+    public function hasStart()
+    {
+        return isset($this->start);
+    }
+
+    public function clearStart()
+    {
+        unset($this->start);
     }
 
     /**
@@ -73,16 +81,10 @@
     {
         GPBUtil::checkInt32($var);
         $this->start = $var;
-        $this->has_start = true;
 
         return $this;
     }
 
-    public function hasStart()
-    {
-        return $this->has_start;
-    }
-
     /**
      * Exclusive.
      *
@@ -91,7 +93,17 @@
      */
     public function getEnd()
     {
-        return $this->end;
+        return isset($this->end) ? $this->end : 0;
+    }
+
+    public function hasEnd()
+    {
+        return isset($this->end);
+    }
+
+    public function clearEnd()
+    {
+        unset($this->end);
     }
 
     /**
@@ -105,16 +117,10 @@
     {
         GPBUtil::checkInt32($var);
         $this->end = $var;
-        $this->has_end = true;
 
         return $this;
     }
 
-    public function hasEnd()
-    {
-        return $this->has_end;
-    }
-
 }
 
 // Adding a class alias for backwards compatibility with the previous class name.
diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php b/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php
index f5c7fe1..85dc246 100644
--- a/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php
+++ b/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php
@@ -20,18 +20,15 @@
     /**
      * Generated from protobuf field <code>optional string name = 1;</code>
      */
-    protected $name = '';
-    private $has_name = false;
+    protected $name = null;
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.EnumValueDescriptorProto value = 2;</code>
      */
     private $value;
-    private $has_value = false;
     /**
      * Generated from protobuf field <code>optional .google.protobuf.EnumOptions options = 3;</code>
      */
     protected $options = null;
-    private $has_options = false;
     /**
      * Range of reserved numeric values. Reserved numeric values may not be used
      * by enum values in the same enum declaration. Reserved ranges may not
@@ -40,7 +37,6 @@
      * Generated from protobuf field <code>repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;</code>
      */
     private $reserved_range;
-    private $has_reserved_range = false;
     /**
      * Reserved enum value names, which may not be reused. A given name may only
      * be reserved once.
@@ -48,7 +44,6 @@
      * Generated from protobuf field <code>repeated string reserved_name = 5;</code>
      */
     private $reserved_name;
-    private $has_reserved_name = false;
 
     /**
      * Constructor.
@@ -79,7 +74,17 @@
      */
     public function getName()
     {
-        return $this->name;
+        return isset($this->name) ? $this->name : '';
+    }
+
+    public function hasName()
+    {
+        return isset($this->name);
+    }
+
+    public function clearName()
+    {
+        unset($this->name);
     }
 
     /**
@@ -91,16 +96,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->name = $var;
-        $this->has_name = true;
 
         return $this;
     }
 
-    public function hasName()
-    {
-        return $this->has_name;
-    }
-
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.EnumValueDescriptorProto value = 2;</code>
      * @return \Google\Protobuf\Internal\RepeatedField
@@ -119,23 +118,27 @@
     {
         $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()
-    {
-        return $this->has_value;
-    }
-
     /**
      * Generated from protobuf field <code>optional .google.protobuf.EnumOptions options = 3;</code>
      * @return \Google\Protobuf\Internal\EnumOptions
      */
     public function getOptions()
     {
-        return $this->options;
+        return isset($this->options) ? $this->options : null;
+    }
+
+    public function hasOptions()
+    {
+        return isset($this->options);
+    }
+
+    public function clearOptions()
+    {
+        unset($this->options);
     }
 
     /**
@@ -147,16 +150,10 @@
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\EnumOptions::class);
         $this->options = $var;
-        $this->has_options = true;
 
         return $this;
     }
 
-    public function hasOptions()
-    {
-        return $this->has_options;
-    }
-
     /**
      * Range of reserved numeric values. Reserved numeric values may not be used
      * by enum values in the same enum declaration. Reserved ranges may not
@@ -183,16 +180,10 @@
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange::class);
         $this->reserved_range = $arr;
-        $this->has_reserved_range = true;
 
         return $this;
     }
 
-    public function hasReservedRange()
-    {
-        return $this->has_reserved_range;
-    }
-
     /**
      * Reserved enum value names, which may not be reused. A given name may only
      * be reserved once.
@@ -217,15 +208,9 @@
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING);
         $this->reserved_name = $arr;
-        $this->has_reserved_name = true;
 
         return $this;
     }
 
-    public function hasReservedName()
-    {
-        return $this->has_reserved_name;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php b/php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php
index 949dd89..7282fcc 100644
--- a/php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php
+++ b/php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php
@@ -26,15 +26,13 @@
      *
      * Generated from protobuf field <code>optional int32 start = 1;</code>
      */
-    protected $start = 0;
-    private $has_start = false;
+    protected $start = null;
     /**
      * Inclusive.
      *
      * Generated from protobuf field <code>optional int32 end = 2;</code>
      */
-    protected $end = 0;
-    private $has_end = false;
+    protected $end = null;
 
     /**
      * Constructor.
@@ -61,7 +59,17 @@
      */
     public function getStart()
     {
-        return $this->start;
+        return isset($this->start) ? $this->start : 0;
+    }
+
+    public function hasStart()
+    {
+        return isset($this->start);
+    }
+
+    public function clearStart()
+    {
+        unset($this->start);
     }
 
     /**
@@ -75,16 +83,10 @@
     {
         GPBUtil::checkInt32($var);
         $this->start = $var;
-        $this->has_start = true;
 
         return $this;
     }
 
-    public function hasStart()
-    {
-        return $this->has_start;
-    }
-
     /**
      * Inclusive.
      *
@@ -93,7 +95,17 @@
      */
     public function getEnd()
     {
-        return $this->end;
+        return isset($this->end) ? $this->end : 0;
+    }
+
+    public function hasEnd()
+    {
+        return isset($this->end);
+    }
+
+    public function clearEnd()
+    {
+        unset($this->end);
     }
 
     /**
@@ -107,16 +119,10 @@
     {
         GPBUtil::checkInt32($var);
         $this->end = $var;
-        $this->has_end = true;
 
         return $this;
     }
 
-    public function hasEnd()
-    {
-        return $this->has_end;
-    }
-
 }
 
 // Adding a class alias for backwards compatibility with the previous class name.
diff --git a/php/src/Google/Protobuf/Internal/EnumOptions.php b/php/src/Google/Protobuf/Internal/EnumOptions.php
index e650042..7a69676 100644
--- a/php/src/Google/Protobuf/Internal/EnumOptions.php
+++ b/php/src/Google/Protobuf/Internal/EnumOptions.php
@@ -21,8 +21,7 @@
      *
      * Generated from protobuf field <code>optional bool allow_alias = 2;</code>
      */
-    protected $allow_alias = false;
-    private $has_allow_alias = false;
+    protected $allow_alias = null;
     /**
      * Is this enum deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
@@ -31,15 +30,13 @@
      *
      * Generated from protobuf field <code>optional bool deprecated = 3 [default = false];</code>
      */
-    protected $deprecated = false;
-    private $has_deprecated = false;
+    protected $deprecated = null;
     /**
      * 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;
 
     /**
      * Constructor.
@@ -73,7 +70,17 @@
      */
     public function getAllowAlias()
     {
-        return $this->allow_alias;
+        return isset($this->allow_alias) ? $this->allow_alias : false;
+    }
+
+    public function hasAllowAlias()
+    {
+        return isset($this->allow_alias);
+    }
+
+    public function clearAllowAlias()
+    {
+        unset($this->allow_alias);
     }
 
     /**
@@ -88,16 +95,10 @@
     {
         GPBUtil::checkBool($var);
         $this->allow_alias = $var;
-        $this->has_allow_alias = true;
 
         return $this;
     }
 
-    public function hasAllowAlias()
-    {
-        return $this->has_allow_alias;
-    }
-
     /**
      * Is this enum deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
@@ -109,7 +110,17 @@
      */
     public function getDeprecated()
     {
-        return $this->deprecated;
+        return isset($this->deprecated) ? $this->deprecated : false;
+    }
+
+    public function hasDeprecated()
+    {
+        return isset($this->deprecated);
+    }
+
+    public function clearDeprecated()
+    {
+        unset($this->deprecated);
     }
 
     /**
@@ -126,16 +137,10 @@
     {
         GPBUtil::checkBool($var);
         $this->deprecated = $var;
-        $this->has_deprecated = true;
 
         return $this;
     }
 
-    public function hasDeprecated()
-    {
-        return $this->has_deprecated;
-    }
-
     /**
      * The parser stores options it doesn't recognize here. See above.
      *
@@ -158,15 +163,9 @@
     {
         $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()
-    {
-        return $this->has_uninterpreted_option;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php b/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php
index 3dd9558..01097b6 100644
--- a/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php
+++ b/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php
@@ -20,18 +20,15 @@
     /**
      * Generated from protobuf field <code>optional string name = 1;</code>
      */
-    protected $name = '';
-    private $has_name = false;
+    protected $name = null;
     /**
      * Generated from protobuf field <code>optional int32 number = 2;</code>
      */
-    protected $number = 0;
-    private $has_number = false;
+    protected $number = null;
     /**
      * Generated from protobuf field <code>optional .google.protobuf.EnumValueOptions options = 3;</code>
      */
     protected $options = null;
-    private $has_options = false;
 
     /**
      * Constructor.
@@ -55,7 +52,17 @@
      */
     public function getName()
     {
-        return $this->name;
+        return isset($this->name) ? $this->name : '';
+    }
+
+    public function hasName()
+    {
+        return isset($this->name);
+    }
+
+    public function clearName()
+    {
+        unset($this->name);
     }
 
     /**
@@ -67,23 +74,27 @@
     {
         GPBUtil::checkString($var, True);
         $this->name = $var;
-        $this->has_name = true;
 
         return $this;
     }
 
-    public function hasName()
-    {
-        return $this->has_name;
-    }
-
     /**
      * Generated from protobuf field <code>optional int32 number = 2;</code>
      * @return int
      */
     public function getNumber()
     {
-        return $this->number;
+        return isset($this->number) ? $this->number : 0;
+    }
+
+    public function hasNumber()
+    {
+        return isset($this->number);
+    }
+
+    public function clearNumber()
+    {
+        unset($this->number);
     }
 
     /**
@@ -95,23 +106,27 @@
     {
         GPBUtil::checkInt32($var);
         $this->number = $var;
-        $this->has_number = true;
 
         return $this;
     }
 
-    public function hasNumber()
-    {
-        return $this->has_number;
-    }
-
     /**
      * Generated from protobuf field <code>optional .google.protobuf.EnumValueOptions options = 3;</code>
      * @return \Google\Protobuf\Internal\EnumValueOptions
      */
     public function getOptions()
     {
-        return $this->options;
+        return isset($this->options) ? $this->options : null;
+    }
+
+    public function hasOptions()
+    {
+        return isset($this->options);
+    }
+
+    public function clearOptions()
+    {
+        unset($this->options);
     }
 
     /**
@@ -123,15 +138,9 @@
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\EnumValueOptions::class);
         $this->options = $var;
-        $this->has_options = true;
 
         return $this;
     }
 
-    public function hasOptions()
-    {
-        return $this->has_options;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/EnumValueOptions.php b/php/src/Google/Protobuf/Internal/EnumValueOptions.php
index 9f9fb3b..84ba7bc 100644
--- a/php/src/Google/Protobuf/Internal/EnumValueOptions.php
+++ b/php/src/Google/Protobuf/Internal/EnumValueOptions.php
@@ -23,15 +23,13 @@
      *
      * Generated from protobuf field <code>optional bool deprecated = 1 [default = false];</code>
      */
-    protected $deprecated = false;
-    private $has_deprecated = false;
+    protected $deprecated = null;
     /**
      * 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;
 
     /**
      * Constructor.
@@ -64,7 +62,17 @@
      */
     public function getDeprecated()
     {
-        return $this->deprecated;
+        return isset($this->deprecated) ? $this->deprecated : false;
+    }
+
+    public function hasDeprecated()
+    {
+        return isset($this->deprecated);
+    }
+
+    public function clearDeprecated()
+    {
+        unset($this->deprecated);
     }
 
     /**
@@ -81,16 +89,10 @@
     {
         GPBUtil::checkBool($var);
         $this->deprecated = $var;
-        $this->has_deprecated = true;
 
         return $this;
     }
 
-    public function hasDeprecated()
-    {
-        return $this->has_deprecated;
-    }
-
     /**
      * The parser stores options it doesn't recognize here. See above.
      *
@@ -113,15 +115,9 @@
     {
         $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()
-    {
-        return $this->has_uninterpreted_option;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php b/php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php
index 00fbebe..b5e27c3 100644
--- a/php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php
+++ b/php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php
@@ -21,7 +21,6 @@
      * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
      */
     private $uninterpreted_option;
-    private $has_uninterpreted_option = false;
 
     /**
      * Constructor.
@@ -60,15 +59,9 @@
     {
         $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()
-    {
-        return $this->has_uninterpreted_option;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptor.php b/php/src/Google/Protobuf/Internal/FieldDescriptor.php
index 98b516f..ce83f63 100644
--- a/php/src/Google/Protobuf/Internal/FieldDescriptor.php
+++ b/php/src/Google/Protobuf/Internal/FieldDescriptor.php
@@ -229,7 +229,17 @@
         }
 
         $oneof_index = $proto->hasOneofIndex() ? $proto->getOneofIndex() : -1;
-        $packed = false;
+        // TODO: once proto2 is supported, this default should be false
+        // for proto2.
+        if ($proto->getLabel() === GPBLabel::REPEATED &&
+            $proto->getType() !== GPBType::MESSAGE &&
+            $proto->getType() !== GPBType::GROUP &&
+            $proto->getType() !== GPBType::STRING &&
+            $proto->getType() !== GPBType::BYTES) {
+          $packed = true;
+        } else {
+          $packed = false;
+        }
         $options = $proto->getOptions();
         if ($options !== null) {
             $packed = $options->getPacked();
diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php
index a65ce70..5c8823f 100644
--- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php
+++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php
@@ -20,26 +20,22 @@
     /**
      * Generated from protobuf field <code>optional string name = 1;</code>
      */
-    protected $name = '';
-    private $has_name = false;
+    protected $name = null;
     /**
      * Generated from protobuf field <code>optional int32 number = 3;</code>
      */
-    protected $number = 0;
-    private $has_number = false;
+    protected $number = null;
     /**
      * Generated from protobuf field <code>optional .google.protobuf.FieldDescriptorProto.Label label = 4;</code>
      */
-    protected $label = 0;
-    private $has_label = false;
+    protected $label = null;
     /**
      * 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.
      *
      * Generated from protobuf field <code>optional .google.protobuf.FieldDescriptorProto.Type type = 5;</code>
      */
-    protected $type = 0;
-    private $has_type = false;
+    protected $type = null;
     /**
      * 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
@@ -49,16 +45,14 @@
      *
      * Generated from protobuf field <code>optional string type_name = 6;</code>
      */
-    protected $type_name = '';
-    private $has_type_name = false;
+    protected $type_name = null;
     /**
      * For extensions, this is the name of the type being extended.  It is
      * resolved in the same manner as type_name.
      *
      * Generated from protobuf field <code>optional string extendee = 2;</code>
      */
-    protected $extendee = '';
-    private $has_extendee = false;
+    protected $extendee = null;
     /**
      * For numeric types, contains the original text representation of the value.
      * For booleans, "true" or "false".
@@ -68,16 +62,14 @@
      *
      * Generated from protobuf field <code>optional string default_value = 7;</code>
      */
-    protected $default_value = '';
-    private $has_default_value = false;
+    protected $default_value = null;
     /**
      * If set, gives the index of a oneof in the containing type's oneof_decl
      * list.  This field is a member of that oneof.
      *
      * Generated from protobuf field <code>optional int32 oneof_index = 9;</code>
      */
-    protected $oneof_index = 0;
-    private $has_oneof_index = false;
+    protected $oneof_index = null;
     /**
      * 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
@@ -86,13 +78,11 @@
      *
      * Generated from protobuf field <code>optional string json_name = 10;</code>
      */
-    protected $json_name = '';
-    private $has_json_name = false;
+    protected $json_name = null;
     /**
      * Generated from protobuf field <code>optional .google.protobuf.FieldOptions options = 8;</code>
      */
     protected $options = null;
-    private $has_options = false;
     /**
      * If true, this is a proto3 "optional". When a proto3 field is optional, it
      * tracks presence regardless of field type.
@@ -115,8 +105,7 @@
      *
      * Generated from protobuf field <code>optional bool proto3_optional = 17;</code>
      */
-    protected $proto3_optional = false;
-    private $has_proto3_optional = false;
+    protected $proto3_optional = null;
 
     /**
      * Constructor.
@@ -186,7 +175,17 @@
      */
     public function getName()
     {
-        return $this->name;
+        return isset($this->name) ? $this->name : '';
+    }
+
+    public function hasName()
+    {
+        return isset($this->name);
+    }
+
+    public function clearName()
+    {
+        unset($this->name);
     }
 
     /**
@@ -198,23 +197,27 @@
     {
         GPBUtil::checkString($var, True);
         $this->name = $var;
-        $this->has_name = true;
 
         return $this;
     }
 
-    public function hasName()
-    {
-        return $this->has_name;
-    }
-
     /**
      * Generated from protobuf field <code>optional int32 number = 3;</code>
      * @return int
      */
     public function getNumber()
     {
-        return $this->number;
+        return isset($this->number) ? $this->number : 0;
+    }
+
+    public function hasNumber()
+    {
+        return isset($this->number);
+    }
+
+    public function clearNumber()
+    {
+        unset($this->number);
     }
 
     /**
@@ -226,23 +229,27 @@
     {
         GPBUtil::checkInt32($var);
         $this->number = $var;
-        $this->has_number = true;
 
         return $this;
     }
 
-    public function hasNumber()
-    {
-        return $this->has_number;
-    }
-
     /**
      * Generated from protobuf field <code>optional .google.protobuf.FieldDescriptorProto.Label label = 4;</code>
      * @return int
      */
     public function getLabel()
     {
-        return $this->label;
+        return isset($this->label) ? $this->label : 0;
+    }
+
+    public function hasLabel()
+    {
+        return isset($this->label);
+    }
+
+    public function clearLabel()
+    {
+        unset($this->label);
     }
 
     /**
@@ -254,16 +261,10 @@
     {
         GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldDescriptorProto\Label::class);
         $this->label = $var;
-        $this->has_label = true;
 
         return $this;
     }
 
-    public function hasLabel()
-    {
-        return $this->has_label;
-    }
-
     /**
      * 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.
@@ -273,7 +274,17 @@
      */
     public function getType()
     {
-        return $this->type;
+        return isset($this->type) ? $this->type : 0;
+    }
+
+    public function hasType()
+    {
+        return isset($this->type);
+    }
+
+    public function clearType()
+    {
+        unset($this->type);
     }
 
     /**
@@ -288,16 +299,10 @@
     {
         GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldDescriptorProto\Type::class);
         $this->type = $var;
-        $this->has_type = true;
 
         return $this;
     }
 
-    public function hasType()
-    {
-        return $this->has_type;
-    }
-
     /**
      * 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
@@ -310,7 +315,17 @@
      */
     public function getTypeName()
     {
-        return $this->type_name;
+        return isset($this->type_name) ? $this->type_name : '';
+    }
+
+    public function hasTypeName()
+    {
+        return isset($this->type_name);
+    }
+
+    public function clearTypeName()
+    {
+        unset($this->type_name);
     }
 
     /**
@@ -328,16 +343,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->type_name = $var;
-        $this->has_type_name = true;
 
         return $this;
     }
 
-    public function hasTypeName()
-    {
-        return $this->has_type_name;
-    }
-
     /**
      * For extensions, this is the name of the type being extended.  It is
      * resolved in the same manner as type_name.
@@ -347,7 +356,17 @@
      */
     public function getExtendee()
     {
-        return $this->extendee;
+        return isset($this->extendee) ? $this->extendee : '';
+    }
+
+    public function hasExtendee()
+    {
+        return isset($this->extendee);
+    }
+
+    public function clearExtendee()
+    {
+        unset($this->extendee);
     }
 
     /**
@@ -362,16 +381,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->extendee = $var;
-        $this->has_extendee = true;
 
         return $this;
     }
 
-    public function hasExtendee()
-    {
-        return $this->has_extendee;
-    }
-
     /**
      * For numeric types, contains the original text representation of the value.
      * For booleans, "true" or "false".
@@ -384,7 +397,17 @@
      */
     public function getDefaultValue()
     {
-        return $this->default_value;
+        return isset($this->default_value) ? $this->default_value : '';
+    }
+
+    public function hasDefaultValue()
+    {
+        return isset($this->default_value);
+    }
+
+    public function clearDefaultValue()
+    {
+        unset($this->default_value);
     }
 
     /**
@@ -402,16 +425,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->default_value = $var;
-        $this->has_default_value = true;
 
         return $this;
     }
 
-    public function hasDefaultValue()
-    {
-        return $this->has_default_value;
-    }
-
     /**
      * If set, gives the index of a oneof in the containing type's oneof_decl
      * list.  This field is a member of that oneof.
@@ -421,7 +438,17 @@
      */
     public function getOneofIndex()
     {
-        return $this->oneof_index;
+        return isset($this->oneof_index) ? $this->oneof_index : 0;
+    }
+
+    public function hasOneofIndex()
+    {
+        return isset($this->oneof_index);
+    }
+
+    public function clearOneofIndex()
+    {
+        unset($this->oneof_index);
     }
 
     /**
@@ -436,16 +463,10 @@
     {
         GPBUtil::checkInt32($var);
         $this->oneof_index = $var;
-        $this->has_oneof_index = true;
 
         return $this;
     }
 
-    public function hasOneofIndex()
-    {
-        return $this->has_oneof_index;
-    }
-
     /**
      * 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
@@ -457,7 +478,17 @@
      */
     public function getJsonName()
     {
-        return $this->json_name;
+        return isset($this->json_name) ? $this->json_name : '';
+    }
+
+    public function hasJsonName()
+    {
+        return isset($this->json_name);
+    }
+
+    public function clearJsonName()
+    {
+        unset($this->json_name);
     }
 
     /**
@@ -474,23 +505,27 @@
     {
         GPBUtil::checkString($var, True);
         $this->json_name = $var;
-        $this->has_json_name = true;
 
         return $this;
     }
 
-    public function hasJsonName()
-    {
-        return $this->has_json_name;
-    }
-
     /**
      * Generated from protobuf field <code>optional .google.protobuf.FieldOptions options = 8;</code>
      * @return \Google\Protobuf\Internal\FieldOptions
      */
     public function getOptions()
     {
-        return $this->options;
+        return isset($this->options) ? $this->options : null;
+    }
+
+    public function hasOptions()
+    {
+        return isset($this->options);
+    }
+
+    public function clearOptions()
+    {
+        unset($this->options);
     }
 
     /**
@@ -502,16 +537,10 @@
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FieldOptions::class);
         $this->options = $var;
-        $this->has_options = true;
 
         return $this;
     }
 
-    public function hasOptions()
-    {
-        return $this->has_options;
-    }
-
     /**
      * If true, this is a proto3 "optional". When a proto3 field is optional, it
      * tracks presence regardless of field type.
@@ -537,7 +566,17 @@
      */
     public function getProto3Optional()
     {
-        return $this->proto3_optional;
+        return isset($this->proto3_optional) ? $this->proto3_optional : false;
+    }
+
+    public function hasProto3Optional()
+    {
+        return isset($this->proto3_optional);
+    }
+
+    public function clearProto3Optional()
+    {
+        unset($this->proto3_optional);
     }
 
     /**
@@ -568,15 +607,9 @@
     {
         GPBUtil::checkBool($var);
         $this->proto3_optional = $var;
-        $this->has_proto3_optional = true;
 
         return $this;
     }
 
-    public function hasProto3Optional()
-    {
-        return $this->has_proto3_optional;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/FieldOptions.php b/php/src/Google/Protobuf/Internal/FieldOptions.php
index c57077d..c6c63a9 100644
--- a/php/src/Google/Protobuf/Internal/FieldOptions.php
+++ b/php/src/Google/Protobuf/Internal/FieldOptions.php
@@ -23,8 +23,7 @@
      *
      * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];</code>
      */
-    protected $ctype = 0;
-    private $has_ctype = false;
+    protected $ctype = null;
     /**
      * The packed option can be enabled for repeated primitive fields to enable
      * a more efficient representation on the wire. Rather than repeatedly
@@ -34,8 +33,7 @@
      *
      * Generated from protobuf field <code>optional bool packed = 2;</code>
      */
-    protected $packed = false;
-    private $has_packed = false;
+    protected $packed = null;
     /**
      * 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
@@ -50,8 +48,7 @@
      *
      * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];</code>
      */
-    protected $jstype = 0;
-    private $has_jstype = false;
+    protected $jstype = null;
     /**
      * Should this field be parsed lazily?  Lazy applies only to message-type
      * fields.  It means that when the outer message is initially parsed, the
@@ -80,8 +77,7 @@
      *
      * Generated from protobuf field <code>optional bool lazy = 5 [default = false];</code>
      */
-    protected $lazy = false;
-    private $has_lazy = false;
+    protected $lazy = null;
     /**
      * Is this field deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
@@ -90,22 +86,19 @@
      *
      * Generated from protobuf field <code>optional bool deprecated = 3 [default = false];</code>
      */
-    protected $deprecated = false;
-    private $has_deprecated = false;
+    protected $deprecated = null;
     /**
      * For Google-internal migration only. Do not use.
      *
      * Generated from protobuf field <code>optional bool weak = 10 [default = false];</code>
      */
-    protected $weak = false;
-    private $has_weak = false;
+    protected $weak = null;
     /**
      * 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;
 
     /**
      * Constructor.
@@ -187,7 +180,17 @@
      */
     public function getCtype()
     {
-        return $this->ctype;
+        return isset($this->ctype) ? $this->ctype : 0;
+    }
+
+    public function hasCtype()
+    {
+        return isset($this->ctype);
+    }
+
+    public function clearCtype()
+    {
+        unset($this->ctype);
     }
 
     /**
@@ -204,16 +207,10 @@
     {
         GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldOptions\CType::class);
         $this->ctype = $var;
-        $this->has_ctype = true;
 
         return $this;
     }
 
-    public function hasCtype()
-    {
-        return $this->has_ctype;
-    }
-
     /**
      * The packed option can be enabled for repeated primitive fields to enable
      * a more efficient representation on the wire. Rather than repeatedly
@@ -226,7 +223,17 @@
      */
     public function getPacked()
     {
-        return $this->packed;
+        return isset($this->packed) ? $this->packed : false;
+    }
+
+    public function hasPacked()
+    {
+        return isset($this->packed);
+    }
+
+    public function clearPacked()
+    {
+        unset($this->packed);
     }
 
     /**
@@ -244,16 +251,10 @@
     {
         GPBUtil::checkBool($var);
         $this->packed = $var;
-        $this->has_packed = true;
 
         return $this;
     }
 
-    public function hasPacked()
-    {
-        return $this->has_packed;
-    }
-
     /**
      * 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
@@ -271,7 +272,17 @@
      */
     public function getJstype()
     {
-        return $this->jstype;
+        return isset($this->jstype) ? $this->jstype : 0;
+    }
+
+    public function hasJstype()
+    {
+        return isset($this->jstype);
+    }
+
+    public function clearJstype()
+    {
+        unset($this->jstype);
     }
 
     /**
@@ -294,16 +305,10 @@
     {
         GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldOptions\JSType::class);
         $this->jstype = $var;
-        $this->has_jstype = true;
 
         return $this;
     }
 
-    public function hasJstype()
-    {
-        return $this->has_jstype;
-    }
-
     /**
      * Should this field be parsed lazily?  Lazy applies only to message-type
      * fields.  It means that when the outer message is initially parsed, the
@@ -335,7 +340,17 @@
      */
     public function getLazy()
     {
-        return $this->lazy;
+        return isset($this->lazy) ? $this->lazy : false;
+    }
+
+    public function hasLazy()
+    {
+        return isset($this->lazy);
+    }
+
+    public function clearLazy()
+    {
+        unset($this->lazy);
     }
 
     /**
@@ -372,16 +387,10 @@
     {
         GPBUtil::checkBool($var);
         $this->lazy = $var;
-        $this->has_lazy = true;
 
         return $this;
     }
 
-    public function hasLazy()
-    {
-        return $this->has_lazy;
-    }
-
     /**
      * Is this field deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
@@ -393,7 +402,17 @@
      */
     public function getDeprecated()
     {
-        return $this->deprecated;
+        return isset($this->deprecated) ? $this->deprecated : false;
+    }
+
+    public function hasDeprecated()
+    {
+        return isset($this->deprecated);
+    }
+
+    public function clearDeprecated()
+    {
+        unset($this->deprecated);
     }
 
     /**
@@ -410,16 +429,10 @@
     {
         GPBUtil::checkBool($var);
         $this->deprecated = $var;
-        $this->has_deprecated = true;
 
         return $this;
     }
 
-    public function hasDeprecated()
-    {
-        return $this->has_deprecated;
-    }
-
     /**
      * For Google-internal migration only. Do not use.
      *
@@ -428,7 +441,17 @@
      */
     public function getWeak()
     {
-        return $this->weak;
+        return isset($this->weak) ? $this->weak : false;
+    }
+
+    public function hasWeak()
+    {
+        return isset($this->weak);
+    }
+
+    public function clearWeak()
+    {
+        unset($this->weak);
     }
 
     /**
@@ -442,16 +465,10 @@
     {
         GPBUtil::checkBool($var);
         $this->weak = $var;
-        $this->has_weak = true;
 
         return $this;
     }
 
-    public function hasWeak()
-    {
-        return $this->has_weak;
-    }
-
     /**
      * The parser stores options it doesn't recognize here. See above.
      *
@@ -474,15 +491,9 @@
     {
         $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()
-    {
-        return $this->has_uninterpreted_option;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/FileDescriptorProto.php b/php/src/Google/Protobuf/Internal/FileDescriptorProto.php
index c9e3648..96e2c6a 100644
--- a/php/src/Google/Protobuf/Internal/FileDescriptorProto.php
+++ b/php/src/Google/Protobuf/Internal/FileDescriptorProto.php
@@ -22,29 +22,25 @@
      *
      * Generated from protobuf field <code>optional string name = 1;</code>
      */
-    protected $name = '';
-    private $has_name = false;
+    protected $name = null;
     /**
      * e.g. "foo", "foo.bar", etc.
      *
      * Generated from protobuf field <code>optional string package = 2;</code>
      */
-    protected $package = '';
-    private $has_package = false;
+    protected $package = null;
     /**
      * Names of files imported by this file.
      *
      * Generated from protobuf field <code>repeated string dependency = 3;</code>
      */
     private $dependency;
-    private $has_dependency = false;
     /**
      * Indexes of the public imported files in the dependency list above.
      *
      * Generated from protobuf field <code>repeated int32 public_dependency = 10;</code>
      */
     private $public_dependency;
-    private $has_public_dependency = false;
     /**
      * Indexes of the weak imported files in the dependency list.
      * For Google-internal migration only. Do not use.
@@ -52,34 +48,28 @@
      * Generated from protobuf field <code>repeated int32 weak_dependency = 11;</code>
      */
     private $weak_dependency;
-    private $has_weak_dependency = false;
     /**
      * All top-level definitions in this file.
      *
      * Generated from protobuf field <code>repeated .google.protobuf.DescriptorProto message_type = 4;</code>
      */
     private $message_type;
-    private $has_message_type = false;
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.EnumDescriptorProto enum_type = 5;</code>
      */
     private $enum_type;
-    private $has_enum_type = false;
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.ServiceDescriptorProto service = 6;</code>
      */
     private $service;
-    private $has_service = false;
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.FieldDescriptorProto extension = 7;</code>
      */
     private $extension;
-    private $has_extension = false;
     /**
      * Generated from protobuf field <code>optional .google.protobuf.FileOptions options = 8;</code>
      */
     protected $options = null;
-    private $has_options = false;
     /**
      * This field contains optional information about the original source code.
      * You may safely remove this entire field without harming runtime
@@ -89,15 +79,13 @@
      * Generated from protobuf field <code>optional .google.protobuf.SourceCodeInfo source_code_info = 9;</code>
      */
     protected $source_code_info = null;
-    private $has_source_code_info = false;
     /**
      * The syntax of the proto file.
      * The supported values are "proto2" and "proto3".
      *
      * Generated from protobuf field <code>optional string syntax = 12;</code>
      */
-    protected $syntax = '';
-    private $has_syntax = false;
+    protected $syntax = null;
 
     /**
      * Constructor.
@@ -145,7 +133,17 @@
      */
     public function getName()
     {
-        return $this->name;
+        return isset($this->name) ? $this->name : '';
+    }
+
+    public function hasName()
+    {
+        return isset($this->name);
+    }
+
+    public function clearName()
+    {
+        unset($this->name);
     }
 
     /**
@@ -159,16 +157,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->name = $var;
-        $this->has_name = true;
 
         return $this;
     }
 
-    public function hasName()
-    {
-        return $this->has_name;
-    }
-
     /**
      * e.g. "foo", "foo.bar", etc.
      *
@@ -177,7 +169,17 @@
      */
     public function getPackage()
     {
-        return $this->package;
+        return isset($this->package) ? $this->package : '';
+    }
+
+    public function hasPackage()
+    {
+        return isset($this->package);
+    }
+
+    public function clearPackage()
+    {
+        unset($this->package);
     }
 
     /**
@@ -191,16 +193,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->package = $var;
-        $this->has_package = true;
 
         return $this;
     }
 
-    public function hasPackage()
-    {
-        return $this->has_package;
-    }
-
     /**
      * Names of files imported by this file.
      *
@@ -223,16 +219,10 @@
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING);
         $this->dependency = $arr;
-        $this->has_dependency = true;
 
         return $this;
     }
 
-    public function hasDependency()
-    {
-        return $this->has_dependency;
-    }
-
     /**
      * Indexes of the public imported files in the dependency list above.
      *
@@ -255,16 +245,10 @@
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
         $this->public_dependency = $arr;
-        $this->has_public_dependency = true;
 
         return $this;
     }
 
-    public function hasPublicDependency()
-    {
-        return $this->has_public_dependency;
-    }
-
     /**
      * Indexes of the weak imported files in the dependency list.
      * For Google-internal migration only. Do not use.
@@ -289,16 +273,10 @@
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
         $this->weak_dependency = $arr;
-        $this->has_weak_dependency = true;
 
         return $this;
     }
 
-    public function hasWeakDependency()
-    {
-        return $this->has_weak_dependency;
-    }
-
     /**
      * All top-level definitions in this file.
      *
@@ -321,16 +299,10 @@
     {
         $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()
-    {
-        return $this->has_message_type;
-    }
-
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.EnumDescriptorProto enum_type = 5;</code>
      * @return \Google\Protobuf\Internal\RepeatedField
@@ -349,16 +321,10 @@
     {
         $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()
-    {
-        return $this->has_enum_type;
-    }
-
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.ServiceDescriptorProto service = 6;</code>
      * @return \Google\Protobuf\Internal\RepeatedField
@@ -377,16 +343,10 @@
     {
         $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()
-    {
-        return $this->has_service;
-    }
-
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.FieldDescriptorProto extension = 7;</code>
      * @return \Google\Protobuf\Internal\RepeatedField
@@ -405,23 +365,27 @@
     {
         $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()
-    {
-        return $this->has_extension;
-    }
-
     /**
      * Generated from protobuf field <code>optional .google.protobuf.FileOptions options = 8;</code>
      * @return \Google\Protobuf\Internal\FileOptions
      */
     public function getOptions()
     {
-        return $this->options;
+        return isset($this->options) ? $this->options : null;
+    }
+
+    public function hasOptions()
+    {
+        return isset($this->options);
+    }
+
+    public function clearOptions()
+    {
+        unset($this->options);
     }
 
     /**
@@ -433,16 +397,10 @@
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FileOptions::class);
         $this->options = $var;
-        $this->has_options = true;
 
         return $this;
     }
 
-    public function hasOptions()
-    {
-        return $this->has_options;
-    }
-
     /**
      * This field contains optional information about the original source code.
      * You may safely remove this entire field without harming runtime
@@ -454,7 +412,17 @@
      */
     public function getSourceCodeInfo()
     {
-        return $this->source_code_info;
+        return isset($this->source_code_info) ? $this->source_code_info : null;
+    }
+
+    public function hasSourceCodeInfo()
+    {
+        return isset($this->source_code_info);
+    }
+
+    public function clearSourceCodeInfo()
+    {
+        unset($this->source_code_info);
     }
 
     /**
@@ -471,16 +439,10 @@
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\SourceCodeInfo::class);
         $this->source_code_info = $var;
-        $this->has_source_code_info = true;
 
         return $this;
     }
 
-    public function hasSourceCodeInfo()
-    {
-        return $this->has_source_code_info;
-    }
-
     /**
      * The syntax of the proto file.
      * The supported values are "proto2" and "proto3".
@@ -490,7 +452,17 @@
      */
     public function getSyntax()
     {
-        return $this->syntax;
+        return isset($this->syntax) ? $this->syntax : '';
+    }
+
+    public function hasSyntax()
+    {
+        return isset($this->syntax);
+    }
+
+    public function clearSyntax()
+    {
+        unset($this->syntax);
     }
 
     /**
@@ -505,15 +477,9 @@
     {
         GPBUtil::checkString($var, True);
         $this->syntax = $var;
-        $this->has_syntax = true;
 
         return $this;
     }
 
-    public function hasSyntax()
-    {
-        return $this->has_syntax;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/FileDescriptorSet.php b/php/src/Google/Protobuf/Internal/FileDescriptorSet.php
index 9907b17..794e634 100644
--- a/php/src/Google/Protobuf/Internal/FileDescriptorSet.php
+++ b/php/src/Google/Protobuf/Internal/FileDescriptorSet.php
@@ -22,7 +22,6 @@
      * Generated from protobuf field <code>repeated .google.protobuf.FileDescriptorProto file = 1;</code>
      */
     private $file;
-    private $has_file = false;
 
     /**
      * Constructor.
@@ -56,15 +55,9 @@
     {
         $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()
-    {
-        return $this->has_file;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/FileOptions.php b/php/src/Google/Protobuf/Internal/FileOptions.php
index 666c6c9..f415b07 100644
--- a/php/src/Google/Protobuf/Internal/FileOptions.php
+++ b/php/src/Google/Protobuf/Internal/FileOptions.php
@@ -23,8 +23,7 @@
      *
      * Generated from protobuf field <code>optional string java_package = 1;</code>
      */
-    protected $java_package = '';
-    private $has_java_package = false;
+    protected $java_package = null;
     /**
      * 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
@@ -34,8 +33,7 @@
      *
      * Generated from protobuf field <code>optional string java_outer_classname = 8;</code>
      */
-    protected $java_outer_classname = '';
-    private $has_java_outer_classname = false;
+    protected $java_outer_classname = null;
     /**
      * 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
@@ -46,15 +44,13 @@
      *
      * Generated from protobuf field <code>optional bool java_multiple_files = 10 [default = false];</code>
      */
-    protected $java_multiple_files = false;
-    private $has_java_multiple_files = false;
+    protected $java_multiple_files = null;
     /**
      * This option does nothing.
      *
      * Generated from protobuf field <code>optional bool java_generate_equals_and_hash = 20 [deprecated = true];</code>
      */
-    protected $java_generate_equals_and_hash = false;
-    private $has_java_generate_equals_and_hash = false;
+    protected $java_generate_equals_and_hash = null;
     /**
      * 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
@@ -65,13 +61,11 @@
      *
      * Generated from protobuf field <code>optional bool java_string_check_utf8 = 27 [default = false];</code>
      */
-    protected $java_string_check_utf8 = false;
-    private $has_java_string_check_utf8 = false;
+    protected $java_string_check_utf8 = null;
     /**
      * Generated from protobuf field <code>optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];</code>
      */
-    protected $optimize_for = 0;
-    private $has_optimize_for = false;
+    protected $optimize_for = null;
     /**
      * Sets the Go package where structs generated from this .proto will be
      * placed. If omitted, the Go package will be derived from the following:
@@ -81,8 +75,7 @@
      *
      * Generated from protobuf field <code>optional string go_package = 11;</code>
      */
-    protected $go_package = '';
-    private $has_go_package = false;
+    protected $go_package = null;
     /**
      * Should generic services be generated in each language?  "Generic" services
      * are not specific to any particular RPC system.  They are generated by the
@@ -96,23 +89,19 @@
      *
      * Generated from protobuf field <code>optional bool cc_generic_services = 16 [default = false];</code>
      */
-    protected $cc_generic_services = false;
-    private $has_cc_generic_services = false;
+    protected $cc_generic_services = null;
     /**
      * Generated from protobuf field <code>optional bool java_generic_services = 17 [default = false];</code>
      */
-    protected $java_generic_services = false;
-    private $has_java_generic_services = false;
+    protected $java_generic_services = null;
     /**
      * Generated from protobuf field <code>optional bool py_generic_services = 18 [default = false];</code>
      */
-    protected $py_generic_services = false;
-    private $has_py_generic_services = false;
+    protected $py_generic_services = null;
     /**
      * Generated from protobuf field <code>optional bool php_generic_services = 42 [default = false];</code>
      */
-    protected $php_generic_services = false;
-    private $has_php_generic_services = false;
+    protected $php_generic_services = null;
     /**
      * Is this file deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
@@ -121,31 +110,27 @@
      *
      * Generated from protobuf field <code>optional bool deprecated = 23 [default = false];</code>
      */
-    protected $deprecated = false;
-    private $has_deprecated = false;
+    protected $deprecated = null;
     /**
      * Enables the use of arenas for the proto messages in this file. This applies
      * only to generated classes for C++.
      *
      * Generated from protobuf field <code>optional bool cc_enable_arenas = 31 [default = true];</code>
      */
-    protected $cc_enable_arenas = false;
-    private $has_cc_enable_arenas = false;
+    protected $cc_enable_arenas = null;
     /**
      * Sets the objective c class prefix which is prepended to all objective c
      * generated classes from this .proto. There is no default.
      *
      * Generated from protobuf field <code>optional string objc_class_prefix = 36;</code>
      */
-    protected $objc_class_prefix = '';
-    private $has_objc_class_prefix = false;
+    protected $objc_class_prefix = null;
     /**
      * Namespace for generated classes; defaults to the package.
      *
      * Generated from protobuf field <code>optional string csharp_namespace = 37;</code>
      */
-    protected $csharp_namespace = '';
-    private $has_csharp_namespace = false;
+    protected $csharp_namespace = null;
     /**
      * By default Swift generators will take the proto package and CamelCase it
      * replacing '.' with underscore and use that to prefix the types/symbols
@@ -154,16 +139,14 @@
      *
      * Generated from protobuf field <code>optional string swift_prefix = 39;</code>
      */
-    protected $swift_prefix = '';
-    private $has_swift_prefix = false;
+    protected $swift_prefix = null;
     /**
      * Sets the php class prefix which is prepended to all php generated classes
      * from this .proto. Default is empty.
      *
      * Generated from protobuf field <code>optional string php_class_prefix = 40;</code>
      */
-    protected $php_class_prefix = '';
-    private $has_php_class_prefix = false;
+    protected $php_class_prefix = null;
     /**
      * 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
@@ -171,8 +154,7 @@
      *
      * Generated from protobuf field <code>optional string php_namespace = 41;</code>
      */
-    protected $php_namespace = '';
-    private $has_php_namespace = false;
+    protected $php_namespace = null;
     /**
      * Use this option to change the namespace of php generated metadata classes.
      * Default is empty. When this option is empty, the proto file name will be
@@ -180,8 +162,7 @@
      *
      * Generated from protobuf field <code>optional string php_metadata_namespace = 44;</code>
      */
-    protected $php_metadata_namespace = '';
-    private $has_php_metadata_namespace = false;
+    protected $php_metadata_namespace = null;
     /**
      * Use this option to change the package of ruby generated classes. Default
      * is empty. When this option is not set, the package name will be used for
@@ -189,8 +170,7 @@
      *
      * Generated from protobuf field <code>optional string ruby_package = 45;</code>
      */
-    protected $ruby_package = '';
-    private $has_ruby_package = false;
+    protected $ruby_package = null;
     /**
      * The parser stores options it doesn't recognize here.
      * See the documentation for the "Options" section above.
@@ -198,7 +178,6 @@
      * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
      */
     private $uninterpreted_option;
-    private $has_uninterpreted_option = false;
 
     /**
      * Constructor.
@@ -307,7 +286,17 @@
      */
     public function getJavaPackage()
     {
-        return $this->java_package;
+        return isset($this->java_package) ? $this->java_package : '';
+    }
+
+    public function hasJavaPackage()
+    {
+        return isset($this->java_package);
+    }
+
+    public function clearJavaPackage()
+    {
+        unset($this->java_package);
     }
 
     /**
@@ -324,16 +313,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->java_package = $var;
-        $this->has_java_package = true;
 
         return $this;
     }
 
-    public function hasJavaPackage()
-    {
-        return $this->has_java_package;
-    }
-
     /**
      * 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
@@ -346,7 +329,17 @@
      */
     public function getJavaOuterClassname()
     {
-        return $this->java_outer_classname;
+        return isset($this->java_outer_classname) ? $this->java_outer_classname : '';
+    }
+
+    public function hasJavaOuterClassname()
+    {
+        return isset($this->java_outer_classname);
+    }
+
+    public function clearJavaOuterClassname()
+    {
+        unset($this->java_outer_classname);
     }
 
     /**
@@ -364,16 +357,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->java_outer_classname = $var;
-        $this->has_java_outer_classname = true;
 
         return $this;
     }
 
-    public function hasJavaOuterClassname()
-    {
-        return $this->has_java_outer_classname;
-    }
-
     /**
      * 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
@@ -387,7 +374,17 @@
      */
     public function getJavaMultipleFiles()
     {
-        return $this->java_multiple_files;
+        return isset($this->java_multiple_files) ? $this->java_multiple_files : false;
+    }
+
+    public function hasJavaMultipleFiles()
+    {
+        return isset($this->java_multiple_files);
+    }
+
+    public function clearJavaMultipleFiles()
+    {
+        unset($this->java_multiple_files);
     }
 
     /**
@@ -406,16 +403,10 @@
     {
         GPBUtil::checkBool($var);
         $this->java_multiple_files = $var;
-        $this->has_java_multiple_files = true;
 
         return $this;
     }
 
-    public function hasJavaMultipleFiles()
-    {
-        return $this->has_java_multiple_files;
-    }
-
     /**
      * This option does nothing.
      *
@@ -424,7 +415,17 @@
      */
     public function getJavaGenerateEqualsAndHash()
     {
-        return $this->java_generate_equals_and_hash;
+        return isset($this->java_generate_equals_and_hash) ? $this->java_generate_equals_and_hash : false;
+    }
+
+    public function hasJavaGenerateEqualsAndHash()
+    {
+        return isset($this->java_generate_equals_and_hash);
+    }
+
+    public function clearJavaGenerateEqualsAndHash()
+    {
+        unset($this->java_generate_equals_and_hash);
     }
 
     /**
@@ -438,16 +439,10 @@
     {
         GPBUtil::checkBool($var);
         $this->java_generate_equals_and_hash = $var;
-        $this->has_java_generate_equals_and_hash = true;
 
         return $this;
     }
 
-    public function hasJavaGenerateEqualsAndHash()
-    {
-        return $this->has_java_generate_equals_and_hash;
-    }
-
     /**
      * 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
@@ -461,7 +456,17 @@
      */
     public function getJavaStringCheckUtf8()
     {
-        return $this->java_string_check_utf8;
+        return isset($this->java_string_check_utf8) ? $this->java_string_check_utf8 : false;
+    }
+
+    public function hasJavaStringCheckUtf8()
+    {
+        return isset($this->java_string_check_utf8);
+    }
+
+    public function clearJavaStringCheckUtf8()
+    {
+        unset($this->java_string_check_utf8);
     }
 
     /**
@@ -480,23 +485,27 @@
     {
         GPBUtil::checkBool($var);
         $this->java_string_check_utf8 = $var;
-        $this->has_java_string_check_utf8 = true;
 
         return $this;
     }
 
-    public function hasJavaStringCheckUtf8()
-    {
-        return $this->has_java_string_check_utf8;
-    }
-
     /**
      * Generated from protobuf field <code>optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];</code>
      * @return int
      */
     public function getOptimizeFor()
     {
-        return $this->optimize_for;
+        return isset($this->optimize_for) ? $this->optimize_for : 0;
+    }
+
+    public function hasOptimizeFor()
+    {
+        return isset($this->optimize_for);
+    }
+
+    public function clearOptimizeFor()
+    {
+        unset($this->optimize_for);
     }
 
     /**
@@ -508,16 +517,10 @@
     {
         GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FileOptions\OptimizeMode::class);
         $this->optimize_for = $var;
-        $this->has_optimize_for = true;
 
         return $this;
     }
 
-    public function hasOptimizeFor()
-    {
-        return $this->has_optimize_for;
-    }
-
     /**
      * Sets the Go package where structs generated from this .proto will be
      * placed. If omitted, the Go package will be derived from the following:
@@ -530,7 +533,17 @@
      */
     public function getGoPackage()
     {
-        return $this->go_package;
+        return isset($this->go_package) ? $this->go_package : '';
+    }
+
+    public function hasGoPackage()
+    {
+        return isset($this->go_package);
+    }
+
+    public function clearGoPackage()
+    {
+        unset($this->go_package);
     }
 
     /**
@@ -548,16 +561,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->go_package = $var;
-        $this->has_go_package = true;
 
         return $this;
     }
 
-    public function hasGoPackage()
-    {
-        return $this->has_go_package;
-    }
-
     /**
      * Should generic services be generated in each language?  "Generic" services
      * are not specific to any particular RPC system.  They are generated by the
@@ -574,7 +581,17 @@
      */
     public function getCcGenericServices()
     {
-        return $this->cc_generic_services;
+        return isset($this->cc_generic_services) ? $this->cc_generic_services : false;
+    }
+
+    public function hasCcGenericServices()
+    {
+        return isset($this->cc_generic_services);
+    }
+
+    public function clearCcGenericServices()
+    {
+        unset($this->cc_generic_services);
     }
 
     /**
@@ -596,23 +613,27 @@
     {
         GPBUtil::checkBool($var);
         $this->cc_generic_services = $var;
-        $this->has_cc_generic_services = true;
 
         return $this;
     }
 
-    public function hasCcGenericServices()
-    {
-        return $this->has_cc_generic_services;
-    }
-
     /**
      * Generated from protobuf field <code>optional bool java_generic_services = 17 [default = false];</code>
      * @return bool
      */
     public function getJavaGenericServices()
     {
-        return $this->java_generic_services;
+        return isset($this->java_generic_services) ? $this->java_generic_services : false;
+    }
+
+    public function hasJavaGenericServices()
+    {
+        return isset($this->java_generic_services);
+    }
+
+    public function clearJavaGenericServices()
+    {
+        unset($this->java_generic_services);
     }
 
     /**
@@ -624,23 +645,27 @@
     {
         GPBUtil::checkBool($var);
         $this->java_generic_services = $var;
-        $this->has_java_generic_services = true;
 
         return $this;
     }
 
-    public function hasJavaGenericServices()
-    {
-        return $this->has_java_generic_services;
-    }
-
     /**
      * Generated from protobuf field <code>optional bool py_generic_services = 18 [default = false];</code>
      * @return bool
      */
     public function getPyGenericServices()
     {
-        return $this->py_generic_services;
+        return isset($this->py_generic_services) ? $this->py_generic_services : false;
+    }
+
+    public function hasPyGenericServices()
+    {
+        return isset($this->py_generic_services);
+    }
+
+    public function clearPyGenericServices()
+    {
+        unset($this->py_generic_services);
     }
 
     /**
@@ -652,23 +677,27 @@
     {
         GPBUtil::checkBool($var);
         $this->py_generic_services = $var;
-        $this->has_py_generic_services = true;
 
         return $this;
     }
 
-    public function hasPyGenericServices()
-    {
-        return $this->has_py_generic_services;
-    }
-
     /**
      * Generated from protobuf field <code>optional bool php_generic_services = 42 [default = false];</code>
      * @return bool
      */
     public function getPhpGenericServices()
     {
-        return $this->php_generic_services;
+        return isset($this->php_generic_services) ? $this->php_generic_services : false;
+    }
+
+    public function hasPhpGenericServices()
+    {
+        return isset($this->php_generic_services);
+    }
+
+    public function clearPhpGenericServices()
+    {
+        unset($this->php_generic_services);
     }
 
     /**
@@ -680,16 +709,10 @@
     {
         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
@@ -701,7 +724,17 @@
      */
     public function getDeprecated()
     {
-        return $this->deprecated;
+        return isset($this->deprecated) ? $this->deprecated : false;
+    }
+
+    public function hasDeprecated()
+    {
+        return isset($this->deprecated);
+    }
+
+    public function clearDeprecated()
+    {
+        unset($this->deprecated);
     }
 
     /**
@@ -718,16 +751,10 @@
     {
         GPBUtil::checkBool($var);
         $this->deprecated = $var;
-        $this->has_deprecated = true;
 
         return $this;
     }
 
-    public function hasDeprecated()
-    {
-        return $this->has_deprecated;
-    }
-
     /**
      * Enables the use of arenas for the proto messages in this file. This applies
      * only to generated classes for C++.
@@ -737,7 +764,17 @@
      */
     public function getCcEnableArenas()
     {
-        return $this->cc_enable_arenas;
+        return isset($this->cc_enable_arenas) ? $this->cc_enable_arenas : false;
+    }
+
+    public function hasCcEnableArenas()
+    {
+        return isset($this->cc_enable_arenas);
+    }
+
+    public function clearCcEnableArenas()
+    {
+        unset($this->cc_enable_arenas);
     }
 
     /**
@@ -752,16 +789,10 @@
     {
         GPBUtil::checkBool($var);
         $this->cc_enable_arenas = $var;
-        $this->has_cc_enable_arenas = true;
 
         return $this;
     }
 
-    public function hasCcEnableArenas()
-    {
-        return $this->has_cc_enable_arenas;
-    }
-
     /**
      * Sets the objective c class prefix which is prepended to all objective c
      * generated classes from this .proto. There is no default.
@@ -771,7 +802,17 @@
      */
     public function getObjcClassPrefix()
     {
-        return $this->objc_class_prefix;
+        return isset($this->objc_class_prefix) ? $this->objc_class_prefix : '';
+    }
+
+    public function hasObjcClassPrefix()
+    {
+        return isset($this->objc_class_prefix);
+    }
+
+    public function clearObjcClassPrefix()
+    {
+        unset($this->objc_class_prefix);
     }
 
     /**
@@ -786,16 +827,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->objc_class_prefix = $var;
-        $this->has_objc_class_prefix = true;
 
         return $this;
     }
 
-    public function hasObjcClassPrefix()
-    {
-        return $this->has_objc_class_prefix;
-    }
-
     /**
      * Namespace for generated classes; defaults to the package.
      *
@@ -804,7 +839,17 @@
      */
     public function getCsharpNamespace()
     {
-        return $this->csharp_namespace;
+        return isset($this->csharp_namespace) ? $this->csharp_namespace : '';
+    }
+
+    public function hasCsharpNamespace()
+    {
+        return isset($this->csharp_namespace);
+    }
+
+    public function clearCsharpNamespace()
+    {
+        unset($this->csharp_namespace);
     }
 
     /**
@@ -818,16 +863,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->csharp_namespace = $var;
-        $this->has_csharp_namespace = true;
 
         return $this;
     }
 
-    public function hasCsharpNamespace()
-    {
-        return $this->has_csharp_namespace;
-    }
-
     /**
      * By default Swift generators will take the proto package and CamelCase it
      * replacing '.' with underscore and use that to prefix the types/symbols
@@ -839,7 +878,17 @@
      */
     public function getSwiftPrefix()
     {
-        return $this->swift_prefix;
+        return isset($this->swift_prefix) ? $this->swift_prefix : '';
+    }
+
+    public function hasSwiftPrefix()
+    {
+        return isset($this->swift_prefix);
+    }
+
+    public function clearSwiftPrefix()
+    {
+        unset($this->swift_prefix);
     }
 
     /**
@@ -856,16 +905,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->swift_prefix = $var;
-        $this->has_swift_prefix = true;
 
         return $this;
     }
 
-    public function hasSwiftPrefix()
-    {
-        return $this->has_swift_prefix;
-    }
-
     /**
      * Sets the php class prefix which is prepended to all php generated classes
      * from this .proto. Default is empty.
@@ -875,7 +918,17 @@
      */
     public function getPhpClassPrefix()
     {
-        return $this->php_class_prefix;
+        return isset($this->php_class_prefix) ? $this->php_class_prefix : '';
+    }
+
+    public function hasPhpClassPrefix()
+    {
+        return isset($this->php_class_prefix);
+    }
+
+    public function clearPhpClassPrefix()
+    {
+        unset($this->php_class_prefix);
     }
 
     /**
@@ -890,16 +943,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->php_class_prefix = $var;
-        $this->has_php_class_prefix = true;
 
         return $this;
     }
 
-    public function hasPhpClassPrefix()
-    {
-        return $this->has_php_class_prefix;
-    }
-
     /**
      * 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
@@ -910,7 +957,17 @@
      */
     public function getPhpNamespace()
     {
-        return $this->php_namespace;
+        return isset($this->php_namespace) ? $this->php_namespace : '';
+    }
+
+    public function hasPhpNamespace()
+    {
+        return isset($this->php_namespace);
+    }
+
+    public function clearPhpNamespace()
+    {
+        unset($this->php_namespace);
     }
 
     /**
@@ -926,16 +983,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->php_namespace = $var;
-        $this->has_php_namespace = true;
 
         return $this;
     }
 
-    public function hasPhpNamespace()
-    {
-        return $this->has_php_namespace;
-    }
-
     /**
      * Use this option to change the namespace of php generated metadata classes.
      * Default is empty. When this option is empty, the proto file name will be
@@ -946,7 +997,17 @@
      */
     public function getPhpMetadataNamespace()
     {
-        return $this->php_metadata_namespace;
+        return isset($this->php_metadata_namespace) ? $this->php_metadata_namespace : '';
+    }
+
+    public function hasPhpMetadataNamespace()
+    {
+        return isset($this->php_metadata_namespace);
+    }
+
+    public function clearPhpMetadataNamespace()
+    {
+        unset($this->php_metadata_namespace);
     }
 
     /**
@@ -962,16 +1023,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->php_metadata_namespace = $var;
-        $this->has_php_metadata_namespace = true;
 
         return $this;
     }
 
-    public function hasPhpMetadataNamespace()
-    {
-        return $this->has_php_metadata_namespace;
-    }
-
     /**
      * Use this option to change the package of ruby generated classes. Default
      * is empty. When this option is not set, the package name will be used for
@@ -982,7 +1037,17 @@
      */
     public function getRubyPackage()
     {
-        return $this->ruby_package;
+        return isset($this->ruby_package) ? $this->ruby_package : '';
+    }
+
+    public function hasRubyPackage()
+    {
+        return isset($this->ruby_package);
+    }
+
+    public function clearRubyPackage()
+    {
+        unset($this->ruby_package);
     }
 
     /**
@@ -998,16 +1063,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->ruby_package = $var;
-        $this->has_ruby_package = true;
 
         return $this;
     }
 
-    public function hasRubyPackage()
-    {
-        return $this->has_ruby_package;
-    }
-
     /**
      * The parser stores options it doesn't recognize here.
      * See the documentation for the "Options" section above.
@@ -1032,15 +1091,9 @@
     {
         $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()
-    {
-        return $this->has_uninterpreted_option;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php
index f5a65be..c261ed6 100644
--- a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php
+++ b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php
@@ -26,7 +26,6 @@
      * Generated from protobuf field <code>repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;</code>
      */
     private $annotation;
-    private $has_annotation = false;
 
     /**
      * Constructor.
@@ -68,15 +67,9 @@
     {
         $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()
-    {
-        return $this->has_annotation;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php
index 369fea4..0b043d0 100644
--- a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php
+++ b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php
@@ -22,22 +22,19 @@
      * Generated from protobuf field <code>repeated int32 path = 1 [packed = true];</code>
      */
     private $path;
-    private $has_path = false;
     /**
      * Identifies the filesystem path to the original source .proto.
      *
      * Generated from protobuf field <code>optional string source_file = 2;</code>
      */
-    protected $source_file = '';
-    private $has_source_file = false;
+    protected $source_file = null;
     /**
      * Identifies the starting offset in bytes in the generated code
      * that relates to the identified object.
      *
      * Generated from protobuf field <code>optional int32 begin = 3;</code>
      */
-    protected $begin = 0;
-    private $has_begin = false;
+    protected $begin = null;
     /**
      * Identifies the ending offset in bytes in the generated code that
      * relates to the identified offset. The end offset should be one past
@@ -45,8 +42,7 @@
      *
      * Generated from protobuf field <code>optional int32 end = 4;</code>
      */
-    protected $end = 0;
-    private $has_end = false;
+    protected $end = null;
 
     /**
      * Constructor.
@@ -97,16 +93,10 @@
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
         $this->path = $arr;
-        $this->has_path = true;
 
         return $this;
     }
 
-    public function hasPath()
-    {
-        return $this->has_path;
-    }
-
     /**
      * Identifies the filesystem path to the original source .proto.
      *
@@ -115,7 +105,17 @@
      */
     public function getSourceFile()
     {
-        return $this->source_file;
+        return isset($this->source_file) ? $this->source_file : '';
+    }
+
+    public function hasSourceFile()
+    {
+        return isset($this->source_file);
+    }
+
+    public function clearSourceFile()
+    {
+        unset($this->source_file);
     }
 
     /**
@@ -129,16 +129,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->source_file = $var;
-        $this->has_source_file = true;
 
         return $this;
     }
 
-    public function hasSourceFile()
-    {
-        return $this->has_source_file;
-    }
-
     /**
      * Identifies the starting offset in bytes in the generated code
      * that relates to the identified object.
@@ -148,7 +142,17 @@
      */
     public function getBegin()
     {
-        return $this->begin;
+        return isset($this->begin) ? $this->begin : 0;
+    }
+
+    public function hasBegin()
+    {
+        return isset($this->begin);
+    }
+
+    public function clearBegin()
+    {
+        unset($this->begin);
     }
 
     /**
@@ -163,16 +167,10 @@
     {
         GPBUtil::checkInt32($var);
         $this->begin = $var;
-        $this->has_begin = true;
 
         return $this;
     }
 
-    public function hasBegin()
-    {
-        return $this->has_begin;
-    }
-
     /**
      * Identifies the ending offset in bytes in the generated code that
      * relates to the identified offset. The end offset should be one past
@@ -183,7 +181,17 @@
      */
     public function getEnd()
     {
-        return $this->end;
+        return isset($this->end) ? $this->end : 0;
+    }
+
+    public function hasEnd()
+    {
+        return isset($this->end);
+    }
+
+    public function clearEnd()
+    {
+        unset($this->end);
     }
 
     /**
@@ -199,16 +207,10 @@
     {
         GPBUtil::checkInt32($var);
         $this->end = $var;
-        $this->has_end = true;
 
         return $this;
     }
 
-    public function hasEnd()
-    {
-        return $this->has_end;
-    }
-
 }
 
 // Adding a class alias for backwards compatibility with the previous class name.
diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php
index 77614bc..c02d2b4 100644
--- a/php/src/Google/Protobuf/Internal/Message.php
+++ b/php/src/Google/Protobuf/Internal/Message.php
@@ -225,6 +225,15 @@
         }
     }
 
+    protected function hasOneof($number)
+    {
+        $field = $this->desc->getFieldByNumber($number);
+        $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
+        $oneof_name = $oneof->getName();
+        $oneof_field = $this->$oneof_name;
+        return $number === $oneof_field->getNumber();
+    }
+
     protected function writeOneof($number, $value)
     {
         $field = $this->desc->getFieldByNumber($number);
@@ -1559,14 +1568,19 @@
      */
     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();
+        $hazzer = "has" . substr($getter, 3);
+
+        if (method_exists($this, $hazzer)) {
+          return $this->$hazzer();
+        } else if ($field->getOneofIndex() !== -1) {
+          // For old generated code, which does not have hazzers for oneof
+          // fields.
+          $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
+          $oneof_name = $oneof->getName();
+          return $this->$oneof_name->getNumber() === $field->getNumber();
         }
 
-        $getter = $field->getGetter();
         $values = $this->$getter();
         if ($field->isMap()) {
             return count($values) !== 0;
diff --git a/php/src/Google/Protobuf/Internal/MessageOptions.php b/php/src/Google/Protobuf/Internal/MessageOptions.php
index 95bb706a..2f4e3cb 100644
--- a/php/src/Google/Protobuf/Internal/MessageOptions.php
+++ b/php/src/Google/Protobuf/Internal/MessageOptions.php
@@ -34,8 +34,7 @@
      *
      * Generated from protobuf field <code>optional bool message_set_wire_format = 1 [default = false];</code>
      */
-    protected $message_set_wire_format = false;
-    private $has_message_set_wire_format = false;
+    protected $message_set_wire_format = null;
     /**
      * Disables the generation of the standard "descriptor()" accessor, which can
      * conflict with a field of the same name.  This is meant to make migration
@@ -43,8 +42,7 @@
      *
      * Generated from protobuf field <code>optional bool no_standard_descriptor_accessor = 2 [default = false];</code>
      */
-    protected $no_standard_descriptor_accessor = false;
-    private $has_no_standard_descriptor_accessor = false;
+    protected $no_standard_descriptor_accessor = null;
     /**
      * Is this message deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
@@ -53,8 +51,7 @@
      *
      * Generated from protobuf field <code>optional bool deprecated = 3 [default = false];</code>
      */
-    protected $deprecated = false;
-    private $has_deprecated = false;
+    protected $deprecated = null;
     /**
      * Whether the message is an automatically generated map entry type for the
      * maps field.
@@ -77,15 +74,13 @@
      *
      * Generated from protobuf field <code>optional bool map_entry = 7;</code>
      */
-    protected $map_entry = false;
-    private $has_map_entry = false;
+    protected $map_entry = null;
     /**
      * 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;
 
     /**
      * Constructor.
@@ -168,7 +163,17 @@
      */
     public function getMessageSetWireFormat()
     {
-        return $this->message_set_wire_format;
+        return isset($this->message_set_wire_format) ? $this->message_set_wire_format : false;
+    }
+
+    public function hasMessageSetWireFormat()
+    {
+        return isset($this->message_set_wire_format);
+    }
+
+    public function clearMessageSetWireFormat()
+    {
+        unset($this->message_set_wire_format);
     }
 
     /**
@@ -196,16 +201,10 @@
     {
         GPBUtil::checkBool($var);
         $this->message_set_wire_format = $var;
-        $this->has_message_set_wire_format = true;
 
         return $this;
     }
 
-    public function hasMessageSetWireFormat()
-    {
-        return $this->has_message_set_wire_format;
-    }
-
     /**
      * Disables the generation of the standard "descriptor()" accessor, which can
      * conflict with a field of the same name.  This is meant to make migration
@@ -216,7 +215,17 @@
      */
     public function getNoStandardDescriptorAccessor()
     {
-        return $this->no_standard_descriptor_accessor;
+        return isset($this->no_standard_descriptor_accessor) ? $this->no_standard_descriptor_accessor : false;
+    }
+
+    public function hasNoStandardDescriptorAccessor()
+    {
+        return isset($this->no_standard_descriptor_accessor);
+    }
+
+    public function clearNoStandardDescriptorAccessor()
+    {
+        unset($this->no_standard_descriptor_accessor);
     }
 
     /**
@@ -232,16 +241,10 @@
     {
         GPBUtil::checkBool($var);
         $this->no_standard_descriptor_accessor = $var;
-        $this->has_no_standard_descriptor_accessor = true;
 
         return $this;
     }
 
-    public function hasNoStandardDescriptorAccessor()
-    {
-        return $this->has_no_standard_descriptor_accessor;
-    }
-
     /**
      * Is this message deprecated?
      * Depending on the target platform, this can emit Deprecated annotations
@@ -253,7 +256,17 @@
      */
     public function getDeprecated()
     {
-        return $this->deprecated;
+        return isset($this->deprecated) ? $this->deprecated : false;
+    }
+
+    public function hasDeprecated()
+    {
+        return isset($this->deprecated);
+    }
+
+    public function clearDeprecated()
+    {
+        unset($this->deprecated);
     }
 
     /**
@@ -270,16 +283,10 @@
     {
         GPBUtil::checkBool($var);
         $this->deprecated = $var;
-        $this->has_deprecated = true;
 
         return $this;
     }
 
-    public function hasDeprecated()
-    {
-        return $this->has_deprecated;
-    }
-
     /**
      * Whether the message is an automatically generated map entry type for the
      * maps field.
@@ -305,7 +312,17 @@
      */
     public function getMapEntry()
     {
-        return $this->map_entry;
+        return isset($this->map_entry) ? $this->map_entry : false;
+    }
+
+    public function hasMapEntry()
+    {
+        return isset($this->map_entry);
+    }
+
+    public function clearMapEntry()
+    {
+        unset($this->map_entry);
     }
 
     /**
@@ -336,16 +353,10 @@
     {
         GPBUtil::checkBool($var);
         $this->map_entry = $var;
-        $this->has_map_entry = true;
 
         return $this;
     }
 
-    public function hasMapEntry()
-    {
-        return $this->has_map_entry;
-    }
-
     /**
      * The parser stores options it doesn't recognize here. See above.
      *
@@ -368,15 +379,9 @@
     {
         $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()
-    {
-        return $this->has_uninterpreted_option;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php b/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php
index f40f20f..e2ea8ea 100644
--- a/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php
+++ b/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php
@@ -20,40 +20,34 @@
     /**
      * Generated from protobuf field <code>optional string name = 1;</code>
      */
-    protected $name = '';
-    private $has_name = false;
+    protected $name = null;
     /**
      * Input and output type names.  These are resolved in the same way as
      * FieldDescriptorProto.type_name, but must refer to a message type.
      *
      * Generated from protobuf field <code>optional string input_type = 2;</code>
      */
-    protected $input_type = '';
-    private $has_input_type = false;
+    protected $input_type = null;
     /**
      * Generated from protobuf field <code>optional string output_type = 3;</code>
      */
-    protected $output_type = '';
-    private $has_output_type = false;
+    protected $output_type = null;
     /**
      * Generated from protobuf field <code>optional .google.protobuf.MethodOptions options = 4;</code>
      */
     protected $options = null;
-    private $has_options = false;
     /**
      * Identifies if client streams multiple client messages
      *
      * Generated from protobuf field <code>optional bool client_streaming = 5 [default = false];</code>
      */
-    protected $client_streaming = false;
-    private $has_client_streaming = false;
+    protected $client_streaming = null;
     /**
      * Identifies if server streams multiple server messages
      *
      * Generated from protobuf field <code>optional bool server_streaming = 6 [default = false];</code>
      */
-    protected $server_streaming = false;
-    private $has_server_streaming = false;
+    protected $server_streaming = null;
 
     /**
      * Constructor.
@@ -84,7 +78,17 @@
      */
     public function getName()
     {
-        return $this->name;
+        return isset($this->name) ? $this->name : '';
+    }
+
+    public function hasName()
+    {
+        return isset($this->name);
+    }
+
+    public function clearName()
+    {
+        unset($this->name);
     }
 
     /**
@@ -96,16 +100,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->name = $var;
-        $this->has_name = true;
 
         return $this;
     }
 
-    public function hasName()
-    {
-        return $this->has_name;
-    }
-
     /**
      * Input and output type names.  These are resolved in the same way as
      * FieldDescriptorProto.type_name, but must refer to a message type.
@@ -115,7 +113,17 @@
      */
     public function getInputType()
     {
-        return $this->input_type;
+        return isset($this->input_type) ? $this->input_type : '';
+    }
+
+    public function hasInputType()
+    {
+        return isset($this->input_type);
+    }
+
+    public function clearInputType()
+    {
+        unset($this->input_type);
     }
 
     /**
@@ -130,23 +138,27 @@
     {
         GPBUtil::checkString($var, True);
         $this->input_type = $var;
-        $this->has_input_type = true;
 
         return $this;
     }
 
-    public function hasInputType()
-    {
-        return $this->has_input_type;
-    }
-
     /**
      * Generated from protobuf field <code>optional string output_type = 3;</code>
      * @return string
      */
     public function getOutputType()
     {
-        return $this->output_type;
+        return isset($this->output_type) ? $this->output_type : '';
+    }
+
+    public function hasOutputType()
+    {
+        return isset($this->output_type);
+    }
+
+    public function clearOutputType()
+    {
+        unset($this->output_type);
     }
 
     /**
@@ -158,23 +170,27 @@
     {
         GPBUtil::checkString($var, True);
         $this->output_type = $var;
-        $this->has_output_type = true;
 
         return $this;
     }
 
-    public function hasOutputType()
-    {
-        return $this->has_output_type;
-    }
-
     /**
      * Generated from protobuf field <code>optional .google.protobuf.MethodOptions options = 4;</code>
      * @return \Google\Protobuf\Internal\MethodOptions
      */
     public function getOptions()
     {
-        return $this->options;
+        return isset($this->options) ? $this->options : null;
+    }
+
+    public function hasOptions()
+    {
+        return isset($this->options);
+    }
+
+    public function clearOptions()
+    {
+        unset($this->options);
     }
 
     /**
@@ -186,16 +202,10 @@
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\MethodOptions::class);
         $this->options = $var;
-        $this->has_options = true;
 
         return $this;
     }
 
-    public function hasOptions()
-    {
-        return $this->has_options;
-    }
-
     /**
      * Identifies if client streams multiple client messages
      *
@@ -204,7 +214,17 @@
      */
     public function getClientStreaming()
     {
-        return $this->client_streaming;
+        return isset($this->client_streaming) ? $this->client_streaming : false;
+    }
+
+    public function hasClientStreaming()
+    {
+        return isset($this->client_streaming);
+    }
+
+    public function clearClientStreaming()
+    {
+        unset($this->client_streaming);
     }
 
     /**
@@ -218,16 +238,10 @@
     {
         GPBUtil::checkBool($var);
         $this->client_streaming = $var;
-        $this->has_client_streaming = true;
 
         return $this;
     }
 
-    public function hasClientStreaming()
-    {
-        return $this->has_client_streaming;
-    }
-
     /**
      * Identifies if server streams multiple server messages
      *
@@ -236,7 +250,17 @@
      */
     public function getServerStreaming()
     {
-        return $this->server_streaming;
+        return isset($this->server_streaming) ? $this->server_streaming : false;
+    }
+
+    public function hasServerStreaming()
+    {
+        return isset($this->server_streaming);
+    }
+
+    public function clearServerStreaming()
+    {
+        unset($this->server_streaming);
     }
 
     /**
@@ -250,15 +274,9 @@
     {
         GPBUtil::checkBool($var);
         $this->server_streaming = $var;
-        $this->has_server_streaming = true;
 
         return $this;
     }
 
-    public function hasServerStreaming()
-    {
-        return $this->has_server_streaming;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/MethodOptions.php b/php/src/Google/Protobuf/Internal/MethodOptions.php
index f96dd3c..a4595b7 100644
--- a/php/src/Google/Protobuf/Internal/MethodOptions.php
+++ b/php/src/Google/Protobuf/Internal/MethodOptions.php
@@ -23,20 +23,17 @@
      *
      * Generated from protobuf field <code>optional bool deprecated = 33 [default = false];</code>
      */
-    protected $deprecated = false;
-    private $has_deprecated = false;
+    protected $deprecated = null;
     /**
      * Generated from protobuf field <code>optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];</code>
      */
-    protected $idempotency_level = 0;
-    private $has_idempotency_level = false;
+    protected $idempotency_level = null;
     /**
      * 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;
 
     /**
      * Constructor.
@@ -70,7 +67,17 @@
      */
     public function getDeprecated()
     {
-        return $this->deprecated;
+        return isset($this->deprecated) ? $this->deprecated : false;
+    }
+
+    public function hasDeprecated()
+    {
+        return isset($this->deprecated);
+    }
+
+    public function clearDeprecated()
+    {
+        unset($this->deprecated);
     }
 
     /**
@@ -87,23 +94,27 @@
     {
         GPBUtil::checkBool($var);
         $this->deprecated = $var;
-        $this->has_deprecated = true;
 
         return $this;
     }
 
-    public function hasDeprecated()
-    {
-        return $this->has_deprecated;
-    }
-
     /**
      * Generated from protobuf field <code>optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];</code>
      * @return int
      */
     public function getIdempotencyLevel()
     {
-        return $this->idempotency_level;
+        return isset($this->idempotency_level) ? $this->idempotency_level : 0;
+    }
+
+    public function hasIdempotencyLevel()
+    {
+        return isset($this->idempotency_level);
+    }
+
+    public function clearIdempotencyLevel()
+    {
+        unset($this->idempotency_level);
     }
 
     /**
@@ -115,16 +126,10 @@
     {
         GPBUtil::checkEnum($var, \Google\Protobuf\Internal\MethodOptions\IdempotencyLevel::class);
         $this->idempotency_level = $var;
-        $this->has_idempotency_level = true;
 
         return $this;
     }
 
-    public function hasIdempotencyLevel()
-    {
-        return $this->has_idempotency_level;
-    }
-
     /**
      * The parser stores options it doesn't recognize here. See above.
      *
@@ -147,15 +152,9 @@
     {
         $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()
-    {
-        return $this->has_uninterpreted_option;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php b/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php
index 413b8e5..5ae36ce 100644
--- a/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php
+++ b/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php
@@ -20,13 +20,11 @@
     /**
      * Generated from protobuf field <code>optional string name = 1;</code>
      */
-    protected $name = '';
-    private $has_name = false;
+    protected $name = null;
     /**
      * Generated from protobuf field <code>optional .google.protobuf.OneofOptions options = 2;</code>
      */
     protected $options = null;
-    private $has_options = false;
 
     /**
      * Constructor.
@@ -49,7 +47,17 @@
      */
     public function getName()
     {
-        return $this->name;
+        return isset($this->name) ? $this->name : '';
+    }
+
+    public function hasName()
+    {
+        return isset($this->name);
+    }
+
+    public function clearName()
+    {
+        unset($this->name);
     }
 
     /**
@@ -61,23 +69,27 @@
     {
         GPBUtil::checkString($var, True);
         $this->name = $var;
-        $this->has_name = true;
 
         return $this;
     }
 
-    public function hasName()
-    {
-        return $this->has_name;
-    }
-
     /**
      * Generated from protobuf field <code>optional .google.protobuf.OneofOptions options = 2;</code>
      * @return \Google\Protobuf\Internal\OneofOptions
      */
     public function getOptions()
     {
-        return $this->options;
+        return isset($this->options) ? $this->options : null;
+    }
+
+    public function hasOptions()
+    {
+        return isset($this->options);
+    }
+
+    public function clearOptions()
+    {
+        unset($this->options);
     }
 
     /**
@@ -89,15 +101,9 @@
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\OneofOptions::class);
         $this->options = $var;
-        $this->has_options = true;
 
         return $this;
     }
 
-    public function hasOptions()
-    {
-        return $this->has_options;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/OneofOptions.php b/php/src/Google/Protobuf/Internal/OneofOptions.php
index 46b516f..8dde8f3 100644
--- a/php/src/Google/Protobuf/Internal/OneofOptions.php
+++ b/php/src/Google/Protobuf/Internal/OneofOptions.php
@@ -21,7 +21,6 @@
      * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
      */
     private $uninterpreted_option;
-    private $has_uninterpreted_option = false;
 
     /**
      * Constructor.
@@ -60,15 +59,9 @@
     {
         $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()
-    {
-        return $this->has_uninterpreted_option;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php b/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php
index aaeefbc..9c2cc8f 100644
--- a/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php
+++ b/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php
@@ -20,18 +20,15 @@
     /**
      * Generated from protobuf field <code>optional string name = 1;</code>
      */
-    protected $name = '';
-    private $has_name = false;
+    protected $name = null;
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.MethodDescriptorProto method = 2;</code>
      */
     private $method;
-    private $has_method = false;
     /**
      * Generated from protobuf field <code>optional .google.protobuf.ServiceOptions options = 3;</code>
      */
     protected $options = null;
-    private $has_options = false;
 
     /**
      * Constructor.
@@ -55,7 +52,17 @@
      */
     public function getName()
     {
-        return $this->name;
+        return isset($this->name) ? $this->name : '';
+    }
+
+    public function hasName()
+    {
+        return isset($this->name);
+    }
+
+    public function clearName()
+    {
+        unset($this->name);
     }
 
     /**
@@ -67,16 +74,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->name = $var;
-        $this->has_name = true;
 
         return $this;
     }
 
-    public function hasName()
-    {
-        return $this->has_name;
-    }
-
     /**
      * Generated from protobuf field <code>repeated .google.protobuf.MethodDescriptorProto method = 2;</code>
      * @return \Google\Protobuf\Internal\RepeatedField
@@ -95,23 +96,27 @@
     {
         $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()
-    {
-        return $this->has_method;
-    }
-
     /**
      * Generated from protobuf field <code>optional .google.protobuf.ServiceOptions options = 3;</code>
      * @return \Google\Protobuf\Internal\ServiceOptions
      */
     public function getOptions()
     {
-        return $this->options;
+        return isset($this->options) ? $this->options : null;
+    }
+
+    public function hasOptions()
+    {
+        return isset($this->options);
+    }
+
+    public function clearOptions()
+    {
+        unset($this->options);
     }
 
     /**
@@ -123,15 +128,9 @@
     {
         GPBUtil::checkMessage($var, \Google\Protobuf\Internal\ServiceOptions::class);
         $this->options = $var;
-        $this->has_options = true;
 
         return $this;
     }
 
-    public function hasOptions()
-    {
-        return $this->has_options;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/ServiceOptions.php b/php/src/Google/Protobuf/Internal/ServiceOptions.php
index 0581efb..d15a36a 100644
--- a/php/src/Google/Protobuf/Internal/ServiceOptions.php
+++ b/php/src/Google/Protobuf/Internal/ServiceOptions.php
@@ -23,15 +23,13 @@
      *
      * Generated from protobuf field <code>optional bool deprecated = 33 [default = false];</code>
      */
-    protected $deprecated = false;
-    private $has_deprecated = false;
+    protected $deprecated = null;
     /**
      * 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;
 
     /**
      * Constructor.
@@ -64,7 +62,17 @@
      */
     public function getDeprecated()
     {
-        return $this->deprecated;
+        return isset($this->deprecated) ? $this->deprecated : false;
+    }
+
+    public function hasDeprecated()
+    {
+        return isset($this->deprecated);
+    }
+
+    public function clearDeprecated()
+    {
+        unset($this->deprecated);
     }
 
     /**
@@ -81,16 +89,10 @@
     {
         GPBUtil::checkBool($var);
         $this->deprecated = $var;
-        $this->has_deprecated = true;
 
         return $this;
     }
 
-    public function hasDeprecated()
-    {
-        return $this->has_deprecated;
-    }
-
     /**
      * The parser stores options it doesn't recognize here. See above.
      *
@@ -113,15 +115,9 @@
     {
         $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()
-    {
-        return $this->has_uninterpreted_option;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo.php
index dfeb69f..1c572e7 100644
--- a/php/src/Google/Protobuf/Internal/SourceCodeInfo.php
+++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo.php
@@ -64,7 +64,6 @@
      * Generated from protobuf field <code>repeated .google.protobuf.SourceCodeInfo.Location location = 1;</code>
      */
     private $location;
-    private $has_location = false;
 
     /**
      * Constructor.
@@ -223,15 +222,9 @@
     {
         $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()
-    {
-        return $this->has_location;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php
index 0aeea61..c4cc667 100644
--- a/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php
+++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php
@@ -41,7 +41,6 @@
      * Generated from protobuf field <code>repeated int32 path = 1 [packed = true];</code>
      */
     private $path;
-    private $has_path = false;
     /**
      * Always has exactly three or four elements: start line, start column,
      * end line (optional, otherwise assumed same as start line), end column.
@@ -52,7 +51,6 @@
      * Generated from protobuf field <code>repeated int32 span = 2 [packed = true];</code>
      */
     private $span;
-    private $has_span = false;
     /**
      * If this SourceCodeInfo represents a complete declaration, these are any
      * comments appearing before and after the declaration which appear to be
@@ -93,18 +91,15 @@
      *
      * Generated from protobuf field <code>optional string leading_comments = 3;</code>
      */
-    protected $leading_comments = '';
-    private $has_leading_comments = false;
+    protected $leading_comments = null;
     /**
      * Generated from protobuf field <code>optional string trailing_comments = 4;</code>
      */
-    protected $trailing_comments = '';
-    private $has_trailing_comments = false;
+    protected $trailing_comments = null;
     /**
      * Generated from protobuf field <code>repeated string leading_detached_comments = 6;</code>
      */
     private $leading_detached_comments;
-    private $has_leading_detached_comments = false;
 
     /**
      * Constructor.
@@ -248,16 +243,10 @@
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
         $this->path = $arr;
-        $this->has_path = true;
 
         return $this;
     }
 
-    public function hasPath()
-    {
-        return $this->has_path;
-    }
-
     /**
      * Always has exactly three or four elements: start line, start column,
      * end line (optional, otherwise assumed same as start line), end column.
@@ -288,16 +277,10 @@
     {
         $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32);
         $this->span = $arr;
-        $this->has_span = true;
 
         return $this;
     }
 
-    public function hasSpan()
-    {
-        return $this->has_span;
-    }
-
     /**
      * If this SourceCodeInfo represents a complete declaration, these are any
      * comments appearing before and after the declaration which appear to be
@@ -341,7 +324,17 @@
      */
     public function getLeadingComments()
     {
-        return $this->leading_comments;
+        return isset($this->leading_comments) ? $this->leading_comments : '';
+    }
+
+    public function hasLeadingComments()
+    {
+        return isset($this->leading_comments);
+    }
+
+    public function clearLeadingComments()
+    {
+        unset($this->leading_comments);
     }
 
     /**
@@ -390,23 +383,27 @@
     {
         GPBUtil::checkString($var, True);
         $this->leading_comments = $var;
-        $this->has_leading_comments = true;
 
         return $this;
     }
 
-    public function hasLeadingComments()
-    {
-        return $this->has_leading_comments;
-    }
-
     /**
      * Generated from protobuf field <code>optional string trailing_comments = 4;</code>
      * @return string
      */
     public function getTrailingComments()
     {
-        return $this->trailing_comments;
+        return isset($this->trailing_comments) ? $this->trailing_comments : '';
+    }
+
+    public function hasTrailingComments()
+    {
+        return isset($this->trailing_comments);
+    }
+
+    public function clearTrailingComments()
+    {
+        unset($this->trailing_comments);
     }
 
     /**
@@ -418,16 +415,10 @@
     {
         GPBUtil::checkString($var, True);
         $this->trailing_comments = $var;
-        $this->has_trailing_comments = true;
 
         return $this;
     }
 
-    public function hasTrailingComments()
-    {
-        return $this->has_trailing_comments;
-    }
-
     /**
      * Generated from protobuf field <code>repeated string leading_detached_comments = 6;</code>
      * @return \Google\Protobuf\Internal\RepeatedField
@@ -446,16 +437,10 @@
     {
         $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()
-    {
-        return $this->has_leading_detached_comments;
-    }
-
 }
 
 // Adding a class alias for backwards compatibility with the previous class name.
diff --git a/php/src/Google/Protobuf/Internal/UninterpretedOption.php b/php/src/Google/Protobuf/Internal/UninterpretedOption.php
index 6c871cc..a2aae3e 100644
--- a/php/src/Google/Protobuf/Internal/UninterpretedOption.php
+++ b/php/src/Google/Protobuf/Internal/UninterpretedOption.php
@@ -26,40 +26,33 @@
      * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption.NamePart name = 2;</code>
      */
     private $name;
-    private $has_name = false;
     /**
      * The value of the uninterpreted option, in whatever type the tokenizer
      * identified it as during parsing. Exactly one of these should be set.
      *
      * Generated from protobuf field <code>optional string identifier_value = 3;</code>
      */
-    protected $identifier_value = '';
-    private $has_identifier_value = false;
+    protected $identifier_value = null;
     /**
      * Generated from protobuf field <code>optional uint64 positive_int_value = 4;</code>
      */
-    protected $positive_int_value = 0;
-    private $has_positive_int_value = false;
+    protected $positive_int_value = null;
     /**
      * Generated from protobuf field <code>optional int64 negative_int_value = 5;</code>
      */
-    protected $negative_int_value = 0;
-    private $has_negative_int_value = false;
+    protected $negative_int_value = null;
     /**
      * Generated from protobuf field <code>optional double double_value = 6;</code>
      */
-    protected $double_value = 0.0;
-    private $has_double_value = false;
+    protected $double_value = null;
     /**
      * Generated from protobuf field <code>optional bytes string_value = 7;</code>
      */
-    protected $string_value = '';
-    private $has_string_value = false;
+    protected $string_value = null;
     /**
      * Generated from protobuf field <code>optional string aggregate_value = 8;</code>
      */
-    protected $aggregate_value = '';
-    private $has_aggregate_value = false;
+    protected $aggregate_value = null;
 
     /**
      * Constructor.
@@ -101,16 +94,10 @@
     {
         $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()
-    {
-        return $this->has_name;
-    }
-
     /**
      * The value of the uninterpreted option, in whatever type the tokenizer
      * identified it as during parsing. Exactly one of these should be set.
@@ -120,7 +107,17 @@
      */
     public function getIdentifierValue()
     {
-        return $this->identifier_value;
+        return isset($this->identifier_value) ? $this->identifier_value : '';
+    }
+
+    public function hasIdentifierValue()
+    {
+        return isset($this->identifier_value);
+    }
+
+    public function clearIdentifierValue()
+    {
+        unset($this->identifier_value);
     }
 
     /**
@@ -135,23 +132,27 @@
     {
         GPBUtil::checkString($var, True);
         $this->identifier_value = $var;
-        $this->has_identifier_value = true;
 
         return $this;
     }
 
-    public function hasIdentifierValue()
-    {
-        return $this->has_identifier_value;
-    }
-
     /**
      * Generated from protobuf field <code>optional uint64 positive_int_value = 4;</code>
      * @return int|string
      */
     public function getPositiveIntValue()
     {
-        return $this->positive_int_value;
+        return isset($this->positive_int_value) ? $this->positive_int_value : 0;
+    }
+
+    public function hasPositiveIntValue()
+    {
+        return isset($this->positive_int_value);
+    }
+
+    public function clearPositiveIntValue()
+    {
+        unset($this->positive_int_value);
     }
 
     /**
@@ -163,23 +164,27 @@
     {
         GPBUtil::checkUint64($var);
         $this->positive_int_value = $var;
-        $this->has_positive_int_value = true;
 
         return $this;
     }
 
-    public function hasPositiveIntValue()
-    {
-        return $this->has_positive_int_value;
-    }
-
     /**
      * Generated from protobuf field <code>optional int64 negative_int_value = 5;</code>
      * @return int|string
      */
     public function getNegativeIntValue()
     {
-        return $this->negative_int_value;
+        return isset($this->negative_int_value) ? $this->negative_int_value : 0;
+    }
+
+    public function hasNegativeIntValue()
+    {
+        return isset($this->negative_int_value);
+    }
+
+    public function clearNegativeIntValue()
+    {
+        unset($this->negative_int_value);
     }
 
     /**
@@ -191,23 +196,27 @@
     {
         GPBUtil::checkInt64($var);
         $this->negative_int_value = $var;
-        $this->has_negative_int_value = true;
 
         return $this;
     }
 
-    public function hasNegativeIntValue()
-    {
-        return $this->has_negative_int_value;
-    }
-
     /**
      * Generated from protobuf field <code>optional double double_value = 6;</code>
      * @return float
      */
     public function getDoubleValue()
     {
-        return $this->double_value;
+        return isset($this->double_value) ? $this->double_value : 0.0;
+    }
+
+    public function hasDoubleValue()
+    {
+        return isset($this->double_value);
+    }
+
+    public function clearDoubleValue()
+    {
+        unset($this->double_value);
     }
 
     /**
@@ -219,23 +228,27 @@
     {
         GPBUtil::checkDouble($var);
         $this->double_value = $var;
-        $this->has_double_value = true;
 
         return $this;
     }
 
-    public function hasDoubleValue()
-    {
-        return $this->has_double_value;
-    }
-
     /**
      * Generated from protobuf field <code>optional bytes string_value = 7;</code>
      * @return string
      */
     public function getStringValue()
     {
-        return $this->string_value;
+        return isset($this->string_value) ? $this->string_value : '';
+    }
+
+    public function hasStringValue()
+    {
+        return isset($this->string_value);
+    }
+
+    public function clearStringValue()
+    {
+        unset($this->string_value);
     }
 
     /**
@@ -247,23 +260,27 @@
     {
         GPBUtil::checkString($var, False);
         $this->string_value = $var;
-        $this->has_string_value = true;
 
         return $this;
     }
 
-    public function hasStringValue()
-    {
-        return $this->has_string_value;
-    }
-
     /**
      * Generated from protobuf field <code>optional string aggregate_value = 8;</code>
      * @return string
      */
     public function getAggregateValue()
     {
-        return $this->aggregate_value;
+        return isset($this->aggregate_value) ? $this->aggregate_value : '';
+    }
+
+    public function hasAggregateValue()
+    {
+        return isset($this->aggregate_value);
+    }
+
+    public function clearAggregateValue()
+    {
+        unset($this->aggregate_value);
     }
 
     /**
@@ -275,15 +292,9 @@
     {
         GPBUtil::checkString($var, True);
         $this->aggregate_value = $var;
-        $this->has_aggregate_value = true;
 
         return $this;
     }
 
-    public function hasAggregateValue()
-    {
-        return $this->has_aggregate_value;
-    }
-
 }
 
diff --git a/php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php b/php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php
index 1956ba7..6212d1e 100644
--- a/php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php
+++ b/php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php
@@ -24,13 +24,11 @@
     /**
      * Generated from protobuf field <code>required string name_part = 1;</code>
      */
-    protected $name_part = '';
-    private $has_name_part = false;
+    protected $name_part = null;
     /**
      * Generated from protobuf field <code>required bool is_extension = 2;</code>
      */
-    protected $is_extension = false;
-    private $has_is_extension = false;
+    protected $is_extension = null;
 
     /**
      * Constructor.
@@ -53,7 +51,17 @@
      */
     public function getNamePart()
     {
-        return $this->name_part;
+        return isset($this->name_part) ? $this->name_part : '';
+    }
+
+    public function hasNamePart()
+    {
+        return isset($this->name_part);
+    }
+
+    public function clearNamePart()
+    {
+        unset($this->name_part);
     }
 
     /**
@@ -65,23 +73,27 @@
     {
         GPBUtil::checkString($var, True);
         $this->name_part = $var;
-        $this->has_name_part = true;
 
         return $this;
     }
 
-    public function hasNamePart()
-    {
-        return $this->has_name_part;
-    }
-
     /**
      * Generated from protobuf field <code>required bool is_extension = 2;</code>
      * @return bool
      */
     public function getIsExtension()
     {
-        return $this->is_extension;
+        return isset($this->is_extension) ? $this->is_extension : false;
+    }
+
+    public function hasIsExtension()
+    {
+        return isset($this->is_extension);
+    }
+
+    public function clearIsExtension()
+    {
+        unset($this->is_extension);
     }
 
     /**
@@ -93,16 +105,10 @@
     {
         GPBUtil::checkBool($var);
         $this->is_extension = $var;
-        $this->has_is_extension = true;
 
         return $this;
     }
 
-    public function hasIsExtension()
-    {
-        return $this->has_is_extension;
-    }
-
 }
 
 // Adding a class alias for backwards compatibility with the previous class name.
diff --git a/php/src/Google/Protobuf/Mixin.php b/php/src/Google/Protobuf/Mixin.php
index a2ea59c..cf6277e 100644
--- a/php/src/Google/Protobuf/Mixin.php
+++ b/php/src/Google/Protobuf/Mixin.php
@@ -46,7 +46,7 @@
  * The mixin construct implies that all methods in `AccessControl` are
  * also declared with same name and request/response types in
  * `Storage`. A documentation generator or annotation processor will
- * see the effective `Storage.GetAcl` method after inherting
+ * see the effective `Storage.GetAcl` method after inheriting
  * documentation and annotations as follows:
  *     service Storage {
  *       // Get the underlying ACL object.
diff --git a/php/src/Google/Protobuf/NullValue.php b/php/src/Google/Protobuf/NullValue.php
index a72cbb2..61569f8 100644
--- a/php/src/Google/Protobuf/NullValue.php
+++ b/php/src/Google/Protobuf/NullValue.php
@@ -35,6 +35,7 @@
         return self::$valueToName[$value];
     }
 
+
     public static function value($name)
     {
         $const = __CLASS__ . '::' . strtoupper($name);
diff --git a/php/src/Google/Protobuf/OneofDescriptor.php b/php/src/Google/Protobuf/OneofDescriptor.php
index d973663..92b4e27 100644
--- a/php/src/Google/Protobuf/OneofDescriptor.php
+++ b/php/src/Google/Protobuf/OneofDescriptor.php
@@ -72,4 +72,9 @@
     {
         return count($this->internal_desc->getFields());
     }
+
+    public function isSynthetic()
+    {
+      return $this->internal_desc->isSynthetic();
+    }
 }
diff --git a/php/src/Google/Protobuf/Value.php b/php/src/Google/Protobuf/Value.php
index 5c1e864..20db3cc 100644
--- a/php/src/Google/Protobuf/Value.php
+++ b/php/src/Google/Protobuf/Value.php
@@ -57,6 +57,11 @@
         return $this->readOneof(1);
     }
 
+    public function hasNullValue()
+    {
+        return $this->hasOneof(1);
+    }
+
     /**
      * Represents a null value.
      *
@@ -83,6 +88,11 @@
         return $this->readOneof(2);
     }
 
+    public function hasNumberValue()
+    {
+        return $this->hasOneof(2);
+    }
+
     /**
      * Represents a double value.
      *
@@ -109,6 +119,11 @@
         return $this->readOneof(3);
     }
 
+    public function hasStringValue()
+    {
+        return $this->hasOneof(3);
+    }
+
     /**
      * Represents a string value.
      *
@@ -135,6 +150,11 @@
         return $this->readOneof(4);
     }
 
+    public function hasBoolValue()
+    {
+        return $this->hasOneof(4);
+    }
+
     /**
      * Represents a boolean value.
      *
@@ -161,6 +181,11 @@
         return $this->readOneof(5);
     }
 
+    public function hasStructValue()
+    {
+        return $this->hasOneof(5);
+    }
+
     /**
      * Represents a structured value.
      *
@@ -187,6 +212,11 @@
         return $this->readOneof(6);
     }
 
+    public function hasListValue()
+    {
+        return $this->hasOneof(6);
+    }
+
     /**
      * Represents a repeated `Value`.
      *
diff --git a/php/tests/array_test.php b/php/tests/ArrayTest.php
similarity index 99%
rename from php/tests/array_test.php
rename to php/tests/ArrayTest.php
index b251404..2cb4b39 100644
--- a/php/tests/array_test.php
+++ b/php/tests/ArrayTest.php
@@ -7,7 +7,7 @@
 use Foo\TestMessage;
 use Foo\TestMessage\Sub;
 
-class RepeatedFieldTest extends \PHPUnit\Framework\TestCase
+class ArrayTest extends \PHPUnit\Framework\TestCase
 {
 
     #########################################################
diff --git a/php/tests/descriptors_test.php b/php/tests/DescriptorsTest.php
similarity index 98%
rename from php/tests/descriptors_test.php
rename to php/tests/DescriptorsTest.php
index 60a6292..b2c5e01 100644
--- a/php/tests/descriptors_test.php
+++ b/php/tests/DescriptorsTest.php
@@ -108,7 +108,7 @@
 
     public function testEnumDescriptor()
     {
-        // WARNINIG - we need to do this so that TestDescriptorsEnum is registered!!?
+        // WARNING - we need to do this so that TestDescriptorsEnum is registered!!?
         new TestDescriptorsMessage();
 
         $pool = DescriptorPool::getGeneratedPool();
diff --git a/php/tests/encode_decode_test.php b/php/tests/EncodeDecodeTest.php
similarity index 97%
rename from php/tests/encode_decode_test.php
rename to php/tests/EncodeDecodeTest.php
index 5442f50..cea1e6a 100644
--- a/php/tests/encode_decode_test.php
+++ b/php/tests/EncodeDecodeTest.php
@@ -326,6 +326,42 @@
 
     }
 
+    public function testEncodeDecodeOptional()
+    {
+      $m = new TestMessage();
+      $this->assertFalse($m->hasTrueOptionalInt32());
+      $data = $m->serializeToString();
+      $this->assertSame("", $data);
+
+      $m->setTrueOptionalInt32(0);
+      $this->assertTrue($m->hasTrueOptionalInt32());
+      $data = $m->serializeToString();
+      $this->assertNotSame("", $data);
+
+      $m2 = new TestMessage();
+      $m2->mergeFromString($data);
+      $this->assertTrue($m2->hasTrueOptionalInt32());
+      $this->assertSame(0, $m2->getTrueOptionalInt32());
+    }
+
+    public function testJsonEncodeDecodeOptional()
+    {
+      $m = new TestMessage();
+      $this->assertFalse($m->hasTrueOptionalInt32());
+      $data = $m->serializeToJsonString();
+      $this->assertSame("{}", $data);
+
+      $m->setTrueOptionalInt32(0);
+      $this->assertTrue($m->hasTrueOptionalInt32());
+      $data = $m->serializeToJsonString();
+      $this->assertNotSame("{}", $data);
+
+      $m2 = new TestMessage();
+      $m2->mergeFromJsonString($data);
+      $this->assertTrue($m2->hasTrueOptionalInt32());
+      $this->assertSame(0, $m2->getTrueOptionalInt32());
+    }
+
     public function testJsonEncodeDecodeOneof()
     {
         $m = new TestMessage();
diff --git a/php/tests/generated_class_test.php b/php/tests/GeneratedClassTest.php
similarity index 98%
rename from php/tests/generated_class_test.php
rename to php/tests/GeneratedClassTest.php
index 053697d..f49c4e9 100644
--- a/php/tests/generated_class_test.php
+++ b/php/tests/GeneratedClassTest.php
@@ -72,6 +72,28 @@
     }
 
     #########################################################
+    # Test optional int32 field.
+    #########################################################
+
+    public function testOptionalInt32Field()
+    {
+        $m = new TestMessage();
+
+        $this->assertFalse($m->hasTrueOptionalInt32());
+        $this->assertSame(0, $m->getTrueOptionalInt32());
+
+        // Set integer.
+        $m->setTrueOptionalInt32(MAX_INT32);
+        $this->assertTrue($m->hasTrueOptionalInt32());
+        $this->assertSame(MAX_INT32, $m->getTrueOptionalInt32());
+
+        // Clear integer.
+        $m->clearTrueOptionalInt32();
+        $this->assertFalse($m->hasTrueOptionalInt32());
+        $this->assertSame(0, $m->getTrueOptionalInt32());
+    }
+
+    #########################################################
     # Test uint32 field.
     #########################################################
 
diff --git a/php/tests/generated_phpdoc_test.php b/php/tests/GeneratedPhpdocTest.php
similarity index 100%
rename from php/tests/generated_phpdoc_test.php
rename to php/tests/GeneratedPhpdocTest.php
diff --git a/php/tests/generated_service_test.php b/php/tests/GeneratedServiceTest.php
similarity index 100%
rename from php/tests/generated_service_test.php
rename to php/tests/GeneratedServiceTest.php
diff --git a/php/tests/map_field_test.php b/php/tests/MapFieldTest.php
similarity index 100%
rename from php/tests/map_field_test.php
rename to php/tests/MapFieldTest.php
diff --git a/php/tests/php_implementation_test.php b/php/tests/PhpImplementationTest.php
similarity index 99%
rename from php/tests/php_implementation_test.php
rename to php/tests/PhpImplementationTest.php
index db3c361..f9fc1fd 100644
--- a/php/tests/php_implementation_test.php
+++ b/php/tests/PhpImplementationTest.php
@@ -515,7 +515,7 @@
     {
         $m = new TestMessage();
         TestUtil::setTestMessage($m);
-        $this->assertSame(518, $m->byteSize());
+        $this->assertSame(504, $m->byteSize());
     }
 
     public function testPackedByteSize()
diff --git a/php/tests/well_known_test.php b/php/tests/WellKnownTest.php
similarity index 100%
rename from php/tests/well_known_test.php
rename to php/tests/WellKnownTest.php
diff --git a/php/tests/wrapper_type_setters_test.php b/php/tests/WrapperTypeSettersTest.php
similarity index 100%
rename from php/tests/wrapper_type_setters_test.php
rename to php/tests/WrapperTypeSettersTest.php
diff --git a/php/tests/compatibility_test.sh b/php/tests/compatibility_test.sh
index ddf05e8..7e44cce 100755
--- a/php/tests/compatibility_test.sh
+++ b/php/tests/compatibility_test.sh
@@ -100,11 +100,18 @@
 composer install
 
 # Remove implementation detail tests.
-tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php )
+# TODO(teboring): Temporarily disable encode_decode_test.php. In 3.13.0-rc1,
+# repeated primitive field encoding is changed to packed, which is a bug fix.
+# However, this fails the compatibility test which hard coded old encoding.
+# Will re-enable the test after making a release. After the version bump, the
+# compatibility test will use the updated test code.
+tests=( array_test.php generated_class_test.php map_field_test.php well_known_test.php )
 sed -i.bak '/php_implementation_test.php/d' phpunit.xml
 sed -i.bak '/generated_phpdoc_test.php/d' phpunit.xml
+sed -i.bak '/encode_decode_test.php/d' phpunit.xml
 sed -i.bak 's/generated_phpdoc_test.php//g' tests/test.sh
 sed -i.bak 's/generated_service_test.php//g' tests/test.sh
+sed -i.bak 's/encode_decode_test.php//g' tests/test.sh
 sed -i.bak '/memory_leak_test.php/d' tests/test.sh
 sed -i.bak '/^    public function testTimestamp()$/,/^    }$/d' tests/well_known_test.php
 sed -i.bak 's/PHPUnit_Framework_TestCase/\\PHPUnit\\Framework\\TestCase/g' tests/array_test.php
diff --git a/php/tests/compile_extension.sh b/php/tests/compile_extension.sh
index 5834249..d6dcabc 100755
--- a/php/tests/compile_extension.sh
+++ b/php/tests/compile_extension.sh
@@ -4,17 +4,17 @@
 
 cd $(dirname $0)
 
-if [ "$1" = "--release" ]; then
-  CFLAGS="-Wall"
-else
-  # To get debugging symbols in PHP itself, build PHP with:
-  #   $ ./configure --enable-debug CFLAGS='-g -O0'
-  CFLAGS="-g -O0 -Wall"
-fi
-
 pushd  ../ext/google/protobuf
 phpize --clean
 rm -f configure.in configure.ac
 php make-preload.php
-phpize && ./configure --with-php-config=$(which php-config) CFLAGS="$CFLAGS" && make
+phpize
+if [ "$1" = "--release" ]; then
+  ./configure --with-php-config=$(which php-config)
+else
+  # To get debugging symbols in PHP itself, build PHP with:
+  #   $ ./configure --enable-debug CFLAGS='-g -O0'
+  ./configure --with-php-config=$(which php-config) CFLAGS="-g -O0 -Wall"
+fi
+make
 popd
diff --git a/php/tests/generate_protos.sh b/php/tests/generate_protos.sh
index 0c2a555..e83c3c1 100755
--- a/php/tests/generate_protos.sh
+++ b/php/tests/generate_protos.sh
@@ -7,10 +7,10 @@
 rm -rf generated
 mkdir -p generated
 
-find proto -type f -name "*.proto"| xargs ../../src/protoc --php_out=generated -I../../src -I.
+find proto -type f -name "*.proto"| xargs ../../src/protoc --experimental_allow_proto3_optional --php_out=generated -I../../src -I.
 
 if [ "$1" = "--aggregate_metadata" ]; then
   # Overwrite some of the files to use aggregation.
   AGGREGATED_FILES="proto/test.proto proto/test_include.proto proto/test_import_descriptor_proto.proto"
-  ../../src/protoc --php_out=aggregate_metadata=foo#bar:generated -I../../src -I. $AGGREGATED_FILES
+  ../../src/protoc --experimental_allow_proto3_optional --php_out=aggregate_metadata=foo#bar:generated -I../../src -I. $AGGREGATED_FILES
 fi
diff --git a/php/tests/proto/test.proto b/php/tests/proto/test.proto
index 9505709..368b19e 100644
--- a/php/tests/proto/test.proto
+++ b/php/tests/proto/test.proto
@@ -34,6 +34,27 @@
   bar.TestInclude optional_included_message = 18;
   TestMessage recursive = 19;
 
+  // True optional
+  optional int32 true_optional_int32 = 201;
+  optional int64 true_optional_int64 = 202;
+  optional uint32 true_optional_uint32 = 203;
+  optional uint64 true_optional_uint64 = 204;
+  optional sint32 true_optional_sint32 = 205;
+  optional sint64 true_optional_sint64 = 206;
+  optional fixed32 true_optional_fixed32 = 207;
+  optional fixed64 true_optional_fixed64 = 208;
+  optional sfixed32 true_optional_sfixed32 = 209;
+  optional sfixed64 true_optional_sfixed64 = 210;
+  optional float true_optional_float = 211;
+  optional double true_optional_double = 212;
+  optional bool true_optional_bool = 213;
+  optional string true_optional_string = 214;
+  optional bytes true_optional_bytes = 215;
+
+  optional TestEnum true_optional_enum = 216;
+  optional Sub true_optional_message = 217;
+  optional bar.TestInclude true_optional_included_message = 218;
+
   // Repeated
   repeated    int32 repeated_int32    = 31;
   repeated    int64 repeated_int64    = 32;
diff --git a/php/tests/test.sh b/php/tests/test.sh
index b10b57f..91ea56e 100755
--- a/php/tests/test.sh
+++ b/php/tests/test.sh
@@ -18,6 +18,9 @@
   7.3.*|7.4.*)
     PHPUNIT=phpunit-8.phar
     ;;
+  8.0.*)
+    PHPUNIT=phpunit-9.phar
+    ;;
   *)
     echo "ERROR: Unsupported PHP version $PHP_VERSION"
     exit 1
@@ -26,7 +29,7 @@
 
 [ -f $PHPUNIT ] || wget https://phar.phpunit.de/$PHPUNIT
 
-tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php descriptors_test.php wrapper_type_setters_test.php)
+tests=( ArrayTest.php EncodeDecodeTest.php GeneratedClassTest.php MapFieldTest.php WellKnownTest.php DescriptorsTest.php WrapperTypeSettersTest.php)
 
 for t in "${tests[@]}"
 do
@@ -51,11 +54,11 @@
 
 export ZEND_DONT_UNLOAD_MODULES=1
 export USE_ZEND_ALLOC=0
-valgrind --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php
-valgrind --leak-check=yes php -d protobuf.keep_descriptor_pool_after_request=1 -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php
+valgrind --suppressions=valgrind.supp --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php
+valgrind --suppressions=valgrind.supp --leak-check=yes php -d protobuf.keep_descriptor_pool_after_request=1 -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php
 
 # TODO(teboring): Only for debug (phpunit has memory leak which blocks this beging used by
-# regresssion test.)
+# regression test.)
 
 # for t in "${tests[@]}"
 # do
diff --git a/php/tests/test_util.php b/php/tests/test_util.php
index 2c5b595..c47bf58 100644
--- a/php/tests/test_util.php
+++ b/php/tests/test_util.php
@@ -338,38 +338,24 @@
             "800101" .
             "8A01020821" .
 
-            "F801D6FFFFFFFFFFFFFFFF01" .
-            "F801CCFFFFFFFFFFFFFFFF01" .
-            "8002D5FFFFFFFFFFFFFFFF01" .
-            "8002CBFFFFFFFFFFFFFFFF01" .
-            "88022A" .
-            "880234" .
-            "90022B" .
-            "900235" .
-            "980257" .
-            "98026B" .
-            "A00259" .
-            "A0026D" .
-            "AD022E000000" .
-            "AD0238000000" .
-            "B1022F00000000000000" .
-            "B1023900000000000000" .
-            "BD02D2FFFFFF" .
-            "BD02C8FFFFFF" .
-            "C102D1FFFFFFFFFFFFFF" .
-            "C102C7FFFFFFFFFFFFFF" .
-            "CD020000C03F" .
-            "CD0200002040" .
-            "D1029A9999999999F93F" .
-            "D102CDCCCCCCCCCC0440" .
-            "D80201" .
-            "D80200" .
+            "FA0114D6FFFFFFFFFFFFFFFF01CCFFFFFFFFFFFFFFFF01" .
+            "820214D5FFFFFFFFFFFFFFFF01CBFFFFFFFFFFFFFFFF01" .
+            "8A02022A34" .
+            "9202022B35" .
+            "9A0202576B" .
+            "A20202596D" .
+            "AA02082E00000038000000" .
+            "B202102F000000000000003900000000000000" .
+            "BA0208D2FFFFFFC8FFFFFF" .
+            "C20210D1FFFFFFFFFFFFFFC7FFFFFFFFFFFFFF" .
+            "CA02080000C03F00002040" .
+            "D202109A9999999999F93FCDCCCCCCCCCC0440" .
+            "DA02020100" .
             "E2020161" .
             "E2020163" .
             "EA020462626262" .
             "EA020464646464" .
-            "F00200" .
-            "F00201" .
+            "F202020001" .
             "FA02020822" .
             "FA02020823" .
 
diff --git a/php/tests/valgrind.supp b/php/tests/valgrind.supp
new file mode 100644
index 0000000..e83b0a3
--- /dev/null
+++ b/php/tests/valgrind.supp
@@ -0,0 +1,12 @@
+{
+   PHP_Equal_Val
+   Memcheck:Cond
+   fun:zend_string_equal_val
+}
+
+{
+   PHP_ScanDir_Tail
+   Memcheck:Cond
+   obj:/usr/bin/php7.3
+   fun:__scandir64_tail
+}
diff --git a/protoc-artifacts/pom.xml b/protoc-artifacts/pom.xml
index 6d750c5..27315e8 100644
--- a/protoc-artifacts/pom.xml
+++ b/protoc-artifacts/pom.xml
@@ -8,7 +8,7 @@
   </parent>
   <groupId>com.google.protobuf</groupId>
   <artifactId>protoc</artifactId>
-  <version>3.12.3</version>
+  <version>3.13.0</version>
   <packaging>pom</packaging>
   <name>Protobuf Compiler</name>
   <description>
diff --git a/python/README.md b/python/README.md
index a987c2d..cb8b7e9 100644
--- a/python/README.md
+++ b/python/README.md
@@ -22,7 +22,7 @@
 Development Warning
 ===================
 
-The pure python performance is slow. For better preformance please
+The pure python performance is slow. For better performance please
 use python c++ implementation.
 
 Installation
diff --git a/python/google/protobuf/internal/enum_type_wrapper.py b/python/google/protobuf/internal/enum_type_wrapper.py
index c8e1013..9ae0066 100644
--- a/python/google/protobuf/internal/enum_type_wrapper.py
+++ b/python/google/protobuf/internal/enum_type_wrapper.py
@@ -108,7 +108,9 @@
   def __getattr__(self, name):
     """Returns the value corresponding to the given enum name."""
     try:
-      return self._enum_type.values_by_name[name].number
+      return super(
+          EnumTypeWrapper,
+          self).__getattribute__('_enum_type').values_by_name[name].number
     except KeyError:
       pass  # fall out to break exception chaining
     raise AttributeError('Enum {} has no value defined for name {!r}'.format(
diff --git a/python/release.sh b/python/release.sh
index c915e12..6db87f0 100755
--- a/python/release.sh
+++ b/python/release.sh
@@ -11,7 +11,10 @@
   local PYTHON=$2
   local PYPI=$3
 
-  virtualenv --no-site-packages -p `which $PYTHON` test-venv
+  # Setuptools 45.0 removed support for Python 2, so to test with Python 2 we
+  # pass --no-setuptools here and then install an older setuptools version
+  # below.
+  virtualenv -p `which $PYTHON` --no-setuptools test-venv
 
   # Intentionally put a broken protoc in the path to make sure installation
   # doesn't require protoc installed.
@@ -19,6 +22,7 @@
   chmod +x test-venv/bin/protoc
 
   source test-venv/bin/activate
+  pip install "setuptools<45"
   pip install -i ${PYPI} protobuf==${VERSION} --no-cache-dir
   deactivate
   rm -fr test-venv
diff --git a/ruby/ext/google/protobuf_c/upb.h b/ruby/ext/google/protobuf_c/upb.h
index bdc20eb..b7da76f 100644
--- a/ruby/ext/google/protobuf_c/upb.h
+++ b/ruby/ext/google/protobuf_c/upb.h
@@ -200,7 +200,7 @@
 ** store pointers or integers of at least 32 bits (upb isn't really useful on
 ** systems where sizeof(void*) < 4).
 **
-** The table must be homogenous (all values of the same type).  In debug
+** The table must be homogeneous (all values of the same type).  In debug
 ** mode, we check this on insert and lookup.
 */
 
@@ -6057,7 +6057,7 @@
 typedef struct {
   /* Space optimization note: we store two pointers here that the JIT
    * doesn't need at all; the upb_handlers* inside the sink and
-   * the dispatch table pointer.  We can optimze so that the JIT uses
+   * the dispatch table pointer.  We can optimize so that the JIT uses
    * smaller stack frames than the interpreter.  The only thing we need
    * to guarantee is that the fallback routines can find end_ofs. */
   upb_sink sink;
diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec
index 2160d52..21528fe 100644
--- a/ruby/google-protobuf.gemspec
+++ b/ruby/google-protobuf.gemspec
@@ -1,6 +1,6 @@
 Gem::Specification.new do |s|
   s.name        = "google-protobuf"
-  s.version     = "3.12.3"
+  s.version     = "3.13.0"
   git_tag       = "v#{s.version.to_s.sub('.rc.', '-rc')}" # Converts X.Y.Z.rc.N to vX.Y.Z-rcN, used for the git tag
   s.licenses    = ["BSD-3-Clause"]
   s.summary     = "Protocol Buffers"
diff --git a/src/Makefile.am b/src/Makefile.am
index 714fe71..ca460aa 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -208,6 +208,7 @@
   google/protobuf/generated_message_table_driven_lite.h        \
   google/protobuf/generated_message_table_driven_lite.cc       \
   google/protobuf/implicit_weak_message.cc                     \
+  google/protobuf/map.cc                                       \
   google/protobuf/message_lite.cc                              \
   google/protobuf/parse_context.cc                             \
   google/protobuf/repeated_field.cc                            \
diff --git a/src/google/protobuf/any.cc b/src/google/protobuf/any.cc
index a9876fc..ebe9ba7 100644
--- a/src/google/protobuf/any.cc
+++ b/src/google/protobuf/any.cc
@@ -47,18 +47,20 @@
 
 void AnyMetadata::PackFrom(const Message& message,
                            StringPiece type_url_prefix) {
-  type_url_->SetNoArena(
+  type_url_->Set(
       &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString(),
-      GetTypeUrl(message.GetDescriptor()->full_name(), type_url_prefix));
-  message.SerializeToString(value_->MutableNoArena(
-      &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()));
+      GetTypeUrl(message.GetDescriptor()->full_name(), type_url_prefix),
+      nullptr);
+  message.SerializeToString(value_->Mutable(
+      &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
+      nullptr));
 }
 
 bool AnyMetadata::UnpackTo(Message* message) const {
   if (!InternalIs(message->GetDescriptor()->full_name())) {
     return false;
   }
-  return message->ParseFromString(value_->GetNoArena());
+  return message->ParseFromString(value_->Get());
 }
 
 bool GetAnyFieldDescriptors(const Message& message,
diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc
index 7eed87c..3170748 100644
--- a/src/google/protobuf/any.pb.cc
+++ b/src/google/protobuf/any.pb.cc
@@ -28,7 +28,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::Any();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::Any::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Any_google_2fprotobuf_2fany_2eproto =
@@ -82,8 +81,6 @@
 
 // ===================================================================
 
-void Any::InitAsDefaultInstance() {
-}
 bool Any::GetAnyFieldDescriptors(
     const ::PROTOBUF_NAMESPACE_ID::Message& message,
     const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** type_url_field,
diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h
index 90cd342..1c50d6e 100644
--- a/src/google/protobuf/any.pb.h
+++ b/src/google/protobuf/any.pb.h
@@ -102,7 +102,6 @@
   }
   static const Any& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const Any* internal_default_instance() {
     return reinterpret_cast<const Any*>(
                &_Any_default_instance_);
diff --git a/src/google/protobuf/any_lite.cc b/src/google/protobuf/any_lite.cc
index 3badb41..206b01f 100644
--- a/src/google/protobuf/any_lite.cc
+++ b/src/google/protobuf/any_lite.cc
@@ -59,10 +59,10 @@
 void AnyMetadata::InternalPackFrom(const MessageLite& message,
                                    StringPiece type_url_prefix,
                                    StringPiece type_name) {
-  type_url_->SetNoArena(&::google::protobuf::internal::GetEmptyString(),
-                        GetTypeUrl(type_name, type_url_prefix));
-  message.SerializeToString(value_->MutableNoArena(
-      &::google::protobuf::internal::GetEmptyStringAlreadyInited()));
+  type_url_->Set(&::google::protobuf::internal::GetEmptyString(),
+                 GetTypeUrl(type_name, type_url_prefix), nullptr);
+  message.SerializeToString(value_->Mutable(
+      &::google::protobuf::internal::GetEmptyStringAlreadyInited(), nullptr));
 }
 
 bool AnyMetadata::InternalUnpackTo(StringPiece type_name,
@@ -70,31 +70,11 @@
   if (!InternalIs(type_name)) {
     return false;
   }
-  return message->ParseFromString(value_->GetNoArena());
+  return message->ParseFromString(value_->Get());
 }
 
-namespace {
-
-// The type URL could be stored in either an ArenaStringPtr or a
-// StringPieceField, so we provide these helpers to get a string_view from
-// either type. We use a template function as a way to avoid depending on
-// StringPieceField.
-
-template <typename T>
-StringPiece Get(const T* ptr) {
-  return ptr->Get();
-}
-
-template <>
-// NOLINTNEXTLINE: clang-diagnostic-unused-function
-StringPiece Get(const ArenaStringPtr* ptr) {
-  return ptr->GetNoArena();
-}
-
-}  // namespace
-
 bool AnyMetadata::InternalIs(StringPiece type_name) const {
-  StringPiece type_url = Get(type_url_);
+  StringPiece type_url = type_url_->Get();
   return type_url.size() >= type_name.size() + 1 &&
          type_url[type_url.size() - type_name.size() - 1] == '/' &&
          HasSuffixString(type_url, type_name);
diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc
index 6ae678a..f8e20a1 100644
--- a/src/google/protobuf/api.pb.cc
+++ b/src/google/protobuf/api.pb.cc
@@ -40,7 +40,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::Api();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::Api::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<4> scc_info_Api_google_2fprotobuf_2fapi_2eproto =
@@ -58,7 +57,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::Method();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::Method::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Method_google_2fprotobuf_2fapi_2eproto =
@@ -73,7 +71,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::Mixin();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::Mixin::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Mixin_google_2fprotobuf_2fapi_2eproto =
@@ -172,10 +169,6 @@
 
 // ===================================================================
 
-void Api::InitAsDefaultInstance() {
-  PROTOBUF_NAMESPACE_ID::_Api_default_instance_._instance.get_mutable()->source_context_ = const_cast< PROTOBUF_NAMESPACE_ID::SourceContext*>(
-      PROTOBUF_NAMESPACE_ID::SourceContext::internal_default_instance());
-}
 class Api::_Internal {
  public:
   static const PROTOBUF_NAMESPACE_ID::SourceContext& source_context(const Api* msg);
@@ -601,8 +594,6 @@
 
 // ===================================================================
 
-void Method::InitAsDefaultInstance() {
-}
 class Method::_Internal {
  public:
 };
@@ -1002,8 +993,6 @@
 
 // ===================================================================
 
-void Mixin::InitAsDefaultInstance() {
-}
 class Mixin::_Internal {
  public:
 };
diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h
index a3c61a4..64f90ee 100644
--- a/src/google/protobuf/api.pb.h
+++ b/src/google/protobuf/api.pb.h
@@ -112,7 +112,6 @@
   }
   static const Api& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const Api* internal_default_instance() {
     return reinterpret_cast<const Api*>(
                &_Api_default_instance_);
@@ -365,7 +364,6 @@
   }
   static const Method& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const Method* internal_default_instance() {
     return reinterpret_cast<const Method*>(
                &_Method_default_instance_);
@@ -598,7 +596,6 @@
   }
   static const Mixin& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const Mixin* internal_default_instance() {
     return reinterpret_cast<const Mixin*>(
                &_Mixin_default_instance_);
@@ -941,8 +938,8 @@
 }
 inline const PROTOBUF_NAMESPACE_ID::SourceContext& Api::_internal_source_context() const {
   const PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_;
-  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::SourceContext*>(
-      &PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_);
+  return p != nullptr ? *p : reinterpret_cast<const PROTOBUF_NAMESPACE_ID::SourceContext&>(
+      PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::SourceContext& Api::source_context() const {
   // @@protoc_insertion_point(field_get:google.protobuf.Api.source_context)
diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc
index 7362b62..13e11b5 100644
--- a/src/google/protobuf/arena.cc
+++ b/src/google/protobuf/arena.cc
@@ -166,27 +166,19 @@
 
 PROTOBUF_NOINLINE
 void* ArenaImpl::AllocateAlignedFallback(size_t n) {
-  return GetSerialArena()->AllocateAligned(n);
+  return GetSerialArenaFallback(&thread_cache())->AllocateAligned(n);
 }
 
 PROTOBUF_NOINLINE
 void* ArenaImpl::AllocateAlignedAndAddCleanupFallback(size_t n,
                                                       void (*cleanup)(void*)) {
-  return GetSerialArena()->AllocateAlignedAndAddCleanup(n, cleanup);
+  return GetSerialArenaFallback(
+      &thread_cache())->AllocateAlignedAndAddCleanup(n, cleanup);
 }
 
 PROTOBUF_NOINLINE
 void ArenaImpl::AddCleanupFallback(void* elem, void (*cleanup)(void*)) {
-  GetSerialArena()->AddCleanup(elem, cleanup);
-}
-
-ArenaImpl::SerialArena* ArenaImpl::GetSerialArena() {
-  SerialArena* arena;
-  if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) {
-    return arena;
-  } else {
-    return GetSerialArenaFallback(&thread_cache());
-  }
+  GetSerialArenaFallback(&thread_cache())->AddCleanup(elem, cleanup);
 }
 
 PROTOBUF_NOINLINE
diff --git a/src/google/protobuf/arena_impl.h b/src/google/protobuf/arena_impl.h
index c9b4c54..2f8d343 100644
--- a/src/google/protobuf/arena_impl.h
+++ b/src/google/protobuf/arena_impl.h
@@ -329,7 +329,6 @@
 
   Block* NewBlock(Block* last_block, size_t min_bytes);
 
-  SerialArena* GetSerialArena();
   PROTOBUF_ALWAYS_INLINE bool GetSerialArenaFast(SerialArena** arena) {
     if (GetSerialArenaFromThreadCache(arena)) return true;
 
diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc
index 8578420..8919027 100644
--- a/src/google/protobuf/arena_unittest.cc
+++ b/src/google/protobuf/arena_unittest.cc
@@ -1166,7 +1166,6 @@
 }
 #endif  // PROTOBUF_RTTI
 
-
 // RepeatedField should support non-POD types, and invoke constructors and
 // destructors appropriately, because it's used this way by lots of other code
 // (even if this was not its original intent).
diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h
index 122f391..b87be8e 100644
--- a/src/google/protobuf/arenastring.h
+++ b/src/google/protobuf/arenastring.h
@@ -229,7 +229,6 @@
   // Clears content, assuming that the current value is not the empty string
   // default.
   inline void ClearNonDefaultToEmpty() { ptr_->clear(); }
-  inline void ClearNonDefaultToEmptyNoArena() { ptr_->clear(); }
 
   // Clears content, but keeps allocated string if arena != NULL, to avoid the
   // overhead of heap operations. After this returns, the content (as seen by
@@ -257,93 +256,13 @@
     ptr_ = const_cast< ::std::string*>(default_value);
   }
 
-  // The 'NoArena' variants of methods below assume arena == NULL and are
-  // optimized to provide very little overhead relative to a raw string pointer
-  // (while still being in-memory compatible with other code that assumes
-  // ArenaStringPtr). Note the invariant that a class instance that has only
-  // ever been mutated by NoArena methods must *only* be in the String state
-  // (i.e., tag bits are not used), *NEVER* ArenaString. This allows all
-  // tagged-pointer manipulations to be avoided.
-  inline void SetNoArena(const ::std::string* default_value,
-                         const ::std::string& value) {
-    if (ptr_ == default_value) {
-      CreateInstanceNoArena(&value);
-    } else {
-      *ptr_ = value;
-    }
-  }
-
-  void SetNoArena(const ::std::string* default_value, ::std::string&& value) {
-    if (IsDefault(default_value)) {
-      ptr_ = new ::std::string(std::move(value));
-    } else {
-      *ptr_ = std::move(value);
-    }
-  }
-
-  void AssignWithDefault(const ::std::string* default_value,
-                         ArenaStringPtr value);
-
-  inline const ::std::string& GetNoArena() const { return *ptr_; }
-
-  inline ::std::string* MutableNoArena(const ::std::string* default_value) {
-    if (ptr_ == default_value) {
-      CreateInstanceNoArena(default_value);
-    }
-    return ptr_;
-  }
-
-  inline ::std::string* ReleaseNoArena(const ::std::string* default_value) {
-    if (ptr_ == default_value) {
-      return NULL;
-    } else {
-      return ReleaseNonDefaultNoArena(default_value);
-    }
-  }
-
-  inline ::std::string* ReleaseNonDefaultNoArena(
-      const ::std::string* default_value) {
-    GOOGLE_DCHECK(!IsDefault(default_value));
-    ::std::string* released = ptr_;
-    ptr_ = const_cast< ::std::string*>(default_value);
-    return released;
-  }
-
-  inline void SetAllocatedNoArena(const ::std::string* default_value,
-                                  ::std::string* value) {
-    if (ptr_ != default_value) {
-      delete ptr_;
-    }
-    if (value != NULL) {
-      ptr_ = value;
-    } else {
-      ptr_ = const_cast< ::std::string*>(default_value);
-    }
-  }
-
+  // Destroy the string. Assumes `arena == nullptr`.
   inline void DestroyNoArena(const ::std::string* default_value) {
     if (ptr_ != default_value) {
       delete ptr_;
     }
   }
 
-  inline void ClearToEmptyNoArena(const ::std::string* default_value) {
-    if (ptr_ == default_value) {
-      // Nothing: already equal to default (which is the empty string).
-    } else {
-      ptr_->clear();
-    }
-  }
-
-  inline void ClearToDefaultNoArena(const ::std::string* default_value) {
-    if (ptr_ == default_value) {
-      // Nothing: already set to default.
-    } else {
-      // Reuse existing allocated instance.
-      *ptr_ = *default_value;
-    }
-  }
-
   // Internal accessor used only at parse time to provide direct access to the
   // raw pointer from the shared parse routine (in the non-arenas case). The
   // parse routine does the string allocation in order to save code size in the
@@ -381,22 +300,6 @@
 
 }  // namespace internal
 }  // namespace protobuf
-
-namespace protobuf {
-namespace internal {
-
-inline void ArenaStringPtr::AssignWithDefault(
-    const ::std::string* default_value, ArenaStringPtr value) {
-  const ::std::string* me = *UnsafeRawStringPointer();
-  const ::std::string* other = *value.UnsafeRawStringPointer();
-  // If the pointers are the same then do nothing.
-  if (me != other) {
-    SetNoArena(default_value, value.GetNoArena());
-  }
-}
-
-}  // namespace internal
-}  // namespace protobuf
 }  // namespace google
 
 
diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc
index 693300d..4d78bb1 100644
--- a/src/google/protobuf/compiler/code_generator.cc
+++ b/src/google/protobuf/compiler/code_generator.cc
@@ -85,6 +85,12 @@
   return NULL;  // make compiler happy
 }
 
+io::ZeroCopyOutputStream* GeneratorContext::OpenForInsertWithGeneratedCodeInfo(
+    const std::string& filename, const std::string& insertion_point,
+    const google::protobuf::GeneratedCodeInfo& /*info*/) {
+  return OpenForInsert(filename, insertion_point);
+}
+
 void GeneratorContext::ListParsedFiles(
     std::vector<const FileDescriptor*>* output) {
   GOOGLE_LOG(FATAL) << "This GeneratorContext does not support ListParsedFiles";
diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h
index 21131d5..323f48e 100644
--- a/src/google/protobuf/compiler/code_generator.h
+++ b/src/google/protobuf/compiler/code_generator.h
@@ -52,6 +52,7 @@
 class ZeroCopyOutputStream;
 }
 class FileDescriptor;
+class GeneratedCodeInfo;
 
 namespace compiler {
 class AccessInfoMap;
@@ -156,6 +157,15 @@
   virtual io::ZeroCopyOutputStream* OpenForInsert(
       const std::string& filename, const std::string& insertion_point);
 
+  // Similar to OpenForInsert, but if `info` is non-empty, will open (or create)
+  // filename.pb.meta and insert info at the appropriate place with the
+  // necessary shifts. The default implementation ignores `info`.
+  //
+  // WARNING:  This feature will be REMOVED in the near future.
+  virtual io::ZeroCopyOutputStream* OpenForInsertWithGeneratedCodeInfo(
+      const std::string& filename, const std::string& insertion_point,
+      const google::protobuf::GeneratedCodeInfo& info);
+
   // Returns a vector of FileDescriptors for all the files being compiled
   // in this run.  Useful for languages, such as Go, that treat files
   // differently when compiled as a set rather than individually.
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index 1ada897..859eb8b 100644
--- a/src/google/protobuf/compiler/command_line_interface.cc
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -386,6 +386,9 @@
   io::ZeroCopyOutputStream* OpenForAppend(const std::string& filename);
   io::ZeroCopyOutputStream* OpenForInsert(const std::string& filename,
                                           const std::string& insertion_point);
+  io::ZeroCopyOutputStream* OpenForInsertWithGeneratedCodeInfo(
+      const std::string& filename, const std::string& insertion_point,
+      const google::protobuf::GeneratedCodeInfo& info);
   void ListParsedFiles(std::vector<const FileDescriptor*>* output) {
     *output = parsed_files_;
   }
@@ -393,7 +396,8 @@
  private:
   friend class MemoryOutputStream;
 
-  // map instead of unordered_map so that files are written in order (good when
+  // The files_ field maps from path keys to file content values. It's a map
+  // instead of an unordered_map so that files are written in order (good when
   // writing zips).
   std::map<std::string, std::string> files_;
   const std::vector<const FileDescriptor*>& parsed_files_;
@@ -408,6 +412,10 @@
   MemoryOutputStream(GeneratorContextImpl* directory,
                      const std::string& filename,
                      const std::string& insertion_point);
+  MemoryOutputStream(GeneratorContextImpl* directory,
+                     const std::string& filename,
+                     const std::string& insertion_point,
+                     const google::protobuf::GeneratedCodeInfo& info);
   virtual ~MemoryOutputStream();
 
   // implements ZeroCopyOutputStream ---------------------------------
@@ -418,12 +426,23 @@
   int64_t ByteCount() const override { return inner_->ByteCount(); }
 
  private:
-  // Checks to see if "filename_.meta" exists in directory_; if so, fixes the
+  // Checks to see if "filename_.pb.meta" exists in directory_; if so, fixes the
   // offsets in that GeneratedCodeInfo record to reflect bytes inserted in
   // filename_ at original offset insertion_offset with length insertion_length.
-  // We assume that insertions will not occur within any given annotated span
-  // of text.
-  void UpdateMetadata(size_t insertion_offset, size_t insertion_length);
+  // Also adds in the data from info_to_insert_ with updated offsets governed by
+  // insertion_offset and indent_length. We assume that insertions will not
+  // occur within any given annotated span of text. insertion_content must end
+  // with an endline.
+  void UpdateMetadata(const std::string& insertion_content,
+                      size_t insertion_offset, size_t insertion_length,
+                      size_t indent_length);
+
+  // Inserts info_to_insert_ into target_info, assuming that the relevant
+  // insertion was made at insertion_offset in file_content with the given
+  // indent_length. insertion_content must end with an endline.
+  void InsertShiftedInfo(const std::string& insertion_content,
+                         size_t insertion_offset, size_t indent_length,
+                         google::protobuf::GeneratedCodeInfo& target_info);
 
   // Where to insert the string when it's done.
   GeneratorContextImpl* directory_;
@@ -438,6 +457,9 @@
 
   // StringOutputStream writing to data_.
   std::unique_ptr<io::StringOutputStream> inner_;
+
+  // The GeneratedCodeInfo to insert at the insertion point.
+  google::protobuf::GeneratedCodeInfo info_to_insert_;
 };
 
 // -------------------------------------------------------------------
@@ -594,6 +616,13 @@
   return new MemoryOutputStream(this, filename, insertion_point);
 }
 
+io::ZeroCopyOutputStream*
+CommandLineInterface::GeneratorContextImpl::OpenForInsertWithGeneratedCodeInfo(
+    const std::string& filename, const std::string& insertion_point,
+    const google::protobuf::GeneratedCodeInfo& info) {
+  return new MemoryOutputStream(this, filename, insertion_point, info);
+}
+
 // -------------------------------------------------------------------
 
 CommandLineInterface::MemoryOutputStream::MemoryOutputStream(
@@ -612,40 +641,114 @@
       insertion_point_(insertion_point),
       inner_(new io::StringOutputStream(&data_)) {}
 
+CommandLineInterface::MemoryOutputStream::MemoryOutputStream(
+    GeneratorContextImpl* directory, const std::string& filename,
+    const std::string& insertion_point, const google::protobuf::GeneratedCodeInfo& info)
+    : directory_(directory),
+      filename_(filename),
+      insertion_point_(insertion_point),
+      inner_(new io::StringOutputStream(&data_)),
+      info_to_insert_(info) {}
+
+void CommandLineInterface::MemoryOutputStream::InsertShiftedInfo(
+    const std::string& insertion_content, size_t insertion_offset,
+    size_t indent_length, google::protobuf::GeneratedCodeInfo& target_info) {
+  // Keep track of how much extra data was added for indents before the
+  // current annotation being inserted. `pos` and `source_annotation.begin()`
+  // are offsets in `insertion_content`. `insertion_offset` is updated so that
+  // it can be added to an annotation's `begin` field to reflect that
+  // annotation's updated location after `insertion_content` was inserted into
+  // the target file.
+  size_t pos = 0;
+  insertion_offset += indent_length;
+  for (const auto& source_annotation : info_to_insert_.annotation()) {
+    GeneratedCodeInfo::Annotation* annotation = target_info.add_annotation();
+    int inner_indent = 0;
+    // insertion_content is guaranteed to end in an endline. This last endline
+    // has no effect on indentation.
+    for (; pos < source_annotation.end() && pos < insertion_content.size() - 1;
+         ++pos) {
+      if (insertion_content[pos] == '\n') {
+        if (pos >= source_annotation.begin()) {
+          // The beginning of the annotation is at insertion_offset, but the end
+          // can still move further in the target file.
+          inner_indent += indent_length;
+        } else {
+          insertion_offset += indent_length;
+        }
+      }
+    }
+    *annotation = source_annotation;
+    annotation->set_begin(annotation->begin() + insertion_offset);
+    insertion_offset += inner_indent;
+    annotation->set_end(annotation->end() + insertion_offset);
+  }
+}
+
 void CommandLineInterface::MemoryOutputStream::UpdateMetadata(
-    size_t insertion_offset, size_t insertion_length) {
-  auto it = directory_->files_.find(filename_ + ".meta");
-  if (it == directory_->files_.end()) {
+    const std::string& insertion_content, size_t insertion_offset,
+    size_t insertion_length, size_t indent_length) {
+  auto it = directory_->files_.find(filename_ + ".pb.meta");
+  if (it == directory_->files_.end() && info_to_insert_.annotation().empty()) {
     // No metadata was recorded for this file.
     return;
   }
-  std::string& encoded_data = it->second;
   GeneratedCodeInfo metadata;
   bool is_text_format = false;
-  if (!metadata.ParseFromString(encoded_data)) {
-    if (!TextFormat::ParseFromString(encoded_data, &metadata)) {
-      // The metadata is invalid.
-      std::cerr << filename_
-                << ".meta: Could not parse metadata as wire or text format."
-                << std::endl;
-      return;
+  std::string* encoded_data = nullptr;
+  if (it != directory_->files_.end()) {
+    encoded_data = &it->second;
+    // Try to decode a GeneratedCodeInfo proto from the .pb.meta file. It may be
+    // in wire or text format. Keep the same format when the data is written out
+    // later.
+    if (!metadata.ParseFromString(*encoded_data)) {
+      if (!TextFormat::ParseFromString(*encoded_data, &metadata)) {
+        // The metadata is invalid.
+        std::cerr
+            << filename_
+            << ".pb.meta: Could not parse metadata as wire or text format."
+            << std::endl;
+        return;
+      }
+      // Generators that use the public plugin interface emit text-format
+      // metadata (because in the public plugin protocol, file content must be
+      // UTF8-encoded strings).
+      is_text_format = true;
     }
-    // Generators that use the public plugin interface emit text-format
-    // metadata (because in the public plugin protocol, file content must be
-    // UTF8-encoded strings).
-    is_text_format = true;
+  } else {
+    // Create a new file to store the new metadata in info_to_insert_.
+    encoded_data =
+        &directory_->files_.insert({filename_ + ".pb.meta", ""}).first->second;
   }
-  for (int i = 0; i < metadata.annotation_size(); ++i) {
-    GeneratedCodeInfo::Annotation* annotation = metadata.mutable_annotation(i);
-    if (annotation->begin() >= insertion_offset) {
-      annotation->set_begin(annotation->begin() + insertion_length);
-      annotation->set_end(annotation->end() + insertion_length);
+  GeneratedCodeInfo new_metadata;
+  bool crossed_offset = false;
+  size_t to_add = 0;
+  for (const auto& source_annotation : metadata.annotation()) {
+    // The first time an annotation at or after the insertion point is found,
+    // insert the new metadata from info_to_insert_. Shift all annotations
+    // after the new metadata by the length of the text that was inserted
+    // (including any additional indent length).
+    if (source_annotation.begin() >= insertion_offset && !crossed_offset) {
+      crossed_offset = true;
+      InsertShiftedInfo(insertion_content, insertion_offset, indent_length,
+                        new_metadata);
+      to_add += insertion_length;
     }
+    GeneratedCodeInfo::Annotation* annotation = new_metadata.add_annotation();
+    *annotation = source_annotation;
+    annotation->set_begin(annotation->begin() + to_add);
+    annotation->set_end(annotation->end() + to_add);
+  }
+  // If there were never any annotations at or after the insertion point,
+  // make sure to still insert the new metadata from info_to_insert_.
+  if (!crossed_offset) {
+    InsertShiftedInfo(insertion_content, insertion_offset, indent_length,
+                      new_metadata);
   }
   if (is_text_format) {
-    TextFormat::PrintToString(metadata, &encoded_data);
+    TextFormat::PrintToString(new_metadata, encoded_data);
   } else {
-    metadata.SerializeToString(&encoded_data);
+    new_metadata.SerializeToString(encoded_data);
   }
 }
 
@@ -728,7 +831,7 @@
     if (indent_.empty()) {
       // No indent.  This makes things easier.
       target->insert(pos, data_);
-      UpdateMetadata(pos, data_.size());
+      UpdateMetadata(data_, pos, data_.size(), 0);
     } else {
       // Calculate how much space we need.
       int indent_size = 0;
@@ -738,7 +841,6 @@
 
       // Make a hole for it.
       target->insert(pos, data_.size() + indent_size, '\0');
-      UpdateMetadata(pos, data_.size() + indent_size);
 
       // Now copy in the data.
       std::string::size_type data_pos = 0;
@@ -757,6 +859,7 @@
         target_ptr += line_length;
         data_pos += line_length;
       }
+      UpdateMetadata(data_, pos, data_.size() + indent_size, indent_.size());
 
       GOOGLE_CHECK_EQ(target_ptr,
                ::google::protobuf::string_as_array(target) + pos + data_.size() + indent_size);
@@ -1427,13 +1530,33 @@
     proto_path_.push_back(std::pair<std::string, std::string>("", "."));
   }
 
-  // Check some error cases.
-  bool decoding_raw = (mode_ == MODE_DECODE) && codec_type_.empty();
-  if (decoding_raw && !input_files_.empty()) {
-    std::cerr << "When using --decode_raw, no input files should be given."
+  // Check error cases that span multiple flag values.
+  bool missing_proto_definitions;
+  switch (mode_) {
+    case MODE_COMPILE:
+      missing_proto_definitions = input_files_.empty();
+      break;
+    case MODE_DECODE:
+      // Handle --decode_raw separately, since it requires that no proto
+      // definitions are specified.
+      if (codec_type_.empty()) {
+        if (!input_files_.empty() || !descriptor_set_in_names_.empty()) {
+          std::cerr
+              << "When using --decode_raw, no input files should be given."
               << std::endl;
-    return PARSE_ARGUMENT_FAIL;
-  } else if (!decoding_raw && input_files_.empty()) {
+          return PARSE_ARGUMENT_FAIL;
+        }
+        missing_proto_definitions = false;
+        break;  // only for --decode_raw
+      }
+      // --decode (not raw) is handled the same way as the rest of the modes.
+      PROTOBUF_FALLTHROUGH_INTENDED;
+    case MODE_ENCODE:
+    case MODE_PRINT:
+      missing_proto_definitions =
+          input_files_.empty() && descriptor_set_in_names_.empty();
+  }
+  if (missing_proto_definitions) {
     std::cerr << "Missing input file." << std::endl;
     return PARSE_ARGUMENT_FAIL;
   }
@@ -2224,8 +2347,10 @@
       // We reset current_output to NULL first so that the old file is closed
       // before the new one is opened.
       current_output.reset();
-      current_output.reset(generator_context->OpenForInsert(
-          filename, output_file.insertion_point()));
+      current_output.reset(
+          generator_context->OpenForInsertWithGeneratedCodeInfo(
+              filename, output_file.insertion_point(),
+              output_file.generated_code_info()));
     } else if (!output_file.name().empty()) {
       // Starting a new file.  Open it.
       // We reset current_output to NULL first so that the old file is closed
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index e42ca26..5d91042 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -1192,8 +1192,8 @@
   Run("protocol_compiler "
       "--test_out=TestParameter:$tmpdir "
       "--plug_out=TestPluginParameter:$tmpdir "
-      "--test_out=insert=test_generator,test_plugin:$tmpdir "
-      "--plug_out=insert=test_generator,test_plugin:$tmpdir "
+      "--test_out=insert_endlines=test_generator,test_plugin:$tmpdir "
+      "--plug_out=insert_endlines=test_generator,test_plugin:$tmpdir "
       "--proto_path=$tmpdir foo.proto");
 
   ExpectNoErrors();
@@ -2564,20 +2564,22 @@
   enum Type { TEXT, BINARY };
   enum ReturnCode { SUCCESS, ERROR };
 
-  bool Run(const std::string& command) {
+  bool Run(const std::string& command, bool specify_proto_files = true) {
     std::vector<std::string> args;
     args.push_back("protoc");
     SplitStringUsing(command, " ", &args);
-    switch (GetParam()) {
-      case PROTO_PATH:
-        args.push_back("--proto_path=" + TestUtil::TestSourceDir());
-        break;
-      case DESCRIPTOR_SET_IN:
-        args.push_back(StrCat("--descriptor_set_in=",
-                                    unittest_proto_descriptor_set_filename_));
-        break;
-      default:
-        ADD_FAILURE() << "unexpected EncodeDecodeTestMode: " << GetParam();
+    if (specify_proto_files) {
+      switch (GetParam()) {
+        case PROTO_PATH:
+          args.push_back("--proto_path=" + TestUtil::TestSourceDir());
+          break;
+        case DESCRIPTOR_SET_IN:
+          args.push_back(StrCat("--descriptor_set_in=",
+                                      unittest_proto_descriptor_set_filename_));
+          break;
+        default:
+          ADD_FAILURE() << "unexpected EncodeDecodeTestMode: " << GetParam();
+      }
     }
 
     std::unique_ptr<const char*[]> argv(new const char*[args.size()]);
@@ -2659,9 +2661,12 @@
   RedirectStdinFromFile(TestUtil::GetTestDataPath(
       "net/proto2/internal/"
       "testdata/text_format_unittest_data_oneof_implemented.txt"));
-  EXPECT_TRUE(
-      Run(TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto") +
-          " --encode=protobuf_unittest.TestAllTypes"));
+  std::string args;
+  if (GetParam() != DESCRIPTOR_SET_IN) {
+    args.append(
+        TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto"));
+  }
+  EXPECT_TRUE(Run(args + " --encode=protobuf_unittest.TestAllTypes"));
   ExpectStdoutMatchesBinaryFile(TestUtil::GetTestDataPath(
       "net/proto2/internal/testdata/golden_message_oneof_implemented"));
   ExpectStderrMatchesText("");
@@ -2697,7 +2702,7 @@
   message.SerializeToString(&data);
 
   RedirectStdinFromText(data);
-  EXPECT_TRUE(Run("--decode_raw"));
+  EXPECT_TRUE(Run("--decode_raw", /*specify_proto_files=*/false));
   ExpectStdoutMatchesText(
       "1: 123\n"
       "14: \"foo\"\n");
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index 7d69eb5..c27b464 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -441,12 +441,11 @@
       "  ::$proto_ns$::internal::ExplicitlyConstructed<$2$> _instance;\n",
       DefaultInstanceType(generator->descriptor_, options_),
       generator->classname_);
-  format.Indent();
-  generator->GenerateExtraDefaultFields(printer);
-  format.Outdent();
   format("} $1$;\n", DefaultInstanceName(generator->descriptor_, options_));
+
   if (options_.lite_implicit_weak_fields) {
-    format("$1$DefaultTypeInternal* $2$ = &$3$;\n", generator->classname_,
+    format("$1$* $2$ = &$3$;\n",
+           DefaultInstanceType(generator->descriptor_, options_),
            DefaultInstancePtr(generator->descriptor_, options_),
            DefaultInstanceName(generator->descriptor_, options_));
   }
@@ -942,8 +941,6 @@
     if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) {
       continue;
     }
-    // TODO(gerbens) This requires this function to be friend. Remove
-    // the need for this.
     message_generators_[i]->GenerateFieldDefaultInstances(printer);
     format(
         "{\n"
@@ -961,17 +958,6 @@
     }
     format("}\n");
   }
-
-  // TODO(gerbens) make default instances be the same as normal instances.
-  // Default instances differ from normal instances because they have cross
-  // linked message fields.
-  for (int i = 0; i < message_generators_.size(); i++) {
-    if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) {
-      continue;
-    }
-    format("$1$::InitAsDefaultInstance();\n",
-           QualifiedClassName(message_generators_[i]->descriptor_, options_));
-  }
   format.Outdent();
   format("}\n\n");
 
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index 976823a..2a338ae 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -1388,7 +1388,7 @@
 
     std::vector<const FieldDescriptor*> ordered_fields;
     for (auto field : FieldRange(descriptor)) {
-      if (IsFieldUsed(field, options_)) {
+      if (!IsFieldStripped(field, options_)) {
         ordered_fields.push_back(field);
       }
     }
@@ -1615,9 +1615,13 @@
             }
           } else if (IsWeak(field, options_)) {
             format_(
-                "ptr = ctx->ParseMessage(_weak_field_map_.MutableMessage($1$,"
-                " _$classname$_default_instance_.$2$_), ptr);\n",
-                field->number(), FieldName(field));
+                "{\n"
+                "  auto* default_ = &reinterpret_cast<const Message&>($1$);\n"
+                "  ptr = ctx->ParseMessage(_weak_field_map_.MutableMessage($2$,"
+                " default_), ptr);\n"
+                "}\n",
+                QualifiedDefaultInstanceName(field->message_type(), options_),
+                field->number());
           } else {
             format_("ptr = ctx->ParseMessage(_internal_$1$_$2$(), ptr);\n",
                     field->is_repeated() ? "add" : "mutable", FieldName(field));
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h
index 988e609..4ee19b8 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.h
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -347,12 +347,16 @@
          !options.opensource_runtime;
 }
 
-// Returns true if "field" is used.
-inline bool IsFieldUsed(const FieldDescriptor* /*field*/,
-                        const Options& /*options*/) {
+inline bool IsFieldUsed(const FieldDescriptor* field, const Options& options) {
   return true;
 }
 
+// Returns true if "field" is stripped.
+inline bool IsFieldStripped(const FieldDescriptor* /*field*/,
+                            const Options& /*options*/) {
+  return false;
+}
+
 // Does the file contain any definitions that need extension_set.h?
 bool HasExtensionsOrExtendableMessage(const FileDescriptor* file);
 
@@ -450,27 +454,11 @@
   return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3;
 }
 
-inline bool SupportsArenas(const FileDescriptor* file) {
-  return file->options().cc_enable_arenas();
-}
-
-inline bool SupportsArenas(const Descriptor* desc) {
-  return SupportsArenas(desc->file());
-}
-
-inline bool SupportsArenas(const FieldDescriptor* field) {
-  return SupportsArenas(field->file());
-}
-
 inline bool IsCrossFileMessage(const FieldDescriptor* field) {
   return field->type() == FieldDescriptor::TYPE_MESSAGE &&
          field->message_type()->file() != field->file();
 }
 
-inline std::string MessageCreateFunction(const Descriptor* d) {
-  return SupportsArenas(d) ? "CreateMessage" : "Create";
-}
-
 inline std::string MakeDefaultName(const FieldDescriptor* field) {
   return "_i_give_permission_to_break_this_code_default_" + FieldName(field) +
          "_";
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index 7c7461f..19bf425 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -316,6 +316,17 @@
          options.opensource_runtime;
 }
 
+// Returns true to make the message serialize in order, decided by the following
+// factors in the order of precedence.
+// --options().message_set_wire_format() == true
+// --the message is in the allowlist (true)
+// --GOOGLE_PROTOBUF_SHUFFLE_SERIALIZE is defined (false)
+// --a ranage of message names that are allowed to stay in order (true)
+bool ShouldSerializeInOrder(const Descriptor* descriptor,
+                            const Options& options) {
+  return true;
+}
+
 bool TableDrivenParsingEnabled(const Descriptor* descriptor,
                                const Options& options) {
   if (!options.table_driven_parsing) {
@@ -584,7 +595,7 @@
   // Compute optimized field order to be used for layout and initialization
   // purposes.
   for (auto field : FieldRange(descriptor_)) {
-    if (!IsFieldUsed(field, options_)) {
+    if (IsFieldStripped(field, options_)) {
       continue;
     }
 
@@ -673,7 +684,7 @@
                         optimized_order_.end());
   for (auto field : FieldRange(descriptor_)) {
     if (!field->real_containing_oneof() && !field->options().weak() &&
-        IsFieldUsed(field, options_)) {
+        !IsFieldStripped(field, options_)) {
       continue;
     }
     ordered_fields.push_back(field);
@@ -702,8 +713,8 @@
 
     if (field->is_repeated()) {
       format("$deprecated_attr$int ${1$$name$_size$}$() const$2$\n", field,
-             IsFieldUsed(field, options_) ? ";" : " {__builtin_trap();}");
-      if (IsFieldUsed(field, options_)) {
+             !IsFieldStripped(field, options_) ? ";" : " {__builtin_trap();}");
+      if (!IsFieldStripped(field, options_)) {
         format(
             "private:\n"
             "int ${1$_internal_$name$_size$}$() const;\n"
@@ -712,15 +723,15 @@
       }
     } else if (HasHasMethod(field)) {
       format("$deprecated_attr$bool ${1$has_$name$$}$() const$2$\n", field,
-             IsFieldUsed(field, options_) ? ";" : " {__builtin_trap();}");
-      if (IsFieldUsed(field, options_)) {
+             !IsFieldStripped(field, options_) ? ";" : " {__builtin_trap();}");
+      if (!IsFieldStripped(field, options_)) {
         format(
             "private:\n"
             "bool _internal_has_$name$() const;\n"
             "public:\n");
       }
     } else if (HasPrivateHasMethod(field)) {
-      if (IsFieldUsed(field, options_)) {
+      if (!IsFieldStripped(field, options_)) {
         format(
             "private:\n"
             "bool ${1$_internal_has_$name$$}$() const;\n"
@@ -729,7 +740,7 @@
       }
     }
     format("$deprecated_attr$void ${1$clear_$name$$}$()$2$\n", field,
-           IsFieldUsed(field, options_) ? ";" : "{__builtin_trap();}");
+           !IsFieldStripped(field, options_) ? ";" : "{__builtin_trap();}");
 
     // Generate type-specific accessor declarations.
     field_generators_.get(field).GenerateAccessorDeclarations(printer);
@@ -764,7 +775,7 @@
 
 void MessageGenerator::GenerateSingularFieldHasBits(
     const FieldDescriptor* field, Formatter format) {
-  if (!IsFieldUsed(field, options_)) {
+  if (IsFieldStripped(field, options_)) {
     format(
         "inline bool $classname$::has_$name$() const { "
         "__builtin_trap(); }\n");
@@ -845,7 +856,7 @@
 
 void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field,
                                                   const Formatter& format) {
-  if (!IsFieldUsed(field, options_)) {
+  if (IsFieldStripped(field, options_)) {
     if (HasHasMethod(field)) {
       format(
           "inline bool $classname$::has_$name$() const { "
@@ -890,7 +901,7 @@
 
 void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field,
                                           bool is_inline, Formatter format) {
-  if (!IsFieldUsed(field, options_)) {
+  if (IsFieldStripped(field, options_)) {
     format("void $classname$::clear_$name$() { __builtin_trap(); }\n");
     return;
   }
@@ -936,7 +947,7 @@
   for (auto field : FieldRange(descriptor_)) {
     PrintFieldComment(format, field);
 
-    if (!IsFieldUsed(field, options_)) {
+    if (IsFieldStripped(field, options_)) {
       continue;
     }
 
@@ -948,7 +959,7 @@
 
     // Generate has_$name$() or $name$_size().
     if (field->is_repeated()) {
-      if (!IsFieldUsed(field, options_)) {
+      if (IsFieldStripped(field, options_)) {
         format(
             "inline int $classname$::$name$_size() const { "
             "__builtin_trap(); }\n");
@@ -982,7 +993,7 @@
     }
 
     // Generate type-specific accessors.
-    if (IsFieldUsed(field, options_)) {
+    if (!IsFieldStripped(field, options_)) {
       field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
     }
 
@@ -1105,13 +1116,8 @@
   format(" public:\n");
   format.Indent();
 
-  if (SupportsArenas(descriptor_)) {
-    format("inline $classname$() : $classname$(nullptr) {}\n");
-  } else {
-    format("$classname$();\n");
-  }
-
   format(
+      "inline $classname$() : $classname$(nullptr) {}\n"
       "virtual ~$classname$();\n"
       "\n"
       "$classname$(const $classname$& from);\n"
@@ -1207,7 +1213,6 @@
 
   // TODO(gerbens) make this private, while still granting other protos access.
   format(
-      "static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY\n"
       "static inline const $classname$* internal_default_instance() {\n"
       "  return reinterpret_cast<const $classname$*>(\n"
       "             &_$classname$_default_instance_);\n"
@@ -1290,31 +1295,21 @@
   format(
       "friend void swap($classname$& a, $classname$& b) {\n"
       "  a.Swap(&b);\n"
+      "}\n"
+      "inline void Swap($classname$* other) {\n"
+      "  if (other == this) return;\n"
+      "  if (GetArena() == other->GetArena()) {\n"
+      "    InternalSwap(other);\n"
+      "  } else {\n"
+      "    ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);\n"
+      "  }\n"
+      "}\n"
+      "void UnsafeArenaSwap($classname$* other) {\n"
+      "  if (other == this) return;\n"
+      "  $DCHK$(GetArena() == other->GetArena());\n"
+      "  InternalSwap(other);\n"
       "}\n");
 
-  if (SupportsArenas(descriptor_)) {
-    format(
-        "inline void Swap($classname$* other) {\n"
-        "  if (other == this) return;\n"
-        "  if (GetArena() == other->GetArena()) {\n"
-        "    InternalSwap(other);\n"
-        "  } else {\n"
-        "    ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);\n"
-        "  }\n"
-        "}\n"
-        "void UnsafeArenaSwap($classname$* other) {\n"
-        "  if (other == this) return;\n"
-        "  $DCHK$(GetArena() == other->GetArena());\n"
-        "  InternalSwap(other);\n"
-        "}\n");
-  } else {
-    format(
-        "inline void Swap($classname$* other) {\n"
-        "  if (other == this) return;\n"
-        "  InternalSwap(other);\n"
-        "}\n");
-  }
-
   format(
       "\n"
       "// implements Message ----------------------------------------------\n"
@@ -1387,17 +1382,15 @@
       options_.opensource_runtime ? "::PROTOBUF_NAMESPACE_ID::StringPiece"
                                   : "::StringPiece");
 
-  if (SupportsArenas(descriptor_)) {
-    format(
-        // TODO(gerbens) Make this private! Currently people are deriving from
-        // protos to give access to this constructor, breaking the invariants
-        // we rely on.
-        "protected:\n"
-        "explicit $classname$(::$proto_ns$::Arena* arena);\n"
-        "private:\n"
-        "static void ArenaDtor(void* object);\n"
-        "inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n");
-  }
+  format(
+      // TODO(gerbens) Make this private! Currently people are deriving from
+      // protos to give access to this constructor, breaking the invariants
+      // we rely on.
+      "protected:\n"
+      "explicit $classname$(::$proto_ns$::Arena* arena);\n"
+      "private:\n"
+      "static void ArenaDtor(void* object);\n"
+      "inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n");
 
   format(
       "public:\n"
@@ -1520,13 +1513,11 @@
         "\n");
   }
 
-  if (SupportsArenas(descriptor_)) {
-    format(
-        "template <typename T> friend class "
-        "::$proto_ns$::Arena::InternalHelper;\n"
-        "typedef void InternalArenaConstructable_;\n"
-        "typedef void DestructorSkippable_;\n");
-  }
+  format(
+      "template <typename T> friend class "
+      "::$proto_ns$::Arena::InternalHelper;\n"
+      "typedef void InternalArenaConstructable_;\n"
+      "typedef void DestructorSkippable_;\n");
 
   if (!has_bit_indices_.empty()) {
     // _has_bits_ is frequently accessed, so to reduce code size and improve
@@ -1558,14 +1549,14 @@
         camel_oneof_name);
     format.Indent();
     for (auto field : FieldRange(oneof)) {
-      if (IsFieldUsed(field, options_)) {
+      if (!IsFieldStripped(field, options_)) {
         field_generators_.get(field).GeneratePrivateMembers(printer);
       }
     }
     format.Outdent();
     format("} $1$_;\n", oneof->name());
     for (auto field : FieldRange(oneof)) {
-      if (IsFieldUsed(field, options_)) {
+      if (!IsFieldStripped(field, options_)) {
         field_generators_.get(field).GenerateStaticMembers(printer);
       }
     }
@@ -1623,30 +1614,6 @@
   }
 }
 
-void MessageGenerator::GenerateExtraDefaultFields(io::Printer* printer) {
-  // Generate oneof default instance and weak field instances for reflection
-  // usage.
-  Formatter format(printer, variables_);
-  for (auto oneof : OneOfRange(descriptor_)) {
-    for (auto field : FieldRange(oneof)) {
-      if (!IsFieldUsed(field, options_)) {
-        continue;
-      }
-      if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
-          (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
-           EffectiveStringCType(field, options_) != FieldOptions::STRING)) {
-        format("const ");
-      }
-      field_generators_.get(field).GeneratePrivateMembers(printer);
-    }
-  }
-  for (auto field : FieldRange(descriptor_)) {
-    if (field->options().weak() && IsFieldUsed(field, options_)) {
-      format("  const ::$proto_ns$::Message* $1$_;\n", FieldName(field));
-    }
-  }
-}
-
 bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset,
                                           size_t aux_offset) {
   Formatter format(printer, variables_);
@@ -1938,66 +1905,6 @@
   }
 }
 
-void MessageGenerator::GenerateDefaultInstanceInitializer(
-    io::Printer* printer) {
-  Formatter format(printer, variables_);
-
-  // The default instance needs all of its embedded message pointers
-  // cross-linked to other default instances.  We can't do this initialization
-  // in the constructor because some other default instances may not have been
-  // constructed yet at that time.
-  // TODO(kenton):  Maybe all message fields (even for non-default messages)
-  //   should be initialized to point at default instances rather than NULL?
-  for (auto field : FieldRange(descriptor_)) {
-    if (!IsFieldUsed(field, options_)) {
-      continue;
-    }
-    Formatter::SaveState saver(&format);
-
-    if (!field->is_repeated() && !IsLazy(field, options_) &&
-        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
-        (!field->real_containing_oneof() ||
-         HasDescriptorMethods(descriptor_->file(), options_))) {
-      std::string name;
-      if (field->real_containing_oneof() || field->options().weak()) {
-        name = "_" + classname_ + "_default_instance_.";
-      } else {
-        name =
-            "_" + classname_ + "_default_instance_._instance.get_mutable()->";
-      }
-      name += FieldName(field);
-      format.Set("name", name);
-      if (IsWeak(field, options_)) {
-        format(
-            "$package_ns$::$name$_ = reinterpret_cast<const "
-            "::$proto_ns$::Message*>(&$1$);\n"
-            "if ($package_ns$::$name$_ == nullptr) {\n"
-            "  $package_ns$::$name$_ = "
-            "::$proto_ns$::Empty::internal_default_instance();\n"
-            "}\n",
-            QualifiedDefaultInstanceName(field->message_type(),
-                                         options_));  // 1
-        continue;
-      }
-      if (IsImplicitWeakField(field, options_, scc_analyzer_)) {
-        format(
-            "$package_ns$::$name$_ = reinterpret_cast<$1$*>(\n"
-            "    $2$);\n",
-            FieldMessageTypeName(field, options_),
-            QualifiedDefaultInstancePtr(field->message_type(), options_));
-      } else {
-        format(
-            "$package_ns$::$name$_ = const_cast< $1$*>(\n"
-            "    $1$::internal_default_instance());\n",
-            FieldMessageTypeName(field, options_));
-      }
-    } else if (field->real_containing_oneof() &&
-               HasDescriptorMethods(descriptor_->file(), options_)) {
-      field_generators_.get(field).GenerateConstructorCode(printer);
-    }
-  }
-}
-
 void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
   Formatter format(printer, variables_);
   if (IsMapEntryMessage(descriptor_)) {
@@ -2023,14 +1930,6 @@
     return;
   }
 
-  // TODO(gerbens) Remove this function. With a little bit of cleanup and
-  // refactoring this is superfluous.
-  format("void $classname$::InitAsDefaultInstance() {\n");
-  format.Indent();
-  GenerateDefaultInstanceInitializer(printer);
-  format.Outdent();
-  format("}\n");
-
   if (IsAnyMessage(descriptor_, options_)) {
     if (HasDescriptorMethods(descriptor_->file(), options_)) {
       format(
@@ -2062,7 +1961,7 @@
   }
   for (auto field : FieldRange(descriptor_)) {
     field_generators_.get(field).GenerateInternalAccessorDeclarations(printer);
-    if (!IsFieldUsed(field, options_)) {
+    if (IsFieldStripped(field, options_)) {
       continue;
     }
     if (HasHasbit(field)) {
@@ -2088,14 +1987,14 @@
   format.Outdent();
   format("};\n\n");
   for (auto field : FieldRange(descriptor_)) {
-    if (IsFieldUsed(field, options_)) {
+    if (!IsFieldStripped(field, options_)) {
       field_generators_.get(field).GenerateInternalAccessorDefinitions(printer);
     }
   }
 
   // Generate non-inline field definitions.
   for (auto field : FieldRange(descriptor_)) {
-    if (!IsFieldUsed(field, options_)) {
+    if (IsFieldStripped(field, options_)) {
       continue;
     }
     field_generators_.get(field).GenerateNonInlineAccessorDefinitions(printer);
@@ -2400,13 +2299,16 @@
                          descriptor_->real_oneof_decl_count();
   size_t entries = offsets;
   for (auto field : FieldRange(descriptor_)) {
-    if (!IsFieldUsed(field, options_)) {
+    if (IsFieldStripped(field, options_)) {
       format("~0u,  // stripped\n");
       continue;
     }
-    if (field->real_containing_oneof() || field->options().weak()) {
-      format("offsetof($classtype$DefaultTypeInternal, $1$_)",
-             FieldName(field));
+    // TODO(sbenza): We should not have an entry in the offset table for fields
+    // that do not use them.
+    if (field->options().weak() || field->real_containing_oneof()) {
+      // Mark the field to prevent unintentional access through reflection.
+      // Don't use the top bit because that is for unused fields.
+      format("::$proto_ns$::internal::kInvalidFieldOffsetTag");
     } else {
       format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_)", FieldName(field));
     }
@@ -2416,7 +2318,11 @@
       format(" | $1$", tag);
     }
 
-    format(",\n");
+    if (!IsFieldUsed(field, options_)) {
+      format(" | 0x80000000u, // unused\n");
+    } else {
+      format(",\n");
+    }
   }
 
   int count = 0;
@@ -2470,9 +2376,7 @@
 
   format("void $classname$::SharedDtor() {\n");
   format.Indent();
-  if (SupportsArenas(descriptor_)) {
-    format("$DCHK$(GetArena() == nullptr);\n");
-  }
+  format("$DCHK$(GetArena() == nullptr);\n");
   // Write the destructors for each field except oneof members.
   // optimized_order_ does not contain oneof fields.
   for (auto field : optimized_order_) {
@@ -2528,7 +2432,7 @@
   // and returns false for oneof fields.
   for (auto oneof : OneOfRange(descriptor_)) {
     for (auto field : FieldRange(oneof)) {
-      if (IsFieldUsed(field, options_) &&
+      if (!IsFieldStripped(field, options_) &&
           field_generators_.get(field).GenerateArenaDestructorCode(printer)) {
         need_registration = true;
       }
@@ -2631,7 +2535,7 @@
 
   // Initialize member variables with arena constructor.
   for (auto field : optimized_order_) {
-    GOOGLE_DCHECK(IsFieldUsed(field, options_));
+    GOOGLE_DCHECK(!IsFieldStripped(field, options_));
     bool has_arena_constructor = field->is_repeated();
     if (!field->real_containing_oneof() &&
         (IsLazy(field, options_) || IsStringPiece(field, options_))) {
@@ -2658,24 +2562,14 @@
     initializer_null += ", _weak_field_map_(nullptr)";
   }
 
-  if (SupportsArenas(descriptor_)) {
-    format(
-        "$classname$::$classname$(::$proto_ns$::Arena* arena)\n"
-        "  : $1$ {\n"
-        "  SharedCtor();\n"
-        "  RegisterArenaDtor(arena);\n"
-        "  // @@protoc_insertion_point(arena_constructor:$full_name$)\n"
-        "}\n",
-        initializer_with_arena);
-  } else {
-    format(
-        "$classname$::$classname$()\n"
-        "  : $1$ {\n"
-        "  SharedCtor();\n"
-        "  // @@protoc_insertion_point(constructor:$full_name$)\n"
-        "}\n",
-        initializer_null);
-  }
+  format(
+      "$classname$::$classname$(::$proto_ns$::Arena* arena)\n"
+      "  : $1$ {\n"
+      "  SharedCtor();\n"
+      "  RegisterArenaDtor(arena);\n"
+      "  // @@protoc_insertion_point(arena_constructor:$full_name$)\n"
+      "}\n",
+      initializer_with_arena);
 
   std::map<std::string, std::string> vars;
   SetUnknkownFieldsVariable(descriptor_, options_, &vars);
@@ -2747,7 +2641,7 @@
       for (auto field : FieldRange(oneof)) {
         format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
         format.Indent();
-        if (IsFieldUsed(field, options_)) {
+        if (!IsFieldStripped(field, options_)) {
           field_generators_.get(field).GenerateMergingCode(printer);
         }
         format("break;\n");
@@ -2786,9 +2680,7 @@
   GenerateSharedDestructorCode(printer);
 
   // Generate the arena-specific destructor code.
-  if (SupportsArenas(descriptor_)) {
-    GenerateArenaDestructorCode(printer);
-  }
+  GenerateArenaDestructorCode(printer);
 
   // Generate SetCachedSize.
   format(
@@ -2811,9 +2703,8 @@
       "template<> "
       "PROTOBUF_NOINLINE "
       "$classtype$* Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n"
-      "  return Arena::$1$Internal< $classtype$ >(arena);\n"
-      "}\n",
-      MessageCreateFunction(descriptor_));
+      "  return Arena::CreateMessageInternal< $classtype$ >(arena);\n"
+      "}\n");
 }
 
 void MessageGenerator::GenerateClear(io::Printer* printer) {
@@ -3005,7 +2896,7 @@
       format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
       format.Indent();
       // We clear only allocated objects in oneofs
-      if (!IsStringOrMessage(field) || !IsFieldUsed(field, options_)) {
+      if (!IsStringOrMessage(field) || IsFieldStripped(field, options_)) {
         format("// No need to clear\n");
       } else {
         field_generators_.get(field).GenerateClearingCode(printer);
@@ -3294,7 +3185,7 @@
     for (auto field : FieldRange(oneof)) {
       format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
       format.Indent();
-      if (IsFieldUsed(field, options_)) {
+      if (!IsFieldStripped(field, options_)) {
         field_generators_.get(field).GenerateMergingCode(printer);
       }
       format("break;\n");
@@ -3514,8 +3405,26 @@
 
   format("// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n");
 
+  if (!ShouldSerializeInOrder(descriptor_, options_)) {
+    format.Outdent();
+    format("#ifdef NDEBUG\n");
+    format.Indent();
+  }
+
   GenerateSerializeWithCachedSizesBody(printer);
 
+  if (!ShouldSerializeInOrder(descriptor_, options_)) {
+    format.Outdent();
+    format("#else  // NDEBUG\n");
+    format.Indent();
+
+    GenerateSerializeWithCachedSizesBodyShuffled(printer);
+
+    format.Outdent();
+    format("#endif  // !NDEBUG\n");
+    format.Indent();
+  }
+
   format("// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n");
 
   format.Outdent();
@@ -3630,11 +3539,14 @@
           (i < descriptor_->field_count() &&
            ordered_fields[i]->number() < sorted_extensions[j]->start)) {
         const FieldDescriptor* field = ordered_fields[i++];
-        if (!IsFieldUsed(field, options_)) {
+        if (IsFieldStripped(field, options_)) {
           continue;
         }
         if (field->options().weak()) {
-          last_weak_field = field;
+          if (last_weak_field == nullptr ||
+              last_weak_field->number() < field->number()) {
+            last_weak_field = field;
+          }
           PrintFieldComment(format, field);
         } else {
           if (last_weak_field != nullptr) {
@@ -3677,6 +3589,115 @@
   format("}\n");
 }
 
+void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled(
+    io::Printer* printer) {
+  Formatter format(printer, variables_);
+
+  std::vector<const FieldDescriptor*> ordered_fields =
+      SortFieldsByNumber(descriptor_);
+  ordered_fields.erase(
+      std::remove_if(ordered_fields.begin(), ordered_fields.end(),
+                     [this](const FieldDescriptor* f) {
+                       return !IsFieldUsed(f, options_);
+                     }),
+      ordered_fields.end());
+
+  std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
+  sorted_extensions.reserve(descriptor_->extension_range_count());
+  for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
+    sorted_extensions.push_back(descriptor_->extension_range(i));
+  }
+  std::sort(sorted_extensions.begin(), sorted_extensions.end(),
+            ExtensionRangeSorter());
+
+  int num_fields = ordered_fields.size() + sorted_extensions.size();
+  constexpr int kLargePrime = 1000003;
+  GOOGLE_CHECK_LT(num_fields, kLargePrime)
+      << "Prime offset must be greater than the number of fields to ensure "
+         "those are coprime.";
+
+  if (num_weak_fields_) {
+    format(
+        "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer("
+        "_weak_field_map_);\n");
+  }
+
+  format(
+      "static const int kStart = GetInvariantPerBuild($1$UL) % $2$;\n"
+      "bool first_pass = true;\n"
+      "for (int i = kStart; i != kStart || first_pass; i = ((i + $3$) % $2$)) "
+      "{\n",
+      0,
+      num_fields, kLargePrime);
+
+  format.Indent();
+  format("switch(i) {\n");
+  format.Indent();
+
+  bool first_pass_set = false;
+  int index = 0;
+  for (const auto* f : ordered_fields) {
+    format("case $1$: {\n", index++);
+    format.Indent();
+
+    if (!first_pass_set) {
+      first_pass_set = true;
+      format("first_pass = false;\n");
+    }
+
+    GenerateSerializeOneField(printer, f, -1);
+
+    format("break;\n");
+    format.Outdent();
+    format("}\n");
+  }
+
+  for (const auto* r : sorted_extensions) {
+    format("case $1$: {\n", index++);
+    format.Indent();
+
+    if (!first_pass_set) {
+      first_pass_set = true;
+      format("first_pass = false;\n");
+    }
+
+    GenerateSerializeOneExtensionRange(printer, r);
+
+    format("break;\n");
+    format.Outdent();
+    format("}\n");
+  }
+
+  format(
+      "default: {\n"
+      "  $DCHK$(false) << \"Unexpected index: \" << i;\n"
+      "}\n");
+  format.Outdent();
+  format("}\n");
+
+  format.Outdent();
+  format("}\n");
+
+  std::map<std::string, std::string> vars;
+  SetUnknkownFieldsVariable(descriptor_, options_, &vars);
+  format.AddMap(vars);
+  format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n");
+  format.Indent();
+  if (UseUnknownFieldSet(descriptor_->file(), options_)) {
+    format(
+        "target = "
+        "::$proto_ns$::internal::WireFormat::"
+        "InternalSerializeUnknownFieldsToArray(\n"
+        "    $unknown_fields$, target, stream);\n");
+  } else {
+    format(
+        "target = stream->WriteRaw($unknown_fields$.data(),\n"
+        "    static_cast<int>($unknown_fields$.size()), target);\n");
+  }
+  format.Outdent();
+  format("}\n");
+}
+
 std::vector<uint32> MessageGenerator::RequiredFieldsBitMask() const {
   const int array_size = HasBitsSize();
   std::vector<uint32> masks(array_size, 0);
@@ -3898,7 +3919,7 @@
       PrintFieldComment(format, field);
       format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
       format.Indent();
-      if (IsFieldUsed(field, options_)) {
+      if (!IsFieldStripped(field, options_)) {
         field_generators_.get(field).GenerateByteSize(printer);
       }
       format("break;\n");
@@ -4026,7 +4047,7 @@
       format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
       format.Indent();
 
-      if (IsFieldUsed(field, options_) &&
+      if (!IsFieldStripped(field, options_) &&
           field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
           !ShouldIgnoreRequiredFieldCheck(field, options_) &&
           scc_analyzer_->HasRequiredFields(field->message_type())) {
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h
index a212ff4..8917d13 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message.h
@@ -82,17 +82,9 @@
 
   // Source file stuff.
 
-  // Generate extra fields
-  void GenerateExtraDefaultFields(io::Printer* printer);
-
   // Generates code that creates default instances for fields.
   void GenerateFieldDefaultInstances(io::Printer* printer);
 
-  // Generates code that initializes the message's default instance.  This
-  // is separate from allocating because all default instances must be
-  // allocated before any can be initialized.
-  void GenerateDefaultInstanceInitializer(io::Printer* printer);
-
   // Generate all non-inline methods for this class.
   void GenerateClassMethods(io::Printer* printer);
 
@@ -142,6 +134,7 @@
   void GenerateSerializeWithCachedSizes(io::Printer* printer);
   void GenerateSerializeWithCachedSizesToArray(io::Printer* printer);
   void GenerateSerializeWithCachedSizesBody(io::Printer* printer);
+  void GenerateSerializeWithCachedSizesBodyShuffled(io::Printer* printer);
   void GenerateByteSize(io::Printer* printer);
   void GenerateMergeFrom(io::Printer* printer);
   void GenerateClassSpecificMergeFrom(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
index 38fcb52..f1a5cef 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -67,8 +67,9 @@
       QualifiedDefaultInstancePtr(descriptor->message_type(), options);
   (*variables)["type_reference_function"] =
       implicit_weak ? ("  ::" + (*variables)["proto_ns"] +
-                       "::internal::StrongReference(" +
-                       (*variables)["type_default_instance"] + ");\n")
+                       "::internal::StrongReference(reinterpret_cast<const " +
+                       (*variables)["type"] + "&>(\n" +
+                       (*variables)["type_default_instance"] + "));\n")
                     : "";
   // NOTE: Escaped here to unblock proto1->proto2 migration.
   // TODO(liujisi): Extend this to apply for other conflicting methods.
@@ -104,7 +105,7 @@
 void MessageFieldGenerator::GenerateAccessorDeclarations(
     io::Printer* printer) const {
   Formatter format(printer, variables_);
-  if (!IsFieldUsed(descriptor_, options_)) {
+  if (IsFieldStripped(descriptor_, options_)) {
     format(
         "$deprecated_attr$const $type$& ${1$$name$$}$() const { "
         "__builtin_trap(); }\n"
@@ -113,17 +114,13 @@
         "$deprecated_attr$$type$* ${1$mutable_$name$$}$() { "
         "__builtin_trap(); }\n"
         "$deprecated_attr$void ${1$set_allocated_$name$$}$"
-        "($type$* $name$) { __builtin_trap(); }\n",
+        "($type$* $name$) { __builtin_trap(); }\n"
+        "$deprecated_attr$void "
+        "${1$unsafe_arena_set_allocated_$name$$}$(\n"
+        "    $type$* $name$) { __builtin_trap(); }\n"
+        "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$() { "
+        "__builtin_trap(); }\n",
         descriptor_);
-    if (SupportsArenas(descriptor_)) {
-      format(
-          "$deprecated_attr$void "
-          "${1$unsafe_arena_set_allocated_$name$$}$(\n"
-          "    $type$* $name$) { __builtin_trap(); }\n"
-          "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$() { "
-          "__builtin_trap(); }\n",
-          descriptor_);
-    }
     return;
   }
   format(
@@ -133,7 +130,7 @@
       "$deprecated_attr$void ${1$set_allocated_$name$$}$"
       "($type$* $name$);\n",
       descriptor_);
-  if (IsFieldUsed(descriptor_, options_)) {
+  if (!IsFieldStripped(descriptor_, options_)) {
     format(
         "private:\n"
         "const $type$& ${1$_internal_$name$$}$() const;\n"
@@ -141,14 +138,12 @@
         "public:\n",
         descriptor_);
   }
-  if (SupportsArenas(descriptor_)) {
-    format(
-        "$deprecated_attr$void "
-        "${1$unsafe_arena_set_allocated_$name$$}$(\n"
-        "    $type$* $name$);\n"
-        "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$();\n",
-        descriptor_);
-  }
+  format(
+      "$deprecated_attr$void "
+      "${1$unsafe_arena_set_allocated_$name$$}$(\n"
+      "    $type$* $name$);\n"
+      "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$();\n",
+      descriptor_);
 }
 
 void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
@@ -162,8 +157,8 @@
       "inline const $type$& $classname$::_internal_$name$() const {\n"
       "$type_reference_function$"
       "  const $type$* p = $casted_member$;\n"
-      "  return p != nullptr ? *p : *reinterpret_cast<const $type$*>(\n"
-      "      &$type_default_instance$);\n"
+      "  return p != nullptr ? *p : reinterpret_cast<const $type$&>(\n"
+      "      $type_default_instance$);\n"
       "}\n"
       "inline const $type$& $classname$::$name$() const {\n"
       "$annotate_accessor$"
@@ -171,48 +166,43 @@
       "  return _internal_$name$();\n"
       "}\n");
 
-  if (SupportsArenas(descriptor_)) {
+  format(
+      "inline void $classname$::unsafe_arena_set_allocated_$name$(\n"
+      "    $type$* $name$) {\n"
+      "$annotate_accessor$"
+      // If we're not on an arena, free whatever we were holding before.
+      // (If we are on arena, we can just forget the earlier pointer.)
+      "  if (GetArena() == nullptr) {\n"
+      "    delete reinterpret_cast<::$proto_ns$::MessageLite*>($name$_);\n"
+      "  }\n");
+  if (implicit_weak_field_) {
     format(
-        "inline void $classname$::unsafe_arena_set_allocated_$name$(\n"
-        "    $type$* $name$) {\n"
-        "$annotate_accessor$"
-        // If we're not on an arena, free whatever we were holding before.
-        // (If we are on arena, we can just forget the earlier pointer.)
-        "  if (GetArena() == nullptr) {\n"
-        "    delete reinterpret_cast<::$proto_ns$::MessageLite*>($name$_);\n"
-        "  }\n");
-    if (implicit_weak_field_) {
-      format(
-          "  $name$_ = "
-          "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n");
-    } else {
-      format("  $name$_ = $name$;\n");
-    }
-    format(
-        "  if ($name$) {\n"
-        "    $set_hasbit$\n"
-        "  } else {\n"
-        "    $clear_hasbit$\n"
-        "  }\n"
-        "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated"
-        ":$full_name$)\n"
-        "}\n");
-    format(
-        "inline $type$* $classname$::$release_name$() {\n"
-        "$type_reference_function$"
-        "  $clear_hasbit$\n"
-        "  $type$* temp = $casted_member$;\n"
-        "  $name$_ = nullptr;\n"
-        "  if (GetArena() != nullptr) {\n"
-        "    temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
-        "  }\n"
-        "  return temp;\n"
-        "}\n"
-        "inline $type$* $classname$::unsafe_arena_release_$name$() {\n");
+        "  $name$_ = "
+        "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n");
   } else {
-    format("inline $type$* $classname$::$release_name$() {\n");
+    format("  $name$_ = $name$;\n");
   }
   format(
+      "  if ($name$) {\n"
+      "    $set_hasbit$\n"
+      "  } else {\n"
+      "    $clear_hasbit$\n"
+      "  }\n"
+      "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated"
+      ":$full_name$)\n"
+      "}\n");
+  format(
+      "inline $type$* $classname$::$release_name$() {\n"
+      "$type_reference_function$"
+      "  $clear_hasbit$\n"
+      "  $type$* temp = $casted_member$;\n"
+      "  $name$_ = nullptr;\n"
+      "  if (GetArena() != nullptr) {\n"
+      "    temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
+      "  }\n"
+      "  return temp;\n"
+      "}\n"
+      "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
       "$annotate_accessor$"
       "  // @@protoc_insertion_point(field_release:$full_name$)\n"
       "$type_reference_function$"
@@ -259,16 +249,13 @@
   format(
       "  }\n"
       "  if ($name$) {\n");
-  if (SupportsArenas(descriptor_->message_type()) &&
-      IsCrossFileMessage(descriptor_)) {
+  if (IsCrossFileMessage(descriptor_)) {
     // We have to read the arena through the virtual method, because the type
     // isn't defined in this file.
     format(
         "    ::$proto_ns$::Arena* submessage_arena =\n"
         "      "
         "reinterpret_cast<::$proto_ns$::MessageLite*>($name$)->GetArena();\n");
-  } else if (!SupportsArenas(descriptor_->message_type())) {
-    format("    ::$proto_ns$::Arena* submessage_arena = nullptr;\n");
   } else {
     format(
         "    ::$proto_ns$::Arena* submessage_arena =\n"
@@ -330,48 +317,26 @@
         "*::$proto_ns$::internal::ImplicitWeakMessage::default_instance();\n"
         "  }\n"
         "}\n");
-    if (SupportsArenas(descriptor_)) {
-      format(
-          "::$proto_ns$::MessageLite*\n"
-          "$classname$::_Internal::mutable_$name$($classname$* msg) {\n");
-      if (HasFieldPresence(descriptor_->file())) {
-        format("  msg->$set_hasbit$\n");
-      }
-      format(
-          "  if (msg->$name$_ == nullptr) {\n"
-          "    if ($type_default_instance_ptr$ == nullptr) {\n"
-          "      msg->$name$_ = ::$proto_ns$::Arena::CreateMessage<\n"
-          "          ::$proto_ns$::internal::ImplicitWeakMessage>(\n"
-          "              msg->GetArena());\n"
-          "    } else {\n"
-          "      msg->$name$_ = reinterpret_cast<const "
-          "::$proto_ns$::MessageLite*>(\n"
-          "          $type_default_instance_ptr$)->New(msg->GetArena());\n"
-          "    }\n"
-          "  }\n"
-          "  return msg->$name$_;\n"
-          "}\n");
-    } else {
-      format(
-          "::$proto_ns$::MessageLite*\n"
-          "$classname$::_Internal::mutable_$name$($classname$* msg) {\n");
-      if (HasFieldPresence(descriptor_->file())) {
-        format("  msg->$set_hasbit$\n");
-      }
-      format(
-          "  if (msg->$name$_ == nullptr) {\n"
-          "    if ($type_default_instance_ptr$ == nullptr) {\n"
-          "      msg->$name$_ = "
-          "new ::$proto_ns$::internal::ImplicitWeakMessage;\n"
-          "    } else {\n"
-          "      msg->$name$_ = "
-          "reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
-          "          $type_default_instance_ptr$)->New();\n"
-          "    }\n"
-          "  }\n"
-          "  return msg->$name$_;\n"
-          "}\n");
+    format(
+        "::$proto_ns$::MessageLite*\n"
+        "$classname$::_Internal::mutable_$name$($classname$* msg) {\n");
+    if (HasFieldPresence(descriptor_->file())) {
+      format("  msg->$set_hasbit$\n");
     }
+    format(
+        "  if (msg->$name$_ == nullptr) {\n"
+        "    if ($type_default_instance_ptr$ == nullptr) {\n"
+        "      msg->$name$_ = ::$proto_ns$::Arena::CreateMessage<\n"
+        "          ::$proto_ns$::internal::ImplicitWeakMessage>(\n"
+        "              msg->GetArena());\n"
+        "    } else {\n"
+        "      msg->$name$_ = reinterpret_cast<const "
+        "::$proto_ns$::MessageLite*>(\n"
+        "          $type_default_instance_ptr$)->New(msg->GetArena());\n"
+        "    }\n"
+        "  }\n"
+        "  return msg->$name$_;\n"
+        "}\n");
   } else {
     // This inline accessor directly returns member field and is used in
     // Serialize such that AFDO profile correctly captures access information to
@@ -385,7 +350,7 @@
 }
 
 void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
-  GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
+  GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
 
   Formatter format(printer, variables_);
   if (!HasFieldPresence(descriptor_->file())) {
@@ -403,7 +368,7 @@
 
 void MessageFieldGenerator::GenerateMessageClearingCode(
     io::Printer* printer) const {
-  GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
+  GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
 
   Formatter format(printer, variables_);
   if (!HasFieldPresence(descriptor_->file())) {
@@ -422,7 +387,7 @@
 }
 
 void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
-  GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
+  GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
 
   Formatter format(printer, variables_);
   if (implicit_weak_field_) {
@@ -437,14 +402,14 @@
 }
 
 void MessageFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
-  GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
+  GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
 
   Formatter format(printer, variables_);
   format("swap($name$_, other->$name$_);\n");
 }
 
 void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
-  GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
+  GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
 
   Formatter format(printer, variables_);
   if (options_.opensource_runtime) {
@@ -460,7 +425,7 @@
 
 void MessageFieldGenerator::GenerateConstructorCode(
     io::Printer* printer) const {
-  GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
+  GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
 
   Formatter format(printer, variables_);
   format("$name$_ = nullptr;\n");
@@ -468,7 +433,7 @@
 
 void MessageFieldGenerator::GenerateCopyConstructorCode(
     io::Printer* printer) const {
-  GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
+  GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
 
   Formatter format(printer, variables_);
   format(
@@ -481,7 +446,7 @@
 
 void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
     io::Printer* printer) const {
-  GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
+  GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
 
   Formatter format(printer, variables_);
   format(
@@ -492,7 +457,7 @@
 }
 
 void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const {
-  GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
+  GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
 
   Formatter format(printer, variables_);
   format(
@@ -521,16 +486,13 @@
       "  ::$proto_ns$::Arena* message_arena = GetArena();\n"
       "  clear_$oneof_name$();\n"
       "  if ($name$) {\n");
-  if (SupportsArenas(descriptor_->message_type()) &&
-      descriptor_->file() != descriptor_->message_type()->file()) {
+  if (descriptor_->file() != descriptor_->message_type()->file()) {
     // We have to read the arena through the virtual method, because the type
     // isn't defined in this file.
     format(
         "    ::$proto_ns$::Arena* submessage_arena =\n"
         "      "
         "reinterpret_cast<::$proto_ns$::MessageLite*>($name$)->GetArena();\n");
-  } else if (!SupportsArenas(descriptor_->message_type())) {
-    format("    ::$proto_ns$::Arena* submessage_arena = nullptr;\n");
   } else {
     format(
         "    ::$proto_ns$::Arena* submessage_arena =\n"
@@ -557,14 +519,10 @@
       "  // @@protoc_insertion_point(field_release:$full_name$)\n"
       "  if (_internal_has_$name$()) {\n"
       "    clear_has_$oneof_name$();\n"
-      "      $type$* temp = $field_member$;\n");
-  if (SupportsArenas(descriptor_)) {
-    format(
-        "    if (GetArena() != nullptr) {\n"
-        "      temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
-        "    }\n");
-  }
-  format(
+      "      $type$* temp = $field_member$;\n"
+      "    if (GetArena() != nullptr) {\n"
+      "      temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
+      "    }\n"
       "    $field_member$ = nullptr;\n"
       "    return temp;\n"
       "  } else {\n"
@@ -576,46 +534,40 @@
       "inline const $type$& $classname$::_internal_$name$() const {\n"
       "  return _internal_has_$name$()\n"
       "      ? *$field_member$\n"
-      "      : *reinterpret_cast< $type$*>(&$type_default_instance$);\n"
+      "      : reinterpret_cast< $type$&>($type_default_instance$);\n"
       "}\n"
       "inline const $type$& $classname$::$name$() const {\n"
       "$annotate_accessor$"
       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
       "  return _internal_$name$();\n"
-      "}\n");
-
-  if (SupportsArenas(descriptor_)) {
-    format(
-        "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
-        "$annotate_accessor$"
-        "  // @@protoc_insertion_point(field_unsafe_arena_release"
-        ":$full_name$)\n"
-        "  if (_internal_has_$name$()) {\n"
-        "    clear_has_$oneof_name$();\n"
-        "    $type$* temp = $field_member$;\n"
-        "    $field_member$ = nullptr;\n"
-        "    return temp;\n"
-        "  } else {\n"
-        "    return nullptr;\n"
-        "  }\n"
-        "}\n"
-        "inline void $classname$::unsafe_arena_set_allocated_$name$"
-        "($type$* $name$) {\n"
-        "$annotate_accessor$"
-        // We rely on the oneof clear method to free the earlier contents of
-        // this oneof. We can directly use the pointer we're given to set the
-        // new value.
-        "  clear_$oneof_name$();\n"
-        "  if ($name$) {\n"
-        "    set_has_$name$();\n"
-        "    $field_member$ = $name$;\n"
-        "  }\n"
-        "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
-        "$full_name$)\n"
-        "}\n");
-  }
-
-  format(
+      "}\n"
+      "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
+      "$annotate_accessor$"
+      "  // @@protoc_insertion_point(field_unsafe_arena_release"
+      ":$full_name$)\n"
+      "  if (_internal_has_$name$()) {\n"
+      "    clear_has_$oneof_name$();\n"
+      "    $type$* temp = $field_member$;\n"
+      "    $field_member$ = nullptr;\n"
+      "    return temp;\n"
+      "  } else {\n"
+      "    return nullptr;\n"
+      "  }\n"
+      "}\n"
+      "inline void $classname$::unsafe_arena_set_allocated_$name$"
+      "($type$* $name$) {\n"
+      "$annotate_accessor$"
+      // We rely on the oneof clear method to free the earlier contents of
+      // this oneof. We can directly use the pointer we're given to set the
+      // new value.
+      "  clear_$oneof_name$();\n"
+      "  if ($name$) {\n"
+      "    set_has_$name$();\n"
+      "    $field_member$ = $name$;\n"
+      "  }\n"
+      "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
+      "$full_name$)\n"
+      "}\n"
       "inline $type$* $classname$::_internal_mutable_$name$() {\n"
       "  if (!_internal_has_$name$()) {\n"
       "    clear_$oneof_name$();\n"
@@ -633,17 +585,13 @@
 
 void MessageOneofFieldGenerator::GenerateClearingCode(
     io::Printer* printer) const {
-  GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
+  GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
 
   Formatter format(printer, variables_);
-  if (SupportsArenas(descriptor_)) {
-    format(
-        "if (GetArena() == nullptr) {\n"
-        "  delete $field_member$;\n"
-        "}\n");
-  } else {
-    format("delete $field_member$;\n");
-  }
+  format(
+      "if (GetArena() == nullptr) {\n"
+      "  delete $field_member$;\n"
+      "}\n");
 }
 
 void MessageOneofFieldGenerator::GenerateMessageClearingCode(
@@ -694,7 +642,7 @@
 void RepeatedMessageFieldGenerator::GenerateAccessorDeclarations(
     io::Printer* printer) const {
   Formatter format(printer, variables_);
-  if (!IsFieldUsed(descriptor_, options_)) {
+  if (IsFieldStripped(descriptor_, options_)) {
     format(
         "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index) { "
         "__builtin_trap(); }\n"
@@ -714,7 +662,7 @@
       "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n"
       "    ${1$mutable_$name$$}$();\n",
       descriptor_);
-  if (IsFieldUsed(descriptor_, options_)) {
+  if (!IsFieldStripped(descriptor_, options_)) {
     format(
         "private:\n"
         "const $type$& ${1$_internal_$name$$}$(int index) const;\n"
@@ -756,7 +704,7 @@
         "inline const $type$& $classname$::_internal_$name$(int index) const "
         "{\n"
         "  return $name$_$weak$.InternalCheckedGet(index,\n"
-        "      *reinterpret_cast<const $type$*>(&$type_default_instance$));\n"
+        "      reinterpret_cast<const $type$&>($type_default_instance$));\n"
         "}\n");
   } else {
     format(
@@ -794,7 +742,7 @@
 
 void RepeatedMessageFieldGenerator::GenerateClearingCode(
     io::Printer* printer) const {
-  GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
+  GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
 
   Formatter format(printer, variables_);
   format("$name$_.Clear();\n");
@@ -802,7 +750,7 @@
 
 void RepeatedMessageFieldGenerator::GenerateMergingCode(
     io::Printer* printer) const {
-  GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
+  GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
 
   Formatter format(printer, variables_);
   format("$name$_.MergeFrom(from.$name$_);\n");
@@ -810,7 +758,7 @@
 
 void RepeatedMessageFieldGenerator::GenerateSwappingCode(
     io::Printer* printer) const {
-  GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
+  GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
 
   Formatter format(printer, variables_);
   format("$name$_.InternalSwap(&other->$name$_);\n");
@@ -823,7 +771,7 @@
 
 void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
     io::Printer* printer) const {
-  GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
+  GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
 
   Formatter format(printer, variables_);
   if (implicit_weak_field_) {
@@ -850,7 +798,7 @@
 
 void RepeatedMessageFieldGenerator::GenerateByteSize(
     io::Printer* printer) const {
-  GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
+  GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
 
   Formatter format(printer, variables_);
   format(
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index 5cf82f6..9acc447 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -99,18 +99,6 @@
   if (inlined_) {
     format("::$proto_ns$::internal::InlinedStringField $name$_;\n");
   } else {
-    // N.B. that we continue to use |ArenaStringPtr| instead of |string*| for
-    // string fields, even when SupportArenas(descriptor_) == false. Why?  The
-    // simple answer is to avoid unmaintainable complexity. The reflection code
-    // assumes ArenaStringPtrs. These are *almost* in-memory-compatible with
-    // string*, except for the pointer tags and related ownership semantics. We
-    // could modify the runtime code to use string* for the
-    // not-supporting-arenas case, but this would require a way to detect which
-    // type of class was generated (adding overhead and complexity to
-    // GeneratedMessageReflection) and littering the runtime code paths with
-    // conditionals. It's simpler to stick with this but use lightweight
-    // accessors that assume arena == NULL.  There should be very little
-    // overhead anyway because it's just a tagged pointer in-memory.
     format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n");
   }
 }
@@ -211,163 +199,82 @@
       "$annotate_accessor$"
       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
       "  return _internal_mutable_$name$();\n"
+      "}\n"
+      "inline const std::string& $classname$::_internal_$name$() const {\n"
+      "  return $name$_.Get();\n"
+      "}\n"
+      "inline void $classname$::_internal_set_$name$(const std::string& "
+      "value) {\n"
+      "  $set_hasbit$\n"
+      "  $name$_.Set$lite$($default_variable$, value, GetArena());\n"
+      "}\n"
+      "inline void $classname$::set_$name$(std::string&& value) {\n"
+      "$annotate_accessor$"
+      "  $set_hasbit$\n"
+      "  $name$_.Set$lite$(\n"
+      "    $default_variable$, ::std::move(value), GetArena());\n"
+      "  // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
+      "}\n"
+      "inline void $classname$::set_$name$(const char* value) {\n"
+      "$annotate_accessor$"
+      "  $null_check$"
+      "  $set_hasbit$\n"
+      "  $name$_.Set$lite$($default_variable$, $string_piece$(value),\n"
+      "              GetArena());\n"
+      "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
       "}\n");
-  if (SupportsArenas(descriptor_)) {
+  if (!options_.opensource_runtime) {
     format(
-        "inline const std::string& $classname$::_internal_$name$() const {\n"
-        "  return $name$_.Get();\n"
-        "}\n"
-        "inline void $classname$::_internal_set_$name$(const std::string& "
-        "value) {\n"
-        "  $set_hasbit$\n"
-        "  $name$_.Set$lite$($default_variable$, value, GetArena());\n"
-        "}\n"
-        "inline void $classname$::set_$name$(std::string&& value) {\n"
+        "inline void $classname$::set_$name$(::StringPiece value) {\n"
         "$annotate_accessor$"
         "  $set_hasbit$\n"
-        "  $name$_.Set$lite$(\n"
-        "    $default_variable$, ::std::move(value), GetArena());\n"
-        "  // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
-        "}\n"
-        "inline void $classname$::set_$name$(const char* value) {\n"
-        "$annotate_accessor$"
-        "  $null_check$"
-        "  $set_hasbit$\n"
-        "  $name$_.Set$lite$($default_variable$, $string_piece$(value),\n"
-        "              GetArena());\n"
-        "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
-        "}\n");
-    if (!options_.opensource_runtime) {
-      format(
-          "inline void $classname$::set_$name$(::StringPiece value) {\n"
-          "$annotate_accessor$"
-          "  $set_hasbit$\n"
-          "  $name$_.Set$lite$($default_variable$, value,GetArena());\n"
-          "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
-          "}\n");
-    }
-    format(
-        "inline "
-        "void $classname$::set_$name$(const $pointer_type$* value,\n"
-        "    size_t size) {\n"
-        "$annotate_accessor$"
-        "  $set_hasbit$\n"
-        "  $name$_.Set$lite$($default_variable$, $string_piece$(\n"
-        "      reinterpret_cast<const char*>(value), size), GetArena());\n"
-        "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
-        "}\n"
-        "inline std::string* $classname$::_internal_mutable_$name$() {\n"
-        "  $set_hasbit$\n"
-        "  return $name$_.Mutable($default_variable$, GetArena());\n"
-        "}\n"
-        "inline std::string* $classname$::$release_name$() {\n"
-        "$annotate_accessor$"
-        "  // @@protoc_insertion_point(field_release:$full_name$)\n");
-
-    if (HasHasbit(descriptor_)) {
-      format(
-          "  if (!_internal_has_$name$()) {\n"
-          "    return nullptr;\n"
-          "  }\n"
-          "  $clear_hasbit$\n"
-          "  return $name$_.ReleaseNonDefault("
-          "$default_variable$, GetArena());\n");
-    } else {
-      format(
-          "  return $name$_.Release($default_variable$, GetArena());\n");
-    }
-
-    format(
-        "}\n"
-        "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
-        "$annotate_accessor$"
-        "  if ($name$ != nullptr) {\n"
-        "    $set_hasbit$\n"
-        "  } else {\n"
-        "    $clear_hasbit$\n"
-        "  }\n"
-        "  $name$_.SetAllocated($default_variable$, $name$,\n"
-        "      GetArena());\n"
-        "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
-        "}\n");
-  } else {
-    // No-arena case.
-    format(
-        "inline const std::string& $classname$::_internal_$name$() const {\n"
-        "  return $name$_.GetNoArena();\n"
-        "}\n"
-        "inline void $classname$::_internal_set_$name$(const std::string& "
-        "value) {\n"
-        "  $set_hasbit$\n"
-        "  $name$_.SetNoArena($default_variable$, value);\n"
-        "}\n"
-        "inline void $classname$::set_$name$(std::string&& value) {\n"
-        "$annotate_accessor$"
-        "  $set_hasbit$\n"
-        "  $name$_.SetNoArena(\n"
-        "    $default_variable$, ::std::move(value));\n"
-        "  // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
-        "}\n"
-        "inline void $classname$::set_$name$(const char* value) {\n"
-        "$annotate_accessor$"
-        "  $null_check$"
-        "  $set_hasbit$\n"
-        "  $name$_.SetNoArena($default_variable$, $string_piece$(value));\n"
-        "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
-        "}\n");
-    if (!options_.opensource_runtime) {
-      format(
-          "inline void $classname$::set_$name$(::StringPiece value) {\n"
-          "$annotate_accessor$"
-          "  $set_hasbit$\n"
-          "  $name$_.SetNoArena($default_variable$, value);\n"
-          "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
-          "}\n");
-    }
-    format(
-        "inline "
-        "void $classname$::set_$name$(const $pointer_type$* value, "
-        "size_t size) {\n"
-        "$annotate_accessor$"
-        "  $set_hasbit$\n"
-        "  $name$_.SetNoArena($default_variable$,\n"
-        "      $string_piece$(reinterpret_cast<const char*>(value), size));\n"
-        "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
-        "}\n"
-        "inline std::string* $classname$::_internal_mutable_$name$() {\n"
-        "  $set_hasbit$\n"
-        "  return $name$_.MutableNoArena($default_variable$);\n"
-        "}\n"
-        "inline std::string* $classname$::$release_name$() {\n"
-        "$annotate_accessor$"
-        "  // @@protoc_insertion_point(field_release:$full_name$)\n");
-
-    if (HasHasbit(descriptor_)) {
-      format(
-          "  if (!_internal_has_$name$()) {\n"
-          "    return nullptr;\n"
-          "  }\n"
-          "  $clear_hasbit$\n"
-          "  return $name$_.ReleaseNonDefaultNoArena($default_variable$);\n");
-    } else {
-      format(
-          "  $clear_hasbit$\n"
-          "  return $name$_.ReleaseNoArena($default_variable$);\n");
-    }
-
-    format(
-        "}\n"
-        "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
-        "$annotate_accessor$"
-        "  if ($name$ != nullptr) {\n"
-        "    $set_hasbit$\n"
-        "  } else {\n"
-        "    $clear_hasbit$\n"
-        "  }\n"
-        "  $name$_.SetAllocatedNoArena($default_variable$, $name$);\n"
-        "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+        "  $name$_.Set$lite$($default_variable$, value,GetArena());\n"
+        "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
         "}\n");
   }
+  format(
+      "inline "
+      "void $classname$::set_$name$(const $pointer_type$* value,\n"
+      "    size_t size) {\n"
+      "$annotate_accessor$"
+      "  $set_hasbit$\n"
+      "  $name$_.Set$lite$($default_variable$, $string_piece$(\n"
+      "      reinterpret_cast<const char*>(value), size), GetArena());\n"
+      "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
+      "}\n"
+      "inline std::string* $classname$::_internal_mutable_$name$() {\n"
+      "  $set_hasbit$\n"
+      "  return $name$_.Mutable($default_variable$, GetArena());\n"
+      "}\n"
+      "inline std::string* $classname$::$release_name$() {\n"
+      "$annotate_accessor$"
+      "  // @@protoc_insertion_point(field_release:$full_name$)\n");
+
+  if (HasHasbit(descriptor_)) {
+    format(
+        "  if (!_internal_has_$name$()) {\n"
+        "    return nullptr;\n"
+        "  }\n"
+        "  $clear_hasbit$\n"
+        "  return $name$_.ReleaseNonDefault("
+        "$default_variable$, GetArena());\n");
+  } else {
+    format("  return $name$_.Release($default_variable$, GetArena());\n");
+  }
+
+  format(
+      "}\n"
+      "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
+      "$annotate_accessor$"
+      "  if ($name$ != nullptr) {\n"
+      "    $set_hasbit$\n"
+      "  } else {\n"
+      "    $clear_hasbit$\n"
+      "  }\n"
+      "  $name$_.SetAllocated($default_variable$, $name$,\n"
+      "      GetArena());\n"
+      "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+      "}\n");
 }
 
 void StringFieldGenerator::GenerateNonInlineAccessorDefinitions(
@@ -387,18 +294,10 @@
   // value is the empty string or not. Complexity here ensures the minimal
   // number of branches / amount of extraneous code at runtime (given that the
   // below methods are inlined one-liners)!
-  if (SupportsArenas(descriptor_)) {
-    if (descriptor_->default_value_string().empty()) {
-      format("$name$_.ClearToEmpty($default_variable$, GetArena());\n");
-    } else {
-      format("$name$_.ClearToDefault($default_variable$, GetArena());\n");
-    }
+  if (descriptor_->default_value_string().empty()) {
+    format("$name$_.ClearToEmpty($default_variable$, GetArena());\n");
   } else {
-    if (descriptor_->default_value_string().empty()) {
-      format("$name$_.ClearToEmptyNoArena($default_variable$);\n");
-    } else {
-      format("$name$_.ClearToDefaultNoArena($default_variable$);\n");
-    }
+    format("$name$_.ClearToDefault($default_variable$, GetArena());\n");
   }
 }
 
@@ -427,45 +326,23 @@
     format("$DCHK$(!$name$_.IsDefault($default_variable$));\n");
   }
 
-  if (SupportsArenas(descriptor_)) {
-    if (descriptor_->default_value_string().empty()) {
-      if (must_be_present) {
-        format("$name$_.ClearNonDefaultToEmpty();\n");
-      } else {
-        format("$name$_.ClearToEmpty($default_variable$, GetArena());\n");
-      }
+  if (descriptor_->default_value_string().empty()) {
+    if (must_be_present) {
+      format("$name$_.ClearNonDefaultToEmpty();\n");
     } else {
-      // Clear to a non-empty default is more involved, as we try to use the
-      // Arena if one is present and may need to reallocate the string.
-      format("$name$_.ClearToDefault($default_variable$, GetArena());\n");
-    }
-  } else if (must_be_present) {
-    // When Arenas are disabled and field presence has been checked, we can
-    // safely treat the ArenaStringPtr as a string*.
-    if (descriptor_->default_value_string().empty()) {
-      format("$name$_.ClearNonDefaultToEmptyNoArena();\n");
-    } else {
-      format("$name$_.UnsafeMutablePointer()->assign(*$default_variable$);\n");
+      format("$name$_.ClearToEmpty($default_variable$, GetArena());\n");
     }
   } else {
-    if (descriptor_->default_value_string().empty()) {
-      format("$name$_.ClearToEmptyNoArena($default_variable$);\n");
-    } else {
-      format("$name$_.ClearToDefaultNoArena($default_variable$);\n");
-    }
+    // Clear to a non-empty default is more involved, as we try to use the
+    // Arena if one is present and may need to reallocate the string.
+    format("$name$_.ClearToDefault($default_variable$, GetArena());\n");
   }
 }
 
 void StringFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
   Formatter format(printer, variables_);
-  if (SupportsArenas(descriptor_) || descriptor_->real_containing_oneof()) {
-    // TODO(gpike): improve this
-    format("_internal_set_$name$(from._internal_$name$());\n");
-  } else {
-    format(
-        "$set_hasbit$\n"
-        "$name$_.AssignWithDefault($default_variable$, from.$name$_);\n");
-  }
+  // TODO(gpike): improve this
+  format("_internal_set_$name$(from._internal_$name$());\n");
 }
 
 void StringFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
@@ -502,14 +379,10 @@
 
   format.Indent();
 
-  if (SupportsArenas(descriptor_) || descriptor_->real_containing_oneof()) {
-    // TODO(gpike): improve this
-    format(
-        "$name$_.Set$lite$($default_variable$, from._internal_$name$(),\n"
-        "  GetArena());\n");
-  } else {
-    format("$name$_.AssignWithDefault($default_variable$, from.$name$_);\n");
-  }
+  // TODO(gpike): improve this
+  format(
+      "$name$_.Set$lite$($default_variable$, from._internal_$name$(),\n"
+      "  GetArena());\n");
 
   format.Outdent();
   format("}\n");
@@ -613,219 +486,115 @@
       "$annotate_accessor$"
       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
       "  return _internal_mutable_$name$();\n"
+      "}\n"
+      "inline const std::string& $classname$::_internal_$name$() const {\n"
+      "  if (_internal_has_$name$()) {\n"
+      "    return $field_member$.Get();\n"
+      "  }\n"
+      "  return *$default_variable$;\n"
+      "}\n"
+      "inline void $classname$::_internal_set_$name$(const std::string& "
+      "value) {\n"
+      "  if (!_internal_has_$name$()) {\n"
+      "    clear_$oneof_name$();\n"
+      "    set_has_$name$();\n"
+      "    $field_member$.UnsafeSetDefault($default_variable$);\n"
+      "  }\n"
+      "  $field_member$.Set$lite$($default_variable$, value, GetArena());\n"
+      "}\n"
+      "inline void $classname$::set_$name$(std::string&& value) {\n"
+      "$annotate_accessor$"
+      "  // @@protoc_insertion_point(field_set:$full_name$)\n"
+      "  if (!_internal_has_$name$()) {\n"
+      "    clear_$oneof_name$();\n"
+      "    set_has_$name$();\n"
+      "    $field_member$.UnsafeSetDefault($default_variable$);\n"
+      "  }\n"
+      "  $field_member$.Set$lite$(\n"
+      "    $default_variable$, ::std::move(value), GetArena());\n"
+      "  // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
+      "}\n"
+      "inline void $classname$::set_$name$(const char* value) {\n"
+      "$annotate_accessor$"
+      "  $null_check$"
+      "  if (!_internal_has_$name$()) {\n"
+      "    clear_$oneof_name$();\n"
+      "    set_has_$name$();\n"
+      "    $field_member$.UnsafeSetDefault($default_variable$);\n"
+      "  }\n"
+      "  $field_member$.Set$lite$($default_variable$,\n"
+      "      $string_piece$(value), GetArena());\n"
+      "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
       "}\n");
-  if (SupportsArenas(descriptor_)) {
+  if (!options_.opensource_runtime) {
     format(
-        "inline const std::string& $classname$::_internal_$name$() const {\n"
-        "  if (_internal_has_$name$()) {\n"
-        "    return $field_member$.Get();\n"
-        "  }\n"
-        "  return *$default_variable$;\n"
-        "}\n"
-        "inline void $classname$::_internal_set_$name$(const std::string& "
-        "value) {\n"
-        "  if (!_internal_has_$name$()) {\n"
-        "    clear_$oneof_name$();\n"
-        "    set_has_$name$();\n"
-        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
-        "  }\n"
-        "  $field_member$.Set$lite$($default_variable$, value, GetArena());\n"
-        "}\n"
-        "inline void $classname$::set_$name$(std::string&& value) {\n"
-        "$annotate_accessor$"
-        "  // @@protoc_insertion_point(field_set:$full_name$)\n"
-        "  if (!_internal_has_$name$()) {\n"
-        "    clear_$oneof_name$();\n"
-        "    set_has_$name$();\n"
-        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
-        "  }\n"
-        "  $field_member$.Set$lite$(\n"
-        "    $default_variable$, ::std::move(value), GetArena());\n"
-        "  // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
-        "}\n"
-        "inline void $classname$::set_$name$(const char* value) {\n"
-        "$annotate_accessor$"
-        "  $null_check$"
-        "  if (!_internal_has_$name$()) {\n"
-        "    clear_$oneof_name$();\n"
-        "    set_has_$name$();\n"
-        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
-        "  }\n"
-        "  $field_member$.Set$lite$($default_variable$,\n"
-        "      $string_piece$(value), GetArena());\n"
-        "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
-        "}\n");
-    if (!options_.opensource_runtime) {
-      format(
-          "inline void $classname$::set_$name$(::StringPiece value) {\n"
-          "$annotate_accessor$"
-          "  if (!_internal_has_$name$()) {\n"
-          "    clear_$oneof_name$();\n"
-          "    set_has_$name$();\n"
-          "    $field_member$.UnsafeSetDefault($default_variable$);\n"
-          "  }\n"
-          "  $field_member$.Set$lite$($default_variable$, value,\n"
-          "      GetArena());\n"
-          "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
-          "}\n");
-    }
-    format(
-        "inline "
-        "void $classname$::set_$name$(const $pointer_type$* value,\n"
-        "                             size_t size) {\n"
+        "inline void $classname$::set_$name$(::StringPiece value) {\n"
         "$annotate_accessor$"
         "  if (!_internal_has_$name$()) {\n"
         "    clear_$oneof_name$();\n"
         "    set_has_$name$();\n"
         "    $field_member$.UnsafeSetDefault($default_variable$);\n"
         "  }\n"
-        "  $field_member$.Set$lite$(\n"
-        "      $default_variable$, $string_piece$(\n"
-        "      reinterpret_cast<const char*>(value), size),\n"
+        "  $field_member$.Set$lite$($default_variable$, value,\n"
         "      GetArena());\n"
-        "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
-        "}\n"
-        "inline std::string* $classname$::_internal_mutable_$name$() {\n"
-        "  if (!_internal_has_$name$()) {\n"
-        "    clear_$oneof_name$();\n"
-        "    set_has_$name$();\n"
-        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
-        "  }\n"
-        "  return $field_member$.Mutable($default_variable$, GetArena());\n"
-        "}\n"
-        "inline std::string* $classname$::$release_name$() {\n"
-        "$annotate_accessor$"
-        "  // @@protoc_insertion_point(field_release:$full_name$)\n"
-        "  if (_internal_has_$name$()) {\n"
-        "    clear_has_$oneof_name$();\n"
-        "    return $field_member$.Release($default_variable$, GetArena());\n"
-        "  } else {\n"
-        "    return nullptr;\n"
-        "  }\n"
-        "}\n"
-        "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
-        "$annotate_accessor$"
-        "  if (has_$oneof_name$()) {\n"
-        "    clear_$oneof_name$();\n"
-        "  }\n"
-        "  if ($name$ != nullptr) {\n"
-        "    set_has_$name$();\n"
-        "    $field_member$.UnsafeSetDefault($name$);\n"
-        "    ::$proto_ns$::Arena* arena = GetArena();\n"
-        "    if (arena != nullptr) {\n"
-        "      arena->Own($name$);\n"
-        "    }\n"
-        "  }\n"
-        "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
-        "}\n");
-  } else {
-    // No-arena case.
-    format(
-        "inline const std::string& $classname$::_internal_$name$() const {\n"
-        "  if (_internal_has_$name$()) {\n"
-        "    return $field_member$.GetNoArena();\n"
-        "  }\n"
-        "  return *$default_variable$;\n"
-        "}\n"
-        "inline void $classname$::_internal_set_$name$(const std::string& "
-        "value) {\n"
-        "  if (!_internal_has_$name$()) {\n"
-        "    clear_$oneof_name$();\n"
-        "    set_has_$name$();\n"
-        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
-        "  }\n"
-        "  $field_member$.SetNoArena($default_variable$, value);\n"
-        "}\n"
-        "inline void $classname$::set_$name$(std::string&& value) {\n"
-        "$annotate_accessor$"
-        "  // @@protoc_insertion_point(field_set:$full_name$)\n"
-        "  if (!_internal_has_$name$()) {\n"
-        "    clear_$oneof_name$();\n"
-        "    set_has_$name$();\n"
-        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
-        "  }\n"
-        "  $field_member$.SetNoArena($default_variable$, ::std::move(value));\n"
-        "  // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
-        "}\n"
-        "inline void $classname$::set_$name$(const char* value) {\n"
-        "$annotate_accessor$"
-        "  $null_check$"
-        "  if (!_internal_has_$name$()) {\n"
-        "    clear_$oneof_name$();\n"
-        "    set_has_$name$();\n"
-        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
-        "  }\n"
-        "  $field_member$.SetNoArena($default_variable$,\n"
-        "      $string_piece$(value));\n"
-        "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
-        "}\n");
-    if (!options_.opensource_runtime) {
-      format(
-          "inline void $classname$::set_$name$(::StringPiece value) {\n"
-          "$annotate_accessor$"
-          "  if (!_internal_has_$name$()) {\n"
-          "    clear_$oneof_name$();\n"
-          "    set_has_$name$();\n"
-          "    $field_member$.UnsafeSetDefault($default_variable$);\n"
-          "  }\n"
-          "  $field_member$.SetNoArena($default_variable$, value);\n"
-          "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
-          "}\n");
-    }
-    format(
-        "inline "
-        "void $classname$::set_$name$(const $pointer_type$* value, size_t "
-        "size) {\n"
-        "$annotate_accessor$"
-        "  if (!_internal_has_$name$()) {\n"
-        "    clear_$oneof_name$();\n"
-        "    set_has_$name$();\n"
-        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
-        "  }\n"
-        "  $field_member$.SetNoArena($default_variable$, $string_piece$(\n"
-        "      reinterpret_cast<const char*>(value), size));\n"
-        "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
-        "}\n"
-        "inline std::string* $classname$::_internal_mutable_$name$() {\n"
-        "  if (!_internal_has_$name$()) {\n"
-        "    clear_$oneof_name$();\n"
-        "    set_has_$name$();\n"
-        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
-        "  }\n"
-        "  return $field_member$.MutableNoArena($default_variable$);\n"
-        "}\n"
-        "inline std::string* $classname$::$release_name$() {\n"
-        "$annotate_accessor$"
-        "  // @@protoc_insertion_point(field_release:$full_name$)\n"
-        "  if (_internal_has_$name$()) {\n"
-        "    clear_has_$oneof_name$();\n"
-        "    return $field_member$.ReleaseNoArena($default_variable$);\n"
-        "  } else {\n"
-        "    return nullptr;\n"
-        "  }\n"
-        "}\n"
-        "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
-        "$annotate_accessor$"
-        "  if (has_$oneof_name$()) {\n"
-        "    clear_$oneof_name$();\n"
-        "  }\n"
-        "  if ($name$ != nullptr) {\n"
-        "    set_has_$name$();\n"
-        "    $field_member$.UnsafeSetDefault($name$);\n"
-        "  }\n"
-        "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+        "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
         "}\n");
   }
+  format(
+      "inline "
+      "void $classname$::set_$name$(const $pointer_type$* value,\n"
+      "                             size_t size) {\n"
+      "$annotate_accessor$"
+      "  if (!_internal_has_$name$()) {\n"
+      "    clear_$oneof_name$();\n"
+      "    set_has_$name$();\n"
+      "    $field_member$.UnsafeSetDefault($default_variable$);\n"
+      "  }\n"
+      "  $field_member$.Set$lite$(\n"
+      "      $default_variable$, $string_piece$(\n"
+      "      reinterpret_cast<const char*>(value), size),\n"
+      "      GetArena());\n"
+      "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
+      "}\n"
+      "inline std::string* $classname$::_internal_mutable_$name$() {\n"
+      "  if (!_internal_has_$name$()) {\n"
+      "    clear_$oneof_name$();\n"
+      "    set_has_$name$();\n"
+      "    $field_member$.UnsafeSetDefault($default_variable$);\n"
+      "  }\n"
+      "  return $field_member$.Mutable($default_variable$, GetArena());\n"
+      "}\n"
+      "inline std::string* $classname$::$release_name$() {\n"
+      "$annotate_accessor$"
+      "  // @@protoc_insertion_point(field_release:$full_name$)\n"
+      "  if (_internal_has_$name$()) {\n"
+      "    clear_has_$oneof_name$();\n"
+      "    return $field_member$.Release($default_variable$, GetArena());\n"
+      "  } else {\n"
+      "    return nullptr;\n"
+      "  }\n"
+      "}\n"
+      "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
+      "$annotate_accessor$"
+      "  if (has_$oneof_name$()) {\n"
+      "    clear_$oneof_name$();\n"
+      "  }\n"
+      "  if ($name$ != nullptr) {\n"
+      "    set_has_$name$();\n"
+      "    $field_member$.UnsafeSetDefault($name$);\n"
+      "    ::$proto_ns$::Arena* arena = GetArena();\n"
+      "    if (arena != nullptr) {\n"
+      "      arena->Own($name$);\n"
+      "    }\n"
+      "  }\n"
+      "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+      "}\n");
 }
 
 void StringOneofFieldGenerator::GenerateClearingCode(
     io::Printer* printer) const {
   Formatter format(printer, variables_);
-  if (SupportsArenas(descriptor_)) {
-    format("$field_member$.Destroy($default_variable$, GetArena());\n");
-  } else {
-    format("$field_member$.DestroyNoArena($default_variable$);\n");
-  }
+  format("$field_member$.Destroy($default_variable$, GetArena());\n");
 }
 
 void StringOneofFieldGenerator::GenerateMessageClearingCode(
diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc
index ab5c356..1ff8aad 100644
--- a/src/google/protobuf/compiler/importer.cc
+++ b/src/google/protobuf/compiler/importer.cc
@@ -495,7 +495,7 @@
   do {
     ret = stat(filename.c_str(), &sb);
   } while (ret != 0 && errno == EINTR);
-  if (sb.st_mode & S_IFDIR) {
+  if (ret == 0 && sb.st_mode & S_IFDIR) {
     last_error_message_ = "Input file is a directory.";
     return NULL;
   }
diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc
index 0b85056..b463622 100644
--- a/src/google/protobuf/compiler/mock_code_generator.cc
+++ b/src/google/protobuf/compiler/mock_code_generator.cc
@@ -166,17 +166,36 @@
                         &file_content, true));
   std::string meta_content;
   GOOGLE_CHECK_OK(File::GetContents(
-      output_directory + "/" + GetOutputFileName(name, file) + ".meta",
+      output_directory + "/" + GetOutputFileName(name, file) + ".pb.meta",
       &meta_content, true));
   GeneratedCodeInfo annotations;
   GOOGLE_CHECK(TextFormat::ParseFromString(meta_content, &annotations));
-  ASSERT_EQ(3, annotations.annotation_size());
+  ASSERT_EQ(7, annotations.annotation_size());
+
   CheckSingleAnnotation("first_annotation", "first", file_content,
                         annotations.annotation(0));
+  CheckSingleAnnotation("first_path",
+                        "test_generator: first_insert,\n foo.proto,\n "
+                        "MockCodeGenerator_Annotate,\n foo.proto\n",
+                        file_content, annotations.annotation(1));
+  CheckSingleAnnotation("first_path",
+                        "test_plugin: first_insert,\n foo.proto,\n "
+                        "MockCodeGenerator_Annotate,\n foo.proto\n",
+                        file_content, annotations.annotation(2));
   CheckSingleAnnotation("second_annotation", "second", file_content,
-                        annotations.annotation(1));
+                        annotations.annotation(3));
+  // This annotated text has changed because it was inserted at an indented
+  // insertion point.
+  CheckSingleAnnotation("second_path",
+                        "test_generator: second_insert,\n   foo.proto,\n   "
+                        "MockCodeGenerator_Annotate,\n   foo.proto\n",
+                        file_content, annotations.annotation(4));
+  CheckSingleAnnotation("second_path",
+                        "test_plugin: second_insert,\n   foo.proto,\n   "
+                        "MockCodeGenerator_Annotate,\n   foo.proto\n",
+                        file_content, annotations.annotation(5));
   CheckSingleAnnotation("third_annotation", "third", file_content,
-                        annotations.annotation(2));
+                        annotations.annotation(6));
 }
 
 bool MockCodeGenerator::Generate(const FileDescriptor* file,
@@ -229,18 +248,35 @@
     }
   }
 
-  if (HasPrefixString(parameter, "insert=")) {
+  bool insert_endlines = HasPrefixString(parameter, "insert_endlines=");
+  if (insert_endlines || HasPrefixString(parameter, "insert=")) {
     std::vector<std::string> insert_into;
-    SplitStringUsing(StripPrefixString(parameter, "insert="), ",",
-                     &insert_into);
+
+    SplitStringUsing(
+        StripPrefixString(
+            parameter, insert_endlines ? "insert_endlines=" : "insert="),
+        ",", &insert_into);
 
     for (size_t i = 0; i < insert_into.size(); i++) {
       {
-        std::unique_ptr<io::ZeroCopyOutputStream> output(context->OpenForInsert(
-            GetOutputFileName(insert_into[i], file), kFirstInsertionPointName));
+        google::protobuf::GeneratedCodeInfo info;
+        std::string content =
+            GetOutputFileContent(name_, "first_insert", file, context);
+        if (insert_endlines) {
+          GlobalReplaceSubstring(",", ",\n", &content);
+        }
+        if (annotate) {
+          auto* annotation = info.add_annotation();
+          annotation->set_begin(0);
+          annotation->set_end(content.size());
+          annotation->set_source_file("first_path");
+        }
+        std::unique_ptr<io::ZeroCopyOutputStream> output(
+            context->OpenForInsertWithGeneratedCodeInfo(
+                GetOutputFileName(insert_into[i], file),
+                kFirstInsertionPointName, info));
         io::Printer printer(output.get(), '$');
-        printer.PrintRaw(
-            GetOutputFileContent(name_, "first_insert", file, context));
+        printer.PrintRaw(content);
         if (printer.failed()) {
           *error = "MockCodeGenerator detected write error.";
           return false;
@@ -248,12 +284,24 @@
       }
 
       {
+        google::protobuf::GeneratedCodeInfo info;
+        std::string content =
+            GetOutputFileContent(name_, "second_insert", file, context);
+        if (insert_endlines) {
+          GlobalReplaceSubstring(",", ",\n", &content);
+        }
+        if (annotate) {
+          auto* annotation = info.add_annotation();
+          annotation->set_begin(0);
+          annotation->set_end(content.size());
+          annotation->set_source_file("second_path");
+        }
         std::unique_ptr<io::ZeroCopyOutputStream> output(
-            context->OpenForInsert(GetOutputFileName(insert_into[i], file),
-                                   kSecondInsertionPointName));
+            context->OpenForInsertWithGeneratedCodeInfo(
+                GetOutputFileName(insert_into[i], file),
+                kSecondInsertionPointName, info));
         io::Printer printer(output.get(), '$');
-        printer.PrintRaw(
-            GetOutputFileContent(name_, "second_insert", file, context));
+        printer.PrintRaw(content);
         if (printer.failed()) {
           *error = "MockCodeGenerator detected write error.";
           return false;
@@ -272,17 +320,17 @@
     printer.PrintRaw(GetOutputFileContent(name_, parameter, file, context));
     std::string annotate_suffix = "_annotation";
     if (annotate) {
-      printer.Print("$p$", "p", "first");
+      printer.Print("$p$\n", "p", "first");
       printer.Annotate("p", "first" + annotate_suffix);
     }
     printer.PrintRaw(kFirstInsertionPoint);
     if (annotate) {
-      printer.Print("$p$", "p", "second");
+      printer.Print("$p$\n", "p", "second");
       printer.Annotate("p", "second" + annotate_suffix);
     }
     printer.PrintRaw(kSecondInsertionPoint);
     if (annotate) {
-      printer.Print("$p$", "p", "third");
+      printer.Print("$p$\n", "p", "third");
       printer.Annotate("p", "third" + annotate_suffix);
     }
 
@@ -292,9 +340,9 @@
     }
     if (annotate) {
       std::unique_ptr<io::ZeroCopyOutputStream> meta_output(
-          context->Open(GetOutputFileName(name_, file) + ".meta"));
+          context->Open(GetOutputFileName(name_, file) + ".pb.meta"));
       if (!TextFormat::Print(annotations, meta_output.get())) {
-        *error = "MockCodeGenerator couldn't write .meta";
+        *error = "MockCodeGenerator couldn't write .pb.meta";
         return false;
       }
     }
diff --git a/src/google/protobuf/compiler/mock_code_generator.h b/src/google/protobuf/compiler/mock_code_generator.h
index 9a72258..9677d19 100644
--- a/src/google/protobuf/compiler/mock_code_generator.h
+++ b/src/google/protobuf/compiler/mock_code_generator.h
@@ -56,7 +56,9 @@
 // If the parameter is "insert=NAMES", the MockCodeGenerator will insert lines
 // into the files generated by other MockCodeGenerators instead of creating
 // its own file.  NAMES is a comma-separated list of the names of those other
-// MockCodeGenerators.
+// MockCodeGenerators.  If the parameter is "insert_endlines=NAMES", the
+// MockCodeGenerator will insert data guaranteed to contain more than one
+// endline into the files generated by NAMES.
 //
 // MockCodeGenerator will also modify its behavior slightly if the input file
 // contains a message type with one of the following names:
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc
index 58ca9c1..ce4a12c 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc
@@ -421,7 +421,7 @@
       "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n");
   if (includes_oneof) {
     // The generated code for oneof's uses direct ivar access, suppress the
-    // warning incase developer turn that on in the context they compile the
+    // warning in case developer turn that on in the context they compile the
     // generated code.
     printer->Print(
         "#pragma clang diagnostic ignored \"-Wdirect-ivar-access\"\n");
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
index 257e4f9..a1a6f52 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
@@ -29,12 +29,12 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <iostream>
+#include <string>
 #include <google/protobuf/compiler/objectivec/objectivec_generator.h>
 #include <google/protobuf/compiler/objectivec/objectivec_file.h>
 #include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/zero_copy_stream.h>
-#include <google/protobuf/stubs/strutil.h>
 
 namespace google {
 namespace protobuf {
@@ -93,8 +93,11 @@
       // A semicolon delimited string that lists the paths of .proto files to
       // exclude from the package prefix validations (expected_prefixes_path).
       // This is provided as an "out", to skip some files being checked.
-      SplitStringUsing(options[i].second, ";",
-                       &generation_options.expected_prefixes_suppressions);
+      for (StringPiece split_piece : Split(
+               options[i].second, ";", true)) {
+        generation_options.expected_prefixes_suppressions.push_back(
+            std::string(split_piece));
+      }
     } else if (options[i].first == "generate_for_named_framework") {
       // The name of the framework that protos are being generated for. This
       // will cause the #import statements to be framework based using this
@@ -120,7 +123,7 @@
       // Any number of files can be listed for a framework, just separate them
       // with commas.
       //
-      // There can be multiple lines listing the same frameworkName incase it
+      // There can be multiple lines listing the same frameworkName in case it
       // has a lot of proto files included in it; having multiple lines makes
       // things easier to read. If a proto file is not configured in the
       // mappings file, it will use the default framework name if one was passed
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
index 8b2b719..77fe084 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
@@ -78,7 +78,8 @@
   }
   const char* suppressions = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES_SUPPRESSIONS");
   if (suppressions) {
-    SplitStringUsing(suppressions, ";", &expected_prefixes_suppressions);
+    expected_prefixes_suppressions =
+        Split(suppressions, ";", true);
   }
 }
 
diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc
index 4a6206a..365cb64 100644
--- a/src/google/protobuf/compiler/php/php_generator.cc
+++ b/src/google/protobuf/compiler/php/php_generator.cc
@@ -624,21 +624,17 @@
     printer->Print(
         "private $^name^;\n",
         "name", field->name());
-  } else if (field->containing_oneof()) {
+  } else if (field->real_containing_oneof()) {
     // Oneof fields are handled by GenerateOneofField.
     return;
   } else {
+    std::string initial_value =
+        field->has_presence() ? "null" : DefaultForField(field);
     GenerateFieldDocComment(printer, field, is_descriptor, kFieldProperty);
     printer->Print(
-        "protected $^name^ = ^default^;\n",
+        "protected $^name^ = ^initial_value^;\n",
         "name", field->name(),
-        "default", DefaultForField(field));
-  }
-
-  if (is_descriptor) {
-    printer->Print(
-        "private $has_^name^ = false;\n",
-        "name", field->name());
+        "initial_value", initial_value);
   }
 }
 
@@ -652,20 +648,41 @@
 
 void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor,
                            io::Printer* printer) {
-  const OneofDescriptor* oneof = field->containing_oneof();
+  const OneofDescriptor* oneof = field->real_containing_oneof();
 
   // Generate getter.
+  GenerateFieldDocComment(printer, field, is_descriptor, kFieldGetter);
+
   if (oneof != NULL) {
-    GenerateFieldDocComment(printer, field, is_descriptor, kFieldGetter);
     printer->Print(
         "public function get^camel_name^()\n"
         "{\n"
         "    return $this->readOneof(^number^);\n"
+        "}\n\n"
+        "public function has^camel_name^()\n"
+        "{\n"
+        "    return $this->hasOneof(^number^);\n"
         "}\n\n",
         "camel_name", UnderscoresToCamelCase(field->name(), true),
         "number", IntToString(field->number()));
+  } else if (field->has_presence()) {
+    printer->Print(
+        "public function get^camel_name^()\n"
+        "{\n"
+        "    return isset($this->^name^) ? $this->^name^ : ^default_value^;\n"
+        "}\n\n"
+        "public function has^camel_name^()\n"
+        "{\n"
+        "    return isset($this->^name^);\n"
+        "}\n\n"
+        "public function clear^camel_name^()\n"
+        "{\n"
+        "    unset($this->^name^);\n"
+        "}\n\n",
+        "camel_name", UnderscoresToCamelCase(field->name(), true),
+        "name", field->name(),
+        "default_value", DefaultForField(field));
   } else {
-    GenerateFieldDocComment(printer, field, is_descriptor, kFieldGetter);
     printer->Print(
         "public function get^camel_name^()\n"
         "{\n"
@@ -774,13 +791,6 @@
         "name", field->name());
   }
 
-  // Set has bit for proto2 only.
-  if (is_descriptor) {
-    printer->Print(
-        "$this->has_^field_name^ = true;\n",
-        "field_name", field->name());
-  }
-
   printer->Print("\nreturn $this;\n");
 
   Outdent(printer);
@@ -803,17 +813,6 @@
         "camel_name", UnderscoresToCamelCase(field->name(), true),
         "field_name", field->name());
   }
-
-  // Generate has method for proto2 only.
-  if (is_descriptor) {
-    printer->Print(
-        "public function has^camel_name^()\n"
-        "{\n"
-        "    return $this->has_^field_name^;\n"
-        "}\n\n",
-        "camel_name", UnderscoresToCamelCase(field->name(), true),
-        "field_name", field->name());
-  }
 }
 
 void GenerateEnumToPool(const EnumDescriptor* en, io::Printer* printer) {
@@ -878,7 +877,7 @@
           "value", ToUpper(val->type_name()),
           "number", StrCat(field->number()),
           "other", EnumOrMessageSuffix(val, true));
-    } else if (!field->containing_oneof()) {
+    } else if (!field->real_containing_oneof()) {
       printer->Print(
           "->^label^('^field^', "
           "\\Google\\Protobuf\\Internal\\GPBType::^type^, ^number^^other^)\n",
@@ -891,7 +890,7 @@
   }
 
   // oneofs.
-  for (int i = 0; i < message->oneof_decl_count(); i++) {
+  for (int i = 0; i < message->real_oneof_decl_count(); i++) {
     const OneofDescriptor* oneof = message->oneof_decl(i);
     printer->Print("->oneof(^name^)\n",
                    "name", oneof->name());
@@ -1414,7 +1413,7 @@
     const FieldDescriptor* field = message->field(i);
     GenerateField(field, &printer, is_descriptor);
   }
-  for (int i = 0; i < message->oneof_decl_count(); i++) {
+  for (int i = 0; i < message->real_oneof_decl_count(); i++) {
     const OneofDescriptor* oneof = message->oneof_decl(i);
     GenerateOneofField(oneof, &printer);
   }
@@ -1443,7 +1442,7 @@
     const FieldDescriptor* field = message->field(i);
     GenerateFieldAccessor(field, is_descriptor, &printer);
   }
-  for (int i = 0; i < message->oneof_decl_count(); i++) {
+  for (int i = 0; i < message->real_oneof_decl_count(); i++) {
     const OneofDescriptor* oneof = message->oneof_decl(i);
     printer.Print(
       "/**\n"
diff --git a/src/google/protobuf/compiler/php/php_generator.h b/src/google/protobuf/compiler/php/php_generator.h
index ca9d23a..f67bb40 100644
--- a/src/google/protobuf/compiler/php/php_generator.h
+++ b/src/google/protobuf/compiler/php/php_generator.h
@@ -55,6 +55,11 @@
                    const std::string& parameter,
                    GeneratorContext* generator_context,
                    std::string* error) const override;
+
+  uint64_t GetSupportedFeatures() const override {
+    return FEATURE_PROTO3_OPTIONAL;
+  }
+
  private:
   bool Generate(
       const FileDescriptor* file,
diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc
index 7306cf4..cb7801d 100644
--- a/src/google/protobuf/compiler/plugin.cc
+++ b/src/google/protobuf/compiler/plugin.cc
@@ -86,6 +86,16 @@
     return new io::StringOutputStream(file->mutable_content());
   }
 
+  virtual io::ZeroCopyOutputStream* OpenForInsertWithGeneratedCodeInfo(
+      const std::string& filename, const std::string& insertion_point,
+      const google::protobuf::GeneratedCodeInfo& info) {
+    CodeGeneratorResponse::File* file = response_->add_file();
+    file->set_name(filename);
+    file->set_insertion_point(insertion_point);
+    *file->mutable_generated_code_info() = info;
+    return new io::StringOutputStream(file->mutable_content());
+  }
+
   void ListParsedFiles(std::vector<const FileDescriptor*>* output) {
     *output = parsed_files_;
   }
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index c2e430a..2b39bc4 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -15,7 +15,8 @@
 // @@protoc_insertion_point(includes)
 #include <google/protobuf/port_def.inc>
 extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<6> scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto;
-extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fplugin_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fplugin_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
 extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fplugin_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
 PROTOBUF_NAMESPACE_OPEN
 namespace compiler {
@@ -45,7 +46,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest::InitAsDefaultInstance();
 }
 
 PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<2> scc_info_CodeGeneratorRequest_google_2fprotobuf_2fcompiler_2fplugin_2eproto =
@@ -61,7 +61,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse::InitAsDefaultInstance();
 }
 
 PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_CodeGeneratorResponse_google_2fprotobuf_2fcompiler_2fplugin_2eproto =
@@ -76,11 +75,11 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File::InitAsDefaultInstance();
 }
 
-PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto =
-    {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto}, {}};
+PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto =
+    {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, 0, InitDefaultsscc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto}, {
+      &scc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
 static void InitDefaultsscc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
@@ -90,7 +89,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::compiler::Version();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::compiler::Version::InitAsDefaultInstance();
 }
 
 PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto =
@@ -135,9 +133,11 @@
   PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, name_),
   PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, insertion_point_),
   PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, content_),
+  PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, generated_code_info_),
   0,
   1,
   2,
+  3,
   PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, _has_bits_),
   PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, _internal_metadata_),
   ~0u,  // no _extensions_
@@ -153,8 +153,8 @@
 static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
   { 0, 9, sizeof(PROTOBUF_NAMESPACE_ID::compiler::Version)},
   { 13, 22, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest)},
-  { 26, 34, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File)},
-  { 37, 45, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse)},
+  { 26, 35, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File)},
+  { 39, 47, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse)},
 };
 
 static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = {
@@ -174,15 +174,17 @@
   "\t\0228\n\nproto_file\030\017 \003(\0132$.google.protobuf."
   "FileDescriptorProto\022;\n\020compiler_version\030"
   "\003 \001(\0132!.google.protobuf.compiler.Version"
-  "\"\200\002\n\025CodeGeneratorResponse\022\r\n\005error\030\001 \001("
+  "\"\301\002\n\025CodeGeneratorResponse\022\r\n\005error\030\001 \001("
   "\t\022\032\n\022supported_features\030\002 \001(\004\022B\n\004file\030\017 "
   "\003(\01324.google.protobuf.compiler.CodeGener"
-  "atorResponse.File\032>\n\004File\022\014\n\004name\030\001 \001(\t\022"
+  "atorResponse.File\032\177\n\004File\022\014\n\004name\030\001 \001(\t\022"
   "\027\n\017insertion_point\030\002 \001(\t\022\017\n\007content\030\017 \001("
-  "\t\"8\n\007Feature\022\020\n\014FEATURE_NONE\020\000\022\033\n\027FEATUR"
-  "E_PROTO3_OPTIONAL\020\001BW\n\034com.google.protob"
-  "uf.compilerB\014PluginProtosZ)google.golang"
-  ".org/protobuf/types/pluginpb"
+  "\t\022\?\n\023generated_code_info\030\020 \001(\0132\".google."
+  "protobuf.GeneratedCodeInfo\"8\n\007Feature\022\020\n"
+  "\014FEATURE_NONE\020\000\022\033\n\027FEATURE_PROTO3_OPTION"
+  "AL\020\001BW\n\034com.google.protobuf.compilerB\014Pl"
+  "uginProtosZ)google.golang.org/protobuf/t"
+  "ypes/pluginpb"
   ;
 static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps[1] = {
   &::descriptor_table_google_2fprotobuf_2fdescriptor_2eproto,
@@ -195,7 +197,7 @@
 };
 static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once;
 const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = {
-  false, false, descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto, "google/protobuf/compiler/plugin.proto", 708,
+  false, false, descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto, "google/protobuf/compiler/plugin.proto", 773,
   &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_sccs, descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps, 4, 1,
   schemas, file_default_instances, TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets,
   file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto, 4, file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto,
@@ -229,8 +231,6 @@
 
 // ===================================================================
 
-void Version::InitAsDefaultInstance() {
-}
 class Version::_Internal {
  public:
   using HasBits = decltype(std::declval<Version>()._has_bits_);
@@ -558,10 +558,6 @@
 
 // ===================================================================
 
-void CodeGeneratorRequest::InitAsDefaultInstance() {
-  PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorRequest_default_instance_._instance.get_mutable()->compiler_version_ = const_cast< PROTOBUF_NAMESPACE_ID::compiler::Version*>(
-      PROTOBUF_NAMESPACE_ID::compiler::Version::internal_default_instance());
-}
 class CodeGeneratorRequest::_Internal {
  public:
   using HasBits = decltype(std::declval<CodeGeneratorRequest>()._has_bits_);
@@ -912,8 +908,6 @@
 
 // ===================================================================
 
-void CodeGeneratorResponse_File::InitAsDefaultInstance() {
-}
 class CodeGeneratorResponse_File::_Internal {
  public:
   using HasBits = decltype(std::declval<CodeGeneratorResponse_File>()._has_bits_);
@@ -926,8 +920,20 @@
   static void set_has_content(HasBits* has_bits) {
     (*has_bits)[0] |= 4u;
   }
+  static const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& generated_code_info(const CodeGeneratorResponse_File* msg);
+  static void set_has_generated_code_info(HasBits* has_bits) {
+    (*has_bits)[0] |= 8u;
+  }
 };
 
+const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo&
+CodeGeneratorResponse_File::_Internal::generated_code_info(const CodeGeneratorResponse_File* msg) {
+  return *msg->generated_code_info_;
+}
+void CodeGeneratorResponse_File::clear_generated_code_info() {
+  if (generated_code_info_ != nullptr) generated_code_info_->Clear();
+  _has_bits_[0] &= ~0x00000008u;
+}
 CodeGeneratorResponse_File::CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::Arena* arena)
   : ::PROTOBUF_NAMESPACE_ID::Message(arena) {
   SharedCtor();
@@ -953,6 +959,11 @@
     content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_content(),
       GetArena());
   }
+  if (from._internal_has_generated_code_info()) {
+    generated_code_info_ = new PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo(*from.generated_code_info_);
+  } else {
+    generated_code_info_ = nullptr;
+  }
   // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse.File)
 }
 
@@ -961,6 +972,7 @@
   name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
   insertion_point_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
   content_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+  generated_code_info_ = nullptr;
 }
 
 CodeGeneratorResponse_File::~CodeGeneratorResponse_File() {
@@ -974,6 +986,7 @@
   name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
   insertion_point_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
   content_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete generated_code_info_;
 }
 
 void CodeGeneratorResponse_File::ArenaDtor(void* object) {
@@ -998,7 +1011,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 0x00000007u) {
+  if (cached_has_bits & 0x0000000fu) {
     if (cached_has_bits & 0x00000001u) {
       name_.ClearNonDefaultToEmpty();
     }
@@ -1008,6 +1021,10 @@
     if (cached_has_bits & 0x00000004u) {
       content_.ClearNonDefaultToEmpty();
     }
+    if (cached_has_bits & 0x00000008u) {
+      GOOGLE_DCHECK(generated_code_info_ != nullptr);
+      generated_code_info_->Clear();
+    }
   }
   _has_bits_.Clear();
   _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
@@ -1055,6 +1072,13 @@
           CHK_(ptr);
         } else goto handle_unusual;
         continue;
+      // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16;
+      case 16:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 130)) {
+          ptr = ctx->ParseMessage(_internal_mutable_generated_code_info(), ptr);
+          CHK_(ptr);
+        } else goto handle_unusual;
+        continue;
       default: {
       handle_unusual:
         if ((tag & 7) == 4 || tag == 0) {
@@ -1115,6 +1139,14 @@
         15, this->_internal_content(), target);
   }
 
+  // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16;
+  if (cached_has_bits & 0x00000008u) {
+    target = stream->EnsureSpace(target);
+    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+      InternalWriteMessage(
+        16, _Internal::generated_code_info(this), target, stream);
+  }
+
   if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
     target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
         _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
@@ -1132,7 +1164,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 0x00000007u) {
+  if (cached_has_bits & 0x0000000fu) {
     // optional string name = 1;
     if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
@@ -1154,6 +1186,13 @@
           this->_internal_content());
     }
 
+    // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16;
+    if (cached_has_bits & 0x00000008u) {
+      total_size += 2 +
+        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+          *generated_code_info_);
+    }
+
   }
   if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
     return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize(
@@ -1187,7 +1226,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 0x00000007u) {
+  if (cached_has_bits & 0x0000000fu) {
     if (cached_has_bits & 0x00000001u) {
       _internal_set_name(from._internal_name());
     }
@@ -1197,6 +1236,9 @@
     if (cached_has_bits & 0x00000004u) {
       _internal_set_content(from._internal_content());
     }
+    if (cached_has_bits & 0x00000008u) {
+      _internal_mutable_generated_code_info()->PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo::MergeFrom(from._internal_generated_code_info());
+    }
   }
 }
 
@@ -1225,6 +1267,7 @@
   name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
   insertion_point_.Swap(&other->insertion_point_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
   content_.Swap(&other->content_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
+  swap(generated_code_info_, other->generated_code_info_);
 }
 
 ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorResponse_File::GetMetadata() const {
@@ -1234,8 +1277,6 @@
 
 // ===================================================================
 
-void CodeGeneratorResponse::InitAsDefaultInstance() {
-}
 class CodeGeneratorResponse::_Internal {
  public:
   using HasBits = decltype(std::declval<CodeGeneratorResponse>()._has_bits_);
diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h
index 77d45eb..8ee850d 100644
--- a/src/google/protobuf/compiler/plugin.pb.h
+++ b/src/google/protobuf/compiler/plugin.pb.h
@@ -155,7 +155,6 @@
   }
   static const Version& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const Version* internal_default_instance() {
     return reinterpret_cast<const Version*>(
                &_Version_default_instance_);
@@ -356,7 +355,6 @@
   }
   static const CodeGeneratorRequest& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const CodeGeneratorRequest* internal_default_instance() {
     return reinterpret_cast<const CodeGeneratorRequest*>(
                &_CodeGeneratorRequest_default_instance_);
@@ -578,7 +576,6 @@
   }
   static const CodeGeneratorResponse_File& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const CodeGeneratorResponse_File* internal_default_instance() {
     return reinterpret_cast<const CodeGeneratorResponse_File*>(
                &_CodeGeneratorResponse_File_default_instance_);
@@ -658,6 +655,7 @@
     kNameFieldNumber = 1,
     kInsertionPointFieldNumber = 2,
     kContentFieldNumber = 15,
+    kGeneratedCodeInfoFieldNumber = 16,
   };
   // optional string name = 1;
   bool has_name() const;
@@ -719,6 +717,24 @@
   std::string* _internal_mutable_content();
   public:
 
+  // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16;
+  bool has_generated_code_info() const;
+  private:
+  bool _internal_has_generated_code_info() const;
+  public:
+  void clear_generated_code_info();
+  const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& generated_code_info() const;
+  PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* release_generated_code_info();
+  PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* mutable_generated_code_info();
+  void set_allocated_generated_code_info(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info);
+  private:
+  const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& _internal_generated_code_info() const;
+  PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* _internal_mutable_generated_code_info();
+  public:
+  void unsafe_arena_set_allocated_generated_code_info(
+      PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info);
+  PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* unsafe_arena_release_generated_code_info();
+
   // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File)
  private:
   class _Internal;
@@ -731,6 +747,7 @@
   ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
   ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr insertion_point_;
   ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr content_;
+  PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info_;
   friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
 };
 // -------------------------------------------------------------------
@@ -778,7 +795,6 @@
   }
   static const CodeGeneratorResponse& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const CodeGeneratorResponse* internal_default_instance() {
     return reinterpret_cast<const CodeGeneratorResponse*>(
                &_CodeGeneratorResponse_default_instance_);
@@ -1328,8 +1344,8 @@
 }
 inline const PROTOBUF_NAMESPACE_ID::compiler::Version& CodeGeneratorRequest::_internal_compiler_version() const {
   const PROTOBUF_NAMESPACE_ID::compiler::Version* p = compiler_version_;
-  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::compiler::Version*>(
-      &PROTOBUF_NAMESPACE_ID::compiler::_Version_default_instance_);
+  return p != nullptr ? *p : reinterpret_cast<const PROTOBUF_NAMESPACE_ID::compiler::Version&>(
+      PROTOBUF_NAMESPACE_ID::compiler::_Version_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::compiler::Version& CodeGeneratorRequest::compiler_version() const {
   // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
@@ -1622,6 +1638,85 @@
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.content)
 }
 
+// optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16;
+inline bool CodeGeneratorResponse_File::_internal_has_generated_code_info() const {
+  bool value = (_has_bits_[0] & 0x00000008u) != 0;
+  PROTOBUF_ASSUME(!value || generated_code_info_ != nullptr);
+  return value;
+}
+inline bool CodeGeneratorResponse_File::has_generated_code_info() const {
+  return _internal_has_generated_code_info();
+}
+inline const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& CodeGeneratorResponse_File::_internal_generated_code_info() const {
+  const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* p = generated_code_info_;
+  return p != nullptr ? *p : reinterpret_cast<const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo&>(
+      PROTOBUF_NAMESPACE_ID::_GeneratedCodeInfo_default_instance_);
+}
+inline const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& CodeGeneratorResponse_File::generated_code_info() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)
+  return _internal_generated_code_info();
+}
+inline void CodeGeneratorResponse_File::unsafe_arena_set_allocated_generated_code_info(
+    PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info) {
+  if (GetArena() == nullptr) {
+    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info_);
+  }
+  generated_code_info_ = generated_code_info;
+  if (generated_code_info) {
+    _has_bits_[0] |= 0x00000008u;
+  } else {
+    _has_bits_[0] &= ~0x00000008u;
+  }
+  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)
+}
+inline PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::release_generated_code_info() {
+  _has_bits_[0] &= ~0x00000008u;
+  PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* temp = generated_code_info_;
+  generated_code_info_ = nullptr;
+  if (GetArena() != nullptr) {
+    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+  }
+  return temp;
+}
+inline PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::unsafe_arena_release_generated_code_info() {
+  // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)
+  _has_bits_[0] &= ~0x00000008u;
+  PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* temp = generated_code_info_;
+  generated_code_info_ = nullptr;
+  return temp;
+}
+inline PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::_internal_mutable_generated_code_info() {
+  _has_bits_[0] |= 0x00000008u;
+  if (generated_code_info_ == nullptr) {
+    auto* p = CreateMaybeMessage<PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo>(GetArena());
+    generated_code_info_ = p;
+  }
+  return generated_code_info_;
+}
+inline PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::mutable_generated_code_info() {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)
+  return _internal_mutable_generated_code_info();
+}
+inline void CodeGeneratorResponse_File::set_allocated_generated_code_info(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info) {
+  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info_);
+  }
+  if (generated_code_info) {
+    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info)->GetArena();
+    if (message_arena != submessage_arena) {
+      generated_code_info = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+          message_arena, generated_code_info, submessage_arena);
+    }
+    _has_bits_[0] |= 0x00000008u;
+  } else {
+    _has_bits_[0] &= ~0x00000008u;
+  }
+  generated_code_info_ = generated_code_info;
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)
+}
+
 // -------------------------------------------------------------------
 
 // CodeGeneratorResponse
diff --git a/src/google/protobuf/compiler/plugin.proto b/src/google/protobuf/compiler/plugin.proto
index 189db19..9242aac 100644
--- a/src/google/protobuf/compiler/plugin.proto
+++ b/src/google/protobuf/compiler/plugin.proto
@@ -173,6 +173,11 @@
 
     // The file contents.
     optional string content = 15;
+
+    // Information describing the file content being inserted. If an insertion
+    // point is used, this information will be appropriately offset and inserted
+    // into the code generation metadata for the generated files.
+    optional GeneratedCodeInfo generated_code_info = 16;
   }
   repeated File file = 15;
 }
diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc
index cf61d99..ebc972c 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generator.cc
+++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc
@@ -113,7 +113,7 @@
   }
 }
 
-string StringifySyntax(FileDescriptor::Syntax syntax) {
+std::string StringifySyntax(FileDescriptor::Syntax syntax) {
   switch (syntax) {
     case FileDescriptor::SYNTAX_PROTO2:
       return "proto2";
@@ -147,7 +147,7 @@
       return NumberToString(field->default_value_enum()->number());
     case FieldDescriptor::CPPTYPE_STRING: {
       std::ostringstream os;
-      string default_str = field->default_value_string();
+      std::string default_str = field->default_value_string();
 
       if (field->type() == FieldDescriptor::TYPE_STRING) {
         os << "\"" << default_str << "\"";
@@ -413,7 +413,7 @@
 
     // If :: is in the package use the Ruby formatted name as-is
     //    -> A::B::C
-    // otherwise, use the dot seperator
+    // otherwise, use the dot separator
     //    -> A.B.C
     if (package_name.find("::") != std::string::npos) {
       need_change_to_module = false;
@@ -426,14 +426,14 @@
   }
 
   // Use the appropriate delimiter
-  string delimiter = need_change_to_module ? "." : "::";
+  std::string delimiter = need_change_to_module ? "." : "::";
   int delimiter_size = need_change_to_module ? 1 : 2;
 
   // Extract each module name and indent
   while (!package_name.empty()) {
     size_t dot_index = package_name.find(delimiter);
-    string component;
-    if (dot_index == string::npos) {
+    std::string component;
+    if (dot_index == std::string::npos) {
       component = package_name;
       package_name = "";
     } else {
@@ -462,7 +462,7 @@
 }
 
 bool UsesTypeFromFile(const Descriptor* message, const FileDescriptor* file,
-                      string* error) {
+                      std::string* error) {
   for (int i = 0; i < message->field_count(); i++) {
     const FieldDescriptor* field = message->field(i);
     if ((field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
@@ -499,7 +499,7 @@
 bool MaybeEmitDependency(const FileDescriptor* import,
                          const FileDescriptor* from,
                          io::Printer* printer,
-                         string* error) {
+                         std::string* error) {
   if (from->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
       import->syntax() == FileDescriptor::SYNTAX_PROTO2) {
     for (int i = 0; i < from->message_type_count(); i++) {
@@ -524,7 +524,7 @@
 }
 
 bool GenerateFile(const FileDescriptor* file, io::Printer* printer,
-                  string* error) {
+                  std::string* error) {
   printer->Print(
     "# Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
     "# source: $filename$\n"
@@ -580,9 +580,9 @@
 
 bool Generator::Generate(
     const FileDescriptor* file,
-    const string& parameter,
+    const std::string& parameter,
     GeneratorContext* generator_context,
-    string* error) const {
+    std::string* error) const {
 
   if (file->syntax() != FileDescriptor::SYNTAX_PROTO3 &&
       file->syntax() != FileDescriptor::SYNTAX_PROTO2) {
diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.h b/src/google/protobuf/compiler/ruby/ruby_generator.h
index b40fcd0..647bb83 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generator.h
+++ b/src/google/protobuf/compiler/ruby/ruby_generator.h
@@ -49,9 +49,9 @@
 // Ruby output, you can do so by registering an instance of this
 // CodeGenerator with the CommandLineInterface in your main() function.
 class PROTOC_EXPORT Generator : public CodeGenerator {
-  bool Generate(const FileDescriptor* file, const string& parameter,
+  bool Generate(const FileDescriptor* file, const std::string& parameter,
                 GeneratorContext* generator_context,
-                string* error) const override;
+                std::string* error) const override;
   uint64_t GetSupportedFeatures() const override {
     return FEATURE_PROTO3_OPTIONAL;
   }
@@ -65,4 +65,3 @@
 #include <google/protobuf/port_undef.inc>
 
 #endif  // GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__
-
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index 9a448ff..8fb9671 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -2723,7 +2723,7 @@
   if (has_json_name_) {
     if (!bracketed) {
       bracketed = true;
-      contents->append("[");
+      contents->append(" [");
     } else {
       contents->append(", ");
     }
@@ -4883,6 +4883,7 @@
                    DescriptorPool::ErrorCollector::DEFAULT_VALUE,
                    "Messages can't have default values.");
           result->has_default_value_ = false;
+          result->default_generated_instance_ = nullptr;
           break;
       }
 
@@ -4929,6 +4930,7 @@
           result->default_value_string_ = &internal::GetEmptyString();
           break;
         case FieldDescriptor::CPPTYPE_MESSAGE:
+          result->default_generated_instance_ = nullptr;
           break;
       }
     }
diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h
index 078f24a..5bfecf5 100644
--- a/src/google/protobuf/descriptor.h
+++ b/src/google/protobuf/descriptor.h
@@ -54,6 +54,7 @@
 #ifndef GOOGLE_PROTOBUF_DESCRIPTOR_H__
 #define GOOGLE_PROTOBUF_DESCRIPTOR_H__
 
+#include <atomic>
 #include <map>
 #include <memory>
 #include <set>
@@ -839,6 +840,7 @@
   // Allows access to GetLocationPath for annotations.
   friend class io::Printer;
   friend class compiler::cpp::Formatter;
+  friend class Reflection;
 
   // Fill the json_name field of FieldDescriptorProto.
   void CopyJsonNameTo(FieldDescriptorProto* proto) const;
@@ -906,6 +908,7 @@
 
     mutable const EnumValueDescriptor* default_value_enum_;
     const std::string* default_value_string_;
+    mutable std::atomic<const Message*> default_generated_instance_;
   };
 
   static const CppType kTypeToCppTypeMap[MAX_TYPE + 1];
@@ -1235,6 +1238,7 @@
   friend class EnumDescriptor;
   friend class DescriptorPool;
   friend class FileDescriptorTables;
+  friend class Reflection;
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumValueDescriptor);
 };
 
@@ -1857,7 +1861,7 @@
   // Delay the building of dependencies of a file descriptor until absolutely
   // necessary, like when message_type() is called on a field that is defined
   // in that dependency's file. This will cause functional issues if a proto
-  // or one of it's dependencies has errors. Should only be enabled for the
+  // or one of its dependencies has errors. Should only be enabled for the
   // generated_pool_ (because no descriptor build errors are guaranteed by
   // the compilation generation process), testing, or if a lack of descriptor
   // build errors can be guaranteed for a pool.
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index c4e26b6..e3eba97 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -157,7 +157,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::DescriptorProto();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::DescriptorProto::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<6> scc_info_DescriptorProto_google_2fprotobuf_2fdescriptor_2eproto =
@@ -177,7 +176,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_DescriptorProto_ExtensionRange_google_2fprotobuf_2fdescriptor_2eproto =
@@ -192,7 +190,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DescriptorProto_ReservedRange_google_2fprotobuf_2fdescriptor_2eproto =
@@ -206,7 +203,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::EnumDescriptorProto();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::EnumDescriptorProto::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<3> scc_info_EnumDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto =
@@ -223,7 +219,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_EnumDescriptorProto_EnumReservedRange_google_2fprotobuf_2fdescriptor_2eproto =
@@ -237,7 +232,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::EnumOptions();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::EnumOptions::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_EnumOptions_google_2fprotobuf_2fdescriptor_2eproto =
@@ -252,7 +246,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_EnumValueDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto =
@@ -267,7 +260,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::EnumValueOptions();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::EnumValueOptions::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_EnumValueOptions_google_2fprotobuf_2fdescriptor_2eproto =
@@ -282,7 +274,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_ExtensionRangeOptions_google_2fprotobuf_2fdescriptor_2eproto =
@@ -297,7 +288,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::FieldDescriptorProto();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::FieldDescriptorProto::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_FieldDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto =
@@ -312,7 +302,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::FieldOptions();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::FieldOptions::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_FieldOptions_google_2fprotobuf_2fdescriptor_2eproto =
@@ -327,7 +316,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::FileDescriptorProto();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::FileDescriptorProto::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<6> scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto =
@@ -347,7 +335,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::FileDescriptorSet();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::FileDescriptorSet::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_FileDescriptorSet_google_2fprotobuf_2fdescriptor_2eproto =
@@ -362,7 +349,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::FileOptions();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::FileOptions::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_FileOptions_google_2fprotobuf_2fdescriptor_2eproto =
@@ -377,7 +363,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto =
@@ -392,7 +377,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_GeneratedCodeInfo_Annotation_google_2fprotobuf_2fdescriptor_2eproto =
@@ -406,7 +390,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::MessageOptions();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::MessageOptions::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_MessageOptions_google_2fprotobuf_2fdescriptor_2eproto =
@@ -421,7 +404,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::MethodDescriptorProto();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::MethodDescriptorProto::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_MethodDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto =
@@ -436,7 +418,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::MethodOptions();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::MethodOptions::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_MethodOptions_google_2fprotobuf_2fdescriptor_2eproto =
@@ -451,7 +432,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::OneofDescriptorProto();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::OneofDescriptorProto::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_OneofDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto =
@@ -466,7 +446,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::OneofOptions();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::OneofOptions::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_OneofOptions_google_2fprotobuf_2fdescriptor_2eproto =
@@ -481,7 +460,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<2> scc_info_ServiceDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto =
@@ -497,7 +475,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::ServiceOptions();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::ServiceOptions::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_ServiceOptions_google_2fprotobuf_2fdescriptor_2eproto =
@@ -512,7 +489,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::SourceCodeInfo();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::SourceCodeInfo::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_SourceCodeInfo_google_2fprotobuf_2fdescriptor_2eproto =
@@ -527,7 +503,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_SourceCodeInfo_Location_google_2fprotobuf_2fdescriptor_2eproto =
@@ -541,7 +516,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::UninterpretedOption();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::UninterpretedOption::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto =
@@ -556,7 +530,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_UninterpretedOption_NamePart_google_2fprotobuf_2fdescriptor_2eproto =
@@ -1374,8 +1347,6 @@
 
 // ===================================================================
 
-void FileDescriptorSet::InitAsDefaultInstance() {
-}
 class FileDescriptorSet::_Internal {
  public:
 };
@@ -1578,12 +1549,6 @@
 
 // ===================================================================
 
-void FileDescriptorProto::InitAsDefaultInstance() {
-  PROTOBUF_NAMESPACE_ID::_FileDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::FileOptions*>(
-      PROTOBUF_NAMESPACE_ID::FileOptions::internal_default_instance());
-  PROTOBUF_NAMESPACE_ID::_FileDescriptorProto_default_instance_._instance.get_mutable()->source_code_info_ = const_cast< PROTOBUF_NAMESPACE_ID::SourceCodeInfo*>(
-      PROTOBUF_NAMESPACE_ID::SourceCodeInfo::internal_default_instance());
-}
 class FileDescriptorProto::_Internal {
  public:
   using HasBits = decltype(std::declval<FileDescriptorProto>()._has_bits_);
@@ -2243,10 +2208,6 @@
 
 // ===================================================================
 
-void DescriptorProto_ExtensionRange::InitAsDefaultInstance() {
-  PROTOBUF_NAMESPACE_ID::_DescriptorProto_ExtensionRange_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions*>(
-      PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions::internal_default_instance());
-}
 class DescriptorProto_ExtensionRange::_Internal {
  public:
   using HasBits = decltype(std::declval<DescriptorProto_ExtensionRange>()._has_bits_);
@@ -2548,8 +2509,6 @@
 
 // ===================================================================
 
-void DescriptorProto_ReservedRange::InitAsDefaultInstance() {
-}
 class DescriptorProto_ReservedRange::_Internal {
  public:
   using HasBits = decltype(std::declval<DescriptorProto_ReservedRange>()._has_bits_);
@@ -2804,10 +2763,6 @@
 
 // ===================================================================
 
-void DescriptorProto::InitAsDefaultInstance() {
-  PROTOBUF_NAMESPACE_ID::_DescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::MessageOptions*>(
-      PROTOBUF_NAMESPACE_ID::MessageOptions::internal_default_instance());
-}
 class DescriptorProto::_Internal {
  public:
   using HasBits = decltype(std::declval<DescriptorProto>()._has_bits_);
@@ -3355,8 +3310,6 @@
 
 // ===================================================================
 
-void ExtensionRangeOptions::InitAsDefaultInstance() {
-}
 class ExtensionRangeOptions::_Internal {
  public:
 };
@@ -3580,10 +3533,6 @@
 
 // ===================================================================
 
-void FieldDescriptorProto::InitAsDefaultInstance() {
-  PROTOBUF_NAMESPACE_ID::_FieldDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::FieldOptions*>(
-      PROTOBUF_NAMESPACE_ID::FieldOptions::internal_default_instance());
-}
 class FieldDescriptorProto::_Internal {
  public:
   using HasBits = decltype(std::declval<FieldDescriptorProto>()._has_bits_);
@@ -4213,10 +4162,6 @@
 
 // ===================================================================
 
-void OneofDescriptorProto::InitAsDefaultInstance() {
-  PROTOBUF_NAMESPACE_ID::_OneofDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::OneofOptions*>(
-      PROTOBUF_NAMESPACE_ID::OneofOptions::internal_default_instance());
-}
 class OneofDescriptorProto::_Internal {
  public:
   using HasBits = decltype(std::declval<OneofDescriptorProto>()._has_bits_);
@@ -4495,8 +4440,6 @@
 
 // ===================================================================
 
-void EnumDescriptorProto_EnumReservedRange::InitAsDefaultInstance() {
-}
 class EnumDescriptorProto_EnumReservedRange::_Internal {
  public:
   using HasBits = decltype(std::declval<EnumDescriptorProto_EnumReservedRange>()._has_bits_);
@@ -4751,10 +4694,6 @@
 
 // ===================================================================
 
-void EnumDescriptorProto::InitAsDefaultInstance() {
-  PROTOBUF_NAMESPACE_ID::_EnumDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::EnumOptions*>(
-      PROTOBUF_NAMESPACE_ID::EnumOptions::internal_default_instance());
-}
 class EnumDescriptorProto::_Internal {
  public:
   using HasBits = decltype(std::declval<EnumDescriptorProto>()._has_bits_);
@@ -5137,10 +5076,6 @@
 
 // ===================================================================
 
-void EnumValueDescriptorProto::InitAsDefaultInstance() {
-  PROTOBUF_NAMESPACE_ID::_EnumValueDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::EnumValueOptions*>(
-      PROTOBUF_NAMESPACE_ID::EnumValueOptions::internal_default_instance());
-}
 class EnumValueDescriptorProto::_Internal {
  public:
   using HasBits = decltype(std::declval<EnumValueDescriptorProto>()._has_bits_);
@@ -5456,10 +5391,6 @@
 
 // ===================================================================
 
-void ServiceDescriptorProto::InitAsDefaultInstance() {
-  PROTOBUF_NAMESPACE_ID::_ServiceDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::ServiceOptions*>(
-      PROTOBUF_NAMESPACE_ID::ServiceOptions::internal_default_instance());
-}
 class ServiceDescriptorProto::_Internal {
  public:
   using HasBits = decltype(std::declval<ServiceDescriptorProto>()._has_bits_);
@@ -5771,10 +5702,6 @@
 
 // ===================================================================
 
-void MethodDescriptorProto::InitAsDefaultInstance() {
-  PROTOBUF_NAMESPACE_ID::_MethodDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::MethodOptions*>(
-      PROTOBUF_NAMESPACE_ID::MethodOptions::internal_default_instance());
-}
 class MethodDescriptorProto::_Internal {
  public:
   using HasBits = decltype(std::declval<MethodDescriptorProto>()._has_bits_);
@@ -6207,8 +6134,6 @@
 
 // ===================================================================
 
-void FileOptions::InitAsDefaultInstance() {
-}
 class FileOptions::_Internal {
  public:
   using HasBits = decltype(std::declval<FileOptions>()._has_bits_);
@@ -7194,8 +7119,6 @@
 
 // ===================================================================
 
-void MessageOptions::InitAsDefaultInstance() {
-}
 class MessageOptions::_Internal {
  public:
   using HasBits = decltype(std::declval<MessageOptions>()._has_bits_);
@@ -7548,8 +7471,6 @@
 
 // ===================================================================
 
-void FieldOptions::InitAsDefaultInstance() {
-}
 class FieldOptions::_Internal {
  public:
   using HasBits = decltype(std::declval<FieldOptions>()._has_bits_);
@@ -7967,8 +7888,6 @@
 
 // ===================================================================
 
-void OneofOptions::InitAsDefaultInstance() {
-}
 class OneofOptions::_Internal {
  public:
 };
@@ -8192,8 +8111,6 @@
 
 // ===================================================================
 
-void EnumOptions::InitAsDefaultInstance() {
-}
 class EnumOptions::_Internal {
  public:
   using HasBits = decltype(std::declval<EnumOptions>()._has_bits_);
@@ -8496,8 +8413,6 @@
 
 // ===================================================================
 
-void EnumValueOptions::InitAsDefaultInstance() {
-}
 class EnumValueOptions::_Internal {
  public:
   using HasBits = decltype(std::declval<EnumValueOptions>()._has_bits_);
@@ -8758,8 +8673,6 @@
 
 // ===================================================================
 
-void ServiceOptions::InitAsDefaultInstance() {
-}
 class ServiceOptions::_Internal {
  public:
   using HasBits = decltype(std::declval<ServiceOptions>()._has_bits_);
@@ -9020,8 +8933,6 @@
 
 // ===================================================================
 
-void MethodOptions::InitAsDefaultInstance() {
-}
 class MethodOptions::_Internal {
  public:
   using HasBits = decltype(std::declval<MethodOptions>()._has_bits_);
@@ -9333,8 +9244,6 @@
 
 // ===================================================================
 
-void UninterpretedOption_NamePart::InitAsDefaultInstance() {
-}
 class UninterpretedOption_NamePart::_Internal {
  public:
   using HasBits = decltype(std::declval<UninterpretedOption_NamePart>()._has_bits_);
@@ -9612,8 +9521,6 @@
 
 // ===================================================================
 
-void UninterpretedOption::InitAsDefaultInstance() {
-}
 class UninterpretedOption::_Internal {
  public:
   using HasBits = decltype(std::declval<UninterpretedOption>()._has_bits_);
@@ -10057,8 +9964,6 @@
 
 // ===================================================================
 
-void SourceCodeInfo_Location::InitAsDefaultInstance() {
-}
 class SourceCodeInfo_Location::_Internal {
  public:
   using HasBits = decltype(std::declval<SourceCodeInfo_Location>()._has_bits_);
@@ -10451,8 +10356,6 @@
 
 // ===================================================================
 
-void SourceCodeInfo::InitAsDefaultInstance() {
-}
 class SourceCodeInfo::_Internal {
  public:
 };
@@ -10654,8 +10557,6 @@
 
 // ===================================================================
 
-void GeneratedCodeInfo_Annotation::InitAsDefaultInstance() {
-}
 class GeneratedCodeInfo_Annotation::_Internal {
  public:
   using HasBits = decltype(std::declval<GeneratedCodeInfo_Annotation>()._has_bits_);
@@ -10995,8 +10896,6 @@
 
 // ===================================================================
 
-void GeneratedCodeInfo::InitAsDefaultInstance() {
-}
 class GeneratedCodeInfo::_Internal {
  public:
 };
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index b10c78b..21e9b90 100644
--- a/src/google/protobuf/descriptor.pb.h
+++ b/src/google/protobuf/descriptor.pb.h
@@ -373,7 +373,6 @@
   }
   static const FileDescriptorSet& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const FileDescriptorSet* internal_default_instance() {
     return reinterpret_cast<const FileDescriptorSet*>(
                &_FileDescriptorSet_default_instance_);
@@ -526,7 +525,6 @@
   }
   static const FileDescriptorProto& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const FileDescriptorProto* internal_default_instance() {
     return reinterpret_cast<const FileDescriptorProto*>(
                &_FileDescriptorProto_default_instance_);
@@ -920,7 +918,6 @@
   }
   static const DescriptorProto_ExtensionRange& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const DescriptorProto_ExtensionRange* internal_default_instance() {
     return reinterpret_cast<const DescriptorProto_ExtensionRange*>(
                &_DescriptorProto_ExtensionRange_default_instance_);
@@ -1104,7 +1101,6 @@
   }
   static const DescriptorProto_ReservedRange& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const DescriptorProto_ReservedRange* internal_default_instance() {
     return reinterpret_cast<const DescriptorProto_ReservedRange*>(
                &_DescriptorProto_ReservedRange_default_instance_);
@@ -1268,7 +1264,6 @@
   }
   static const DescriptorProto& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const DescriptorProto* internal_default_instance() {
     return reinterpret_cast<const DescriptorProto*>(
                &_DescriptorProto_default_instance_);
@@ -1613,7 +1608,6 @@
   }
   static const ExtensionRangeOptions& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const ExtensionRangeOptions* internal_default_instance() {
     return reinterpret_cast<const ExtensionRangeOptions*>(
                &_ExtensionRangeOptions_default_instance_);
@@ -1769,7 +1763,6 @@
   }
   static const FieldDescriptorProto& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const FieldDescriptorProto* internal_default_instance() {
     return reinterpret_cast<const FieldDescriptorProto*>(
                &_FieldDescriptorProto_default_instance_);
@@ -2202,7 +2195,6 @@
   }
   static const OneofDescriptorProto& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const OneofDescriptorProto* internal_default_instance() {
     return reinterpret_cast<const OneofDescriptorProto*>(
                &_OneofDescriptorProto_default_instance_);
@@ -2378,7 +2370,6 @@
   }
   static const EnumDescriptorProto_EnumReservedRange& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const EnumDescriptorProto_EnumReservedRange* internal_default_instance() {
     return reinterpret_cast<const EnumDescriptorProto_EnumReservedRange*>(
                &_EnumDescriptorProto_EnumReservedRange_default_instance_);
@@ -2542,7 +2533,6 @@
   }
   static const EnumDescriptorProto& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const EnumDescriptorProto* internal_default_instance() {
     return reinterpret_cast<const EnumDescriptorProto*>(
                &_EnumDescriptorProto_default_instance_);
@@ -2786,7 +2776,6 @@
   }
   static const EnumValueDescriptorProto& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const EnumValueDescriptorProto* internal_default_instance() {
     return reinterpret_cast<const EnumValueDescriptorProto*>(
                &_EnumValueDescriptorProto_default_instance_);
@@ -2977,7 +2966,6 @@
   }
   static const ServiceDescriptorProto& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const ServiceDescriptorProto* internal_default_instance() {
     return reinterpret_cast<const ServiceDescriptorProto*>(
                &_ServiceDescriptorProto_default_instance_);
@@ -3173,7 +3161,6 @@
   }
   static const MethodDescriptorProto& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const MethodDescriptorProto* internal_default_instance() {
     return reinterpret_cast<const MethodDescriptorProto*>(
                &_MethodDescriptorProto_default_instance_);
@@ -3423,7 +3410,6 @@
   }
   static const FileOptions& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const FileOptions* internal_default_instance() {
     return reinterpret_cast<const FileOptions*>(
                &_FileOptions_default_instance_);
@@ -3982,7 +3968,6 @@
   }
   static const MessageOptions& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const MessageOptions* internal_default_instance() {
     return reinterpret_cast<const MessageOptions*>(
                &_MessageOptions_default_instance_);
@@ -4199,7 +4184,6 @@
   }
   static const FieldOptions& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const FieldOptions* internal_default_instance() {
     return reinterpret_cast<const FieldOptions*>(
                &_FieldOptions_default_instance_);
@@ -4510,7 +4494,6 @@
   }
   static const OneofOptions& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const OneofOptions* internal_default_instance() {
     return reinterpret_cast<const OneofOptions*>(
                &_OneofOptions_default_instance_);
@@ -4666,7 +4649,6 @@
   }
   static const EnumOptions& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const EnumOptions* internal_default_instance() {
     return reinterpret_cast<const EnumOptions*>(
                &_EnumOptions_default_instance_);
@@ -4853,7 +4835,6 @@
   }
   static const EnumValueOptions& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const EnumValueOptions* internal_default_instance() {
     return reinterpret_cast<const EnumValueOptions*>(
                &_EnumValueOptions_default_instance_);
@@ -5025,7 +5006,6 @@
   }
   static const ServiceOptions& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const ServiceOptions* internal_default_instance() {
     return reinterpret_cast<const ServiceOptions*>(
                &_ServiceOptions_default_instance_);
@@ -5197,7 +5177,6 @@
   }
   static const MethodOptions& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const MethodOptions* internal_default_instance() {
     return reinterpret_cast<const MethodOptions*>(
                &_MethodOptions_default_instance_);
@@ -5416,7 +5395,6 @@
   }
   static const UninterpretedOption_NamePart& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const UninterpretedOption_NamePart* internal_default_instance() {
     return reinterpret_cast<const UninterpretedOption_NamePart*>(
                &_UninterpretedOption_NamePart_default_instance_);
@@ -5590,7 +5568,6 @@
   }
   static const UninterpretedOption& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const UninterpretedOption* internal_default_instance() {
     return reinterpret_cast<const UninterpretedOption*>(
                &_UninterpretedOption_default_instance_);
@@ -5857,7 +5834,6 @@
   }
   static const SourceCodeInfo_Location& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const SourceCodeInfo_Location* internal_default_instance() {
     return reinterpret_cast<const SourceCodeInfo_Location*>(
                &_SourceCodeInfo_Location_default_instance_);
@@ -6111,7 +6087,6 @@
   }
   static const SourceCodeInfo& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const SourceCodeInfo* internal_default_instance() {
     return reinterpret_cast<const SourceCodeInfo*>(
                &_SourceCodeInfo_default_instance_);
@@ -6266,7 +6241,6 @@
   }
   static const GeneratedCodeInfo_Annotation& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const GeneratedCodeInfo_Annotation* internal_default_instance() {
     return reinterpret_cast<const GeneratedCodeInfo_Annotation*>(
                &_GeneratedCodeInfo_Annotation_default_instance_);
@@ -6477,7 +6451,6 @@
   }
   static const GeneratedCodeInfo& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const GeneratedCodeInfo* internal_default_instance() {
     return reinterpret_cast<const GeneratedCodeInfo*>(
                &_GeneratedCodeInfo_default_instance_);
@@ -7128,8 +7101,8 @@
 }
 inline const PROTOBUF_NAMESPACE_ID::FileOptions& FileDescriptorProto::_internal_options() const {
   const PROTOBUF_NAMESPACE_ID::FileOptions* p = options_;
-  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::FileOptions*>(
-      &PROTOBUF_NAMESPACE_ID::_FileOptions_default_instance_);
+  return p != nullptr ? *p : reinterpret_cast<const PROTOBUF_NAMESPACE_ID::FileOptions&>(
+      PROTOBUF_NAMESPACE_ID::_FileOptions_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::FileOptions& FileDescriptorProto::options() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.options)
@@ -7211,8 +7184,8 @@
 }
 inline const PROTOBUF_NAMESPACE_ID::SourceCodeInfo& FileDescriptorProto::_internal_source_code_info() const {
   const PROTOBUF_NAMESPACE_ID::SourceCodeInfo* p = source_code_info_;
-  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::SourceCodeInfo*>(
-      &PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_default_instance_);
+  return p != nullptr ? *p : reinterpret_cast<const PROTOBUF_NAMESPACE_ID::SourceCodeInfo&>(
+      PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::SourceCodeInfo& FileDescriptorProto::source_code_info() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.source_code_info)
@@ -7428,8 +7401,8 @@
 }
 inline const PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& DescriptorProto_ExtensionRange::_internal_options() const {
   const PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* p = options_;
-  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions*>(
-      &PROTOBUF_NAMESPACE_ID::_ExtensionRangeOptions_default_instance_);
+  return p != nullptr ? *p : reinterpret_cast<const PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions&>(
+      PROTOBUF_NAMESPACE_ID::_ExtensionRangeOptions_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& DescriptorProto_ExtensionRange::options() const {
   // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.options)
@@ -7883,8 +7856,8 @@
 }
 inline const PROTOBUF_NAMESPACE_ID::MessageOptions& DescriptorProto::_internal_options() const {
   const PROTOBUF_NAMESPACE_ID::MessageOptions* p = options_;
-  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::MessageOptions*>(
-      &PROTOBUF_NAMESPACE_ID::_MessageOptions_default_instance_);
+  return p != nullptr ? *p : reinterpret_cast<const PROTOBUF_NAMESPACE_ID::MessageOptions&>(
+      PROTOBUF_NAMESPACE_ID::_MessageOptions_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::MessageOptions& DescriptorProto::options() const {
   // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.options)
@@ -8610,8 +8583,8 @@
 }
 inline const PROTOBUF_NAMESPACE_ID::FieldOptions& FieldDescriptorProto::_internal_options() const {
   const PROTOBUF_NAMESPACE_ID::FieldOptions* p = options_;
-  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::FieldOptions*>(
-      &PROTOBUF_NAMESPACE_ID::_FieldOptions_default_instance_);
+  return p != nullptr ? *p : reinterpret_cast<const PROTOBUF_NAMESPACE_ID::FieldOptions&>(
+      PROTOBUF_NAMESPACE_ID::_FieldOptions_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::FieldOptions& FieldDescriptorProto::options() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.options)
@@ -8799,8 +8772,8 @@
 }
 inline const PROTOBUF_NAMESPACE_ID::OneofOptions& OneofDescriptorProto::_internal_options() const {
   const PROTOBUF_NAMESPACE_ID::OneofOptions* p = options_;
-  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::OneofOptions*>(
-      &PROTOBUF_NAMESPACE_ID::_OneofOptions_default_instance_);
+  return p != nullptr ? *p : reinterpret_cast<const PROTOBUF_NAMESPACE_ID::OneofOptions&>(
+      PROTOBUF_NAMESPACE_ID::_OneofOptions_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::OneofOptions& OneofDescriptorProto::options() const {
   // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.options)
@@ -9059,8 +9032,8 @@
 }
 inline const PROTOBUF_NAMESPACE_ID::EnumOptions& EnumDescriptorProto::_internal_options() const {
   const PROTOBUF_NAMESPACE_ID::EnumOptions* p = options_;
-  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::EnumOptions*>(
-      &PROTOBUF_NAMESPACE_ID::_EnumOptions_default_instance_);
+  return p != nullptr ? *p : reinterpret_cast<const PROTOBUF_NAMESPACE_ID::EnumOptions&>(
+      PROTOBUF_NAMESPACE_ID::_EnumOptions_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::EnumOptions& EnumDescriptorProto::options() const {
   // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.options)
@@ -9361,8 +9334,8 @@
 }
 inline const PROTOBUF_NAMESPACE_ID::EnumValueOptions& EnumValueDescriptorProto::_internal_options() const {
   const PROTOBUF_NAMESPACE_ID::EnumValueOptions* p = options_;
-  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::EnumValueOptions*>(
-      &PROTOBUF_NAMESPACE_ID::_EnumValueOptions_default_instance_);
+  return p != nullptr ? *p : reinterpret_cast<const PROTOBUF_NAMESPACE_ID::EnumValueOptions&>(
+      PROTOBUF_NAMESPACE_ID::_EnumValueOptions_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::EnumValueOptions& EnumValueDescriptorProto::options() const {
   // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.options)
@@ -9561,8 +9534,8 @@
 }
 inline const PROTOBUF_NAMESPACE_ID::ServiceOptions& ServiceDescriptorProto::_internal_options() const {
   const PROTOBUF_NAMESPACE_ID::ServiceOptions* p = options_;
-  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::ServiceOptions*>(
-      &PROTOBUF_NAMESPACE_ID::_ServiceOptions_default_instance_);
+  return p != nullptr ? *p : reinterpret_cast<const PROTOBUF_NAMESPACE_ID::ServiceOptions&>(
+      PROTOBUF_NAMESPACE_ID::_ServiceOptions_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::ServiceOptions& ServiceDescriptorProto::options() const {
   // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.options)
@@ -9870,8 +9843,8 @@
 }
 inline const PROTOBUF_NAMESPACE_ID::MethodOptions& MethodDescriptorProto::_internal_options() const {
   const PROTOBUF_NAMESPACE_ID::MethodOptions* p = options_;
-  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::MethodOptions*>(
-      &PROTOBUF_NAMESPACE_ID::_MethodOptions_default_instance_);
+  return p != nullptr ? *p : reinterpret_cast<const PROTOBUF_NAMESPACE_ID::MethodOptions&>(
+      PROTOBUF_NAMESPACE_ID::_MethodOptions_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::MethodOptions& MethodDescriptorProto::options() const {
   // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.options)
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
index 6085a12..6da6ba7 100644
--- a/src/google/protobuf/descriptor_unittest.cc
+++ b/src/google/protobuf/descriptor_unittest.cc
@@ -44,7 +44,6 @@
 #include <google/protobuf/unittest_custom_options.pb.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/stringprintf.h>
 #include <google/protobuf/unittest_lazy_dependencies.pb.h>
 #include <google/protobuf/unittest_proto3_arena.pb.h>
@@ -58,6 +57,7 @@
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
+#include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/substitute.h>
 
 
diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc
index b8bceca..2284cdc 100644
--- a/src/google/protobuf/duration.pb.cc
+++ b/src/google/protobuf/duration.pb.cc
@@ -28,7 +28,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::Duration();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::Duration::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Duration_google_2fprotobuf_2fduration_2eproto =
@@ -82,8 +81,6 @@
 
 // ===================================================================
 
-void Duration::InitAsDefaultInstance() {
-}
 class Duration::_Internal {
  public:
 };
diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h
index a530f51..60f4ee1 100644
--- a/src/google/protobuf/duration.pb.h
+++ b/src/google/protobuf/duration.pb.h
@@ -102,7 +102,6 @@
   }
   static const Duration& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const Duration* internal_default_instance() {
     return reinterpret_cast<const Duration*>(
                &_Duration_default_instance_);
diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc
index 2af5109..3d9adc2 100644
--- a/src/google/protobuf/dynamic_message.cc
+++ b/src/google/protobuf/dynamic_message.cc
@@ -292,6 +292,13 @@
   ~DynamicMessage();
 
   // Called on the prototype after construction to initialize message fields.
+  // Cross linking the default instances allows for fast reflection access of
+  // unset message fields. Without it we would have to go to the MessageFactory
+  // to get the prototype, which is a much more expensive operation.
+  //
+  // Generated messages do not cross-link to avoid dynamic initialization of the
+  // global instances.
+  // Instead, they keep the default instances in the FieldDescriptor objects.
   void CrossLinkPrototypes();
 
   // implements Message ----------------------------------------------
diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc
index 27f801f..f30f2c9 100644
--- a/src/google/protobuf/empty.pb.cc
+++ b/src/google/protobuf/empty.pb.cc
@@ -28,7 +28,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::Empty();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::Empty::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Empty_google_2fprotobuf_2fempty_2eproto =
@@ -79,8 +78,6 @@
 
 // ===================================================================
 
-void Empty::InitAsDefaultInstance() {
-}
 class Empty::_Internal {
  public:
 };
diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h
index 17fda94..c87709a 100644
--- a/src/google/protobuf/empty.pb.h
+++ b/src/google/protobuf/empty.pb.h
@@ -102,7 +102,6 @@
   }
   static const Empty& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const Empty* internal_default_instance() {
     return reinterpret_cast<const Empty*>(
                &_Empty_default_instance_);
diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc
index 3b1441e..0dcabb0 100644
--- a/src/google/protobuf/extension_set.cc
+++ b/src/google/protobuf/extension_set.cc
@@ -1870,28 +1870,32 @@
     return;
   }
 
-  const auto old_flat_capacity = flat_capacity_;
-
+  auto new_flat_capacity = flat_capacity_;
   do {
-    flat_capacity_ = flat_capacity_ == 0 ? 1 : flat_capacity_ * 4;
-  } while (flat_capacity_ < minimum_new_capacity);
+    new_flat_capacity = new_flat_capacity == 0 ? 1 : new_flat_capacity * 4;
+  } while (new_flat_capacity < minimum_new_capacity);
 
   const KeyValue* begin = flat_begin();
   const KeyValue* end = flat_end();
-  if (flat_capacity_ > kMaximumFlatCapacity) {
-    // Switch to LargeMap
-    map_.large = Arena::Create<LargeMap>(arena_);
-    LargeMap::iterator hint = map_.large->begin();
+  AllocatedData new_map;
+  if (new_flat_capacity > kMaximumFlatCapacity) {
+    new_map.large = Arena::Create<LargeMap>(arena_);
+    LargeMap::iterator hint = new_map.large->begin();
     for (const KeyValue* it = begin; it != end; ++it) {
-      hint = map_.large->insert(hint, {it->first, it->second});
+      hint = new_map.large->insert(hint, {it->first, it->second});
     }
-    flat_size_ = 0;
   } else {
-    map_.flat = Arena::CreateArray<KeyValue>(arena_, flat_capacity_);
-    std::copy(begin, end, map_.flat);
+    new_map.flat = Arena::CreateArray<KeyValue>(arena_, new_flat_capacity);
+    std::copy(begin, end, new_map.flat);
   }
+
   if (arena_ == nullptr) {
-    DeleteFlatMap(begin, old_flat_capacity);
+    DeleteFlatMap(begin, flat_capacity_);
+  }
+  flat_capacity_ = new_flat_capacity;
+  map_ = new_map;
+  if (is_large()) {
+    flat_size_ = 0;
   }
 }
 
diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc
index e735b3a..4389093 100644
--- a/src/google/protobuf/field_mask.pb.cc
+++ b/src/google/protobuf/field_mask.pb.cc
@@ -28,7 +28,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::FieldMask();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::FieldMask::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_FieldMask_google_2fprotobuf_2ffield_5fmask_2eproto =
@@ -81,8 +80,6 @@
 
 // ===================================================================
 
-void FieldMask::InitAsDefaultInstance() {
-}
 class FieldMask::_Internal {
  public:
 };
diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h
index a493466..cbea34b 100644
--- a/src/google/protobuf/field_mask.pb.h
+++ b/src/google/protobuf/field_mask.pb.h
@@ -102,7 +102,6 @@
   }
   static const FieldMask& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const FieldMask* internal_default_instance() {
     return reinterpret_cast<const FieldMask*>(
                &_FieldMask_default_instance_);
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc
index d8397ed..0db7dfc 100644
--- a/src/google/protobuf/generated_message_reflection.cc
+++ b/src/google/protobuf/generated_message_reflection.cc
@@ -320,15 +320,16 @@
                 break;
               }
 
-              // Initially, the string points to the default value stored
-              // in the prototype. Only count the string if it has been
-              // changed from the default value.
-              const std::string* default_ptr =
-                  &DefaultRaw<ArenaStringPtr>(field).Get();
               const std::string* ptr =
                   &GetField<ArenaStringPtr>(message, field).Get();
 
-              if (ptr != default_ptr) {
+              // Initially, the string points to the default value stored
+              // in the prototype. Only count the string if it has been
+              // changed from the default value.
+              // Except oneof fields, those never point to a default instance,
+              // and there is no default instance to point to.
+              if (schema_.InRealOneof(field) ||
+                  ptr != &DefaultRaw<ArenaStringPtr>(field).Get()) {
                 // string fields are represented by just a pointer, so also
                 // include sizeof(string) as well.
                 total_size +=
@@ -359,8 +360,6 @@
 
 void Reflection::SwapField(Message* message1, Message* message2,
                            const FieldDescriptor* field) const {
-  CheckInvalidAccess(schema_, field);
-
   if (field->is_repeated()) {
     switch (field->cpp_type()) {
 #define SWAP_ARRAYS(CPPTYPE, TYPE)                                 \
@@ -1121,6 +1120,8 @@
     if (field->is_extension()) {                                               \
       return GetExtensionSet(message).Get##TYPENAME(                           \
           field->number(), field->default_value_##PASSTYPE());                 \
+    } else if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { \
+      return field->default_value_##PASSTYPE();                                \
     } else {                                                                   \
       return GetField<TYPE>(message, field);                                   \
     }                                                                          \
@@ -1190,6 +1191,9 @@
     return GetExtensionSet(message).GetString(field->number(),
                                               field->default_value_string());
   } else {
+    if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
+      return field->default_value_string();
+    }
     switch (field->options().ctype()) {
       default:  // TODO(kenton):  Support other string reps.
       case FieldOptions::STRING: {
@@ -1211,6 +1215,9 @@
     return GetExtensionSet(message).GetString(field->number(),
                                               field->default_value_string());
   } else {
+    if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
+      return field->default_value_string();
+    }
     switch (field->options().ctype()) {
       default:  // TODO(kenton):  Support other string reps.
       case FieldOptions::STRING: {
@@ -1241,16 +1248,21 @@
           break;
         }
 
+        // Oneof string fields are never set as a default instance.
+        // We just need to pass some arbitrary default string to make it work.
+        // This allows us to not have the real default accessible from
+        // reflection.
         const std::string* default_ptr =
-            &DefaultRaw<ArenaStringPtr>(field).Get();
+            schema_.InRealOneof(field)
+                ? &GetEmptyString()
+                : &DefaultRaw<ArenaStringPtr>(field).Get();
         if (schema_.InRealOneof(field) && !HasOneofField(*message, field)) {
           ClearOneof(message, field->containing_oneof());
           MutableField<ArenaStringPtr>(message, field)
               ->UnsafeSetDefault(default_ptr);
         }
         MutableField<ArenaStringPtr>(message, field)
-            ->Mutable(default_ptr, GetArena(message))
-            ->assign(std::move(value));
+            ->Set(default_ptr, std::move(value), GetArena(message));
         break;
       }
     }
@@ -1342,6 +1354,8 @@
   if (field->is_extension()) {
     value = GetExtensionSet(message).GetEnum(
         field->number(), field->default_value_enum()->number());
+  } else if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
+    value = field->default_value_enum()->number();
   } else {
     value = GetField<int>(message, field);
   }
@@ -1476,6 +1490,40 @@
 
 // -------------------------------------------------------------------
 
+const Message* Reflection::GetDefaultMessageInstance(
+    const FieldDescriptor* field) const {
+  // If we are using the generated factory, we cache the prototype in the field
+  // descriptor for faster access.
+  // The default instances of generated messages are not cross-linked, which
+  // means they contain null pointers on their message fields and can't be used
+  // to get the default of submessages.
+  if (message_factory_ == MessageFactory::generated_factory()) {
+    auto& ptr = field->default_generated_instance_;
+    auto* res = ptr.load(std::memory_order_acquire);
+    if (res == nullptr) {
+      // First time asking for this field's default. Load it and cache it.
+      res = message_factory_->GetPrototype(field->message_type());
+      ptr.store(res, std::memory_order_release);
+    }
+    return res;
+  }
+
+  // For other factories, we try the default's object field.
+  // In particular, the DynamicMessageFactory will cross link the default
+  // instances to allow for this. But only do this for real fields.
+  // This is an optimization to avoid going to GetPrototype() below, as that
+  // requires a lock and a map lookup.
+  if (!field->is_extension() && !field->options().weak() &&
+      !field->options().lazy() && !schema_.InRealOneof(field)) {
+    auto* res = DefaultRaw<const Message*>(field);
+    if (res != nullptr) {
+      return res;
+    }
+  }
+  // Otherwise, just go to the factory.
+  return message_factory_->GetPrototype(field->message_type());
+}
+
 const Message& Reflection::GetMessage(const Message& message,
                                       const FieldDescriptor* field,
                                       MessageFactory* factory) const {
@@ -1488,9 +1536,12 @@
     return static_cast<const Message&>(GetExtensionSet(message).GetMessage(
         field->number(), field->message_type(), factory));
   } else {
+    if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
+      return *GetDefaultMessageInstance(field);
+    }
     const Message* result = GetRaw<const Message*>(message, field);
     if (result == nullptr) {
-      result = DefaultRaw<const Message*>(field);
+      result = GetDefaultMessageInstance(field);
     }
     return *result;
   }
@@ -1516,7 +1567,7 @@
       if (!HasOneofField(*message, field)) {
         ClearOneof(message, field->containing_oneof());
         result_holder = MutableField<Message*>(message, field);
-        const Message* default_message = DefaultRaw<const Message*>(field);
+        const Message* default_message = GetDefaultMessageInstance(field);
         *result_holder = default_message->New(message->GetArena());
       }
     } else {
@@ -1524,7 +1575,7 @@
     }
 
     if (*result_holder == nullptr) {
-      const Message* default_message = DefaultRaw<const Message*>(field);
+      const Message* default_message = GetDefaultMessageInstance(field);
       *result_holder = default_message->New(message->GetArena());
     }
     result = *result_holder;
@@ -1903,9 +1954,8 @@
 template <typename Type>
 const Type& Reflection::GetRaw(const Message& message,
                                const FieldDescriptor* field) const {
-  if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
-    return DefaultRaw<Type>(field);
-  }
+  GOOGLE_DCHECK(!schema_.InRealOneof(field) || HasOneofField(message, field))
+      << "Field = " << field->full_name();
   return GetConstRefAtOffset<Type>(message, schema_.GetFieldOffset(field));
 }
 
@@ -2112,8 +2162,11 @@
           switch (field->options().ctype()) {
             default:  // TODO(kenton):  Support other string reps.
             case FieldOptions::STRING: {
-              const std::string* default_ptr =
-                  &DefaultRaw<ArenaStringPtr>(field).Get();
+              // Oneof string fields are never set as a default instance.
+              // We just need to pass some arbitrary default string to make it
+              // work. This allows us to not have the real default accessible
+              // from reflection.
+              const std::string* default_ptr = &GetEmptyString();
               MutableField<ArenaStringPtr>(message, field)
                   ->Destroy(default_ptr, GetArena(message));
               break;
diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h
index cb2ae35..1c28495 100644
--- a/src/google/protobuf/generated_message_reflection.h
+++ b/src/google/protobuf/generated_message_reflection.h
@@ -212,6 +212,12 @@
            OffsetValue(offsets_[field->index()], field->type());
   }
 
+  // Returns true if the field's accessor is called by any external code (aka,
+  // non proto library code).
+  bool IsFieldUsed(const FieldDescriptor* field) const {
+    return true;
+  }
+
   bool IsFieldStripped(const FieldDescriptor* field) const {
     return false;
   }
@@ -242,6 +248,7 @@
   // We tag offset values to provide additional data about fields (such as
   // inlined).
   static uint32 OffsetValue(uint32 v, FieldDescriptor::Type type) {
+    v &= 0x7FFFFFFFu;
     if (type == FieldDescriptor::TYPE_STRING ||
         type == FieldDescriptor::TYPE_BYTES) {
       return v & ~1u;
@@ -296,6 +303,13 @@
   const ServiceDescriptor** file_level_service_descriptors;
 };
 
+enum {
+  // Tag used on offsets for fields that don't have a real offset.
+  // For example, weak message fields go into the WeakFieldMap and not in an
+  // actual field.
+  kInvalidFieldOffsetTag = 0x40000000u,
+};
+
 // AssignDescriptors() pulls the compiled FileDescriptor from the DescriptorPool
 // and uses it to populate all of the global variables which store pointers to
 // the descriptor objects.  It also constructs the reflection objects.  It is
diff --git a/src/google/protobuf/generated_message_reflection_unittest.cc b/src/google/protobuf/generated_message_reflection_unittest.cc
index 1c9d408..7234f5f 100644
--- a/src/google/protobuf/generated_message_reflection_unittest.cc
+++ b/src/google/protobuf/generated_message_reflection_unittest.cc
@@ -486,6 +486,7 @@
                   ->FindKnownExtensionByName(extension1->full_name()) == NULL);
 }
 
+
 TEST(GeneratedMessageReflectionTest, SetAllocatedMessageTest) {
   unittest::TestAllTypes from_message1;
   unittest::TestAllTypes from_message2;
diff --git a/src/google/protobuf/io/zero_copy_stream_impl.h b/src/google/protobuf/io/zero_copy_stream_impl.h
index b23a86d..6e5cdeb 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl.h
+++ b/src/google/protobuf/io/zero_copy_stream_impl.h
@@ -48,7 +48,6 @@
 #include <google/protobuf/io/zero_copy_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 
-
 #include <google/protobuf/port_def.inc>
 
 namespace google {
diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
index 51cda2a..34bf45f 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
+++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
@@ -140,29 +140,25 @@
 
 bool StringOutputStream::Next(void** data, int* size) {
   GOOGLE_CHECK(target_ != NULL);
-  int old_size = target_->size();
+  size_t old_size = target_->size();
 
   // Grow the string.
+  size_t new_size;
   if (old_size < target_->capacity()) {
     // Resize the string to match its capacity, since we can get away
     // without a memory allocation this way.
-    STLStringResizeUninitialized(target_, target_->capacity());
+    new_size = target_->capacity();
   } else {
-    // Size has reached capacity, try to double the size.
-    if (old_size > std::numeric_limits<int>::max() / 2) {
-      // Can not double the size otherwise it is going to cause integer
-      // overflow in the expression below: old_size * 2 ";
-      GOOGLE_LOG(ERROR) << "Cannot allocate buffer larger than kint32max for "
-                 << "StringOutputStream.";
-      return false;
-    }
-    // Double the size, also make sure that the new size is at least
-    // kMinimumSize.
-    STLStringResizeUninitialized(
-        target_,
-        std::max(old_size * 2,
-                 kMinimumSize + 0));  // "+ 0" works around GCC4 weirdness.
+    // Size has reached capacity, try to double it.
+    new_size = old_size * 2;
   }
+  // Avoid integer overflow in returned '*size'.
+  new_size = std::min(new_size, old_size + std::numeric_limits<int>::max());
+  // Increase the size, also make sure that it is at least kMinimumSize.
+  STLStringResizeUninitialized(
+      target_,
+      std::max(new_size,
+               kMinimumSize + 0));  // "+ 0" works around GCC4 weirdness.
 
   *data = mutable_string_data(target_) + old_size;
   *size = target_->size() - old_size;
diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/src/google/protobuf/io/zero_copy_stream_impl_lite.h
index 26572cc..2f0c662 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl_lite.h
+++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.h
@@ -150,7 +150,7 @@
   int64_t ByteCount() const override;
 
  private:
-  static const int kMinimumSize = 16;
+  static constexpr size_t kMinimumSize = 16;
 
   std::string* target_;
 
diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc
index bec9df0..b0f84fb 100644
--- a/src/google/protobuf/io/zero_copy_stream_unittest.cc
+++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc
@@ -712,6 +712,21 @@
   }
 }
 
+// Verifies that outputs up to kint32max can be created.
+TEST_F(IoTest, LargeOutput) {
+  std::string str;
+  StringOutputStream output(&str);
+  void* unused_data;
+  int size;
+  // Repeatedly calling Next should eventually grow the buffer to kint32max.
+  do {
+    EXPECT_TRUE(output.Next(&unused_data, &size));
+  } while (str.size() < std::numeric_limits<int>::max());
+  // Further increases should be possible.
+  output.Next(&unused_data, &size);
+  EXPECT_GT(size, 0);
+}
+
 
 // To test files, we create a temporary file, write, read, truncate, repeat.
 TEST_F(IoTest, FileIo) {
diff --git a/src/google/protobuf/map.cc b/src/google/protobuf/map.cc
new file mode 100644
index 0000000..d60a9a2
--- /dev/null
+++ b/src/google/protobuf/map.cc
@@ -0,0 +1,41 @@
+// 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.
+
+#include <google/protobuf/map.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+void* const kGlobalEmptyTable[kGlobalEmptyTableSize] = {nullptr};
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h
index c3cfb43..c25f334 100644
--- a/src/google/protobuf/map.h
+++ b/src/google/protobuf/map.h
@@ -182,7 +182,7 @@
 
  private:
   using DestructorSkippable_ = void;
-  Arena* const arena_;
+  Arena* arena_;
 };
 
 template <typename T>
@@ -280,6 +280,9 @@
   return message.SpaceUsedLong() - sizeof(T);
 }
 
+constexpr size_t kGlobalEmptyTableSize = 1;
+PROTOBUF_EXPORT extern void* const kGlobalEmptyTable[kGlobalEmptyTableSize];
+
 // Space used for the table, trees, and nodes.
 // Does not include the indirect space used. Eg the data of a std::string.
 template <typename Key>
@@ -377,24 +380,22 @@
   using size_type = size_t;
   using hasher = typename internal::TransparentSupport<Key>::hash;
 
-  Map() : arena_(nullptr) { Init(); }
-  explicit Map(Arena* arena) : arena_(arena) { Init(); }
+  Map() : elements_(nullptr) {}
+  explicit Map(Arena* arena) : elements_(arena) {}
 
-  Map(const Map& other) : arena_(nullptr) {
-    Init();
-    insert(other.begin(), other.end());
-  }
+  Map(const Map& other) : Map() { insert(other.begin(), other.end()); }
 
   Map(Map&& other) noexcept : Map() {
-    if (other.arena_) {
+    if (other.arena() != nullptr) {
       *this = other;
     } else {
       swap(other);
     }
   }
+
   Map& operator=(Map&& other) noexcept {
     if (this != &other) {
-      if (arena_ != other.arena_) {
+      if (arena() != other.arena()) {
         *this = other;
       } else {
         swap(other);
@@ -404,21 +405,13 @@
   }
 
   template <class InputIt>
-  Map(const InputIt& first, const InputIt& last) : arena_(nullptr) {
-    Init();
+  Map(const InputIt& first, const InputIt& last) : Map() {
     insert(first, last);
   }
 
-  ~Map() {
-    if (arena_ == nullptr) {
-      clear();
-      delete elements_;
-    }
-  }
+  ~Map() {}
 
  private:
-  void Init() { elements_ = Arena::CreateMessage<InnerMap>(arena_, 0); }
-
   using Allocator = internal::MapAllocator<void*>;
 
   // InnerMap is a generic hash-based map.  It doesn't contain any
@@ -455,20 +448,18 @@
   //    otherwise. This avoids unncessary copies of string keys, for example.
   class InnerMap : private hasher {
    public:
-    explicit InnerMap(size_type n) : InnerMap(nullptr, n) {}
-    InnerMap(Arena* arena, size_type n)
+    explicit InnerMap(Arena* arena)
         : hasher(),
           num_elements_(0),
+          num_buckets_(internal::kGlobalEmptyTableSize),
           seed_(Seed()),
-          table_(nullptr),
-          alloc_(arena) {
-      n = TableSize(n);
-      table_ = CreateEmptyTable(n);
-      num_buckets_ = index_of_first_non_null_ = n;
-    }
+          index_of_first_non_null_(num_buckets_),
+          table_(const_cast<void**>(internal::kGlobalEmptyTable)),
+          alloc_(arena) {}
 
     ~InnerMap() {
-      if (table_ != nullptr) {
+      if (alloc_.arena() == nullptr &&
+          num_buckets_ != internal::kGlobalEmptyTableSize) {
         clear();
         Dealloc<void*>(table_, num_buckets_);
       }
@@ -627,6 +618,17 @@
     using iterator = iterator_base<value_type>;
     using const_iterator = iterator_base<const value_type>;
 
+    Arena* arena() const { return alloc_.arena(); }
+
+    void Swap(InnerMap* other) {
+      std::swap(num_elements_, other->num_elements_);
+      std::swap(num_buckets_, other->num_buckets_);
+      std::swap(seed_, other->seed_);
+      std::swap(index_of_first_non_null_, other->index_of_first_non_null_);
+      std::swap(table_, other->table_);
+      std::swap(alloc_, other->alloc_);
+    }
+
     iterator begin() { return iterator(this); }
     iterator end() { return iterator(); }
     const_iterator begin() const { return const_iterator(this); }
@@ -676,6 +678,11 @@
       return iterator(FindHelper(k).first);
     }
 
+    template <typename K>
+    const_iterator find(const K& k) const {
+      return FindHelper(k).first;
+    }
+
     // Insert the key into the map, if not present. In that case, the value will
     // be value initialized.
     std::pair<iterator, bool> insert(const Key& k) {
@@ -895,6 +902,14 @@
 
     // Resize to the given number of buckets.
     void Resize(size_t new_num_buckets) {
+      if (num_buckets_ == internal::kGlobalEmptyTableSize) {
+        // This is the global empty array.
+        // Just overwrite with a new one. No need to transfer or free anything.
+        num_buckets_ = index_of_first_non_null_ = kMinTableSize;
+        table_ = CreateEmptyTable(num_buckets_);
+        return;
+      }
+
       GOOGLE_DCHECK_GE(new_num_buckets, kMinTableSize);
       void** const old_table = table_;
       const size_type old_table_size = num_buckets_;
@@ -1057,7 +1072,7 @@
 #if defined(__x86_64__) && defined(__GNUC__) && \
     !defined(GOOGLE_PROTOBUF_NO_RDTSC)
       uint32 hi, lo;
-      asm("rdtsc" : "=a"(lo), "=d"(hi));
+      asm volatile("rdtsc" : "=a"(lo), "=d"(hi));
       s += ((static_cast<uint64>(hi) << 32) | lo);
 #endif
       return s;
@@ -1155,23 +1170,19 @@
     InnerIt it_;
   };
 
-  iterator begin() { return iterator(elements_->begin()); }
-  iterator end() { return iterator(elements_->end()); }
-  const_iterator begin() const {
-    return const_iterator(iterator(elements_->begin()));
-  }
-  const_iterator end() const {
-    return const_iterator(iterator(elements_->end()));
-  }
+  iterator begin() { return iterator(elements_.begin()); }
+  iterator end() { return iterator(elements_.end()); }
+  const_iterator begin() const { return const_iterator(elements_.begin()); }
+  const_iterator end() const { return const_iterator(elements_.end()); }
   const_iterator cbegin() const { return begin(); }
   const_iterator cend() const { return end(); }
 
   // Capacity
-  size_type size() const { return elements_->size(); }
+  size_type size() const { return elements_.size(); }
   bool empty() const { return size() == 0; }
 
   // Element access
-  T& operator[](const key_type& key) { return (*elements_)[key].second; }
+  T& operator[](const key_type& key) { return elements_[key].second; }
 
   template <typename K = key_type>
   const T& at(const key_arg<K>& key) const {
@@ -1195,11 +1206,11 @@
 
   template <typename K = key_type>
   const_iterator find(const key_arg<K>& key) const {
-    return const_iterator(iterator(elements_->find(key)));
+    return const_iterator(elements_.find(key));
   }
   template <typename K = key_type>
   iterator find(const key_arg<K>& key) {
-    return iterator(elements_->find(key));
+    return iterator(elements_.find(key));
   }
 
   template <typename K = key_type>
@@ -1233,7 +1244,7 @@
   // insert
   std::pair<iterator, bool> insert(const value_type& value) {
     std::pair<typename InnerMap::iterator, bool> p =
-        elements_->insert(value.first);
+        elements_.insert(value.first);
     if (p.second) {
       p.first->second = value.second;
     }
@@ -1265,7 +1276,7 @@
   }
   iterator erase(iterator pos) {
     iterator i = pos++;
-    elements_->erase(i.it_);
+    elements_.erase(i.it_);
     return pos;
   }
   void erase(iterator first, iterator last) {
@@ -1273,7 +1284,7 @@
       first = erase(first);
     }
   }
-  void clear() { elements_->clear(); }
+  void clear() { elements_.clear(); }
 
   // Assign
   Map& operator=(const Map& other) {
@@ -1285,8 +1296,8 @@
   }
 
   void swap(Map& other) {
-    if (arena_ == other.arena_) {
-      std::swap(elements_, other.elements_);
+    if (arena() == other.arena()) {
+      elements_.Swap(&other.elements_);
     } else {
       // TODO(zuguang): optimize this. The temporary copy can be allocated
       // in the same arena as the other message, and the "other = copy" can
@@ -1299,16 +1310,16 @@
 
   // Access to hasher.  Currently this returns a copy, but it may
   // be modified to return a const reference in the future.
-  hasher hash_function() const { return elements_->hash_function(); }
+  hasher hash_function() const { return elements_.hash_function(); }
 
   size_t SpaceUsedExcludingSelfLong() const {
-    return sizeof(InnerMap) + elements_->SpaceUsedInternal() +
-           internal::SpaceUsedInValues(this);
+    if (empty()) return 0;
+    return elements_.SpaceUsedInternal() + internal::SpaceUsedInValues(this);
   }
 
  private:
-  Arena* arena_;
-  InnerMap* elements_;
+  Arena* arena() const { return elements_.arena(); }
+  InnerMap elements_;
 
   friend class Arena;
   using InternalArenaConstructable_ = void;
diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h
index 6b5d4e8..92cb4ac 100644
--- a/src/google/protobuf/map_entry_lite.h
+++ b/src/google/protobuf/map_entry_lite.h
@@ -206,8 +206,7 @@
     return KeyTypeHandler::GetExternalReference(key_);
   }
   virtual inline const ValueMapEntryAccessorType& value() const {
-    return ValueTypeHandler::DefaultIfNotInitialized(
-        value_, Derived::internal_default_instance()->value_);
+    return ValueTypeHandler::DefaultIfNotInitialized(value_);
   }
   inline KeyMapEntryAccessorType* mutable_key() {
     set_has_key();
@@ -323,12 +322,6 @@
     clear_has_value();
   }
 
-  static void InitAsDefaultInstance() {
-    Derived* d = const_cast<Derived*>(Derived::internal_default_instance());
-    KeyTypeHandler::AssignDefaultValue(&d->key_);
-    ValueTypeHandler::AssignDefaultValue(&d->value_);
-  }
-
   // Parsing using MergePartialFromCodedStream, above, is not as
   // efficient as it could be.  This helper class provides a speedier way.
   template <typename MapField, typename Map>
diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h
index efca5ee..6a28b6e 100644
--- a/src/google/protobuf/map_field.h
+++ b/src/google/protobuf/map_field.h
@@ -264,6 +264,53 @@
   int type_;
 };
 
+}  // namespace protobuf
+}  // namespace google
+namespace std {
+template <>
+struct hash<::PROTOBUF_NAMESPACE_ID::MapKey> {
+  size_t operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key) const {
+    switch (map_key.type()) {
+      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_DOUBLE:
+      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_FLOAT:
+      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_ENUM:
+      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_MESSAGE:
+        GOOGLE_LOG(FATAL) << "Unsupported";
+        break;
+      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_STRING:
+        return hash<std::string>()(map_key.GetStringValue());
+      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT64: {
+        auto value = map_key.GetInt64Value();
+        return hash<decltype(value)>()(value);
+      }
+      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT32: {
+        auto value = map_key.GetInt32Value();
+        return hash<decltype(value)>()(map_key.GetInt32Value());
+      }
+      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT64: {
+        auto value = map_key.GetUInt64Value();
+        return hash<decltype(value)>()(map_key.GetUInt64Value());
+      }
+      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT32: {
+        auto value = map_key.GetUInt32Value();
+        return hash<decltype(value)>()(map_key.GetUInt32Value());
+      }
+      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_BOOL: {
+        return hash<bool>()(map_key.GetBoolValue());
+      }
+    }
+    GOOGLE_LOG(FATAL) << "Can't get here.";
+    return 0;
+  }
+  bool operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key1,
+                  const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key2) const {
+    return map_key1 < map_key2;
+  }
+};
+}  // namespace std
+
+namespace google {
+namespace protobuf {
 namespace internal {
 
 class ContendedMapCleanTest;
@@ -791,48 +838,6 @@
 }  // namespace protobuf
 }  // namespace google
 
-namespace std {
-template <>
-struct hash<::PROTOBUF_NAMESPACE_ID::MapKey> {
-  size_t operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key) const {
-    switch (map_key.type()) {
-      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_DOUBLE:
-      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_FLOAT:
-      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_ENUM:
-      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_MESSAGE:
-        GOOGLE_LOG(FATAL) << "Unsupported";
-        break;
-      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_STRING:
-        return hash<std::string>()(map_key.GetStringValue());
-      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT64: {
-        auto value = map_key.GetInt64Value();
-        return hash<decltype(value)>()(value);
-      }
-      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT32: {
-        auto value = map_key.GetInt32Value();
-        return hash<decltype(value)>()(map_key.GetInt32Value());
-      }
-      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT64: {
-        auto value = map_key.GetUInt64Value();
-        return hash<decltype(value)>()(map_key.GetUInt64Value());
-      }
-      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT32: {
-        auto value = map_key.GetUInt32Value();
-        return hash<decltype(value)>()(map_key.GetUInt32Value());
-      }
-      case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_BOOL: {
-        return hash<bool>()(map_key.GetBoolValue());
-      }
-    }
-    GOOGLE_LOG(FATAL) << "Can't get here.";
-    return 0;
-  }
-  bool operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key1,
-                  const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key2) const {
-    return map_key1 < map_key2;
-  }
-};
-}  // namespace std
 #include <google/protobuf/port_undef.inc>
 
 #endif  // GOOGLE_PROTOBUF_MAP_FIELD_H__
diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h
index db0ddc9..240903b 100644
--- a/src/google/protobuf/map_field_lite.h
+++ b/src/google/protobuf/map_field_lite.h
@@ -85,7 +85,7 @@
   // Used in the implementation of parsing. Caller should take the ownership iff
   // arena_ is NULL.
   EntryType* NewEntry() const {
-    return Arena::CreateMessage<EntryType>(map_.arena_);
+    return Arena::CreateMessage<EntryType>(map_.arena());
   }
   // Used in the implementation of serializing enum value type. Caller should
   // take the ownership iff arena_ is NULL.
diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc
index 9256f0e..3eb46a0 100644
--- a/src/google/protobuf/map_test.cc
+++ b/src/google/protobuf/map_test.cc
@@ -982,13 +982,10 @@
 
 TEST_F(MapImplTest, SpaceUsed) {
   constexpr size_t kMinCap = 8;
-  constexpr size_t kInnerMapOverhead = sizeof(size_t) * 4 + sizeof(void*) * 2;
 
   Map<int32, int32> m;
-  // To check the current overhead of an empty map.
-  // Ideally this should be zero.
-  EXPECT_EQ(m.SpaceUsedExcludingSelfLong(),
-            sizeof(void*) * kMinCap + kInnerMapOverhead);
+  // An newly constructed map should have no space used.
+  EXPECT_EQ(m.SpaceUsedExcludingSelfLong(), 0);
 
   size_t capacity = kMinCap;
   for (int i = 0; i < 100; ++i) {
@@ -998,7 +995,7 @@
       capacity *= 2;
     }
     EXPECT_EQ(m.SpaceUsedExcludingSelfLong(),
-              sizeof(void*) * capacity + kInnerMapOverhead +
+              sizeof(void*) * capacity +
                   m.size() * sizeof(std::pair<std::pair<int32, int32>, void*>));
   }
 
@@ -1007,7 +1004,7 @@
   std::string str = "Some arbitrarily large string";
   m2[str] = 1;
   EXPECT_EQ(m2.SpaceUsedExcludingSelfLong(),
-            sizeof(void*) * kMinCap + kInnerMapOverhead +
+            sizeof(void*) * kMinCap +
                 sizeof(std::pair<std::pair<std::string, int32>, void*>) +
                 internal::StringSpaceUsedExcludingSelfLong(str));
 
@@ -1015,7 +1012,7 @@
   Map<int32, TestAllTypes> m3;
   m3[0].set_optional_string(str);
   EXPECT_EQ(m3.SpaceUsedExcludingSelfLong(),
-            sizeof(void*) * kMinCap + kInnerMapOverhead +
+            sizeof(void*) * kMinCap +
                 sizeof(std::pair<std::pair<int32, TestAllTypes>, void*>) +
                 m3[0].SpaceUsedLong() - sizeof(m3[0]));
 }
diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h
index aba35be..7908544 100644
--- a/src/google/protobuf/map_type_handler.h
+++ b/src/google/protobuf/map_type_handler.h
@@ -163,12 +163,9 @@
   // SpaceUsedInMapEntry: Return bytes used by value in MapEntry, excluding
   // those already calculate in sizeof(MapField).
   static inline size_t SpaceUsedInMapEntryLong(const Type* value);
-  // Assign default value to given instance.
-  static inline void AssignDefaultValue(Type** value);
   // Return default instance if value is not initialized when calling const
   // reference accessor.
-  static inline const Type& DefaultIfNotInitialized(const Type* value,
-                                                    const Type* default_value);
+  static inline const Type& DefaultIfNotInitialized(const Type* value);
   // Check if all required fields have values set.
   static inline bool IsInitialized(Type* value);
 };
@@ -206,9 +203,8 @@
                              TypeOnMemory* to, Arena* arena);                 \
     static inline void Clear(TypeOnMemory* value, Arena* arena);              \
     static inline size_t SpaceUsedInMapEntryLong(const TypeOnMemory& value);  \
-    static inline void AssignDefaultValue(TypeOnMemory* value);               \
     static inline const MapEntryAccessorType& DefaultIfNotInitialized(        \
-        const TypeOnMemory& value, const TypeOnMemory& default_value);        \
+        const TypeOnMemory& value);                                           \
     static inline bool IsInitialized(const TypeOnMemory& value);              \
     static void DeleteNoArena(TypeOnMemory& value);                           \
     static inline void Initialize(TypeOnMemory* value, Arena* arena);         \
@@ -526,12 +522,6 @@
 }
 
 template <typename Type>
-inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
-                           Type>::AssignDefaultValue(Type** value) {
-  *value = const_cast<Type*>(Type::internal_default_instance());
-}
-
-template <typename Type>
 inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Initialize(
     Type** x, Arena* /* arena */) {
   *x = NULL;
@@ -551,8 +541,8 @@
 template <typename Type>
 inline const Type&
 MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::DefaultIfNotInitialized(
-    const Type* value, const Type* default_value) {
-  return value != NULL ? *value : *default_value;
+    const Type* value) {
+  return value != NULL ? *value : *Type::internal_default_instance();
 }
 
 template <typename Type>
@@ -594,10 +584,6 @@
   }                                                                           \
   template <typename Type>                                                    \
   inline void                                                                 \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::AssignDefaultValue( \
-      TypeOnMemory* /* value */) {}                                           \
-  template <typename Type>                                                    \
-  inline void                                                                 \
   MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Initialize(         \
       TypeOnMemory* value, Arena* /* arena */) {                              \
     value->UnsafeSetDefault(&internal::GetEmptyStringAlreadyInited());        \
@@ -612,9 +598,8 @@
   template <typename Type>                                                    \
   inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType,      \
                                        Type>::MapEntryAccessorType&           \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::                    \
-      DefaultIfNotInitialized(const TypeOnMemory& value,                      \
-                              const TypeOnMemory& /* default_value */) {      \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType,                            \
+                 Type>::DefaultIfNotInitialized(const TypeOnMemory& value) {  \
     return value.Get();                                                       \
   }                                                                           \
   template <typename Type>                                                    \
@@ -627,63 +612,58 @@
 STRING_OR_BYTES_HANDLER_FUNCTIONS(BYTES)
 #undef STRING_OR_BYTES_HANDLER_FUNCTIONS
 
-#define PRIMITIVE_HANDLER_FUNCTIONS(FieldType)                                \
-  template <typename Type>                                                    \
-  inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType,      \
-                                       Type>::MapEntryAccessorType&           \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType,                            \
-                 Type>::GetExternalReference(const TypeOnMemory& value) {     \
-    return value;                                                             \
-  }                                                                           \
-  template <typename Type>                                                    \
-  inline size_t MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::      \
-      SpaceUsedInMapEntryLong(const TypeOnMemory& /* value */) {              \
-    return 0;                                                                 \
-  }                                                                           \
-  template <typename Type>                                                    \
-  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Clear(  \
-      TypeOnMemory* value, Arena* /* arena */) {                              \
-    *value = 0;                                                               \
-  }                                                                           \
-  template <typename Type>                                                    \
-  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Merge(  \
-      const MapEntryAccessorType& from, TypeOnMemory* to,                     \
-      Arena* /* arena */) {                                                   \
-    *to = from;                                                               \
-  }                                                                           \
-  template <typename Type>                                                    \
-  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType,                \
-                             Type>::DeleteNoArena(TypeOnMemory& /* x */) {}   \
-  template <typename Type>                                                    \
-  inline void                                                                 \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::AssignDefaultValue( \
-      TypeOnMemory* /* value */) {}                                           \
-  template <typename Type>                                                    \
-  inline void                                                                 \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Initialize(         \
-      TypeOnMemory* value, Arena* /* arena */) {                              \
-    *value = 0;                                                               \
-  }                                                                           \
-  template <typename Type>                                                    \
-  inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType,            \
-                                 Type>::MapEntryAccessorType*                 \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable(      \
-      TypeOnMemory* value, Arena* /* arena */) {                              \
-    return value;                                                             \
-  }                                                                           \
-  template <typename Type>                                                    \
-  inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType,      \
-                                       Type>::MapEntryAccessorType&           \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::                    \
-      DefaultIfNotInitialized(const TypeOnMemory& value,                      \
-                              const TypeOnMemory& /* default_value */) {      \
-    return value;                                                             \
-  }                                                                           \
-  template <typename Type>                                                    \
-  inline bool                                                                 \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::IsInitialized(      \
-      const TypeOnMemory& /* value */) {                                      \
-    return true;                                                              \
+#define PRIMITIVE_HANDLER_FUNCTIONS(FieldType)                               \
+  template <typename Type>                                                   \
+  inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType,     \
+                                       Type>::MapEntryAccessorType&          \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType,                           \
+                 Type>::GetExternalReference(const TypeOnMemory& value) {    \
+    return value;                                                            \
+  }                                                                          \
+  template <typename Type>                                                   \
+  inline size_t MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::     \
+      SpaceUsedInMapEntryLong(const TypeOnMemory& /* value */) {             \
+    return 0;                                                                \
+  }                                                                          \
+  template <typename Type>                                                   \
+  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Clear( \
+      TypeOnMemory* value, Arena* /* arena */) {                             \
+    *value = 0;                                                              \
+  }                                                                          \
+  template <typename Type>                                                   \
+  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Merge( \
+      const MapEntryAccessorType& from, TypeOnMemory* to,                    \
+      Arena* /* arena */) {                                                  \
+    *to = from;                                                              \
+  }                                                                          \
+  template <typename Type>                                                   \
+  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType,               \
+                             Type>::DeleteNoArena(TypeOnMemory& /* x */) {}  \
+  template <typename Type>                                                   \
+  inline void                                                                \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Initialize(        \
+      TypeOnMemory* value, Arena* /* arena */) {                             \
+    *value = 0;                                                              \
+  }                                                                          \
+  template <typename Type>                                                   \
+  inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType,           \
+                                 Type>::MapEntryAccessorType*                \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable(     \
+      TypeOnMemory* value, Arena* /* arena */) {                             \
+    return value;                                                            \
+  }                                                                          \
+  template <typename Type>                                                   \
+  inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType,     \
+                                       Type>::MapEntryAccessorType&          \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType,                           \
+                 Type>::DefaultIfNotInitialized(const TypeOnMemory& value) { \
+    return value;                                                            \
+  }                                                                          \
+  template <typename Type>                                                   \
+  inline bool                                                                \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::IsInitialized(     \
+      const TypeOnMemory& /* value */) {                                     \
+    return true;                                                             \
   }
 PRIMITIVE_HANDLER_FUNCTIONS(INT64)
 PRIMITIVE_HANDLER_FUNCTIONS(UINT64)
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc
index cfea396..fde10cf 100644
--- a/src/google/protobuf/message.cc
+++ b/src/google/protobuf/message.cc
@@ -162,6 +162,10 @@
   return GetReflection()->SpaceUsedLong(*this);
 }
 
+size_t Message::GetInvariantPerBuild(size_t salt) {
+  return salt;
+}
+
 // =============================================================================
 // MessageFactory
 
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index 24b48de..d0ca036 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -170,6 +170,9 @@
 namespace internal {
 class MapFieldPrinterHelper;  // text_format.cc
 }
+namespace util {
+class MessageDifferencer;
+}
 
 
 namespace internal {
@@ -362,6 +365,9 @@
   inline explicit Message(Arena* arena) : MessageLite(arena) {}
 
 
+ protected:
+  static size_t GetInvariantPerBuild(size_t salt);
+
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message);
 };
@@ -945,6 +951,7 @@
   friend class ::PROTOBUF_NAMESPACE_ID::AssignDescriptorsHelper;
   friend class DynamicMessageFactory;
   friend class python::MapReflectionFriend;
+  friend class util::MessageDifferencer;
 #define GOOGLE_PROTOBUF_HAS_CEL_MAP_REFLECTION_FRIEND
   friend class expr::CelMapReflectionFriend;
   friend class internal::MapFieldReflectionTest;
@@ -1020,6 +1027,8 @@
   template <typename Type>
   const Type& DefaultRaw(const FieldDescriptor* field) const;
 
+  const Message* GetDefaultMessageInstance(const FieldDescriptor* field) const;
+
   inline const uint32* GetHasBits(const Message& message) const;
   inline uint32* MutableHasBits(Message* message) const;
   inline uint32 GetOneofCase(const Message& message,
diff --git a/src/google/protobuf/message_unittest.inc b/src/google/protobuf/message_unittest.inc
index 4b95043..1b0aa33 100644
--- a/src/google/protobuf/message_unittest.inc
+++ b/src/google/protobuf/message_unittest.inc
@@ -48,7 +48,6 @@
 
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/test_util2.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/zero_copy_stream.h>
@@ -59,6 +58,7 @@
 #include <google/protobuf/generated_message_reflection.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
+#include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/io/io_win32.h>
 
 
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index 07800f5..c1c4774 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -334,13 +334,12 @@
   int total_size_;
   struct Rep {
     Arena* arena;
-    Element elements[1];
+    // Here we declare a huge array as a way of approximating C's "flexible
+    // array member" feature without relying on undefined behavior.
+    Element elements[(std::numeric_limits<int>::max() - 2 * sizeof(Arena*)) /
+                     sizeof(Element)];
   };
-  // We can not use sizeof(Rep) - sizeof(Element) due to the trailing padding on
-  // the struct. We can not use sizeof(Arena*) as well because there might be
-  // a "gap" after the field arena and before the field elements (e.g., when
-  // Element is double and pointer is 32bit).
-  static const size_t kRepHeaderSize;
+  static constexpr size_t kRepHeaderSize = offsetof(Rep, elements);
 
   // If total_size_ == 0 this points to an Arena otherwise it points to the
   // elements member of a Rep struct. Using this invariant allows the storage of
@@ -381,14 +380,14 @@
   void CopyArray(Element* to, const Element* from, int size);
 
   // Internal helper to delete all elements and deallocate the storage.
-  // If Element has a trivial destructor (for example, if it's a fundamental
-  // type, like int32), the loop will be removed by the optimizer.
   void InternalDeallocate(Rep* rep, int size) {
     if (rep != NULL) {
       Element* e = &rep->elements[0];
-      Element* limit = &rep->elements[size];
-      for (; e < limit; e++) {
-        e->~Element();
+      if (!std::is_trivial<Element>::value) {
+        Element* limit = &rep->elements[size];
+        for (; e < limit; e++) {
+          e->~Element();
+        }
       }
       if (rep->arena == NULL) {
 #if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
@@ -487,10 +486,6 @@
   friend class ::google::protobuf::internal::ParseContext;
 };
 
-template <typename Element>
-const size_t RepeatedField<Element>::kRepHeaderSize =
-    reinterpret_cast<size_t>(&reinterpret_cast<Rep*>(16)->elements[0]) - 16;
-
 namespace internal {
 template <typename It>
 class RepeatedPtrIterator;
@@ -741,9 +736,12 @@
   int total_size_;
   struct Rep {
     int allocated_size;
-    void* elements[1];
+    // Here we declare a huge array as a way of approximating C's "flexible
+    // array member" feature without relying on undefined behavior.
+    void* elements[(std::numeric_limits<int>::max() - 2 * sizeof(int)) /
+                   sizeof(void*)];
   };
-  static constexpr size_t kRepHeaderSize = sizeof(Rep) - sizeof(void*);
+  static constexpr size_t kRepHeaderSize = offsetof(Rep, elements);
   Rep* rep_;
 
   template <typename TypeHandler>
diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc
index 26b2384..8de9504 100644
--- a/src/google/protobuf/repeated_field_unittest.cc
+++ b/src/google/protobuf/repeated_field_unittest.cc
@@ -328,10 +328,18 @@
   EXPECT_GE(huge_field.Capacity(), min_clamping_size);
   ASSERT_LT(huge_field.Capacity(), std::numeric_limits<int>::max() - 1);
 
+#ifndef ADDRESS_SANITIZER
+  // The array containing all the fields is, in theory, up to MAXINT-1 in size.
+  // However, some compilers can't handle a struct whose size is larger
+  // than 2GB, and the protocol buffer format doesn't handle more than 2GB of
+  // data at once, either.  So we limit it, but the code below accesses beyond
+  // that limit.
+
   // Allocation may return more memory than we requested. However, the updated
   // size must still be clamped to a valid range.
   huge_field.Reserve(huge_field.Capacity() + 1);
   EXPECT_EQ(huge_field.Capacity(), std::numeric_limits<int>::max());
+#endif
 #endif  // PROTOBUF_TEST_ALLOW_LARGE_ALLOC
 }
 
diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc
index 059456f..9256869 100644
--- a/src/google/protobuf/source_context.pb.cc
+++ b/src/google/protobuf/source_context.pb.cc
@@ -28,7 +28,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::SourceContext();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::SourceContext::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_SourceContext_google_2fprotobuf_2fsource_5fcontext_2eproto =
@@ -81,8 +80,6 @@
 
 // ===================================================================
 
-void SourceContext::InitAsDefaultInstance() {
-}
 class SourceContext::_Internal {
  public:
 };
diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h
index 6ebb809..a565129 100644
--- a/src/google/protobuf/source_context.pb.h
+++ b/src/google/protobuf/source_context.pb.h
@@ -102,7 +102,6 @@
   }
   static const SourceContext& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const SourceContext* internal_default_instance() {
     return reinterpret_cast<const SourceContext*>(
                &_SourceContext_default_instance_);
diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc
index 54c9283..d94b86d 100644
--- a/src/google/protobuf/struct.pb.cc
+++ b/src/google/protobuf/struct.pb.cc
@@ -27,12 +27,6 @@
 class ValueDefaultTypeInternal {
  public:
   ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed<Value> _instance;
-  int null_value_;
-  double number_value_;
-  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr string_value_;
-  bool bool_value_;
-  const PROTOBUF_NAMESPACE_ID::Struct* struct_value_;
-  const PROTOBUF_NAMESPACE_ID::ListValue* list_value_;
 } _Value_default_instance_;
 class ListValueDefaultTypeInternal {
  public:
@@ -61,10 +55,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::ListValue();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse::InitAsDefaultInstance();
-  PROTOBUF_NAMESPACE_ID::Struct::InitAsDefaultInstance();
-  PROTOBUF_NAMESPACE_ID::Value::InitAsDefaultInstance();
-  PROTOBUF_NAMESPACE_ID::ListValue::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_ListValue_google_2fprotobuf_2fstruct_2eproto =
@@ -95,12 +85,12 @@
   ~0u,  // no _extensions_
   PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Value, _oneof_case_[0]),
   ~0u,  // no _weak_field_map_
-  offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, null_value_),
-  offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, number_value_),
-  offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, string_value_),
-  offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, bool_value_),
-  offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, struct_value_),
-  offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, list_value_),
+  ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag,
+  ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag,
+  ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag,
+  ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag,
+  ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag,
+  ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag,
   PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Value, kind_),
   ~0u,  // no _has_bits_
   PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::ListValue, _internal_metadata_),
@@ -190,8 +180,6 @@
 
 // ===================================================================
 
-void Struct::InitAsDefaultInstance() {
-}
 class Struct::_Internal {
  public:
 };
@@ -428,17 +416,6 @@
 
 // ===================================================================
 
-void Value::InitAsDefaultInstance() {
-  PROTOBUF_NAMESPACE_ID::_Value_default_instance_.null_value_ = 0;
-  PROTOBUF_NAMESPACE_ID::_Value_default_instance_.number_value_ = 0;
-  PROTOBUF_NAMESPACE_ID::_Value_default_instance_.string_value_.UnsafeSetDefault(
-      &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
-  PROTOBUF_NAMESPACE_ID::_Value_default_instance_.bool_value_ = false;
-  PROTOBUF_NAMESPACE_ID::_Value_default_instance_.struct_value_ = const_cast< PROTOBUF_NAMESPACE_ID::Struct*>(
-      PROTOBUF_NAMESPACE_ID::Struct::internal_default_instance());
-  PROTOBUF_NAMESPACE_ID::_Value_default_instance_.list_value_ = const_cast< PROTOBUF_NAMESPACE_ID::ListValue*>(
-      PROTOBUF_NAMESPACE_ID::ListValue::internal_default_instance());
-}
 class Value::_Internal {
  public:
   static const PROTOBUF_NAMESPACE_ID::Struct& struct_value(const Value* msg);
@@ -885,8 +862,6 @@
 
 // ===================================================================
 
-void ListValue::InitAsDefaultInstance() {
-}
 class ListValue::_Internal {
  public:
 };
diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h
index 772f1a4..b065bd2 100644
--- a/src/google/protobuf/struct.pb.h
+++ b/src/google/protobuf/struct.pb.h
@@ -172,7 +172,6 @@
   }
   static const Struct& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const Struct* internal_default_instance() {
     return reinterpret_cast<const Struct*>(
                &_Struct_default_instance_);
@@ -332,7 +331,6 @@
     KIND_NOT_SET = 0,
   };
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const Value* internal_default_instance() {
     return reinterpret_cast<const Value*>(
                &_Value_default_instance_);
@@ -577,7 +575,6 @@
   }
   static const ListValue& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const ListValue* internal_default_instance() {
     return reinterpret_cast<const ListValue*>(
                &_ListValue_default_instance_);
@@ -977,7 +974,7 @@
 inline const PROTOBUF_NAMESPACE_ID::Struct& Value::_internal_struct_value() const {
   return _internal_has_struct_value()
       ? *kind_.struct_value_
-      : *reinterpret_cast< PROTOBUF_NAMESPACE_ID::Struct*>(&PROTOBUF_NAMESPACE_ID::_Struct_default_instance_);
+      : reinterpret_cast< PROTOBUF_NAMESPACE_ID::Struct&>(PROTOBUF_NAMESPACE_ID::_Struct_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::Struct& Value::struct_value() const {
   // @@protoc_insertion_point(field_get:google.protobuf.Value.struct_value)
@@ -1050,7 +1047,7 @@
 inline const PROTOBUF_NAMESPACE_ID::ListValue& Value::_internal_list_value() const {
   return _internal_has_list_value()
       ? *kind_.list_value_
-      : *reinterpret_cast< PROTOBUF_NAMESPACE_ID::ListValue*>(&PROTOBUF_NAMESPACE_ID::_ListValue_default_instance_);
+      : reinterpret_cast< PROTOBUF_NAMESPACE_ID::ListValue&>(PROTOBUF_NAMESPACE_ID::_ListValue_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::ListValue& Value::list_value() const {
   // @@protoc_insertion_point(field_get:google.protobuf.Value.list_value)
diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc
index 58ed5a4..11e9b00 100644
--- a/src/google/protobuf/text_format.cc
+++ b/src/google/protobuf/text_format.cc
@@ -286,6 +286,15 @@
     // Consume fields until we cannot do so anymore.
     while (true) {
       if (LookingAtType(io::Tokenizer::TYPE_END)) {
+        // Ensures recursion limit properly unwinded, but only for success
+        // cases. This implicitly avoids the check when `Parse` returns false
+        // via `DO(...)`.
+        GOOGLE_DCHECK(had_errors_ || recursion_limit_ == initial_recursion_limit_)
+            << "Recursion limit at end of parse should be "
+            << initial_recursion_limit_ << ", but was " << recursion_limit_
+            << ". Difference of " << initial_recursion_limit_ - recursion_limit_
+            << " stack frames not accounted for stack unwind.";
+
         return !had_errors_;
       }
 
@@ -832,10 +841,19 @@
   }
 
   bool SkipFieldValue() {
+    if (--recursion_limit_ < 0) {
+      ReportError(
+          StrCat("Message is too deep, the parser exceeded the "
+                       "configured recursion limit of ",
+                       initial_recursion_limit_, "."));
+      return false;
+    }
+
     if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
       while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
         tokenizer_.Next();
       }
+      ++recursion_limit_;
       return true;
     }
     if (TryConsume("[")) {
@@ -850,6 +868,7 @@
         }
         DO(Consume(","));
       }
+      ++recursion_limit_;
       return true;
     }
     // Possible field values other than string:
@@ -879,6 +898,7 @@
         !LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
       std::string text = tokenizer_.current().text;
       ReportError("Cannot skip field value, unexpected token: " + text);
+      ++recursion_limit_;
       return false;
     }
     // Combination of '-' and TYPE_IDENTIFIER may result in an invalid field
@@ -893,10 +913,12 @@
       if (text != "inf" &&
           text != "infinity" && text != "nan") {
         ReportError("Invalid float number: " + text);
+        ++recursion_limit_;
         return false;
       }
     }
     tokenizer_.Next();
+    ++recursion_limit_;
     return true;
   }
 
@@ -1432,7 +1454,7 @@
   return MergeUsingImpl(input, output, &parser);
 }
 
-bool TextFormat::Parser::ParseFromString(const std::string& input,
+bool TextFormat::Parser::ParseFromString(ConstStringParam input,
                                          Message* output) {
   DO(CheckParseInputSize(input, error_collector_));
   io::ArrayInputStream input_stream(input.data(), input.size());
@@ -1497,7 +1519,7 @@
   return Parser().Merge(input, output);
 }
 
-/* static */ bool TextFormat::ParseFromString(const std::string& input,
+/* static */ bool TextFormat::ParseFromString(ConstStringParam input,
                                               Message* output) {
   return Parser().ParseFromString(input, output);
 }
@@ -1525,9 +1547,9 @@
 
 // Some compilers do not support ref-qualifiers even in C++11 mode.
 // Disable the optimization for now and revisit it later.
-#if 0   // LANG_CXX11
+#if 0  // LANG_CXX11
   std::string Consume() && { return std::move(output_); }
-#else   // !LANG_CXX11
+#else  // !LANG_CXX11
   const std::string& Get() { return output_; }
 #endif  // LANG_CXX11
 
diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h
index 9eb2eeb..e4b3255 100644
--- a/src/google/protobuf/text_format.h
+++ b/src/google/protobuf/text_format.h
@@ -454,7 +454,7 @@
   // google::protobuf::MessageLite::ParseFromString().
   static bool Parse(io::ZeroCopyInputStream* input, Message* output);
   // Like Parse(), but reads directly from a string.
-  static bool ParseFromString(const std::string& input, Message* output);
+  static bool ParseFromString(ConstStringParam input, Message* output);
 
   // Like Parse(), but the data is merged into the given message, as if
   // using Message::MergeFrom().
@@ -531,7 +531,7 @@
     // Like TextFormat::Parse().
     bool Parse(io::ZeroCopyInputStream* input, Message* output);
     // Like TextFormat::ParseFromString().
-    bool ParseFromString(const std::string& input, Message* output);
+    bool ParseFromString(ConstStringParam input, Message* output);
     // Like TextFormat::Merge().
     bool Merge(io::ZeroCopyInputStream* input, Message* output);
     // Like TextFormat::MergeFromString().
diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc
index 0ae2def..e0e4177 100644
--- a/src/google/protobuf/text_format_unittest.cc
+++ b/src/google/protobuf/text_format_unittest.cc
@@ -42,7 +42,6 @@
 
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/map_unittest.pb.h>
@@ -58,6 +57,7 @@
 #include <gmock/gmock.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
+#include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/substitute.h>
 
 
@@ -1409,9 +1409,8 @@
     parser_.RecordErrorsTo(&error_collector);
     EXPECT_EQ(expected_result, parser_.ParseFromString(input, proto))
         << input << " -> " << proto->DebugString();
-    EXPECT_EQ(
-        StrCat(line) + ":" + StrCat(col) + ": " + message + "\n",
-        error_collector.text_);
+    EXPECT_EQ(StrCat(line, ":", col, ": ", message, "\n"),
+              error_collector.text_);
     parser_.RecordErrorsTo(nullptr);
   }
 
@@ -1920,18 +1919,43 @@
   ExpectSuccessAndTree(input, &message, nullptr);
 }
 
-TEST_F(TextFormatParserTest, SetRecursionLimitUnknownField) {
+TEST_F(TextFormatParserTest, SetRecursionLimitUnknownFieldValue) {
+  const char* format = "[$0]";
+  std::string input = "\"test_value\"";
+  for (int i = 0; i < 99; ++i) input = strings::Substitute(format, input);
+  std::string not_deep_input = StrCat("unknown_nested_array: ", input);
+
+  parser_.AllowUnknownField(true);
+  parser_.SetRecursionLimit(100);
+
+  unittest::NestedTestAllTypes message;
+  ExpectSuccessAndTree(not_deep_input, &message, nullptr);
+
+  input = strings::Substitute(format, input);
+  std::string deep_input = StrCat("unknown_nested_array: ", input);
+  ExpectMessage(
+      deep_input,
+      "WARNING:Message type \"protobuf_unittest.NestedTestAllTypes\" has no "
+      "field named \"unknown_nested_array\".\n1:123: Message is too deep, the "
+      "parser exceeded the configured recursion limit of 100.",
+      1, 21, &message, false);
+
+  parser_.SetRecursionLimit(101);
+  ExpectSuccessAndTree(deep_input, &message, nullptr);
+}
+
+TEST_F(TextFormatParserTest, SetRecursionLimitUnknownFieldMessage) {
   const char* format = "unknown_child: { $0 }";
   std::string input;
   for (int i = 0; i < 100; ++i) input = strings::Substitute(format, input);
 
   parser_.AllowUnknownField(true);
+  parser_.SetRecursionLimit(100);
 
   unittest::NestedTestAllTypes message;
   ExpectSuccessAndTree(input, &message, nullptr);
 
   input = strings::Substitute(format, input);
-  parser_.SetRecursionLimit(100);
   ExpectMessage(
       input,
       "WARNING:Message type \"protobuf_unittest.NestedTestAllTypes\" has no "
diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc
index 1458bc0..65c8d54 100644
--- a/src/google/protobuf/timestamp.pb.cc
+++ b/src/google/protobuf/timestamp.pb.cc
@@ -28,7 +28,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::Timestamp();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::Timestamp::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto =
@@ -82,8 +81,6 @@
 
 // ===================================================================
 
-void Timestamp::InitAsDefaultInstance() {
-}
 class Timestamp::_Internal {
  public:
 };
diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h
index 3429d76..e8476f6 100644
--- a/src/google/protobuf/timestamp.pb.h
+++ b/src/google/protobuf/timestamp.pb.h
@@ -102,7 +102,6 @@
   }
   static const Timestamp& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const Timestamp* internal_default_instance() {
     return reinterpret_cast<const Timestamp*>(
                &_Timestamp_default_instance_);
diff --git a/src/google/protobuf/timestamp.proto b/src/google/protobuf/timestamp.proto
index a343d81..3b2df6d 100644
--- a/src/google/protobuf/timestamp.proto
+++ b/src/google/protobuf/timestamp.proto
@@ -91,7 +91,16 @@
 //         .setNanos((int) ((millis % 1000) * 1000000)).build();
 //
 //
-// Example 5: Compute Timestamp from current time in Python.
+// Example 5: Compute Timestamp from Java `Instant.now()`.
+//
+//     Instant now = Instant.now();
+//
+//     Timestamp timestamp =
+//         Timestamp.newBuilder().setSeconds(now.getEpochSecond())
+//             .setNanos(now.getNano()).build();
+//
+//
+// Example 6: Compute Timestamp from current time in Python.
 //
 //     timestamp = Timestamp()
 //     timestamp.GetCurrentTime()
diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc
index 8da9559..01a79f9 100644
--- a/src/google/protobuf/type.pb.cc
+++ b/src/google/protobuf/type.pb.cc
@@ -49,7 +49,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::Enum();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::Enum::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<3> scc_info_Enum_google_2fprotobuf_2ftype_2eproto =
@@ -66,7 +65,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::EnumValue();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::EnumValue::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_EnumValue_google_2fprotobuf_2ftype_2eproto =
@@ -81,7 +79,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::Field();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::Field::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Field_google_2fprotobuf_2ftype_2eproto =
@@ -96,7 +93,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::Option();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::Option::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Option_google_2fprotobuf_2ftype_2eproto =
@@ -111,7 +107,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::Type();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::Type::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<3> scc_info_Type_google_2fprotobuf_2ftype_2eproto =
@@ -354,10 +349,6 @@
 
 // ===================================================================
 
-void Type::InitAsDefaultInstance() {
-  PROTOBUF_NAMESPACE_ID::_Type_default_instance_._instance.get_mutable()->source_context_ = const_cast< PROTOBUF_NAMESPACE_ID::SourceContext*>(
-      PROTOBUF_NAMESPACE_ID::SourceContext::internal_default_instance());
-}
 class Type::_Internal {
  public:
   static const PROTOBUF_NAMESPACE_ID::SourceContext& source_context(const Type* msg);
@@ -747,8 +738,6 @@
 
 // ===================================================================
 
-void Field::InitAsDefaultInstance() {
-}
 class Field::_Internal {
  public:
 };
@@ -1232,10 +1221,6 @@
 
 // ===================================================================
 
-void Enum::InitAsDefaultInstance() {
-  PROTOBUF_NAMESPACE_ID::_Enum_default_instance_._instance.get_mutable()->source_context_ = const_cast< PROTOBUF_NAMESPACE_ID::SourceContext*>(
-      PROTOBUF_NAMESPACE_ID::SourceContext::internal_default_instance());
-}
 class Enum::_Internal {
  public:
   static const PROTOBUF_NAMESPACE_ID::SourceContext& source_context(const Enum* msg);
@@ -1588,8 +1573,6 @@
 
 // ===================================================================
 
-void EnumValue::InitAsDefaultInstance() {
-}
 class EnumValue::_Internal {
  public:
 };
@@ -1856,10 +1839,6 @@
 
 // ===================================================================
 
-void Option::InitAsDefaultInstance() {
-  PROTOBUF_NAMESPACE_ID::_Option_default_instance_._instance.get_mutable()->value_ = const_cast< PROTOBUF_NAMESPACE_ID::Any*>(
-      PROTOBUF_NAMESPACE_ID::Any::internal_default_instance());
-}
 class Option::_Internal {
  public:
   static const PROTOBUF_NAMESPACE_ID::Any& value(const Option* msg);
diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h
index c843794..443aeb4 100644
--- a/src/google/protobuf/type.pb.h
+++ b/src/google/protobuf/type.pb.h
@@ -215,7 +215,6 @@
   }
   static const Type& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const Type* internal_default_instance() {
     return reinterpret_cast<const Type*>(
                &_Type_default_instance_);
@@ -456,7 +455,6 @@
   }
   static const Field& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const Field* internal_default_instance() {
     return reinterpret_cast<const Field*>(
                &_Field_default_instance_);
@@ -827,7 +825,6 @@
   }
   static const Enum& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const Enum* internal_default_instance() {
     return reinterpret_cast<const Enum*>(
                &_Enum_default_instance_);
@@ -1042,7 +1039,6 @@
   }
   static const EnumValue& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const EnumValue* internal_default_instance() {
     return reinterpret_cast<const EnumValue*>(
                &_EnumValue_default_instance_);
@@ -1217,7 +1213,6 @@
   }
   static const Option& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const Option* internal_default_instance() {
     return reinterpret_cast<const Option*>(
                &_Option_default_instance_);
@@ -1577,8 +1572,8 @@
 }
 inline const PROTOBUF_NAMESPACE_ID::SourceContext& Type::_internal_source_context() const {
   const PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_;
-  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::SourceContext*>(
-      &PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_);
+  return p != nullptr ? *p : reinterpret_cast<const PROTOBUF_NAMESPACE_ID::SourceContext&>(
+      PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::SourceContext& Type::source_context() const {
   // @@protoc_insertion_point(field_get:google.protobuf.Type.source_context)
@@ -2209,8 +2204,8 @@
 }
 inline const PROTOBUF_NAMESPACE_ID::SourceContext& Enum::_internal_source_context() const {
   const PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_;
-  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::SourceContext*>(
-      &PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_);
+  return p != nullptr ? *p : reinterpret_cast<const PROTOBUF_NAMESPACE_ID::SourceContext&>(
+      PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::SourceContext& Enum::source_context() const {
   // @@protoc_insertion_point(field_get:google.protobuf.Enum.source_context)
@@ -2497,8 +2492,8 @@
 }
 inline const PROTOBUF_NAMESPACE_ID::Any& Option::_internal_value() const {
   const PROTOBUF_NAMESPACE_ID::Any* p = value_;
-  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::Any*>(
-      &PROTOBUF_NAMESPACE_ID::_Any_default_instance_);
+  return p != nullptr ? *p : reinterpret_cast<const PROTOBUF_NAMESPACE_ID::Any&>(
+      PROTOBUF_NAMESPACE_ID::_Any_default_instance_);
 }
 inline const PROTOBUF_NAMESPACE_ID::Any& Option::value() const {
   // @@protoc_insertion_point(field_get:google.protobuf.Option.value)
diff --git a/src/google/protobuf/unittest_lite.proto b/src/google/protobuf/unittest_lite.proto
index 652966b..f501f50 100644
--- a/src/google/protobuf/unittest_lite.proto
+++ b/src/google/protobuf/unittest_lite.proto
@@ -49,6 +49,10 @@
     optional int64 cc = 2;
   }
 
+  message NestedMessage2 {
+    optional int32 dd = 1;
+  }
+
   enum NestedEnum {
     FOO = 1;
     BAR = 2;
@@ -163,6 +167,7 @@
     string oneof_string = 113;
     bytes oneof_bytes = 114;
     NestedMessage oneof_lazy_nested_message = 115 [lazy = true];
+    NestedMessage2 oneof_nested_message2 = 117;
   }
 
   // Tests toString for non-repeated fields with a list suffix
diff --git a/src/google/protobuf/util/field_comparator.h b/src/google/protobuf/util/field_comparator.h
index 7b5ce52..9058bbe 100644
--- a/src/google/protobuf/util/field_comparator.h
+++ b/src/google/protobuf/util/field_comparator.h
@@ -170,6 +170,7 @@
   // Defines the map to store the tolerances for floating point comparison.
   typedef std::map<const FieldDescriptor*, Tolerance> ToleranceMap;
 
+  friend class MessageDifferencer;
   // The following methods get executed when CompareFields is called for the
   // basic types (instead of submessages). They return true on success. One
   // can use ResultFromBoolean() to convert that boolean to a ComparisonResult
diff --git a/src/google/protobuf/util/field_mask_util_test.cc b/src/google/protobuf/util/field_mask_util_test.cc
index 9ed35e6..f639b32 100644
--- a/src/google/protobuf/util/field_mask_util_test.cc
+++ b/src/google/protobuf/util/field_mask_util_test.cc
@@ -33,12 +33,12 @@
 #include <algorithm>
 #include <vector>
 
-#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/common.h>
 #include <google/protobuf/field_mask.pb.h>
 #include <google/protobuf/test_util.h>
 #include <google/protobuf/unittest.pb.h>
 #include <gtest/gtest.h>
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/common.h>
 
 namespace google {
 namespace protobuf {
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc
index 71e2d2e..1a9cc9b 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource.cc
@@ -810,8 +810,8 @@
     const google::protobuf::Field* field, StringPiece field_name,
     ObjectWriter* ow) const {
   // Temporary buffers of different types.
-  uint32 buffer32;
-  uint64 buffer64;
+  uint32 buffer32 = 0;
+  uint64 buffer64 = 0;
   std::string strbuffer;
   switch (field->kind()) {
     case google::protobuf::Field::TYPE_BOOL: {
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc
index 7086163..817109b 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc
@@ -588,6 +588,38 @@
 
   if (field == nullptr) return this;
 
+  // Legacy JSON map is a list of key value pairs. Starts a map entry object.
+  if (options_.use_legacy_json_map_format && name.empty()) {
+    Push(name, IsAny(*field) ? Item::ANY : Item::MESSAGE, false, false);
+    return this;
+  }
+
+  if (IsMap(*field)) {
+    // Begin a map. A map is triggered by a StartObject() call if the current
+    // field has a map type.
+    // A map type is always repeated, hence set is_list to true.
+    // Render
+    // "<name>": [
+    Push(name, Item::MAP, false, true);
+    return this;
+  }
+
+  if (options_.disable_implicit_message_list) {
+    // If the incoming object is repeated, the top-level object on stack should
+    // be list. Report an error otherwise.
+    if (IsRepeated(*field) && !current_->is_list()) {
+      IncrementInvalidDepth();
+
+      if (!options_.suppress_implicit_message_list_error) {
+        InvalidValue(
+            field->name(),
+            "Starting an object in a repeated field but the parent object "
+            "is not a list");
+      }
+      return this;
+    }
+  }
+
   if (IsStruct(*field)) {
     // Start a struct object.
     // Render
@@ -611,22 +643,6 @@
     return this;
   }
 
-  // Legacy JSON map is a list of key value pairs. Starts a map entry object.
-  if (options_.use_legacy_json_map_format && name.empty()) {
-    Push(name, IsAny(*field) ? Item::ANY : Item::MESSAGE, false, false);
-    return this;
-  }
-
-  if (IsMap(*field)) {
-    // Begin a map. A map is triggered by a StartObject() call if the current
-    // field has a map type.
-    // A map type is always repeated, hence set is_list to true.
-    // Render
-    // "<name>": [
-    Push(name, Item::MAP, false, true);
-    return this;
-  }
-
   // A regular message type. Pass it directly to ProtoWriter.
   // Render
   // "<name>": {
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.h b/src/google/protobuf/util/internal/protostream_objectwriter.h
index f3aeb61..cc68c6b 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.h
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.h
@@ -100,6 +100,13 @@
     // If true, accepts repeated key/value pair for a map proto field.
     bool use_legacy_json_map_format;
 
+    // If true, disable implicitly creating message list.
+    bool disable_implicit_message_list;
+
+    // If true, suppress the error of implicitly creating message list when it
+    // is disabled.
+    bool suppress_implicit_message_list_error;
+
     Options()
         : struct_integers_as_strings(false),
           ignore_unknown_fields(false),
@@ -107,7 +114,9 @@
           use_lower_camel_for_enums(false),
           case_insensitive_enum_parsing(false),
           ignore_null_value_map_entry(false),
-          use_legacy_json_map_format(false) {}
+          use_legacy_json_map_format(false),
+          disable_implicit_message_list(false),
+          suppress_implicit_message_list_error(false) {}
 
     // Default instance of Options with all options set to defaults.
     static const Options& Defaults() {
diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc
index f5e0860..829a18a 100644
--- a/src/google/protobuf/util/message_differencer.cc
+++ b/src/google/protobuf/util/message_differencer.cc
@@ -47,6 +47,7 @@
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/map_field.h>
 #include <google/protobuf/text_format.h>
 #include <google/protobuf/util/field_comparator.h>
 #include <google/protobuf/stubs/strutil.h>
@@ -916,6 +917,76 @@
   return match;
 }
 
+bool MessageDifferencer::CompareMapFieldByMapReflection(
+    const Message& message1, const Message& message2,
+    const FieldDescriptor* map_field) {
+  const Reflection* reflection1 = message1.GetReflection();
+  const Reflection* reflection2 = message2.GetReflection();
+  const int count1 = reflection1->MapSize(message1, map_field);
+  const int count2 = reflection2->MapSize(message2, map_field);
+  const bool treated_as_subset = IsTreatedAsSubset(map_field);
+  if (count1 != count2 && !treated_as_subset) {
+    return false;
+  }
+  if (count1 > count2) {
+    return false;
+  }
+  const FieldDescriptor* val_des = map_field->message_type()->map_value();
+  switch (val_des->cpp_type()) {
+#define HANDLE_TYPE(CPPTYPE, METHOD, COMPAREMETHOD)                         \
+  case FieldDescriptor::CPPTYPE_##CPPTYPE: {                                \
+    for (MapIterator it = reflection1->MapBegin(                            \
+             const_cast<Message*>(&message1), map_field);                   \
+         it !=                                                              \
+         reflection1->MapEnd(const_cast<Message*>(&message1), map_field);   \
+         ++it) {                                                            \
+      if (!reflection2->ContainsMapKey(message2, map_field, it.GetKey())) { \
+        return false;                                                       \
+      }                                                                     \
+      MapValueRef value2;                                                   \
+      reflection2->InsertOrLookupMapValue(const_cast<Message*>(&message2),  \
+                                          map_field, it.GetKey(), &value2); \
+      if (!default_field_comparator_.Compare##COMPAREMETHOD(                \
+              *val_des, it.GetValueRef().Get##METHOD(),                     \
+              value2.Get##METHOD())) {                                      \
+        return false;                                                       \
+      }                                                                     \
+    }                                                                       \
+    break;                                                                  \
+  }
+    HANDLE_TYPE(INT32, Int32Value, Int32);
+    HANDLE_TYPE(INT64, Int64Value, Int64);
+    HANDLE_TYPE(UINT32, UInt32Value, UInt32);
+    HANDLE_TYPE(UINT64, UInt64Value, UInt64);
+    HANDLE_TYPE(DOUBLE, DoubleValue, Double);
+    HANDLE_TYPE(FLOAT, FloatValue, Float);
+    HANDLE_TYPE(BOOL, BoolValue, Bool);
+    HANDLE_TYPE(STRING, StringValue, String);
+    HANDLE_TYPE(ENUM, EnumValue, Int32);
+#undef HANDLE_TYPE
+    case FieldDescriptor::CPPTYPE_MESSAGE: {
+      for (MapIterator it = reflection1->MapBegin(
+               const_cast<Message*>(&message1), map_field);
+           it !=
+           reflection1->MapEnd(const_cast<Message*>(&message1), map_field);
+           ++it) {
+        if (!reflection2->ContainsMapKey(message2, map_field, it.GetKey())) {
+          return false;
+        }
+        MapValueRef value2;
+        reflection2->InsertOrLookupMapValue(const_cast<Message*>(&message2),
+                                            map_field, it.GetKey(), &value2);
+        if (!Compare(it.GetValueRef().GetMessageValue(),
+                     value2.GetMessageValue())) {
+          return false;
+        }
+      }
+      break;
+    }
+  }
+  return true;
+}
+
 bool MessageDifferencer::CompareRepeatedField(
     const Message& message1, const Message& message2,
     const FieldDescriptor* repeated_field,
@@ -923,6 +994,25 @@
   // the input FieldDescriptor is guaranteed to be repeated field.
   const Reflection* reflection1 = message1.GetReflection();
   const Reflection* reflection2 = message2.GetReflection();
+
+  // When both map fields are on map, do not sync to repeated field.
+  // TODO(jieluo): Add support for reporter
+  if (repeated_field->is_map() && reporter_ == nullptr &&
+      field_comparator_ == nullptr) {
+    const FieldDescriptor* key_des = repeated_field->message_type()->map_key();
+    const FieldDescriptor* val_des =
+        repeated_field->message_type()->map_value();
+    const internal::MapFieldBase* map_field1 =
+        reflection1->GetMapData(message1, repeated_field);
+    const internal::MapFieldBase* map_field2 =
+        reflection2->GetMapData(message2, repeated_field);
+    if (map_field1->IsMapValid() && map_field2->IsMapValid() &&
+        ignored_fields_.find(key_des) == ignored_fields_.end() &&
+        ignored_fields_.find(val_des) == ignored_fields_.end()) {
+      return CompareMapFieldByMapReflection(message1, message2, repeated_field);
+    }
+  }
+
   const int count1 = reflection1->FieldSize(message1, repeated_field);
   const int count2 = reflection2->FieldSize(message2, repeated_field);
   const bool treated_as_subset = IsTreatedAsSubset(repeated_field);
diff --git a/src/google/protobuf/util/message_differencer.h b/src/google/protobuf/util/message_differencer.h
index f7317c8..35a04af 100644
--- a/src/google/protobuf/util/message_differencer.h
+++ b/src/google/protobuf/util/message_differencer.h
@@ -177,43 +177,33 @@
     // For known fields, "field" is filled in and "unknown_field_number" is -1.
     // For unknown fields, "field" is NULL, "unknown_field_number" is the field
     // number, and "unknown_field_type" is its type.
-    const FieldDescriptor* field;
-    int unknown_field_number;
-    UnknownField::Type unknown_field_type;
+    const FieldDescriptor* field = nullptr;
+    int unknown_field_number = -1;
+    UnknownField::Type unknown_field_type = UnknownField::Type::TYPE_VARINT;
 
     // If this a repeated field, "index" is the index within it.  For unknown
     // fields, this is the index of the field among all unknown fields of the
     // same field number and type.
-    int index;
+    int index = -1;
 
     // If "field" is a repeated field which is being treated as a map or
     // a set (see TreatAsMap() and TreatAsSet(), below), new_index indicates
     // the index the position to which the element has moved.  If the element
     // has not moved, "new_index" will have the same value as "index".
-    int new_index;
+    int new_index = -1;
 
     // For unknown fields, these are the pointers to the UnknownFieldSet
     // containing the unknown fields. In certain cases (e.g. proto1's
     // MessageSet, or nested groups of unknown fields), these may differ from
     // the messages' internal UnknownFieldSets.
-    const UnknownFieldSet* unknown_field_set1;
-    const UnknownFieldSet* unknown_field_set2;
+    const UnknownFieldSet* unknown_field_set1 = nullptr;
+    const UnknownFieldSet* unknown_field_set2 = nullptr;
 
     // For unknown fields, these are the index of the field within the
     // UnknownFieldSets. One or the other will be -1 when
     // reporting an addition or deletion.
-    int unknown_field_index1;
-    int unknown_field_index2;
-
-    SpecificField()
-        : field(NULL),
-          unknown_field_number(-1),
-          index(-1),
-          new_index(-1),
-          unknown_field_set1(NULL),
-          unknown_field_set2(NULL),
-          unknown_field_index1(-1),
-          unknown_field_index2(-1) {}
+    int unknown_field_index1 = -1;
+    int unknown_field_index2 = -1;
   };
 
   // Abstract base class from which all MessageDifferencer
@@ -767,6 +757,11 @@
                             const FieldDescriptor* field,
                             std::vector<SpecificField>* parent_fields);
 
+  // Compare the map fields using map reflection instead of sync to repeated.
+  bool CompareMapFieldByMapReflection(const Message& message1,
+                                      const Message& message2,
+                                      const FieldDescriptor* field);
+
   // Shorthand for CompareFieldValueUsingParentFields with NULL parent_fields.
   bool CompareFieldValue(const Message& message1, const Message& message2,
                          const FieldDescriptor* field, int index1, int index2);
diff --git a/src/google/protobuf/util/message_differencer_unittest.cc b/src/google/protobuf/util/message_differencer_unittest.cc
index 2f6be98..3d36e85 100644
--- a/src/google/protobuf/util/message_differencer_unittest.cc
+++ b/src/google/protobuf/util/message_differencer_unittest.cc
@@ -160,6 +160,29 @@
 
   // Compare
   EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
+
+  // Get map entries by index will sync map to repeated field
+  MapTestUtil::GetMapEntries(msg1, 0);
+  EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2));
+
+  // Compare values not match
+  (*msg1.mutable_map_int32_int32())[1] = 2;
+  (*msg2.mutable_map_int32_int32())[1] = 3;
+  EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
+
+  // Compare keys not match
+  msg1.Clear();
+  msg2.Clear();
+  (*msg1.mutable_map_string_string())["1"] = "";
+  (*msg2.mutable_map_string_string())["2"] = "";
+  EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
+
+  // Compare message values not match
+  msg1.Clear();
+  msg2.Clear();
+  (*msg1.mutable_map_int32_foreign_message())[1].set_c(1);
+  (*msg2.mutable_map_int32_foreign_message())[1].set_c(2);
+  EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2));
 }
 
 TEST(MessageDifferencerTest, BasicPartialEqualityTest) {
diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc
index fc9e6a5..e3463e3 100644
--- a/src/google/protobuf/wire_format_unittest.cc
+++ b/src/google/protobuf/wire_format_unittest.cc
@@ -36,7 +36,6 @@
 
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/test_util.h>
 #include <google/protobuf/test_util2.h>
 #include <google/protobuf/unittest.pb.h>
@@ -49,6 +48,7 @@
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/wire_format_lite.h>
 #include <google/protobuf/testing/googletest.h>
+#include <google/protobuf/stubs/logging.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <google/protobuf/stubs/casts.h>
diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc
index e9f53a5..21debfc 100644
--- a/src/google/protobuf/wrappers.pb.cc
+++ b/src/google/protobuf/wrappers.pb.cc
@@ -60,7 +60,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::BoolValue();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::BoolValue::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BoolValue_google_2fprotobuf_2fwrappers_2eproto =
@@ -74,7 +73,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::BytesValue();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::BytesValue::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BytesValue_google_2fprotobuf_2fwrappers_2eproto =
@@ -88,7 +86,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::DoubleValue();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::DoubleValue::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DoubleValue_google_2fprotobuf_2fwrappers_2eproto =
@@ -102,7 +99,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::FloatValue();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::FloatValue::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_FloatValue_google_2fprotobuf_2fwrappers_2eproto =
@@ -116,7 +112,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::Int32Value();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::Int32Value::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Int32Value_google_2fprotobuf_2fwrappers_2eproto =
@@ -130,7 +125,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::Int64Value();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::Int64Value::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Int64Value_google_2fprotobuf_2fwrappers_2eproto =
@@ -144,7 +138,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::StringValue();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::StringValue::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_StringValue_google_2fprotobuf_2fwrappers_2eproto =
@@ -158,7 +151,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::UInt32Value();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::UInt32Value::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_UInt32Value_google_2fprotobuf_2fwrappers_2eproto =
@@ -172,7 +164,6 @@
     new (ptr) PROTOBUF_NAMESPACE_ID::UInt64Value();
     ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr);
   }
-  PROTOBUF_NAMESPACE_ID::UInt64Value::InitAsDefaultInstance();
 }
 
 PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_UInt64Value_google_2fprotobuf_2fwrappers_2eproto =
@@ -303,8 +294,6 @@
 
 // ===================================================================
 
-void DoubleValue::InitAsDefaultInstance() {
-}
 class DoubleValue::_Internal {
  public:
 };
@@ -498,8 +487,6 @@
 
 // ===================================================================
 
-void FloatValue::InitAsDefaultInstance() {
-}
 class FloatValue::_Internal {
  public:
 };
@@ -693,8 +680,6 @@
 
 // ===================================================================
 
-void Int64Value::InitAsDefaultInstance() {
-}
 class Int64Value::_Internal {
  public:
 };
@@ -890,8 +875,6 @@
 
 // ===================================================================
 
-void UInt64Value::InitAsDefaultInstance() {
-}
 class UInt64Value::_Internal {
  public:
 };
@@ -1087,8 +1070,6 @@
 
 // ===================================================================
 
-void Int32Value::InitAsDefaultInstance() {
-}
 class Int32Value::_Internal {
  public:
 };
@@ -1284,8 +1265,6 @@
 
 // ===================================================================
 
-void UInt32Value::InitAsDefaultInstance() {
-}
 class UInt32Value::_Internal {
  public:
 };
@@ -1481,8 +1460,6 @@
 
 // ===================================================================
 
-void BoolValue::InitAsDefaultInstance() {
-}
 class BoolValue::_Internal {
  public:
 };
@@ -1676,8 +1653,6 @@
 
 // ===================================================================
 
-void StringValue::InitAsDefaultInstance() {
-}
 class StringValue::_Internal {
  public:
 };
@@ -1885,8 +1860,6 @@
 
 // ===================================================================
 
-void BytesValue::InitAsDefaultInstance() {
-}
 class BytesValue::_Internal {
  public:
 };
diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h
index c55e9a3..455a50f 100644
--- a/src/google/protobuf/wrappers.pb.h
+++ b/src/google/protobuf/wrappers.pb.h
@@ -134,7 +134,6 @@
   }
   static const DoubleValue& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const DoubleValue* internal_default_instance() {
     return reinterpret_cast<const DoubleValue*>(
                &_DoubleValue_default_instance_);
@@ -271,7 +270,6 @@
   }
   static const FloatValue& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const FloatValue* internal_default_instance() {
     return reinterpret_cast<const FloatValue*>(
                &_FloatValue_default_instance_);
@@ -408,7 +406,6 @@
   }
   static const Int64Value& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const Int64Value* internal_default_instance() {
     return reinterpret_cast<const Int64Value*>(
                &_Int64Value_default_instance_);
@@ -545,7 +542,6 @@
   }
   static const UInt64Value& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const UInt64Value* internal_default_instance() {
     return reinterpret_cast<const UInt64Value*>(
                &_UInt64Value_default_instance_);
@@ -682,7 +678,6 @@
   }
   static const Int32Value& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const Int32Value* internal_default_instance() {
     return reinterpret_cast<const Int32Value*>(
                &_Int32Value_default_instance_);
@@ -819,7 +814,6 @@
   }
   static const UInt32Value& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const UInt32Value* internal_default_instance() {
     return reinterpret_cast<const UInt32Value*>(
                &_UInt32Value_default_instance_);
@@ -956,7 +950,6 @@
   }
   static const BoolValue& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const BoolValue* internal_default_instance() {
     return reinterpret_cast<const BoolValue*>(
                &_BoolValue_default_instance_);
@@ -1093,7 +1086,6 @@
   }
   static const StringValue& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const StringValue* internal_default_instance() {
     return reinterpret_cast<const StringValue*>(
                &_StringValue_default_instance_);
@@ -1237,7 +1229,6 @@
   }
   static const BytesValue& default_instance();
 
-  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
   static inline const BytesValue* internal_default_instance() {
     return reinterpret_cast<const BytesValue*>(
                &_BytesValue_default_instance_);
diff --git a/tests.sh b/tests.sh
index 52b9cf1..3d47b6c 100755
--- a/tests.sh
+++ b/tests.sh
@@ -314,7 +314,7 @@
   if [ $(uname -s) == "Linux" ]; then
     envlist=py\{27,33,34,35,36\}-python
   else
-    envlist=py27-python
+    envlist=py\{27,36\}-python
   fi
   tox -e $envlist
   cd ..
@@ -364,7 +364,7 @@
   if [ $(uname -s) == "Linux" ]; then
     envlist=py\{27,33,34,35,36\}-cpp
   else
-    envlist=py27-cpp
+    envlist=py\{27,36\}-cpp
   fi
   tox -e $envlist
   cd ..
@@ -701,6 +701,51 @@
   popd
 }
 
+build_php8.0() {
+  use_php 8.0
+  pushd php
+  rm -rf vendor
+  composer update
+  composer test
+  popd
+  (cd conformance && make test_php)
+}
+
+build_php8.0_c() {
+  IS_64BIT=$1
+  use_php 8.0
+  php/tests/test.sh
+  pushd conformance
+  if [ "$IS_64BIT" = "true" ]
+  then
+    make test_php_c
+  else
+    make test_php_c_32
+  fi
+  popd
+}
+
+build_php8.0_c_64() {
+  build_php8.0_c true
+}
+
+build_php8.0_mixed() {
+  use_php 8.0
+  pushd php
+  rm -rf vendor
+  composer update
+  tests/compile_extension.sh
+  tests/generate_protos.sh
+  php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit
+  popd
+}
+
+build_php8.0_all() {
+  build_php8.0
+  build_php8.0_c_64
+  build_php8.0_mixed
+}
+
 build_php_all_32() {
   build_php5.5
   build_php5.6