Merge pull request #7698 from haberman/sync-stage

Integrate from Piper for C++, Java, and Python
diff --git a/BUILD b/BUILD
index f3fd3f4..5d4541d 100644
--- a/BUILD
+++ b/BUILD
@@ -175,6 +175,7 @@
         "src/google/protobuf/io/zero_copy_stream.cc",
         "src/google/protobuf/io/zero_copy_stream_impl.cc",
         "src/google/protobuf/io/zero_copy_stream_impl_lite.cc",
+        "src/google/protobuf/map.cc",
         "src/google/protobuf/message_lite.cc",
         "src/google/protobuf/parse_context.cc",
         "src/google/protobuf/repeated_field.cc",
diff --git a/CHANGES.txt b/CHANGES.txt
index 76910c4..8c1bc2f 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,38 @@
+Unreleased Changes
+
+  Protocol Compiler
+  * The proto compiler no longer requires a .proto filename when it is not
+    generating code.
+
+  C++
+  * Arenas are now unconditionally enabled. cc_enable_arenas no longer has
+    any effect.
+  * Fix a memory corruption bug in reflection when mixing optional and
+    non-optional fields.
+  * Make SpaceUsed() calculation more thorough for map fields.
+  * Add stack overflow protection for text format with unknown field values.
+  * FieldPath::FollowAll() now returns a bool to signal if an out-of-bounds
+    error was encountered.
+  * Performance improvements for Map.
+  * Minor formatting fix when dumping a descriptor to .proto format with
+    DebugString.
+  * UBSAN fix in RepeatedField (#2073).
+  * When running under ASAN, skip a test that makes huge allocations.
+  * Fixed a crash that could happen when creating more than 256 extensions in
+    a single message.
+
+  Java
+  * Bugfix in mergeFrom() when a oneof has multiple message fields.
+
+  Python
+  * Print google.protobuf.NullValue as null instead of "NULL_VALUE" when it is
+    used outside WKT Value/Struct.
+  * Fix bug occurring when attempting to deep copy an enum type in python 3.
+
+  Go:
+  * Update go_package options to reference google.golang.org/protobuf module.
+
+
 2020-07-14 version 3.13.0-rc1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
 
   C++:
diff --git a/cmake/README.md b/cmake/README.md
index a780722..89d00c1 100644
--- a/cmake/README.md
+++ b/cmake/README.md
@@ -66,7 +66,7 @@
 step if you are using a release .tar.gz or .zip package):
 
 ```console
-C:\Path\to\protobuf> git submodule update --init --recursive
+C:\Path\to> git submodule update --init --recursive
 ```
 
 Now go to *cmake* folder in protobuf sources:
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/binary_json_conformance_suite.cc b/conformance/binary_json_conformance_suite.cc
index f62c705..4a0d8e8 100644
--- a/conformance/binary_json_conformance_suite.cc
+++ b/conformance/binary_json_conformance_suite.cc
@@ -3051,6 +3051,29 @@
           }
         ]
       )");
+  RunValidJsonTestWithValidator(
+      "NullValueInOtherOneofOldFormat", RECOMMENDED,
+      R"({"oneofNullValue": "NULL_VALUE"})",
+      [](const Json::Value& value) {
+        return (value.isMember("oneofNullValue") &&
+                value["oneofNullValue"].isNull());
+      },
+      true);
+  RunValidJsonTestWithValidator(
+      "NullValueInOtherOneofNewFormat", RECOMMENDED,
+      R"({"oneofNullValue": null})",
+      [](const Json::Value& value) {
+        return (value.isMember("oneofNullValue") &&
+                value["oneofNullValue"].isNull());
+      },
+      true);
+  RunValidJsonTestWithValidator(
+      "NullValueInNormalMessage", RECOMMENDED,
+      R"({"optionalNullValue": null})",
+      [](const Json::Value& value) {
+        return value.empty();
+      },
+      true);
 }
 
 void BinaryAndJsonConformanceSuite::RunJsonTestsForAny() {
diff --git a/conformance/failure_list_php_c.txt b/conformance/failure_list_php_c.txt
index 63c7e8a..2fc03de 100644
--- a/conformance/failure_list_php_c.txt
+++ b/conformance/failure_list_php_c.txt
@@ -1,2 +1,4 @@
 Recommended.Proto2.JsonInput.FieldNameExtension.Validator
+Recommended.Proto3.JsonInput.NullValueInOtherOneofNewFormat.Validator
+Recommended.Proto3.JsonInput.NullValueInOtherOneofOldFormat.Validator
 Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator
diff --git a/conformance/failure_list_php_c_32.txt b/conformance/failure_list_php_c_32.txt
index 63c7e8a..2fc03de 100644
--- a/conformance/failure_list_php_c_32.txt
+++ b/conformance/failure_list_php_c_32.txt
@@ -1,2 +1,4 @@
 Recommended.Proto2.JsonInput.FieldNameExtension.Validator
+Recommended.Proto3.JsonInput.NullValueInOtherOneofNewFormat.Validator
+Recommended.Proto3.JsonInput.NullValueInOtherOneofOldFormat.Validator
 Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator
diff --git a/conformance/failure_list_ruby.txt b/conformance/failure_list_ruby.txt
index ff206dc..1aea145 100644
--- a/conformance/failure_list_ruby.txt
+++ b/conformance/failure_list_ruby.txt
@@ -8,6 +8,9 @@
 Recommended.Proto3.JsonInput.DurationHas6FractionalDigits.Validator
 Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
 Recommended.Proto3.JsonInput.MapFieldValueIsNull
+Recommended.Proto3.JsonInput.NullValueInNormalMessage.Validator
+Recommended.Proto3.JsonInput.NullValueInOtherOneofNewFormat.Validator
+Recommended.Proto3.JsonInput.NullValueInOtherOneofOldFormat.Validator
 Recommended.Proto3.JsonInput.RepeatedFieldMessageElementIsNull
 Recommended.Proto3.JsonInput.RepeatedFieldPrimitiveElementIsNull
 Recommended.Proto3.JsonInput.StringEndsWithEscapeChar
diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs
index 1d49f4c..6f915cb 100644
--- a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs
+++ b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs
@@ -29,7 +29,7 @@
             "dWYvYW55LnByb3RvGh5nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8a",
             "IGdvb2dsZS9wcm90b2J1Zi9maWVsZF9tYXNrLnByb3RvGhxnb29nbGUvcHJv",
             "dG9idWYvc3RydWN0LnByb3RvGh9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1w",
-            "LnByb3RvGh5nb29nbGUvcHJvdG9idWYvd3JhcHBlcnMucHJvdG8iv0QKElRl",
+            "LnByb3RvGh5nb29nbGUvcHJvdG9idWYvd3JhcHBlcnMucHJvdG8isUUKElRl",
             "c3RBbGxUeXBlc1Byb3RvMxIWCg5vcHRpb25hbF9pbnQzMhgBIAEoBRIWCg5v",
             "cHRpb25hbF9pbnQ2NBgCIAEoAxIXCg9vcHRpb25hbF91aW50MzIYAyABKA0S",
             "FwoPb3B0aW9uYWxfdWludDY0GAQgASgEEhcKD29wdGlvbmFsX3NpbnQzMhgF",
@@ -140,99 +140,101 @@
             "IAEoBEgAEhUKC29uZW9mX2Zsb2F0GHUgASgCSAASFgoMb25lb2ZfZG91Ymxl",
             "GHYgASgBSAASUgoKb25lb2ZfZW51bRh3IAEoDjI8LnByb3RvYnVmX3Rlc3Rf",
             "bWVzc2FnZXMucHJvdG8zLlRlc3RBbGxUeXBlc1Byb3RvMy5OZXN0ZWRFbnVt",
-            "SAASOgoVb3B0aW9uYWxfYm9vbF93cmFwcGVyGMkBIAEoCzIaLmdvb2dsZS5w",
-            "cm90b2J1Zi5Cb29sVmFsdWUSPAoWb3B0aW9uYWxfaW50MzJfd3JhcHBlchjK",
-            "ASABKAsyGy5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZRI8ChZvcHRpb25h",
-            "bF9pbnQ2NF93cmFwcGVyGMsBIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQ2",
-            "NFZhbHVlEj4KF29wdGlvbmFsX3VpbnQzMl93cmFwcGVyGMwBIAEoCzIcLmdv",
-            "b2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZRI+ChdvcHRpb25hbF91aW50NjRf",
-            "d3JhcHBlchjNASABKAsyHC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUS",
-            "PAoWb3B0aW9uYWxfZmxvYXRfd3JhcHBlchjOASABKAsyGy5nb29nbGUucHJv",
-            "dG9idWYuRmxvYXRWYWx1ZRI+ChdvcHRpb25hbF9kb3VibGVfd3JhcHBlchjP",
-            "ASABKAsyHC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUSPgoXb3B0aW9u",
-            "YWxfc3RyaW5nX3dyYXBwZXIY0AEgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0",
-            "cmluZ1ZhbHVlEjwKFm9wdGlvbmFsX2J5dGVzX3dyYXBwZXIY0QEgASgLMhsu",
-            "Z29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUSOgoVcmVwZWF0ZWRfYm9vbF93",
-            "cmFwcGVyGNMBIAMoCzIaLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUSPAoW",
-            "cmVwZWF0ZWRfaW50MzJfd3JhcHBlchjUASADKAsyGy5nb29nbGUucHJvdG9i",
-            "dWYuSW50MzJWYWx1ZRI8ChZyZXBlYXRlZF9pbnQ2NF93cmFwcGVyGNUBIAMo",
-            "CzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlEj4KF3JlcGVhdGVkX3Vp",
-            "bnQzMl93cmFwcGVyGNYBIAMoCzIcLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJW",
-            "YWx1ZRI+ChdyZXBlYXRlZF91aW50NjRfd3JhcHBlchjXASADKAsyHC5nb29n",
-            "bGUucHJvdG9idWYuVUludDY0VmFsdWUSPAoWcmVwZWF0ZWRfZmxvYXRfd3Jh",
-            "cHBlchjYASADKAsyGy5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZRI+Chdy",
-            "ZXBlYXRlZF9kb3VibGVfd3JhcHBlchjZASADKAsyHC5nb29nbGUucHJvdG9i",
-            "dWYuRG91YmxlVmFsdWUSPgoXcmVwZWF0ZWRfc3RyaW5nX3dyYXBwZXIY2gEg",
-            "AygLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEjwKFnJlcGVhdGVk",
-            "X2J5dGVzX3dyYXBwZXIY2wEgAygLMhsuZ29vZ2xlLnByb3RvYnVmLkJ5dGVz",
-            "VmFsdWUSNQoRb3B0aW9uYWxfZHVyYXRpb24YrQIgASgLMhkuZ29vZ2xlLnBy",
-            "b3RvYnVmLkR1cmF0aW9uEjcKEm9wdGlvbmFsX3RpbWVzdGFtcBiuAiABKAsy",
-            "Gi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEjgKE29wdGlvbmFsX2ZpZWxk",
-            "X21hc2sYrwIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaxIxCg9v",
-            "cHRpb25hbF9zdHJ1Y3QYsAIgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVj",
-            "dBIrCgxvcHRpb25hbF9hbnkYsQIgASgLMhQuZ29vZ2xlLnByb3RvYnVmLkFu",
-            "eRIvCg5vcHRpb25hbF92YWx1ZRiyAiABKAsyFi5nb29nbGUucHJvdG9idWYu",
-            "VmFsdWUSNQoRcmVwZWF0ZWRfZHVyYXRpb24YtwIgAygLMhkuZ29vZ2xlLnBy",
-            "b3RvYnVmLkR1cmF0aW9uEjcKEnJlcGVhdGVkX3RpbWVzdGFtcBi4AiADKAsy",
-            "Gi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEjcKEnJlcGVhdGVkX2ZpZWxk",
-            "bWFzaxi5AiADKAsyGi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrEjEKD3Jl",
-            "cGVhdGVkX3N0cnVjdBjEAiADKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0",
-            "EisKDHJlcGVhdGVkX2FueRi7AiADKAsyFC5nb29nbGUucHJvdG9idWYuQW55",
-            "Ei8KDnJlcGVhdGVkX3ZhbHVlGLwCIAMoCzIWLmdvb2dsZS5wcm90b2J1Zi5W",
-            "YWx1ZRI4ChNyZXBlYXRlZF9saXN0X3ZhbHVlGL0CIAMoCzIaLmdvb2dsZS5w",
-            "cm90b2J1Zi5MaXN0VmFsdWUSEwoKZmllbGRuYW1lMRiRAyABKAUSFAoLZmll",
-            "bGRfbmFtZTIYkgMgASgFEhUKDF9maWVsZF9uYW1lMxiTAyABKAUSFgoNZmll",
-            "bGRfX25hbWU0XxiUAyABKAUSFAoLZmllbGQwbmFtZTUYlQMgASgFEhYKDWZp",
-            "ZWxkXzBfbmFtZTYYlgMgASgFEhMKCmZpZWxkTmFtZTcYlwMgASgFEhMKCkZp",
-            "ZWxkTmFtZTgYmAMgASgFEhQKC2ZpZWxkX05hbWU5GJkDIAEoBRIVCgxGaWVs",
-            "ZF9OYW1lMTAYmgMgASgFEhUKDEZJRUxEX05BTUUxMRibAyABKAUSFQoMRklF",
-            "TERfbmFtZTEyGJwDIAEoBRIXCg5fX2ZpZWxkX25hbWUxMxidAyABKAUSFwoO",
-            "X19GaWVsZF9uYW1lMTQYngMgASgFEhYKDWZpZWxkX19uYW1lMTUYnwMgASgF",
-            "EhYKDWZpZWxkX19OYW1lMTYYoAMgASgFEhcKDmZpZWxkX25hbWUxN19fGKED",
-            "IAEoBRIXCg5GaWVsZF9uYW1lMThfXxiiAyABKAUaYgoNTmVzdGVkTWVzc2Fn",
-            "ZRIJCgFhGAEgASgFEkYKC2NvcmVjdXJzaXZlGAIgASgLMjEucHJvdG9idWZf",
-            "dGVzdF9tZXNzYWdlcy5wcm90bzMuVGVzdEFsbFR5cGVzUHJvdG8zGjQKEk1h",
-            "cEludDMySW50MzJFbnRyeRILCgNrZXkYASABKAUSDQoFdmFsdWUYAiABKAU6",
-            "AjgBGjQKEk1hcEludDY0SW50NjRFbnRyeRILCgNrZXkYASABKAMSDQoFdmFs",
-            "dWUYAiABKAM6AjgBGjYKFE1hcFVpbnQzMlVpbnQzMkVudHJ5EgsKA2tleRgB",
-            "IAEoDRINCgV2YWx1ZRgCIAEoDToCOAEaNgoUTWFwVWludDY0VWludDY0RW50",
-            "cnkSCwoDa2V5GAEgASgEEg0KBXZhbHVlGAIgASgEOgI4ARo2ChRNYXBTaW50",
-            "MzJTaW50MzJFbnRyeRILCgNrZXkYASABKBESDQoFdmFsdWUYAiABKBE6AjgB",
-            "GjYKFE1hcFNpbnQ2NFNpbnQ2NEVudHJ5EgsKA2tleRgBIAEoEhINCgV2YWx1",
-            "ZRgCIAEoEjoCOAEaOAoWTWFwRml4ZWQzMkZpeGVkMzJFbnRyeRILCgNrZXkY",
-            "ASABKAcSDQoFdmFsdWUYAiABKAc6AjgBGjgKFk1hcEZpeGVkNjRGaXhlZDY0",
-            "RW50cnkSCwoDa2V5GAEgASgGEg0KBXZhbHVlGAIgASgGOgI4ARo6ChhNYXBT",
-            "Zml4ZWQzMlNmaXhlZDMyRW50cnkSCwoDa2V5GAEgASgPEg0KBXZhbHVlGAIg",
-            "ASgPOgI4ARo6ChhNYXBTZml4ZWQ2NFNmaXhlZDY0RW50cnkSCwoDa2V5GAEg",
-            "ASgQEg0KBXZhbHVlGAIgASgQOgI4ARo0ChJNYXBJbnQzMkZsb2F0RW50cnkS",
-            "CwoDa2V5GAEgASgFEg0KBXZhbHVlGAIgASgCOgI4ARo1ChNNYXBJbnQzMkRv",
-            "dWJsZUVudHJ5EgsKA2tleRgBIAEoBRINCgV2YWx1ZRgCIAEoAToCOAEaMgoQ",
-            "TWFwQm9vbEJvb2xFbnRyeRILCgNrZXkYASABKAgSDQoFdmFsdWUYAiABKAg6",
-            "AjgBGjYKFE1hcFN0cmluZ1N0cmluZ0VudHJ5EgsKA2tleRgBIAEoCRINCgV2",
-            "YWx1ZRgCIAEoCToCOAEaNQoTTWFwU3RyaW5nQnl0ZXNFbnRyeRILCgNrZXkY",
-            "ASABKAkSDQoFdmFsdWUYAiABKAw6AjgBGn4KG01hcFN0cmluZ05lc3RlZE1l",
-            "c3NhZ2VFbnRyeRILCgNrZXkYASABKAkSTgoFdmFsdWUYAiABKAsyPy5wcm90",
-            "b2J1Zl90ZXN0X21lc3NhZ2VzLnByb3RvMy5UZXN0QWxsVHlwZXNQcm90bzMu",
-            "TmVzdGVkTWVzc2FnZToCOAEabQocTWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VF",
-            "bnRyeRILCgNrZXkYASABKAkSPAoFdmFsdWUYAiABKAsyLS5wcm90b2J1Zl90",
-            "ZXN0X21lc3NhZ2VzLnByb3RvMy5Gb3JlaWduTWVzc2FnZToCOAEaeAoYTWFw",
-            "U3RyaW5nTmVzdGVkRW51bUVudHJ5EgsKA2tleRgBIAEoCRJLCgV2YWx1ZRgC",
-            "IAEoDjI8LnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8zLlRlc3RBbGxU",
-            "eXBlc1Byb3RvMy5OZXN0ZWRFbnVtOgI4ARpnChlNYXBTdHJpbmdGb3JlaWdu",
-            "RW51bUVudHJ5EgsKA2tleRgBIAEoCRI5CgV2YWx1ZRgCIAEoDjIqLnByb3Rv",
-            "YnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8zLkZvcmVpZ25FbnVtOgI4ASI5CgpO",
-            "ZXN0ZWRFbnVtEgcKA0ZPTxAAEgcKA0JBUhABEgcKA0JBWhACEhAKA05FRxD/",
-            "//////////8BIlkKC0FsaWFzZWRFbnVtEg0KCUFMSUFTX0ZPTxAAEg0KCUFM",
-            "SUFTX0JBUhABEg0KCUFMSUFTX0JBWhACEgcKA1FVWBACEgcKA3F1eBACEgcK",
-            "A2JBehACGgIQAUINCgtvbmVvZl9maWVsZEoGCPUDEP8DIhsKDkZvcmVpZ25N",
-            "ZXNzYWdlEgkKAWMYASABKAUqQAoLRm9yZWlnbkVudW0SDwoLRk9SRUlHTl9G",
-            "T08QABIPCgtGT1JFSUdOX0JBUhABEg8KC0ZPUkVJR05fQkFaEAJCOAooY29t",
-            "Lmdvb2dsZS5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLnByb3RvM0gB+AEBogIG",
-            "UHJvdG8zYgZwcm90bzM="));
+            "SAASNgoQb25lb2ZfbnVsbF92YWx1ZRh4IAEoDjIaLmdvb2dsZS5wcm90b2J1",
+            "Zi5OdWxsVmFsdWVIABI6ChVvcHRpb25hbF9ib29sX3dyYXBwZXIYyQEgASgL",
+            "MhouZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZRI8ChZvcHRpb25hbF9pbnQz",
+            "Ml93cmFwcGVyGMoBIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVl",
+            "EjwKFm9wdGlvbmFsX2ludDY0X3dyYXBwZXIYywEgASgLMhsuZ29vZ2xlLnBy",
+            "b3RvYnVmLkludDY0VmFsdWUSPgoXb3B0aW9uYWxfdWludDMyX3dyYXBwZXIY",
+            "zAEgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlEj4KF29wdGlv",
+            "bmFsX3VpbnQ2NF93cmFwcGVyGM0BIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5V",
+            "SW50NjRWYWx1ZRI8ChZvcHRpb25hbF9mbG9hdF93cmFwcGVyGM4BIAEoCzIb",
+            "Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlEj4KF29wdGlvbmFsX2RvdWJs",
+            "ZV93cmFwcGVyGM8BIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1",
+            "ZRI+ChdvcHRpb25hbF9zdHJpbmdfd3JhcHBlchjQASABKAsyHC5nb29nbGUu",
+            "cHJvdG9idWYuU3RyaW5nVmFsdWUSPAoWb3B0aW9uYWxfYnl0ZXNfd3JhcHBl",
+            "chjRASABKAsyGy5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZRI6ChVyZXBl",
+            "YXRlZF9ib29sX3dyYXBwZXIY0wEgAygLMhouZ29vZ2xlLnByb3RvYnVmLkJv",
+            "b2xWYWx1ZRI8ChZyZXBlYXRlZF9pbnQzMl93cmFwcGVyGNQBIAMoCzIbLmdv",
+            "b2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlEjwKFnJlcGVhdGVkX2ludDY0X3dy",
+            "YXBwZXIY1QEgAygLMhsuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUSPgoX",
+            "cmVwZWF0ZWRfdWludDMyX3dyYXBwZXIY1gEgAygLMhwuZ29vZ2xlLnByb3Rv",
+            "YnVmLlVJbnQzMlZhbHVlEj4KF3JlcGVhdGVkX3VpbnQ2NF93cmFwcGVyGNcB",
+            "IAMoCzIcLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZRI8ChZyZXBlYXRl",
+            "ZF9mbG9hdF93cmFwcGVyGNgBIAMoCzIbLmdvb2dsZS5wcm90b2J1Zi5GbG9h",
+            "dFZhbHVlEj4KF3JlcGVhdGVkX2RvdWJsZV93cmFwcGVyGNkBIAMoCzIcLmdv",
+            "b2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZRI+ChdyZXBlYXRlZF9zdHJpbmdf",
+            "d3JhcHBlchjaASADKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUS",
+            "PAoWcmVwZWF0ZWRfYnl0ZXNfd3JhcHBlchjbASADKAsyGy5nb29nbGUucHJv",
+            "dG9idWYuQnl0ZXNWYWx1ZRI1ChFvcHRpb25hbF9kdXJhdGlvbhitAiABKAsy",
+            "GS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24SNwoSb3B0aW9uYWxfdGltZXN0",
+            "YW1wGK4CIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASOAoTb3B0",
+            "aW9uYWxfZmllbGRfbWFzaxivAiABKAsyGi5nb29nbGUucHJvdG9idWYuRmll",
+            "bGRNYXNrEjEKD29wdGlvbmFsX3N0cnVjdBiwAiABKAsyFy5nb29nbGUucHJv",
+            "dG9idWYuU3RydWN0EisKDG9wdGlvbmFsX2FueRixAiABKAsyFC5nb29nbGUu",
+            "cHJvdG9idWYuQW55Ei8KDm9wdGlvbmFsX3ZhbHVlGLICIAEoCzIWLmdvb2ds",
+            "ZS5wcm90b2J1Zi5WYWx1ZRI4ChNvcHRpb25hbF9udWxsX3ZhbHVlGLMCIAEo",
+            "DjIaLmdvb2dsZS5wcm90b2J1Zi5OdWxsVmFsdWUSNQoRcmVwZWF0ZWRfZHVy",
+            "YXRpb24YtwIgAygLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uEjcKEnJl",
+            "cGVhdGVkX3RpbWVzdGFtcBi4AiADKAsyGi5nb29nbGUucHJvdG9idWYuVGlt",
+            "ZXN0YW1wEjcKEnJlcGVhdGVkX2ZpZWxkbWFzaxi5AiADKAsyGi5nb29nbGUu",
+            "cHJvdG9idWYuRmllbGRNYXNrEjEKD3JlcGVhdGVkX3N0cnVjdBjEAiADKAsy",
+            "Fy5nb29nbGUucHJvdG9idWYuU3RydWN0EisKDHJlcGVhdGVkX2FueRi7AiAD",
+            "KAsyFC5nb29nbGUucHJvdG9idWYuQW55Ei8KDnJlcGVhdGVkX3ZhbHVlGLwC",
+            "IAMoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZRI4ChNyZXBlYXRlZF9saXN0",
+            "X3ZhbHVlGL0CIAMoCzIaLmdvb2dsZS5wcm90b2J1Zi5MaXN0VmFsdWUSEwoK",
+            "ZmllbGRuYW1lMRiRAyABKAUSFAoLZmllbGRfbmFtZTIYkgMgASgFEhUKDF9m",
+            "aWVsZF9uYW1lMxiTAyABKAUSFgoNZmllbGRfX25hbWU0XxiUAyABKAUSFAoL",
+            "ZmllbGQwbmFtZTUYlQMgASgFEhYKDWZpZWxkXzBfbmFtZTYYlgMgASgFEhMK",
+            "CmZpZWxkTmFtZTcYlwMgASgFEhMKCkZpZWxkTmFtZTgYmAMgASgFEhQKC2Zp",
+            "ZWxkX05hbWU5GJkDIAEoBRIVCgxGaWVsZF9OYW1lMTAYmgMgASgFEhUKDEZJ",
+            "RUxEX05BTUUxMRibAyABKAUSFQoMRklFTERfbmFtZTEyGJwDIAEoBRIXCg5f",
+            "X2ZpZWxkX25hbWUxMxidAyABKAUSFwoOX19GaWVsZF9uYW1lMTQYngMgASgF",
+            "EhYKDWZpZWxkX19uYW1lMTUYnwMgASgFEhYKDWZpZWxkX19OYW1lMTYYoAMg",
+            "ASgFEhcKDmZpZWxkX25hbWUxN19fGKEDIAEoBRIXCg5GaWVsZF9uYW1lMThf",
+            "XxiiAyABKAUaYgoNTmVzdGVkTWVzc2FnZRIJCgFhGAEgASgFEkYKC2NvcmVj",
+            "dXJzaXZlGAIgASgLMjEucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5wcm90bzMu",
+            "VGVzdEFsbFR5cGVzUHJvdG8zGjQKEk1hcEludDMySW50MzJFbnRyeRILCgNr",
+            "ZXkYASABKAUSDQoFdmFsdWUYAiABKAU6AjgBGjQKEk1hcEludDY0SW50NjRF",
+            "bnRyeRILCgNrZXkYASABKAMSDQoFdmFsdWUYAiABKAM6AjgBGjYKFE1hcFVp",
+            "bnQzMlVpbnQzMkVudHJ5EgsKA2tleRgBIAEoDRINCgV2YWx1ZRgCIAEoDToC",
+            "OAEaNgoUTWFwVWludDY0VWludDY0RW50cnkSCwoDa2V5GAEgASgEEg0KBXZh",
+            "bHVlGAIgASgEOgI4ARo2ChRNYXBTaW50MzJTaW50MzJFbnRyeRILCgNrZXkY",
+            "ASABKBESDQoFdmFsdWUYAiABKBE6AjgBGjYKFE1hcFNpbnQ2NFNpbnQ2NEVu",
+            "dHJ5EgsKA2tleRgBIAEoEhINCgV2YWx1ZRgCIAEoEjoCOAEaOAoWTWFwRml4",
+            "ZWQzMkZpeGVkMzJFbnRyeRILCgNrZXkYASABKAcSDQoFdmFsdWUYAiABKAc6",
+            "AjgBGjgKFk1hcEZpeGVkNjRGaXhlZDY0RW50cnkSCwoDa2V5GAEgASgGEg0K",
+            "BXZhbHVlGAIgASgGOgI4ARo6ChhNYXBTZml4ZWQzMlNmaXhlZDMyRW50cnkS",
+            "CwoDa2V5GAEgASgPEg0KBXZhbHVlGAIgASgPOgI4ARo6ChhNYXBTZml4ZWQ2",
+            "NFNmaXhlZDY0RW50cnkSCwoDa2V5GAEgASgQEg0KBXZhbHVlGAIgASgQOgI4",
+            "ARo0ChJNYXBJbnQzMkZsb2F0RW50cnkSCwoDa2V5GAEgASgFEg0KBXZhbHVl",
+            "GAIgASgCOgI4ARo1ChNNYXBJbnQzMkRvdWJsZUVudHJ5EgsKA2tleRgBIAEo",
+            "BRINCgV2YWx1ZRgCIAEoAToCOAEaMgoQTWFwQm9vbEJvb2xFbnRyeRILCgNr",
+            "ZXkYASABKAgSDQoFdmFsdWUYAiABKAg6AjgBGjYKFE1hcFN0cmluZ1N0cmlu",
+            "Z0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEaNQoTTWFw",
+            "U3RyaW5nQnl0ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAw6",
+            "AjgBGn4KG01hcFN0cmluZ05lc3RlZE1lc3NhZ2VFbnRyeRILCgNrZXkYASAB",
+            "KAkSTgoFdmFsdWUYAiABKAsyPy5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLnBy",
+            "b3RvMy5UZXN0QWxsVHlwZXNQcm90bzMuTmVzdGVkTWVzc2FnZToCOAEabQoc",
+            "TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VFbnRyeRILCgNrZXkYASABKAkSPAoF",
+            "dmFsdWUYAiABKAsyLS5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLnByb3RvMy5G",
+            "b3JlaWduTWVzc2FnZToCOAEaeAoYTWFwU3RyaW5nTmVzdGVkRW51bUVudHJ5",
+            "EgsKA2tleRgBIAEoCRJLCgV2YWx1ZRgCIAEoDjI8LnByb3RvYnVmX3Rlc3Rf",
+            "bWVzc2FnZXMucHJvdG8zLlRlc3RBbGxUeXBlc1Byb3RvMy5OZXN0ZWRFbnVt",
+            "OgI4ARpnChlNYXBTdHJpbmdGb3JlaWduRW51bUVudHJ5EgsKA2tleRgBIAEo",
+            "CRI5CgV2YWx1ZRgCIAEoDjIqLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJv",
+            "dG8zLkZvcmVpZ25FbnVtOgI4ASI5CgpOZXN0ZWRFbnVtEgcKA0ZPTxAAEgcK",
+            "A0JBUhABEgcKA0JBWhACEhAKA05FRxD///////////8BIlkKC0FsaWFzZWRF",
+            "bnVtEg0KCUFMSUFTX0ZPTxAAEg0KCUFMSUFTX0JBUhABEg0KCUFMSUFTX0JB",
+            "WhACEgcKA1FVWBACEgcKA3F1eBACEgcKA2JBehACGgIQAUINCgtvbmVvZl9m",
+            "aWVsZEoGCPUDEP8DIhsKDkZvcmVpZ25NZXNzYWdlEgkKAWMYASABKAUqQAoL",
+            "Rm9yZWlnbkVudW0SDwoLRk9SRUlHTl9GT08QABIPCgtGT1JFSUdOX0JBUhAB",
+            "Eg8KC0ZPUkVJR05fQkFaEAJCOAooY29tLmdvb2dsZS5wcm90b2J1Zl90ZXN0",
+            "X21lc3NhZ2VzLnByb3RvM0gB+AEBogIGUHJvdG8zYgZwcm90bzM="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.DurationReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.FieldMaskReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor, },
           new pbr::GeneratedClrTypeInfo(new[] {typeof(global::ProtobufTestMessages.Proto3.ForeignEnum), }, null, new pbr::GeneratedClrTypeInfo[] {
-            new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3), global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalNestedMessage", "OptionalForeignMessage", "OptionalNestedEnum", "OptionalForeignEnum", "OptionalAliasedEnum", "OptionalStringPiece", "OptionalCord", "RecursiveMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedStringPiece", "RepeatedCord", "PackedInt32", "PackedInt64", "PackedUint32", "PackedUint64", "PackedSint32", "PackedSint64", "PackedFixed32", "PackedFixed64", "PackedSfixed32", "PackedSfixed64", "PackedFloat", "PackedDouble", "PackedBool", "PackedNestedEnum", "UnpackedInt32", "UnpackedInt64", "UnpackedUint32", "UnpackedUint64", "UnpackedSint32", "UnpackedSint64", "UnpackedFixed32", "UnpackedFixed64", "UnpackedSfixed32", "UnpackedSfixed64", "UnpackedFloat", "UnpackedDouble", "UnpackedBool", "UnpackedNestedEnum", "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapStringBytes", "MapStringNestedMessage", "MapStringForeignMessage", "MapStringNestedEnum", "MapStringForeignEnum", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes", "OneofBool", "OneofUint64", "OneofFloat", "OneofDouble", "OneofEnum", "OptionalBoolWrapper", "OptionalInt32Wrapper", "OptionalInt64Wrapper", "OptionalUint32Wrapper", "OptionalUint64Wrapper", "OptionalFloatWrapper", "OptionalDoubleWrapper", "OptionalStringWrapper", "OptionalBytesWrapper", "RepeatedBoolWrapper", "RepeatedInt32Wrapper", "RepeatedInt64Wrapper", "RepeatedUint32Wrapper", "RepeatedUint64Wrapper", "RepeatedFloatWrapper", "RepeatedDoubleWrapper", "RepeatedStringWrapper", "RepeatedBytesWrapper", "OptionalDuration", "OptionalTimestamp", "OptionalFieldMask", "OptionalStruct", "OptionalAny", "OptionalValue", "RepeatedDuration", "RepeatedTimestamp", "RepeatedFieldmask", "RepeatedStruct", "RepeatedAny", "RepeatedValue", "RepeatedListValue", "Fieldname1", "FieldName2", "FieldName3", "FieldName4", "Field0Name5", "Field0Name6", "FieldName7", "FieldName8", "FieldName9", "FieldName10", "FIELDNAME11", "FIELDName12", "FieldName13", "FieldName14", "FieldName15", "FieldName16", "FieldName17", "FieldName18" }, new[]{ "OneofField" }, new[]{ typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum), typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage), global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage.Parser, new[]{ "A", "Corecursive" }, null, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3), global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalNestedMessage", "OptionalForeignMessage", "OptionalNestedEnum", "OptionalForeignEnum", "OptionalAliasedEnum", "OptionalStringPiece", "OptionalCord", "RecursiveMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedStringPiece", "RepeatedCord", "PackedInt32", "PackedInt64", "PackedUint32", "PackedUint64", "PackedSint32", "PackedSint64", "PackedFixed32", "PackedFixed64", "PackedSfixed32", "PackedSfixed64", "PackedFloat", "PackedDouble", "PackedBool", "PackedNestedEnum", "UnpackedInt32", "UnpackedInt64", "UnpackedUint32", "UnpackedUint64", "UnpackedSint32", "UnpackedSint64", "UnpackedFixed32", "UnpackedFixed64", "UnpackedSfixed32", "UnpackedSfixed64", "UnpackedFloat", "UnpackedDouble", "UnpackedBool", "UnpackedNestedEnum", "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapStringBytes", "MapStringNestedMessage", "MapStringForeignMessage", "MapStringNestedEnum", "MapStringForeignEnum", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes", "OneofBool", "OneofUint64", "OneofFloat", "OneofDouble", "OneofEnum", "OneofNullValue", "OptionalBoolWrapper", "OptionalInt32Wrapper", "OptionalInt64Wrapper", "OptionalUint32Wrapper", "OptionalUint64Wrapper", "OptionalFloatWrapper", "OptionalDoubleWrapper", "OptionalStringWrapper", "OptionalBytesWrapper", "RepeatedBoolWrapper", "RepeatedInt32Wrapper", "RepeatedInt64Wrapper", "RepeatedUint32Wrapper", "RepeatedUint64Wrapper", "RepeatedFloatWrapper", "RepeatedDoubleWrapper", "RepeatedStringWrapper", "RepeatedBytesWrapper", "OptionalDuration", "OptionalTimestamp", "OptionalFieldMask", "OptionalStruct", "OptionalAny", "OptionalValue", "OptionalNullValue", "RepeatedDuration", "RepeatedTimestamp", "RepeatedFieldmask", "RepeatedStruct", "RepeatedAny", "RepeatedValue", "RepeatedListValue", "Fieldname1", "FieldName2", "FieldName3", "FieldName4", "Field0Name5", "Field0Name6", "FieldName7", "FieldName8", "FieldName9", "FieldName10", "FIELDNAME11", "FIELDName12", "FieldName13", "FieldName14", "FieldName15", "FieldName16", "FieldName17", "FieldName18" }, new[]{ "OneofField" }, new[]{ typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum), typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage), global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage.Parser, new[]{ "A", "Corecursive" }, null, null, null, null),
             null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }),
             new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.ForeignMessage), global::ProtobufTestMessages.Proto3.ForeignMessage.Parser, new[]{ "C" }, null, null, null, null)
           }));
@@ -403,6 +405,7 @@
       optionalStruct_ = other.optionalStruct_ != null ? other.optionalStruct_.Clone() : null;
       optionalAny_ = other.optionalAny_ != null ? other.optionalAny_.Clone() : null;
       optionalValue_ = other.optionalValue_ != null ? other.optionalValue_.Clone() : null;
+      optionalNullValue_ = other.optionalNullValue_;
       repeatedDuration_ = other.repeatedDuration_.Clone();
       repeatedTimestamp_ = other.repeatedTimestamp_.Clone();
       repeatedFieldmask_ = other.repeatedFieldmask_.Clone();
@@ -456,6 +459,9 @@
         case OneofFieldOneofCase.OneofEnum:
           OneofEnum = other.OneofEnum;
           break;
+        case OneofFieldOneofCase.OneofNullValue:
+          OneofNullValue = other.OneofNullValue;
+          break;
       }
 
       _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
@@ -1513,6 +1519,17 @@
       }
     }
 
+    /// <summary>Field number for the "oneof_null_value" field.</summary>
+    public const int OneofNullValueFieldNumber = 120;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::Google.Protobuf.WellKnownTypes.NullValue OneofNullValue {
+      get { return oneofFieldCase_ == OneofFieldOneofCase.OneofNullValue ? (global::Google.Protobuf.WellKnownTypes.NullValue) oneofField_ : global::Google.Protobuf.WellKnownTypes.NullValue.NullValue; }
+      set {
+        oneofField_ = value;
+        oneofFieldCase_ = OneofFieldOneofCase.OneofNullValue;
+      }
+    }
+
     /// <summary>Field number for the "optional_bool_wrapper" field.</summary>
     public const int OptionalBoolWrapperFieldNumber = 201;
     private static readonly pb::FieldCodec<bool?> _single_optionalBoolWrapper_codec = pb::FieldCodec.ForStructWrapper<bool>(1610);
@@ -1789,6 +1806,17 @@
       }
     }
 
+    /// <summary>Field number for the "optional_null_value" field.</summary>
+    public const int OptionalNullValueFieldNumber = 307;
+    private global::Google.Protobuf.WellKnownTypes.NullValue optionalNullValue_ = global::Google.Protobuf.WellKnownTypes.NullValue.NullValue;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::Google.Protobuf.WellKnownTypes.NullValue OptionalNullValue {
+      get { return optionalNullValue_; }
+      set {
+        optionalNullValue_ = value;
+      }
+    }
+
     /// <summary>Field number for the "repeated_duration" field.</summary>
     public const int RepeatedDurationFieldNumber = 311;
     private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Duration> _repeated_repeatedDuration_codec
@@ -2074,6 +2102,7 @@
       OneofFloat = 117,
       OneofDouble = 118,
       OneofEnum = 119,
+      OneofNullValue = 120,
     }
     private OneofFieldOneofCase oneofFieldCase_ = OneofFieldOneofCase.None;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2200,6 +2229,7 @@
       if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(OneofFloat, other.OneofFloat)) return false;
       if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(OneofDouble, other.OneofDouble)) return false;
       if (OneofEnum != other.OneofEnum) return false;
+      if (OneofNullValue != other.OneofNullValue) return false;
       if (OptionalBoolWrapper != other.OptionalBoolWrapper) return false;
       if (OptionalInt32Wrapper != other.OptionalInt32Wrapper) return false;
       if (OptionalInt64Wrapper != other.OptionalInt64Wrapper) return false;
@@ -2224,6 +2254,7 @@
       if (!object.Equals(OptionalStruct, other.OptionalStruct)) return false;
       if (!object.Equals(OptionalAny, other.OptionalAny)) return false;
       if (!object.Equals(OptionalValue, other.OptionalValue)) return false;
+      if (OptionalNullValue != other.OptionalNullValue) return false;
       if(!repeatedDuration_.Equals(other.repeatedDuration_)) return false;
       if(!repeatedTimestamp_.Equals(other.repeatedTimestamp_)) return false;
       if(!repeatedFieldmask_.Equals(other.repeatedFieldmask_)) return false;
@@ -2356,6 +2387,7 @@
       if (oneofFieldCase_ == OneofFieldOneofCase.OneofFloat) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(OneofFloat);
       if (oneofFieldCase_ == OneofFieldOneofCase.OneofDouble) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(OneofDouble);
       if (oneofFieldCase_ == OneofFieldOneofCase.OneofEnum) hash ^= OneofEnum.GetHashCode();
+      if (oneofFieldCase_ == OneofFieldOneofCase.OneofNullValue) hash ^= OneofNullValue.GetHashCode();
       if (optionalBoolWrapper_ != null) hash ^= OptionalBoolWrapper.GetHashCode();
       if (optionalInt32Wrapper_ != null) hash ^= OptionalInt32Wrapper.GetHashCode();
       if (optionalInt64Wrapper_ != null) hash ^= OptionalInt64Wrapper.GetHashCode();
@@ -2380,6 +2412,7 @@
       if (optionalStruct_ != null) hash ^= OptionalStruct.GetHashCode();
       if (optionalAny_ != null) hash ^= OptionalAny.GetHashCode();
       if (optionalValue_ != null) hash ^= OptionalValue.GetHashCode();
+      if (OptionalNullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) hash ^= OptionalNullValue.GetHashCode();
       hash ^= repeatedDuration_.GetHashCode();
       hash ^= repeatedTimestamp_.GetHashCode();
       hash ^= repeatedFieldmask_.GetHashCode();
@@ -2618,6 +2651,10 @@
         output.WriteRawTag(184, 7);
         output.WriteEnum((int) OneofEnum);
       }
+      if (oneofFieldCase_ == OneofFieldOneofCase.OneofNullValue) {
+        output.WriteRawTag(192, 7);
+        output.WriteEnum((int) OneofNullValue);
+      }
       if (optionalBoolWrapper_ != null) {
         _single_optionalBoolWrapper_codec.WriteTagAndValue(output, OptionalBoolWrapper);
       }
@@ -2678,6 +2715,10 @@
         output.WriteRawTag(146, 19);
         output.WriteMessage(OptionalValue);
       }
+      if (OptionalNullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) {
+        output.WriteRawTag(152, 19);
+        output.WriteEnum((int) OptionalNullValue);
+      }
       repeatedDuration_.WriteTo(output, _repeated_repeatedDuration_codec);
       repeatedTimestamp_.WriteTo(output, _repeated_repeatedTimestamp_codec);
       repeatedFieldmask_.WriteTo(output, _repeated_repeatedFieldmask_codec);
@@ -2962,6 +3003,10 @@
         output.WriteRawTag(184, 7);
         output.WriteEnum((int) OneofEnum);
       }
+      if (oneofFieldCase_ == OneofFieldOneofCase.OneofNullValue) {
+        output.WriteRawTag(192, 7);
+        output.WriteEnum((int) OneofNullValue);
+      }
       if (optionalBoolWrapper_ != null) {
         _single_optionalBoolWrapper_codec.WriteTagAndValue(ref output, OptionalBoolWrapper);
       }
@@ -3022,6 +3067,10 @@
         output.WriteRawTag(146, 19);
         output.WriteMessage(OptionalValue);
       }
+      if (OptionalNullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) {
+        output.WriteRawTag(152, 19);
+        output.WriteEnum((int) OptionalNullValue);
+      }
       repeatedDuration_.WriteTo(ref output, _repeated_repeatedDuration_codec);
       repeatedTimestamp_.WriteTo(ref output, _repeated_repeatedTimestamp_codec);
       repeatedFieldmask_.WriteTo(ref output, _repeated_repeatedFieldmask_codec);
@@ -3274,6 +3323,9 @@
       if (oneofFieldCase_ == OneofFieldOneofCase.OneofEnum) {
         size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OneofEnum);
       }
+      if (oneofFieldCase_ == OneofFieldOneofCase.OneofNullValue) {
+        size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OneofNullValue);
+      }
       if (optionalBoolWrapper_ != null) {
         size += _single_optionalBoolWrapper_codec.CalculateSizeWithTag(OptionalBoolWrapper);
       }
@@ -3328,6 +3380,9 @@
       if (optionalValue_ != null) {
         size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalValue);
       }
+      if (OptionalNullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) {
+        size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalNullValue);
+      }
       size += repeatedDuration_.CalculateSize(_repeated_repeatedDuration_codec);
       size += repeatedTimestamp_.CalculateSize(_repeated_repeatedTimestamp_codec);
       size += repeatedFieldmask_.CalculateSize(_repeated_repeatedFieldmask_codec);
@@ -3636,6 +3691,9 @@
         }
         OptionalValue.MergeFrom(other.OptionalValue);
       }
+      if (other.OptionalNullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) {
+        OptionalNullValue = other.OptionalNullValue;
+      }
       repeatedDuration_.Add(other.repeatedDuration_);
       repeatedTimestamp_.Add(other.repeatedTimestamp_);
       repeatedFieldmask_.Add(other.repeatedFieldmask_);
@@ -3728,6 +3786,9 @@
         case OneofFieldOneofCase.OneofEnum:
           OneofEnum = other.OneofEnum;
           break;
+        case OneofFieldOneofCase.OneofNullValue:
+          OneofNullValue = other.OneofNullValue;
+          break;
       }
 
       _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
@@ -4202,6 +4263,11 @@
             oneofFieldCase_ = OneofFieldOneofCase.OneofEnum;
             break;
           }
+          case 960: {
+            oneofField_ = input.ReadEnum();
+            oneofFieldCase_ = OneofFieldOneofCase.OneofNullValue;
+            break;
+          }
           case 1610: {
             bool? value = _single_optionalBoolWrapper_codec.Read(input);
             if (optionalBoolWrapper_ == null || value != false) {
@@ -4343,6 +4409,10 @@
             input.ReadMessage(OptionalValue);
             break;
           }
+          case 2456: {
+            OptionalNullValue = (global::Google.Protobuf.WellKnownTypes.NullValue) input.ReadEnum();
+            break;
+          }
           case 2490: {
             repeatedDuration_.AddEntriesFrom(input, _repeated_repeatedDuration_codec);
             break;
@@ -4915,6 +4985,11 @@
             oneofFieldCase_ = OneofFieldOneofCase.OneofEnum;
             break;
           }
+          case 960: {
+            oneofField_ = input.ReadEnum();
+            oneofFieldCase_ = OneofFieldOneofCase.OneofNullValue;
+            break;
+          }
           case 1610: {
             bool? value = _single_optionalBoolWrapper_codec.Read(ref input);
             if (optionalBoolWrapper_ == null || value != false) {
@@ -5056,6 +5131,10 @@
             input.ReadMessage(OptionalValue);
             break;
           }
+          case 2456: {
+            OptionalNullValue = (global::Google.Protobuf.WellKnownTypes.NullValue) input.ReadEnum();
+            break;
+          }
           case 2490: {
             repeatedDuration_.AddEntriesFrom(ref input, _repeated_repeatedDuration_codec);
             break;
diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3Optional.cs b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3Optional.cs
index 451709f..7d3a238 100644
--- a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3Optional.cs
+++ b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3Optional.cs
@@ -55,12 +55,19 @@
             "X2Jvb2xCEgoQX29wdGlvbmFsX3N0cmluZ0IRCg9fb3B0aW9uYWxfYnl0ZXNC",
             "EAoOX29wdGlvbmFsX2NvcmRCGgoYX29wdGlvbmFsX25lc3RlZF9tZXNzYWdl",
             "QhYKFF9sYXp5X25lc3RlZF9tZXNzYWdlQhcKFV9vcHRpb25hbF9uZXN0ZWRf",
-            "ZW51bUIlCiFjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG9QAWIG",
-            "cHJvdG8z"));
+            "ZW51bSKJAgoZVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZRJSCg5uZXN0ZWRf",
+            "bWVzc2FnZRgBIAEoCzI6LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNP",
+            "cHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZRJgChdvcHRpb25hbF9uZXN0",
+            "ZWRfbWVzc2FnZRgCIAEoCzI6LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90",
+            "bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZUgAiAEBGhoKDU5lc3Rl",
+            "ZE1lc3NhZ2USCQoBcxgBIAEoCUIaChhfb3B0aW9uYWxfbmVzdGVkX21lc3Nh",
+            "Z2VCJQohY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvUAFiBnBy",
+            "b3RvMw=="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
-            new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3Optional), global::ProtobufUnittest.TestProto3Optional.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalCord", "OptionalNestedMessage", "LazyNestedMessage", "OptionalNestedEnum", "SingularInt32", "SingularInt64" }, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalCord", "OptionalNestedMessage", "LazyNestedMessage", "OptionalNestedEnum" }, new[]{ typeof(global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage), global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage.Parser, new[]{ "Bb" }, new[]{ "Bb" }, null, null, null)})
+            new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3Optional), global::ProtobufUnittest.TestProto3Optional.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalCord", "OptionalNestedMessage", "LazyNestedMessage", "OptionalNestedEnum", "SingularInt32", "SingularInt64" }, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalCord", "OptionalNestedMessage", "LazyNestedMessage", "OptionalNestedEnum" }, new[]{ typeof(global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage), global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage.Parser, new[]{ "Bb" }, new[]{ "Bb" }, null, null, null)}),
+            new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3OptionalMessage), global::ProtobufUnittest.TestProto3OptionalMessage.Parser, new[]{ "NestedMessage", "OptionalNestedMessage" }, new[]{ "OptionalNestedMessage" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage), global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage.Parser, new[]{ "S" }, null, null, null, null)})
           }));
     }
     #endregion
@@ -1377,6 +1384,411 @@
 
   }
 
+  public sealed partial class TestProto3OptionalMessage : pb::IMessage<TestProto3OptionalMessage>
+  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+      , pb::IBufferMessage
+  #endif
+  {
+    private static readonly pb::MessageParser<TestProto3OptionalMessage> _parser = new pb::MessageParser<TestProto3OptionalMessage>(() => new TestProto3OptionalMessage());
+    private pb::UnknownFieldSet _unknownFields;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<TestProto3OptionalMessage> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::ProtobufUnittest.UnittestProto3OptionalReflection.Descriptor.MessageTypes[1]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public TestProto3OptionalMessage() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public TestProto3OptionalMessage(TestProto3OptionalMessage other) : this() {
+      nestedMessage_ = other.nestedMessage_ != null ? other.nestedMessage_.Clone() : null;
+      optionalNestedMessage_ = other.optionalNestedMessage_ != null ? other.optionalNestedMessage_.Clone() : null;
+      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public TestProto3OptionalMessage Clone() {
+      return new TestProto3OptionalMessage(this);
+    }
+
+    /// <summary>Field number for the "nested_message" field.</summary>
+    public const int NestedMessageFieldNumber = 1;
+    private global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage nestedMessage_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage NestedMessage {
+      get { return nestedMessage_; }
+      set {
+        nestedMessage_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "optional_nested_message" field.</summary>
+    public const int OptionalNestedMessageFieldNumber = 2;
+    private global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage optionalNestedMessage_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage OptionalNestedMessage {
+      get { return optionalNestedMessage_; }
+      set {
+        optionalNestedMessage_ = value;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as TestProto3OptionalMessage);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(TestProto3OptionalMessage other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (!object.Equals(NestedMessage, other.NestedMessage)) return false;
+      if (!object.Equals(OptionalNestedMessage, other.OptionalNestedMessage)) return false;
+      return Equals(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (nestedMessage_ != null) hash ^= NestedMessage.GetHashCode();
+      if (optionalNestedMessage_ != null) hash ^= OptionalNestedMessage.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 (nestedMessage_ != null) {
+        output.WriteRawTag(10);
+        output.WriteMessage(NestedMessage);
+      }
+      if (optionalNestedMessage_ != null) {
+        output.WriteRawTag(18);
+        output.WriteMessage(OptionalNestedMessage);
+      }
+      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 (nestedMessage_ != null) {
+        output.WriteRawTag(10);
+        output.WriteMessage(NestedMessage);
+      }
+      if (optionalNestedMessage_ != null) {
+        output.WriteRawTag(18);
+        output.WriteMessage(OptionalNestedMessage);
+      }
+      if (_unknownFields != null) {
+        _unknownFields.WriteTo(ref output);
+      }
+    }
+    #endif
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (nestedMessage_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(NestedMessage);
+      }
+      if (optionalNestedMessage_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(OptionalNestedMessage);
+      }
+      if (_unknownFields != null) {
+        size += _unknownFields.CalculateSize();
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(TestProto3OptionalMessage other) {
+      if (other == null) {
+        return;
+      }
+      if (other.nestedMessage_ != null) {
+        if (nestedMessage_ == null) {
+          NestedMessage = new global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage();
+        }
+        NestedMessage.MergeFrom(other.NestedMessage);
+      }
+      if (other.optionalNestedMessage_ != null) {
+        if (optionalNestedMessage_ == null) {
+          OptionalNestedMessage = new global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage();
+        }
+        OptionalNestedMessage.MergeFrom(other.OptionalNestedMessage);
+      }
+      _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: {
+            if (nestedMessage_ == null) {
+              NestedMessage = new global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage();
+            }
+            input.ReadMessage(NestedMessage);
+            break;
+          }
+          case 18: {
+            if (optionalNestedMessage_ == null) {
+              OptionalNestedMessage = new global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage();
+            }
+            input.ReadMessage(OptionalNestedMessage);
+            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: {
+            if (nestedMessage_ == null) {
+              NestedMessage = new global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage();
+            }
+            input.ReadMessage(NestedMessage);
+            break;
+          }
+          case 18: {
+            if (optionalNestedMessage_ == null) {
+              OptionalNestedMessage = new global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage();
+            }
+            input.ReadMessage(OptionalNestedMessage);
+            break;
+          }
+        }
+      }
+    }
+    #endif
+
+    #region Nested types
+    /// <summary>Container for nested types declared in the TestProto3OptionalMessage message type.</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static partial class Types {
+      public sealed partial class NestedMessage : pb::IMessage<NestedMessage>
+      #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+          , pb::IBufferMessage
+      #endif
+      {
+        private static readonly pb::MessageParser<NestedMessage> _parser = new pb::MessageParser<NestedMessage>(() => new NestedMessage());
+        private pb::UnknownFieldSet _unknownFields;
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public static pb::MessageParser<NestedMessage> Parser { get { return _parser; } }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public static pbr::MessageDescriptor Descriptor {
+          get { return global::ProtobufUnittest.TestProto3OptionalMessage.Descriptor.NestedTypes[0]; }
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        pbr::MessageDescriptor pb::IMessage.Descriptor {
+          get { return Descriptor; }
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public NestedMessage() {
+          OnConstruction();
+        }
+
+        partial void OnConstruction();
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public NestedMessage(NestedMessage other) : this() {
+          s_ = other.s_;
+          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public NestedMessage Clone() {
+          return new NestedMessage(this);
+        }
+
+        /// <summary>Field number for the "s" field.</summary>
+        public const int SFieldNumber = 1;
+        private string s_ = "";
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public string S {
+          get { return s_; }
+          set {
+            s_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+          }
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public override bool Equals(object other) {
+          return Equals(other as NestedMessage);
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public bool Equals(NestedMessage other) {
+          if (ReferenceEquals(other, null)) {
+            return false;
+          }
+          if (ReferenceEquals(other, this)) {
+            return true;
+          }
+          if (S != other.S) return false;
+          return Equals(_unknownFields, other._unknownFields);
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public override int GetHashCode() {
+          int hash = 1;
+          if (S.Length != 0) hash ^= S.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 (S.Length != 0) {
+            output.WriteRawTag(10);
+            output.WriteString(S);
+          }
+          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 (S.Length != 0) {
+            output.WriteRawTag(10);
+            output.WriteString(S);
+          }
+          if (_unknownFields != null) {
+            _unknownFields.WriteTo(ref output);
+          }
+        }
+        #endif
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public int CalculateSize() {
+          int size = 0;
+          if (S.Length != 0) {
+            size += 1 + pb::CodedOutputStream.ComputeStringSize(S);
+          }
+          if (_unknownFields != null) {
+            size += _unknownFields.CalculateSize();
+          }
+          return size;
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public void MergeFrom(NestedMessage other) {
+          if (other == null) {
+            return;
+          }
+          if (other.S.Length != 0) {
+            S = other.S;
+          }
+          _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: {
+                S = 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: {
+                S = input.ReadString();
+                break;
+              }
+            }
+          }
+        }
+        #endif
+
+      }
+
+    }
+    #endregion
+
+  }
+
   #endregion
 
 }
diff --git a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
index df92228..0a1f4a7 100644
--- a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
@@ -155,10 +155,9 @@
             "dGF0aW9uGAEgAygLMi0uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJ",
             "bmZvLkFubm90YXRpb24aTwoKQW5ub3RhdGlvbhIQCgRwYXRoGAEgAygFQgIQ",
             "ARITCgtzb3VyY2VfZmlsZRgCIAEoCRINCgViZWdpbhgDIAEoBRILCgNlbmQY",
-            "BCABKAVCjwEKE2NvbS5nb29nbGUucHJvdG9idWZCEERlc2NyaXB0b3JQcm90",
-            "b3NIAVo+Z2l0aHViLmNvbS9nb2xhbmcvcHJvdG9idWYvcHJvdG9jLWdlbi1n",
-            "by9kZXNjcmlwdG9yO2Rlc2NyaXB0b3L4AQGiAgNHUEKqAhpHb29nbGUuUHJv",
-            "dG9idWYuUmVmbGVjdGlvbg=="));
+            "BCABKAVCfgoTY29tLmdvb2dsZS5wcm90b2J1ZkIQRGVzY3JpcHRvclByb3Rv",
+            "c0gBWi1nb29nbGUuZ29sYW5nLm9yZy9wcm90b2J1Zi90eXBlcy9kZXNjcmlw",
+            "dG9ycGL4AQGiAgNHUEKqAhpHb29nbGUuUHJvdG9idWYuUmVmbGVjdGlvbg=="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
index 2b33cd4..60ae03d 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
@@ -25,10 +25,10 @@
       byte[] descriptorData = global::System.Convert.FromBase64String(
           string.Concat(
             "Chlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvEg9nb29nbGUucHJvdG9idWYi",
-            "JgoDQW55EhAKCHR5cGVfdXJsGAEgASgJEg0KBXZhbHVlGAIgASgMQm8KE2Nv",
-            "bS5nb29nbGUucHJvdG9idWZCCEFueVByb3RvUAFaJWdpdGh1Yi5jb20vZ29s",
-            "YW5nL3Byb3RvYnVmL3B0eXBlcy9hbnmiAgNHUEKqAh5Hb29nbGUuUHJvdG9i",
-            "dWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
+            "JgoDQW55EhAKCHR5cGVfdXJsGAEgASgJEg0KBXZhbHVlGAIgASgMQnYKE2Nv",
+            "bS5nb29nbGUucHJvdG9idWZCCEFueVByb3RvUAFaLGdvb2dsZS5nb2xhbmcu",
+            "b3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL2FueXBiogIDR1BCqgIeR29vZ2xl",
+            "LlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90bzM="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
@@ -78,10 +78,13 @@
   ///  Example 4: Pack and unpack a message in Go
   ///
   ///      foo := &amp;pb.Foo{...}
-  ///      any, err := ptypes.MarshalAny(foo)
+  ///      any, err := anypb.New(foo)
+  ///      if err != nil {
+  ///        ...
+  ///      }
   ///      ...
   ///      foo := &amp;pb.Foo{}
-  ///      if err := ptypes.UnmarshalAny(any, foo); err != nil {
+  ///      if err := any.UnmarshalTo(foo); err != nil {
   ///        ...
   ///      }
   ///
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
index a323a56..7c65ac7 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
@@ -37,10 +37,10 @@
             "ChFyZXNwb25zZV90eXBlX3VybBgEIAEoCRIaChJyZXNwb25zZV9zdHJlYW1p",
             "bmcYBSABKAgSKAoHb3B0aW9ucxgGIAMoCzIXLmdvb2dsZS5wcm90b2J1Zi5P",
             "cHRpb24SJwoGc3ludGF4GAcgASgOMhcuZ29vZ2xlLnByb3RvYnVmLlN5bnRh",
-            "eCIjCgVNaXhpbhIMCgRuYW1lGAEgASgJEgwKBHJvb3QYAiABKAlCdQoTY29t",
-            "Lmdvb2dsZS5wcm90b2J1ZkIIQXBpUHJvdG9QAVorZ29vZ2xlLmdvbGFuZy5v",
-            "cmcvZ2VucHJvdG8vcHJvdG9idWYvYXBpO2FwaaICA0dQQqoCHkdvb2dsZS5Q",
-            "cm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8z"));
+            "eCIjCgVNaXhpbhIMCgRuYW1lGAEgASgJEgwKBHJvb3QYAiABKAlCdgoTY29t",
+            "Lmdvb2dsZS5wcm90b2J1ZkIIQXBpUHJvdG9QAVosZ29vZ2xlLmdvbGFuZy5v",
+            "cmcvcHJvdG9idWYvdHlwZXMva25vd24vYXBpcGKiAgNHUEKqAh5Hb29nbGUu",
+            "UHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor, },
           new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
index 2d479ba..2a653a3 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
@@ -26,10 +26,10 @@
           string.Concat(
             "Ch5nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8SD2dvb2dsZS5wcm90",
             "b2J1ZiIqCghEdXJhdGlvbhIPCgdzZWNvbmRzGAEgASgDEg0KBW5hbm9zGAIg",
-            "ASgFQnwKE2NvbS5nb29nbGUucHJvdG9idWZCDUR1cmF0aW9uUHJvdG9QAVoq",
-            "Z2l0aHViLmNvbS9nb2xhbmcvcHJvdG9idWYvcHR5cGVzL2R1cmF0aW9u+AEB",
-            "ogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90",
-            "bzM="));
+            "ASgFQoMBChNjb20uZ29vZ2xlLnByb3RvYnVmQg1EdXJhdGlvblByb3RvUAFa",
+            "MWdvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL2R1cmF0",
+            "aW9ucGL4AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlw",
+            "ZXNiBnByb3RvMw=="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
index ce820cb..e2e3518 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
@@ -25,10 +25,10 @@
       byte[] descriptorData = global::System.Convert.FromBase64String(
           string.Concat(
             "Chtnb29nbGUvcHJvdG9idWYvZW1wdHkucHJvdG8SD2dvb2dsZS5wcm90b2J1",
-            "ZiIHCgVFbXB0eUJ2ChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3Rv",
-            "UAFaJ2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy9lbXB0efgB",
-            "AaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJv",
-            "dG8z"));
+            "ZiIHCgVFbXB0eUJ9ChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3Rv",
+            "UAFaLmdvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL2Vt",
+            "cHR5cGL4AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlw",
+            "ZXNiBnByb3RvMw=="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
index ee53861..d5da314 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
@@ -25,11 +25,10 @@
       byte[] descriptorData = global::System.Convert.FromBase64String(
           string.Concat(
             "CiBnb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wcm90bxIPZ29vZ2xlLnBy",
-            "b3RvYnVmIhoKCUZpZWxkTWFzaxINCgVwYXRocxgBIAMoCUKMAQoTY29tLmdv",
-            "b2dsZS5wcm90b2J1ZkIORmllbGRNYXNrUHJvdG9QAVo5Z29vZ2xlLmdvbGFu",
-            "Zy5vcmcvZ2VucHJvdG8vcHJvdG9idWYvZmllbGRfbWFzaztmaWVsZF9tYXNr",
-            "+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZw",
-            "cm90bzM="));
+            "b3RvYnVmIhoKCUZpZWxkTWFzaxINCgVwYXRocxgBIAMoCUKFAQoTY29tLmdv",
+            "b2dsZS5wcm90b2J1ZkIORmllbGRNYXNrUHJvdG9QAVoyZ29vZ2xlLmdvbGFu",
+            "Zy5vcmcvcHJvdG9idWYvdHlwZXMva25vd24vZmllbGRtYXNrcGL4AQGiAgNH",
+            "UEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
index 38240bb..5fe9b89 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
@@ -26,10 +26,10 @@
           string.Concat(
             "CiRnb29nbGUvcHJvdG9idWYvc291cmNlX2NvbnRleHQucHJvdG8SD2dvb2ds",
             "ZS5wcm90b2J1ZiIiCg1Tb3VyY2VDb250ZXh0EhEKCWZpbGVfbmFtZRgBIAEo",
-            "CUKVAQoTY29tLmdvb2dsZS5wcm90b2J1ZkISU291cmNlQ29udGV4dFByb3Rv",
-            "UAFaQWdvb2dsZS5nb2xhbmcub3JnL2dlbnByb3RvL3Byb3RvYnVmL3NvdXJj",
-            "ZV9jb250ZXh0O3NvdXJjZV9jb250ZXh0ogIDR1BCqgIeR29vZ2xlLlByb3Rv",
-            "YnVmLldlbGxLbm93blR5cGVzYgZwcm90bzM="));
+            "CUKKAQoTY29tLmdvb2dsZS5wcm90b2J1ZkISU291cmNlQ29udGV4dFByb3Rv",
+            "UAFaNmdvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL3Nv",
+            "dXJjZWNvbnRleHRwYqICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25v",
+            "d25UeXBlc2IGcHJvdG8z"));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
index 42d37ca..0bbb1fc 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
@@ -35,10 +35,10 @@
             "ABIwCgpsaXN0X3ZhbHVlGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLkxpc3RW",
             "YWx1ZUgAQgYKBGtpbmQiMwoJTGlzdFZhbHVlEiYKBnZhbHVlcxgBIAMoCzIW",
             "Lmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSobCglOdWxsVmFsdWUSDgoKTlVMTF9W",
-            "QUxVRRAAQoEBChNjb20uZ29vZ2xlLnByb3RvYnVmQgtTdHJ1Y3RQcm90b1AB",
-            "WjFnaXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wdHlwZXMvc3RydWN0O3N0",
-            "cnVjdHBi+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5",
-            "cGVzYgZwcm90bzM="));
+            "QUxVRRAAQn8KE2NvbS5nb29nbGUucHJvdG9idWZCC1N0cnVjdFByb3RvUAFa",
+            "L2dvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL3N0cnVj",
+            "dHBi+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVz",
+            "YgZwcm90bzM="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.NullValue), }, null, new pbr::GeneratedClrTypeInfo[] {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
index b2f5d35..2fb1b4d 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
@@ -26,10 +26,10 @@
           string.Concat(
             "Ch9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvEg9nb29nbGUucHJv",
             "dG9idWYiKwoJVGltZXN0YW1wEg8KB3NlY29uZHMYASABKAMSDQoFbmFub3MY",
-            "AiABKAVCfgoTY29tLmdvb2dsZS5wcm90b2J1ZkIOVGltZXN0YW1wUHJvdG9Q",
-            "AVorZ2l0aHViLmNvbS9nb2xhbmcvcHJvdG9idWYvcHR5cGVzL3RpbWVzdGFt",
-            "cPgBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IG",
-            "cHJvdG8z"));
+            "AiABKAVChQEKE2NvbS5nb29nbGUucHJvdG9idWZCDlRpbWVzdGFtcFByb3Rv",
+            "UAFaMmdvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL3Rp",
+            "bWVzdGFtcHBi+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93",
+            "blR5cGVzYgZwcm90bzM="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
@@ -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/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
index c62095a..f5dfdb7 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
@@ -56,10 +56,10 @@
             "ASgFEigKB29wdGlvbnMYAyADKAsyFy5nb29nbGUucHJvdG9idWYuT3B0aW9u",
             "IjsKBk9wdGlvbhIMCgRuYW1lGAEgASgJEiMKBXZhbHVlGAIgASgLMhQuZ29v",
             "Z2xlLnByb3RvYnVmLkFueSouCgZTeW50YXgSEQoNU1lOVEFYX1BST1RPMhAA",
-            "EhEKDVNZTlRBWF9QUk9UTzMQAUJ9ChNjb20uZ29vZ2xlLnByb3RvYnVmQglU",
-            "eXBlUHJvdG9QAVovZ29vZ2xlLmdvbGFuZy5vcmcvZ2VucHJvdG8vcHJvdG9i",
-            "dWYvcHR5cGU7cHR5cGX4AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2Vs",
-            "bEtub3duVHlwZXNiBnByb3RvMw=="));
+            "EhEKDVNZTlRBWF9QUk9UTzMQAUJ7ChNjb20uZ29vZ2xlLnByb3RvYnVmQglU",
+            "eXBlUHJvdG9QAVotZ29vZ2xlLmdvbGFuZy5vcmcvcHJvdG9idWYvdHlwZXMv",
+            "a25vd24vdHlwZXBi+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxL",
+            "bm93blR5cGVzYgZwcm90bzM="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, },
           new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.Syntax), }, null, new pbr::GeneratedClrTypeInfo[] {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
index 5bf47dc..01d3121 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
@@ -30,10 +30,11 @@
             "KAMiHAoLVUludDY0VmFsdWUSDQoFdmFsdWUYASABKAQiGwoKSW50MzJWYWx1",
             "ZRINCgV2YWx1ZRgBIAEoBSIcCgtVSW50MzJWYWx1ZRINCgV2YWx1ZRgBIAEo",
             "DSIaCglCb29sVmFsdWUSDQoFdmFsdWUYASABKAgiHAoLU3RyaW5nVmFsdWUS",
-            "DQoFdmFsdWUYASABKAkiGwoKQnl0ZXNWYWx1ZRINCgV2YWx1ZRgBIAEoDEJ8",
-            "ChNjb20uZ29vZ2xlLnByb3RvYnVmQg1XcmFwcGVyc1Byb3RvUAFaKmdpdGh1",
-            "Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy93cmFwcGVyc/gBAaICA0dQ",
-            "QqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8z"));
+            "DQoFdmFsdWUYASABKAkiGwoKQnl0ZXNWYWx1ZRINCgV2YWx1ZRgBIAEoDEKD",
+            "AQoTY29tLmdvb2dsZS5wcm90b2J1ZkINV3JhcHBlcnNQcm90b1ABWjFnb29n",
+            "bGUuZ29sYW5nLm9yZy9wcm90b2J1Zi90eXBlcy9rbm93bi93cmFwcGVyc3Bi",
+            "+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZw",
+            "cm90bzM="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
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/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/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/gulpfile.js b/js/gulpfile.js
index 2e72a88..8137b90 100644
--- a/js/gulpfile.js
+++ b/js/gulpfile.js
@@ -71,13 +71,16 @@
   });
 });
 
-gulp.task('genproto_group2_closure', function (cb) {
-  exec(protoc + ' --experimental_allow_proto3_optional --js_out=library=testproto_libs2,binary:.  -I ../src -I . -I commonjs ' + group2Protos.join(' '),
-       function (err, stdout, stderr) {
-    console.log(stdout);
-    console.log(stderr);
-    cb(err);
-  });
+gulp.task('genproto_group2_closure', function(cb) {
+  exec(
+      protoc +
+          ' --experimental_allow_proto3_optional --js_out=library=testproto_libs2,binary:.  -I ../src -I . -I commonjs ' +
+          group2Protos.join(' '),
+      function(err, stdout, stderr) {
+        console.log(stdout);
+        console.log(stderr);
+        cb(err);
+      });
 });
 
 gulp.task('genproto_well_known_types_commonjs', function (cb) {
@@ -98,13 +101,16 @@
   });
 });
 
-gulp.task('genproto_group2_commonjs', function (cb) {
-  exec('mkdir -p commonjs_out && ' + protoc + ' --experimental_allow_proto3_optional --js_out=import_style=commonjs,binary:commonjs_out -I ../src -I commonjs -I . ' + group2Protos.join(' '),
-       function (err, stdout, stderr) {
-    console.log(stdout);
-    console.log(stderr);
-    cb(err);
-  });
+gulp.task('genproto_group2_commonjs', function(cb) {
+  exec(
+      'mkdir -p commonjs_out && ' + protoc +
+          ' --experimental_allow_proto3_optional --js_out=import_style=commonjs,binary:commonjs_out -I ../src -I commonjs -I . ' +
+          group2Protos.join(' '),
+      function(err, stdout, stderr) {
+        console.log(stdout);
+        console.log(stderr);
+        cb(err);
+      });
 });
 
 gulp.task('genproto_commonjs_wellknowntypes', function (cb) {
diff --git a/js/proto3_test.js b/js/proto3_test.js
index bd7cce5..fd59ae5 100644
--- a/js/proto3_test.js
+++ b/js/proto3_test.js
@@ -130,8 +130,8 @@
     assertEquals(msg.getSingularBytes_asU8().length, 0);
     assertEquals(msg.getSingularBytes_asB64(), '');
 
-    assertEquals(msg.getSingularForeignEnum(),
-                 proto.jspb.test.Proto3Enum.PROTO3_FOO);
+    assertEquals(
+        msg.getSingularForeignEnum(), proto.jspb.test.Proto3Enum.PROTO3_FOO);
     assertEquals(msg.getSingularForeignMessage(), undefined);
     assertEquals(msg.getSingularForeignMessage(), undefined);
 
@@ -201,7 +201,7 @@
     assertTrue(msg.hasOptionalInt64());
 
     assertFalse(msg.hasOptionalString());
-    msg.setOptionalString("");
+    msg.setOptionalString('');
     assertTrue(msg.hasOptionalString());
 
     // Now the proto will have a non-zero size, even though its values are 0.
@@ -224,7 +224,7 @@
   /**
    * Test that all fields can be set ,and read via a serialization roundtrip.
    */
-  it('testProto3FieldSetGet', function () {
+  it('testProto3FieldSetGet', function() {
     var msg = new proto.jspb.test.TestProto3();
 
     msg.setSingularInt32(-42);
@@ -288,8 +288,8 @@
     assertEquals(msg.getSingularString(), 'hello world');
     assertEquals(true, bytesCompare(msg.getSingularBytes(), BYTES));
     assertEquals(msg.getSingularForeignMessage().getC(), 16);
-    assertEquals(msg.getSingularForeignEnum(),
-        proto.jspb.test.Proto3Enum.PROTO3_BAR);
+    assertEquals(
+        msg.getSingularForeignEnum(), proto.jspb.test.Proto3Enum.PROTO3_BAR);
 
     assertElementsEquals(msg.getRepeatedInt32List(), [-42]);
     assertElementsEquals(msg.getRepeatedInt64List(), [-0x7fffffff00000000]);
diff --git a/js/proto3_test.proto b/js/proto3_test.proto
index 1f6bbed..14f104e 100644
--- a/js/proto3_test.proto
+++ b/js/proto3_test.proto
@@ -30,10 +30,10 @@
 
 syntax = "proto3";
 
-import "testbinary.proto";
-
 package jspb.test;
 
+import "testbinary.proto";
+
 message TestProto3 {
   int32 singular_int32 = 1;
   int64 singular_int64 = 2;
@@ -71,7 +71,7 @@
   optional bytes optional_bytes = 135;
 
   optional ForeignMessage optional_foreign_message = 136;
-  optional Proto3Enum optional_foreign_enum =137;
+  optional Proto3Enum optional_foreign_enum = 137;
 
   repeated int32 repeated_int32 = 31;
   repeated int64 repeated_int64 = 32;
@@ -92,7 +92,6 @@
   repeated ForeignMessage repeated_foreign_message = 49;
   repeated Proto3Enum repeated_foreign_enum = 52;
 
-
   oneof oneof_field {
     uint32 oneof_uint32 = 111;
     ForeignMessage oneof_foreign_message = 112;
diff --git a/objectivec/GPBAny.pbobjc.h b/objectivec/GPBAny.pbobjc.h
index 288d552..21b7dcf 100644
--- a/objectivec/GPBAny.pbobjc.h
+++ b/objectivec/GPBAny.pbobjc.h
@@ -94,10 +94,13 @@
  *  Example 4: Pack and unpack a message in Go
  *
  *      foo := &pb.Foo{...}
- *      any, err := ptypes.MarshalAny(foo)
+ *      any, err := anypb.New(foo)
+ *      if err != nil {
+ *        ...
+ *      }
  *      ...
  *      foo := &pb.Foo{}
- *      if err := ptypes.UnmarshalAny(any, foo); err != nil {
+ *      if err := any.UnmarshalTo(foo); err != nil {
  *        ...
  *      }
  *
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/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/google/protobuf/internal/json_format_test.py b/python/google/protobuf/internal/json_format_test.py
index 2fa951a..4310115 100755
--- a/python/google/protobuf/internal/json_format_test.py
+++ b/python/google/protobuf/internal/json_format_test.py
@@ -636,6 +636,20 @@
     parsed_message = json_format_proto3_pb2.TestListValue()
     self.CheckParseBack(message, parsed_message)
 
+  def testNullValue(self):
+    message = json_format_proto3_pb2.TestOneof()
+    message.oneof_null_value = 0
+    self.assertEqual(json_format.MessageToJson(message),
+                     '{\n  "oneofNullValue": null\n}')
+    parsed_message = json_format_proto3_pb2.TestOneof()
+    self.CheckParseBack(message, parsed_message)
+    # Check old format is also accepted
+    new_message = json_format_proto3_pb2.TestOneof()
+    json_format.Parse('{\n  "oneofNullValue": "NULL_VALUE"\n}',
+                      new_message)
+    self.assertEqual(json_format.MessageToJson(new_message),
+                     '{\n  "oneofNullValue": null\n}')
+
   def testAnyMessage(self):
     message = json_format_proto3_pb2.TestAny()
     value1 = json_format_proto3_pb2.MessageType()
diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py
index 9e84185..987116a 100755
--- a/python/google/protobuf/internal/text_format_test.py
+++ b/python/google/protobuf/internal/text_format_test.py
@@ -142,6 +142,8 @@
     message.repeated_float.append(1.234e10)
     message.repeated_float.append(1.2345e10)
     message.repeated_float.append(1.23456e10)
+    message.repeated_float.append(float('NaN'))
+    message.repeated_float.append(float('inf'))
     message.repeated_double.append(0.0)
     message.repeated_double.append(0.8)
     message.repeated_double.append(1.0)
@@ -190,6 +192,8 @@
         'repeated_float: 12340000000\n'
         'repeated_float: 12345000000\n'
         'repeated_float: 12345600000\n'
+        'repeated_float: nan\n'
+        'repeated_float: inf\n'
         'repeated_double: 0\n'
         'repeated_double: 0.8\n'
         'repeated_double: 1\n'
diff --git a/python/google/protobuf/internal/type_checkers.py b/python/google/protobuf/internal/type_checkers.py
index bfde1c3..eb66f9f 100644
--- a/python/google/protobuf/internal/type_checkers.py
+++ b/python/google/protobuf/internal/type_checkers.py
@@ -74,11 +74,6 @@
 
 def ToShortestFloat(original):
   """Returns the shortest float that has same value in wire."""
-  # Return the original value if it is not truncated. This may happen
-  # if someone mixes this code with an old protobuf runtime.
-  # TODO(jieluo): Remove it after maybe 2022.
-  if TruncateToFourByteFloat(original) != original:
-    return original
   # All 4 byte floats have between 6 and 9 significant digits, so we
   # start with 6 as the lower bound.
   # It has to be iterative because use '.9g' directly can not get rid
diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py
index 4d76d02..c8f5602 100644
--- a/python/google/protobuf/json_format.py
+++ b/python/google/protobuf/json_format.py
@@ -286,6 +286,8 @@
     elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM:
       if self.use_integers_for_enums:
         return value
+      if field.enum_type.full_name == 'google.protobuf.NullValue':
+        return None
       enum_value = field.enum_type.values_by_number.get(value, None)
       if enum_value is not None:
         return enum_value.name
@@ -544,6 +546,9 @@
               and field.message_type.full_name == 'google.protobuf.Value'):
             sub_message = getattr(message, field.name)
             sub_message.null_value = 0
+          elif (field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM
+                and field.enum_type.full_name == 'google.protobuf.NullValue'):
+            setattr(message, field.name, 0)
           else:
             message.ClearField(field.name)
           continue
diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py
index 8387218..2a9a866 100644
--- a/python/google/protobuf/text_format.py
+++ b/python/google/protobuf/text_format.py
@@ -46,19 +46,19 @@
 import encodings.raw_unicode_escape  # pylint: disable=unused-import
 import encodings.unicode_escape  # pylint: disable=unused-import
 import io
+import math
 import re
-
 import six
 
-if six.PY3:
-  long = int  # pylint: disable=redefined-builtin,invalid-name
-
-# pylint: disable=g-import-not-at-top
 from google.protobuf.internal import decoder
 from google.protobuf.internal import type_checkers
 from google.protobuf import descriptor
 from google.protobuf import text_encoding
 
+if six.PY3:
+  long = int  # pylint: disable=redefined-builtin,invalid-name
+
+# pylint: disable=g-import-not-at-top
 __all__ = ['MessageToString', 'Parse', 'PrintMessage', 'PrintField',
            'PrintFieldValue', 'Merge', 'MessageToBytes']
 
@@ -630,7 +630,10 @@
       if self.float_format is not None:
         out.write('{1:{0}}'.format(self.float_format, value))
       else:
-        out.write(str(type_checkers.ToShortestFloat(value)))
+        if math.isnan(value):
+          out.write(str(value))
+        else:
+          out.write(str(type_checkers.ToShortestFloat(value)))
     elif (field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_DOUBLE and
           self.double_format is not None):
       out.write('{1:{0}}'.format(self.double_format, value))
diff --git a/src/Makefile.am b/src/Makefile.am
index 1001abc..b8b1479 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 a79214b..ebe9ba7 100644
--- a/src/google/protobuf/any.cc
+++ b/src/google/protobuf/any.cc
@@ -46,19 +46,21 @@
 }
 
 void AnyMetadata::PackFrom(const Message& message,
-                           const std::string& type_url_prefix) {
-  type_url_->SetNoArena(
+                           StringPiece type_url_prefix) {
+  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.h b/src/google/protobuf/any.h
index 59dd50c..16a68ca 100644
--- a/src/google/protobuf/any.h
+++ b/src/google/protobuf/any.h
@@ -82,7 +82,7 @@
     InternalPackFrom(message, type_url_prefix, T::FullMessageName());
   }
 
-  void PackFrom(const Message& message, const std::string& type_url_prefix);
+  void PackFrom(const Message& message, StringPiece type_url_prefix);
 
   // Unpacks the payload into the given message. Returns false if the message's
   // type doesn't match the type specified in the type URL (i.e., the full
@@ -124,14 +124,14 @@
 //
 // NOTE: this function is available publicly as:
 //   google::protobuf::Any()  // static method on the generated message type.
-bool ParseAnyTypeUrl(const std::string& type_url, std::string* full_type_name);
+bool ParseAnyTypeUrl(StringPiece type_url, std::string* full_type_name);
 
 // Get the proto type name and prefix from Any::type_url value. For example,
 // passing "type.googleapis.com/rpc.QueryOrigin" will return
 // "type.googleapis.com/" in *url_prefix and "rpc.QueryOrigin" in
 // *full_type_name. Returns false if the type_url does not have a "/" in the
 // type url separating the full type name.
-bool ParseAnyTypeUrl(const std::string& type_url, std::string* url_prefix,
+bool ParseAnyTypeUrl(StringPiece type_url, std::string* url_prefix,
                      std::string* full_type_name);
 
 // See if message is of type google.protobuf.Any, if so, return the descriptors
diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc
index 1eba999..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 =
@@ -58,10 +57,10 @@
 const char descriptor_table_protodef_google_2fprotobuf_2fany_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n\031google/protobuf/any.proto\022\017google.prot"
   "obuf\"&\n\003Any\022\020\n\010type_url\030\001 \001(\t\022\r\n\005value\030\002"
-  " \001(\014Bo\n\023com.google.protobufB\010AnyProtoP\001Z"
-  "%github.com/golang/protobuf/ptypes/any\242\002"
-  "\003GPB\252\002\036Google.Protobuf.WellKnownTypesb\006p"
-  "roto3"
+  " \001(\014Bv\n\023com.google.protobufB\010AnyProtoP\001Z"
+  ",google.golang.org/protobuf/types/known/"
+  "anypb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownT"
+  "ypesb\006proto3"
   ;
 static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fany_2eproto_deps[1] = {
 };
@@ -70,7 +69,7 @@
 };
 static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fany_2eproto_once;
 const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto = {
-  false, false, descriptor_table_protodef_google_2fprotobuf_2fany_2eproto, "google/protobuf/any.proto", 205,
+  false, false, descriptor_table_protodef_google_2fprotobuf_2fany_2eproto, "google/protobuf/any.proto", 212,
   &descriptor_table_google_2fprotobuf_2fany_2eproto_once, descriptor_table_google_2fprotobuf_2fany_2eproto_sccs, descriptor_table_google_2fprotobuf_2fany_2eproto_deps, 1, 0,
   schemas, file_default_instances, TableStruct_google_2fprotobuf_2fany_2eproto::offsets,
   file_level_metadata_google_2fprotobuf_2fany_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto, file_level_service_descriptors_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,
@@ -91,8 +88,9 @@
   return ::PROTOBUF_NAMESPACE_ID::internal::GetAnyFieldDescriptors(
       message, type_url_field, value_field);
 }
-bool Any::ParseAnyTypeUrl(const string& type_url,
-                                  std::string* full_type_name) {
+bool Any::ParseAnyTypeUrl(
+    ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url,
+    std::string* full_type_name) {
   return ::PROTOBUF_NAMESPACE_ID::internal::ParseAnyTypeUrl(type_url,
                                              full_type_name);
 }
diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h
index f071b11..ec18f3a 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_);
@@ -116,7 +115,7 @@
     _any_metadata_.PackFrom(message);
   }
   void PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message,
-                const std::string& type_url_prefix) {
+                ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix) {
     _any_metadata_.PackFrom(message, type_url_prefix);
   }
   bool UnpackTo(::PROTOBUF_NAMESPACE_ID::Message* message) const {
@@ -132,7 +131,7 @@
   }
   template <typename T, class = typename std::enable_if<!std::is_convertible<T, const ::PROTOBUF_NAMESPACE_ID::Message&>::value>::type>
   void PackFrom(const T& message,
-                const std::string& type_url_prefix) {
+                ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix) {
     _any_metadata_.PackFrom<T>(message, type_url_prefix);}
   template <typename T, class = typename std::enable_if<!std::is_convertible<T, const ::PROTOBUF_NAMESPACE_ID::Message&>::value>::type>
   bool UnpackTo(T* message) const {
@@ -141,7 +140,7 @@
   template<typename T> bool Is() const {
     return _any_metadata_.Is<T>();
   }
-  static bool ParseAnyTypeUrl(const string& type_url,
+  static bool ParseAnyTypeUrl(::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url,
                               std::string* full_type_name);
   friend void swap(Any& a, Any& b) {
     a.Swap(&b);
diff --git a/src/google/protobuf/any.proto b/src/google/protobuf/any.proto
index c9be854..6ed8a23 100644
--- a/src/google/protobuf/any.proto
+++ b/src/google/protobuf/any.proto
@@ -33,7 +33,7 @@
 package google.protobuf;
 
 option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option go_package = "github.com/golang/protobuf/ptypes/any";
+option go_package = "google.golang.org/protobuf/types/known/anypb";
 option java_package = "com.google.protobuf";
 option java_outer_classname = "AnyProto";
 option java_multiple_files = true;
@@ -77,10 +77,13 @@
 //  Example 4: Pack and unpack a message in Go
 //
 //      foo := &pb.Foo{...}
-//      any, err := ptypes.MarshalAny(foo)
+//      any, err := anypb.New(foo)
+//      if err != nil {
+//        ...
+//      }
 //      ...
 //      foo := &pb.Foo{}
-//      if err := ptypes.UnmarshalAny(any, foo); err != nil {
+//      if err := any.UnmarshalTo(foo); err != nil {
 //        ...
 //      }
 //
diff --git a/src/google/protobuf/any_lite.cc b/src/google/protobuf/any_lite.cc
index 7839381..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,50 +70,30 @@
   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);
 }
 
-bool ParseAnyTypeUrl(const std::string& type_url, std::string* url_prefix,
+bool ParseAnyTypeUrl(StringPiece type_url, std::string* url_prefix,
                      std::string* full_type_name) {
   size_t pos = type_url.find_last_of("/");
   if (pos == std::string::npos || pos + 1 == type_url.size()) {
     return false;
   }
   if (url_prefix) {
-    *url_prefix = type_url.substr(0, pos + 1);
+    *url_prefix = std::string(type_url.substr(0, pos + 1));
   }
-  *full_type_name = type_url.substr(pos + 1);
+  *full_type_name = std::string(type_url.substr(pos + 1));
   return true;
 }
 
-bool ParseAnyTypeUrl(const std::string& type_url, std::string* full_type_name) {
+bool ParseAnyTypeUrl(StringPiece type_url, std::string* full_type_name) {
   return ParseAnyTypeUrl(type_url, nullptr, full_type_name);
 }
 
diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc
index 816df12..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 =
@@ -144,10 +141,10 @@
   "esponse_streaming\030\005 \001(\010\022(\n\007options\030\006 \003(\013"
   "2\027.google.protobuf.Option\022\'\n\006syntax\030\007 \001("
   "\0162\027.google.protobuf.Syntax\"#\n\005Mixin\022\014\n\004n"
-  "ame\030\001 \001(\t\022\014\n\004root\030\002 \001(\tBu\n\023com.google.pr"
-  "otobufB\010ApiProtoP\001Z+google.golang.org/ge"
-  "nproto/protobuf/api;api\242\002\003GPB\252\002\036Google.P"
-  "rotobuf.WellKnownTypesb\006proto3"
+  "ame\030\001 \001(\t\022\014\n\004root\030\002 \001(\tBv\n\023com.google.pr"
+  "otobufB\010ApiProtoP\001Z,google.golang.org/pr"
+  "otobuf/types/known/apipb\242\002\003GPB\252\002\036Google."
+  "Protobuf.WellKnownTypesb\006proto3"
   ;
 static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fapi_2eproto_deps[2] = {
   &::descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto,
@@ -160,7 +157,7 @@
 };
 static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fapi_2eproto_once;
 const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto = {
-  false, false, descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto, "google/protobuf/api.proto", 750,
+  false, false, descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto, "google/protobuf/api.proto", 751,
   &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, descriptor_table_google_2fprotobuf_2fapi_2eproto_sccs, descriptor_table_google_2fprotobuf_2fapi_2eproto_deps, 3, 2,
   schemas, file_default_instances, TableStruct_google_2fprotobuf_2fapi_2eproto::offsets,
   file_level_metadata_google_2fprotobuf_2fapi_2eproto, 3, file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto, file_level_service_descriptors_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 37af1b7..f37ea8c 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/api.proto b/src/google/protobuf/api.proto
index bf5da15..3d598fc 100644
--- a/src/google/protobuf/api.proto
+++ b/src/google/protobuf/api.proto
@@ -40,7 +40,7 @@
 option java_outer_classname = "ApiProto";
 option java_multiple_files = true;
 option objc_class_prefix = "GPB";
-option go_package = "google.golang.org/genproto/protobuf/api;api";
+option go_package = "google.golang.org/protobuf/types/known/apipb";
 
 // Api is a light-weight descriptor for an API Interface.
 //
@@ -52,7 +52,6 @@
 // this message itself. See https://cloud.google.com/apis/design/glossary for
 // detailed terminology.
 message Api {
-
   // The fully qualified name of this interface, including package name
   // followed by the interface's simple name.
   string name = 1;
@@ -99,7 +98,6 @@
 
 // Method represents a method of an API interface.
 message Method {
-
   // The simple name of this method.
   string name = 1;
 
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 0a00c19..3d5c9de 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);
@@ -1278,8 +1381,9 @@
       if (in_fallback_database) {
         return true;
       }
-      std::string error_str = source_tree->GetLastErrorMessage().empty() ?
-        strerror(errno) : source_tree->GetLastErrorMessage();
+      std::string error_str = source_tree->GetLastErrorMessage().empty()
+                                  ? strerror(errno)
+                                  : source_tree->GetLastErrorMessage();
       std::cerr << "Could not map to virtual file: " << *proto << ": "
                 << error_str << std::endl;
       return false;
@@ -1426,13 +1530,36 @@
     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 = false;
+  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();
+      break;
+    default:
+      GOOGLE_LOG(FATAL) << "Unexpected mode: " << mode_;
+  }
+  if (missing_proto_definitions) {
     std::cerr << "Missing input file." << std::endl;
     return PARSE_ARGUMENT_FAIL;
   }
@@ -2223,8 +2350,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_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
index 630c97e..39312b3 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
@@ -81,13 +81,6 @@
   } else {
     (*variables)["lite"] = "Lite";
   }
-
-  if (!IsProto3Field(descriptor) && val->type() == FieldDescriptor::TYPE_ENUM) {
-    const EnumValueDescriptor* default_value = val->default_value_enum();
-    (*variables)["default_enum_value"] = Int32ToString(default_value->number());
-  } else {
-    (*variables)["default_enum_value"] = "0";
-  }
 }
 
 MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
@@ -105,8 +98,8 @@
       "    $map_classname$,\n"
       "    $key_cpp$, $val_cpp$,\n"
       "    ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
-      "    ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n"
-      "    $default_enum_value$ > $name$_;\n");
+      "    ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> "
+      "$name$_;\n");
 }
 
 void MapFieldGenerator::GenerateAccessorDeclarations(
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index 61a2395..19bf425 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -268,13 +268,6 @@
       "TYPE_" + ToUpper(DeclaredTypeMethodName(key->type()));
   vars["val_wire_type"] =
       "TYPE_" + ToUpper(DeclaredTypeMethodName(val->type()));
-  if (descriptor->file()->syntax() != FileDescriptor::SYNTAX_PROTO3 &&
-      val->type() == FieldDescriptor::TYPE_ENUM) {
-    const EnumValueDescriptor* default_value = val->default_value_enum();
-    vars["default_enum_value"] = Int32ToString(default_value->number());
-  } else {
-    vars["default_enum_value"] = "0";
-  }
 }
 
 // Does the given field have a private (internal helper only) has_$name$()
@@ -323,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) {
@@ -591,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;
     }
 
@@ -631,16 +635,7 @@
 MessageGenerator::~MessageGenerator() = default;
 
 size_t MessageGenerator::HasBitsSize() const {
-  size_t sizeof_has_bits = (max_has_bit_index_ + 31) / 32 * 4;
-  if (sizeof_has_bits == 0) {
-    // Zero-size arrays aren't technically allowed, and MSVC in particular
-    // doesn't like them.  We still need to declare these arrays to make
-    // other code compile.  Since this is an uncommon case, we'll just declare
-    // them with size 1 and waste some space.  Oh well.
-    sizeof_has_bits = 4;
-  }
-
-  return sizeof_has_bits;
+  return (max_has_bit_index_ + 31) / 32;
 }
 
 int MessageGenerator::HasBitIndex(const FieldDescriptor* field) const {
@@ -689,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);
@@ -718,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"
@@ -728,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"
@@ -745,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);
@@ -780,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");
@@ -861,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 { "
@@ -906,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;
   }
@@ -952,7 +947,7 @@
   for (auto field : FieldRange(descriptor_)) {
     PrintFieldComment(format, field);
 
-    if (!IsFieldUsed(field, options_)) {
+    if (IsFieldStripped(field, options_)) {
       continue;
     }
 
@@ -964,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");
@@ -998,7 +993,7 @@
     }
 
     // Generate type-specific accessors.
-    if (IsFieldUsed(field, options_)) {
+    if (!IsFieldStripped(field, options_)) {
       field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
     }
 
@@ -1026,14 +1021,13 @@
         "::$proto_ns$::internal::MapEntry$lite$<$classname$, \n"
         "    $key_cpp$, $val_cpp$,\n"
         "    ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
-        "    ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n"
-        "    $default_enum_value$ > {\n"
+        "    ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> {\n"
         "public:\n"
         "  typedef ::$proto_ns$::internal::MapEntry$lite$<$classname$, \n"
         "    $key_cpp$, $val_cpp$,\n"
         "    ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
-        "    ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n"
-        "    $default_enum_value$ > SuperType;\n"
+        "    ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> "
+        "SuperType;\n"
         "  $classname$();\n"
         "  explicit $classname$(::$proto_ns$::Arena* arena);\n"
         "  void MergeFrom(const $classname$& other);\n"
@@ -1122,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"
@@ -1224,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"
@@ -1244,7 +1232,8 @@
           "  _any_metadata_.PackFrom(message);\n"
           "}\n"
           "void PackFrom(const ::$proto_ns$::Message& message,\n"
-          "              const std::string& type_url_prefix) {\n"
+          "              ::PROTOBUF_NAMESPACE_ID::ConstStringParam "
+          "type_url_prefix) {\n"
           "  _any_metadata_.PackFrom(message, type_url_prefix);\n"
           "}\n"
           "bool UnpackTo(::$proto_ns$::Message* message) const {\n"
@@ -1264,7 +1253,8 @@
           "!std::is_convertible<T, const ::$proto_ns$::Message&>"
           "::value>::type>\n"
           "void PackFrom(const T& message,\n"
-          "              const std::string& type_url_prefix) {\n"
+          "              ::PROTOBUF_NAMESPACE_ID::ConstStringParam "
+          "type_url_prefix) {\n"
           "  _any_metadata_.PackFrom<T>(message, type_url_prefix);"
           "}\n"
           "template <typename T, class = typename std::enable_if<"
@@ -1281,7 +1271,8 @@
           "}\n"
           "template <typename T>\n"
           "void PackFrom(const T& message,\n"
-          "              const std::string& type_url_prefix) {\n"
+          "              ::PROTOBUF_NAMESPACE_ID::ConstStringParam "
+          "type_url_prefix) {\n"
           "  _any_metadata_.PackFrom(message, type_url_prefix);\n"
           "}\n"
           "template <typename T>\n"
@@ -1293,7 +1284,8 @@
         "template<typename T> bool Is() const {\n"
         "  return _any_metadata_.Is<T>();\n"
         "}\n"
-        "static bool ParseAnyTypeUrl(const string& type_url,\n"
+        "static bool ParseAnyTypeUrl(::PROTOBUF_NAMESPACE_ID::ConstStringParam "
+        "type_url,\n"
         "                            std::string* full_type_name);\n");
   }
 
@@ -1303,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"
@@ -1400,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"
@@ -1515,10 +1495,9 @@
 
   const size_t sizeof_has_bits = HasBitsSize();
   const std::string has_bits_decl =
-      sizeof_has_bits == 0
-          ? ""
-          : StrCat("::$proto_ns$::internal::HasBits<",
-                         sizeof_has_bits / 4, "> _has_bits_;\n");
+      sizeof_has_bits == 0 ? ""
+                           : StrCat("::$proto_ns$::internal::HasBits<",
+                                          sizeof_has_bits, "> _has_bits_;\n");
 
   // To minimize padding, data members are divided into three sections:
   // (1) members assumed to align to 8 bytes
@@ -1534,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
@@ -1572,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);
       }
     }
@@ -1637,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_);
@@ -1952,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_)) {
@@ -2037,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(
@@ -2057,8 +1942,9 @@
           "}\n");
     }
     format(
-        "bool $classname$::ParseAnyTypeUrl(const string& type_url,\n"
-        "                                  std::string* full_type_name) {\n"
+        "bool $classname$::ParseAnyTypeUrl(\n"
+        "    ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url,\n"
+        "    std::string* full_type_name) {\n"
         "  return ::$proto_ns$::internal::ParseAnyTypeUrl(type_url,\n"
         "                                             full_type_name);\n"
         "}\n"
@@ -2075,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)) {
@@ -2101,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);
@@ -2413,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));
     }
@@ -2429,7 +2318,11 @@
       format(" | $1$", tag);
     }
 
-    format(",\n");
+    if (!IsFieldUsed(field, options_)) {
+      format(" | 0x80000000u, // unused\n");
+    } else {
+      format(",\n");
+    }
   }
 
   int count = 0;
@@ -2483,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_) {
@@ -2541,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;
       }
@@ -2644,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_))) {
@@ -2671,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);
@@ -2760,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");
@@ -2799,9 +2680,7 @@
   GenerateSharedDestructorCode(printer);
 
   // Generate the arena-specific destructor code.
-  if (SupportsArenas(descriptor_)) {
-    GenerateArenaDestructorCode(printer);
-  }
+  GenerateArenaDestructorCode(printer);
 
   // Generate SetCachedSize.
   format(
@@ -2824,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) {
@@ -3018,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);
@@ -3065,7 +2943,7 @@
         "metadata_);\n");
 
     if (!has_bit_indices_.empty()) {
-      for (int i = 0; i < HasBitsSize() / 4; ++i) {
+      for (int i = 0; i < HasBitsSize(); ++i) {
         format("swap(_has_bits_[$1$], other->_has_bits_[$1$]);\n", i);
       }
     }
@@ -3307,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");
@@ -3527,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();
@@ -3643,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) {
@@ -3690,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);
@@ -3911,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");
@@ -4039,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 661b6b6..0bc32b4 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/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc
index 22bbcc8..20c0072 100644
--- a/src/google/protobuf/compiler/js/js_generator.cc
+++ b/src/google/protobuf/compiler/js/js_generator.cc
@@ -2689,8 +2689,7 @@
         "\n"
         "\n",
         "index", JSFieldIndex(field), "oneofgroup",
-        (InRealOneof(field) ? (", " + JSOneofArray(options, field))
-                                   : ""));
+        (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""));
 
     if (field->is_repeated()) {
       GenerateRepeatedMessageHelperMethods(options, printer, field);
@@ -2995,8 +2994,8 @@
       "\n"
       "\n",
       "index", JSFieldIndex(field), "oneofgroup",
-      (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""),
-      "ctor", GetMessagePath(options, field->message_type()));
+      (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""), "ctor",
+      GetMessagePath(options, field->message_type()));
 }
 
 void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options,
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/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 6739215..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,16 +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\001Bg\n\034com.google.protob"
-  "uf.compilerB\014PluginProtosZ9github.com/go"
-  "lang/protobuf/protoc-gen-go/plugin;plugi"
-  "n_go"
+  "\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,
@@ -196,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", 724,
+  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,
@@ -230,8 +231,6 @@
 
 // ===================================================================
 
-void Version::InitAsDefaultInstance() {
-}
 class Version::_Internal {
  public:
   using HasBits = decltype(std::declval<Version>()._has_bits_);
@@ -559,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_);
@@ -913,8 +908,6 @@
 
 // ===================================================================
 
-void CodeGeneratorResponse_File::InitAsDefaultInstance() {
-}
 class CodeGeneratorResponse_File::_Internal {
  public:
   using HasBits = decltype(std::declval<CodeGeneratorResponse_File>()._has_bits_);
@@ -927,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();
@@ -954,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)
 }
 
@@ -962,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() {
@@ -975,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) {
@@ -999,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();
     }
@@ -1009,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>();
@@ -1056,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) {
@@ -1116,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);
@@ -1133,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 +
@@ -1155,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(
@@ -1188,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());
     }
@@ -1198,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());
+    }
   }
 }
 
@@ -1226,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 {
@@ -1235,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 b5d5ac5..09e3bbb 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 492b896..9242aac 100644
--- a/src/google/protobuf/compiler/plugin.proto
+++ b/src/google/protobuf/compiler/plugin.proto
@@ -50,7 +50,7 @@
 option java_package = "com.google.protobuf.compiler";
 option java_outer_classname = "PluginProtos";
 
-option go_package = "github.com/golang/protobuf/protoc-gen-go/plugin;plugin_go";
+option go_package = "google.golang.org/protobuf/types/pluginpb";
 
 import "google/protobuf/descriptor.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/descriptor.cc b/src/google/protobuf/descriptor.cc
index f8fefc9..c3d9655 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 471351c..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 =
@@ -1156,11 +1129,10 @@
   "tation\030\001 \003(\0132-.google.protobuf.Generated"
   "CodeInfo.Annotation\032O\n\nAnnotation\022\020\n\004pat"
   "h\030\001 \003(\005B\002\020\001\022\023\n\013source_file\030\002 \001(\t\022\r\n\005begi"
-  "n\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B\217\001\n\023com.google.prot"
-  "obufB\020DescriptorProtosH\001Z>github.com/gol"
-  "ang/protobuf/protoc-gen-go/descriptor;de"
-  "scriptor\370\001\001\242\002\003GPB\252\002\032Google.Protobuf.Refl"
-  "ection"
+  "n\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B~\n\023com.google.proto"
+  "bufB\020DescriptorProtosH\001Z-google.golang.o"
+  "rg/protobuf/types/descriptorpb\370\001\001\242\002\003GPB\252"
+  "\002\032Google.Protobuf.Reflection"
   ;
 static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_deps[1] = {
 };
@@ -1195,7 +1167,7 @@
 };
 static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once;
 const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto = {
-  false, false, descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto, "google/protobuf/descriptor.proto", 6046,
+  false, false, descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto, "google/protobuf/descriptor.proto", 6028,
   &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_sccs, descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_deps, 27, 0,
   schemas, file_default_instances, TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets,
   file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto, 27, file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto, file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto,
@@ -1375,8 +1347,6 @@
 
 // ===================================================================
 
-void FileDescriptorSet::InitAsDefaultInstance() {
-}
 class FileDescriptorSet::_Internal {
  public:
 };
@@ -1579,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_);
@@ -2244,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_);
@@ -2549,8 +2509,6 @@
 
 // ===================================================================
 
-void DescriptorProto_ReservedRange::InitAsDefaultInstance() {
-}
 class DescriptorProto_ReservedRange::_Internal {
  public:
   using HasBits = decltype(std::declval<DescriptorProto_ReservedRange>()._has_bits_);
@@ -2805,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_);
@@ -3356,8 +3310,6 @@
 
 // ===================================================================
 
-void ExtensionRangeOptions::InitAsDefaultInstance() {
-}
 class ExtensionRangeOptions::_Internal {
  public:
 };
@@ -3581,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_);
@@ -4214,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_);
@@ -4496,8 +4440,6 @@
 
 // ===================================================================
 
-void EnumDescriptorProto_EnumReservedRange::InitAsDefaultInstance() {
-}
 class EnumDescriptorProto_EnumReservedRange::_Internal {
  public:
   using HasBits = decltype(std::declval<EnumDescriptorProto_EnumReservedRange>()._has_bits_);
@@ -4752,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_);
@@ -5138,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_);
@@ -5457,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_);
@@ -5772,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_);
@@ -6208,8 +6134,6 @@
 
 // ===================================================================
 
-void FileOptions::InitAsDefaultInstance() {
-}
 class FileOptions::_Internal {
  public:
   using HasBits = decltype(std::declval<FileOptions>()._has_bits_);
@@ -7195,8 +7119,6 @@
 
 // ===================================================================
 
-void MessageOptions::InitAsDefaultInstance() {
-}
 class MessageOptions::_Internal {
  public:
   using HasBits = decltype(std::declval<MessageOptions>()._has_bits_);
@@ -7549,8 +7471,6 @@
 
 // ===================================================================
 
-void FieldOptions::InitAsDefaultInstance() {
-}
 class FieldOptions::_Internal {
  public:
   using HasBits = decltype(std::declval<FieldOptions>()._has_bits_);
@@ -7968,8 +7888,6 @@
 
 // ===================================================================
 
-void OneofOptions::InitAsDefaultInstance() {
-}
 class OneofOptions::_Internal {
  public:
 };
@@ -8193,8 +8111,6 @@
 
 // ===================================================================
 
-void EnumOptions::InitAsDefaultInstance() {
-}
 class EnumOptions::_Internal {
  public:
   using HasBits = decltype(std::declval<EnumOptions>()._has_bits_);
@@ -8497,8 +8413,6 @@
 
 // ===================================================================
 
-void EnumValueOptions::InitAsDefaultInstance() {
-}
 class EnumValueOptions::_Internal {
  public:
   using HasBits = decltype(std::declval<EnumValueOptions>()._has_bits_);
@@ -8759,8 +8673,6 @@
 
 // ===================================================================
 
-void ServiceOptions::InitAsDefaultInstance() {
-}
 class ServiceOptions::_Internal {
  public:
   using HasBits = decltype(std::declval<ServiceOptions>()._has_bits_);
@@ -9021,8 +8933,6 @@
 
 // ===================================================================
 
-void MethodOptions::InitAsDefaultInstance() {
-}
 class MethodOptions::_Internal {
  public:
   using HasBits = decltype(std::declval<MethodOptions>()._has_bits_);
@@ -9334,8 +9244,6 @@
 
 // ===================================================================
 
-void UninterpretedOption_NamePart::InitAsDefaultInstance() {
-}
 class UninterpretedOption_NamePart::_Internal {
  public:
   using HasBits = decltype(std::declval<UninterpretedOption_NamePart>()._has_bits_);
@@ -9613,8 +9521,6 @@
 
 // ===================================================================
 
-void UninterpretedOption::InitAsDefaultInstance() {
-}
 class UninterpretedOption::_Internal {
  public:
   using HasBits = decltype(std::declval<UninterpretedOption>()._has_bits_);
@@ -10058,8 +9964,6 @@
 
 // ===================================================================
 
-void SourceCodeInfo_Location::InitAsDefaultInstance() {
-}
 class SourceCodeInfo_Location::_Internal {
  public:
   using HasBits = decltype(std::declval<SourceCodeInfo_Location>()._has_bits_);
@@ -10452,8 +10356,6 @@
 
 // ===================================================================
 
-void SourceCodeInfo::InitAsDefaultInstance() {
-}
 class SourceCodeInfo::_Internal {
  public:
 };
@@ -10655,8 +10557,6 @@
 
 // ===================================================================
 
-void GeneratedCodeInfo_Annotation::InitAsDefaultInstance() {
-}
 class GeneratedCodeInfo_Annotation::_Internal {
  public:
   using HasBits = decltype(std::declval<GeneratedCodeInfo_Annotation>()._has_bits_);
@@ -10996,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 cc9eb80..feaae11 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.proto b/src/google/protobuf/descriptor.proto
index d29fdec..9f0ce6c 100644
--- a/src/google/protobuf/descriptor.proto
+++ b/src/google/protobuf/descriptor.proto
@@ -41,7 +41,7 @@
 
 package google.protobuf;
 
-option go_package = "github.com/golang/protobuf/protoc-gen-go/descriptor;descriptor";
+option go_package = "google.golang.org/protobuf/types/descriptorpb";
 option java_package = "com.google.protobuf";
 option java_outer_classname = "DescriptorProtos";
 option csharp_namespace = "Google.Protobuf.Reflection";
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
index a5d41b7..278b07f 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 2682662..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 =
@@ -58,10 +57,10 @@
 const char descriptor_table_protodef_google_2fprotobuf_2fduration_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n\036google/protobuf/duration.proto\022\017google"
   ".protobuf\"*\n\010Duration\022\017\n\007seconds\030\001 \001(\003\022\r"
-  "\n\005nanos\030\002 \001(\005B|\n\023com.google.protobufB\rDu"
-  "rationProtoP\001Z*github.com/golang/protobu"
-  "f/ptypes/duration\370\001\001\242\002\003GPB\252\002\036Google.Prot"
-  "obuf.WellKnownTypesb\006proto3"
+  "\n\005nanos\030\002 \001(\005B\203\001\n\023com.google.protobufB\rD"
+  "urationProtoP\001Z1google.golang.org/protob"
+  "uf/types/known/durationpb\370\001\001\242\002\003GPB\252\002\036Goo"
+  "gle.Protobuf.WellKnownTypesb\006proto3"
   ;
 static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fduration_2eproto_deps[1] = {
 };
@@ -70,7 +69,7 @@
 };
 static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fduration_2eproto_once;
 const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fduration_2eproto = {
-  false, false, descriptor_table_protodef_google_2fprotobuf_2fduration_2eproto, "google/protobuf/duration.proto", 227,
+  false, false, descriptor_table_protodef_google_2fprotobuf_2fduration_2eproto, "google/protobuf/duration.proto", 235,
   &descriptor_table_google_2fprotobuf_2fduration_2eproto_once, descriptor_table_google_2fprotobuf_2fduration_2eproto_sccs, descriptor_table_google_2fprotobuf_2fduration_2eproto_deps, 1, 0,
   schemas, file_default_instances, TableStruct_google_2fprotobuf_2fduration_2eproto::offsets,
   file_level_metadata_google_2fprotobuf_2fduration_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2fduration_2eproto, file_level_service_descriptors_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 146013e..8a9f7f0 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/duration.proto b/src/google/protobuf/duration.proto
index 99cb102..81c3e36 100644
--- a/src/google/protobuf/duration.proto
+++ b/src/google/protobuf/duration.proto
@@ -34,7 +34,7 @@
 
 option csharp_namespace = "Google.Protobuf.WellKnownTypes";
 option cc_enable_arenas = true;
-option go_package = "github.com/golang/protobuf/ptypes/duration";
+option go_package = "google.golang.org/protobuf/types/known/durationpb";
 option java_package = "com.google.protobuf";
 option java_outer_classname = "DurationProto";
 option java_multiple_files = true;
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 855db18..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 =
@@ -55,10 +54,10 @@
 
 const char descriptor_table_protodef_google_2fprotobuf_2fempty_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n\033google/protobuf/empty.proto\022\017google.pr"
-  "otobuf\"\007\n\005EmptyBv\n\023com.google.protobufB\n"
-  "EmptyProtoP\001Z\'github.com/golang/protobuf"
-  "/ptypes/empty\370\001\001\242\002\003GPB\252\002\036Google.Protobuf"
-  ".WellKnownTypesb\006proto3"
+  "otobuf\"\007\n\005EmptyB}\n\023com.google.protobufB\n"
+  "EmptyProtoP\001Z.google.golang.org/protobuf"
+  "/types/known/emptypb\370\001\001\242\002\003GPB\252\002\036Google.P"
+  "rotobuf.WellKnownTypesb\006proto3"
   ;
 static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fempty_2eproto_deps[1] = {
 };
@@ -67,7 +66,7 @@
 };
 static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fempty_2eproto_once;
 const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fempty_2eproto = {
-  false, false, descriptor_table_protodef_google_2fprotobuf_2fempty_2eproto, "google/protobuf/empty.proto", 183,
+  false, false, descriptor_table_protodef_google_2fprotobuf_2fempty_2eproto, "google/protobuf/empty.proto", 190,
   &descriptor_table_google_2fprotobuf_2fempty_2eproto_once, descriptor_table_google_2fprotobuf_2fempty_2eproto_sccs, descriptor_table_google_2fprotobuf_2fempty_2eproto_deps, 1, 0,
   schemas, file_default_instances, TableStruct_google_2fprotobuf_2fempty_2eproto::offsets,
   file_level_metadata_google_2fprotobuf_2fempty_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2fempty_2eproto, file_level_service_descriptors_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 d0711e8..5e6f0f9 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/empty.proto b/src/google/protobuf/empty.proto
index 03cacd2..5f992de 100644
--- a/src/google/protobuf/empty.proto
+++ b/src/google/protobuf/empty.proto
@@ -33,7 +33,7 @@
 package google.protobuf;
 
 option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option go_package = "github.com/golang/protobuf/ptypes/empty";
+option go_package = "google.golang.org/protobuf/types/known/emptypb";
 option java_package = "com.google.protobuf";
 option java_outer_classname = "EmptyProto";
 option java_multiple_files = true;
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/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc
index d5073ee..3e6ecef 100644
--- a/src/google/protobuf/extension_set_unittest.cc
+++ b/src/google/protobuf/extension_set_unittest.cc
@@ -1105,8 +1105,6 @@
     ASSERT_EQ(msg_const_iter->bb(), 1234);
   }
 
-  // Test range-based for as well, but only if compiled as C++11.
-#if __cplusplus >= 201103L
   // Test one primitive field.
   for (auto& x :
        *message.MutableRepeatedExtension(unittest::repeated_int32_extension)) {
@@ -1134,7 +1132,6 @@
            unittest::repeated_nested_message_extension)) {
     ASSERT_EQ(x.bb(), 4321);
   }
-#endif
 }
 
 // From b/12926163
diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc
index 42e077f..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 =
@@ -57,10 +56,10 @@
 const char descriptor_table_protodef_google_2fprotobuf_2ffield_5fmask_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n google/protobuf/field_mask.proto\022\017goog"
   "le.protobuf\"\032\n\tFieldMask\022\r\n\005paths\030\001 \003(\tB"
-  "\214\001\n\023com.google.protobufB\016FieldMaskProtoP"
-  "\001Z9google.golang.org/genproto/protobuf/f"
-  "ield_mask;field_mask\370\001\001\242\002\003GPB\252\002\036Google.P"
-  "rotobuf.WellKnownTypesb\006proto3"
+  "\205\001\n\023com.google.protobufB\016FieldMaskProtoP"
+  "\001Z2google.golang.org/protobuf/types/know"
+  "n/fieldmaskpb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf"
+  ".WellKnownTypesb\006proto3"
   ;
 static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_deps[1] = {
 };
@@ -69,7 +68,7 @@
 };
 static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_once;
 const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto = {
-  false, false, descriptor_table_protodef_google_2fprotobuf_2ffield_5fmask_2eproto, "google/protobuf/field_mask.proto", 230,
+  false, false, descriptor_table_protodef_google_2fprotobuf_2ffield_5fmask_2eproto, "google/protobuf/field_mask.proto", 223,
   &descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_once, descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_sccs, descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_deps, 1, 0,
   schemas, file_default_instances, TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto::offsets,
   file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto, file_level_service_descriptors_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 5cc90b9..443785b 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/field_mask.proto b/src/google/protobuf/field_mask.proto
index baac874..6b5104f 100644
--- a/src/google/protobuf/field_mask.proto
+++ b/src/google/protobuf/field_mask.proto
@@ -37,7 +37,7 @@
 option java_outer_classname = "FieldMaskProto";
 option java_multiple_files = true;
 option objc_class_prefix = "GPB";
-option go_package = "google.golang.org/genproto/protobuf/field_mask;field_mask";
+option go_package = "google.golang.org/protobuf/types/known/fieldmaskpb";
 option cc_enable_arenas = true;
 
 // `FieldMask` represents a set of symbolic field paths, for example:
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc
index 9fb62b9..04f51ce 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));
 }
 
@@ -2044,9 +2094,6 @@
 void Reflection::ClearBit(Message* message,
                           const FieldDescriptor* field) const {
   GOOGLE_DCHECK(!field->options().weak());
-  if (!schema_.HasHasbits()) {
-    return;
-  }
   const uint32 index = schema_.HasBitIndex(field);
   if (index == -1) return;
   MutableHasBits(message)[index / 32] &=
@@ -2115,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/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc
index 15eb9d6..01f65ae 100644
--- a/src/google/protobuf/generated_message_util.cc
+++ b/src/google/protobuf/generated_message_util.cc
@@ -65,7 +65,7 @@
   static_cast<const MessageLite*>(message)->~MessageLite();
 }
 void DestroyString(const void* s) {
-  static_cast<const std::string*>(s)->~string();
+  static_cast<const std::string*>(s)->~basic_string();
 }
 
 ExplicitlyConstructed<std::string> fixed_address_empty_string;
diff --git a/src/google/protobuf/io/tokenizer.cc b/src/google/protobuf/io/tokenizer.cc
index ff83946..6853b1a 100644
--- a/src/google/protobuf/io/tokenizer.cc
+++ b/src/google/protobuf/io/tokenizer.cc
@@ -940,14 +940,15 @@
     tmp = 0x00e08080 | ((code_point & 0xf000) << 4) |
           ((code_point & 0x0fc0) << 2) | (code_point & 0x003f);
     len = 3;
-  } else if (code_point <= 0x1fffff) {
+  } else if (code_point <= 0x10ffff) {
     tmp = 0xf0808080 | ((code_point & 0x1c0000) << 6) |
           ((code_point & 0x03f000) << 4) | ((code_point & 0x000fc0) << 2) |
           (code_point & 0x003f);
     len = 4;
   } else {
-    // UTF-16 is only defined for code points up to 0x10FFFF, and UTF-8 is
-    // normally only defined up to there as well.
+    // Unicode code points end at 0x10FFFF, so this is out-of-range.
+    // ConsumeString permits hex values up to 0x1FFFFF, and FetchUnicodePoint
+    // doesn't perform a range check.
     StringAppendF(output, "\\U%08x", code_point);
     return;
   }
diff --git a/src/google/protobuf/io/tokenizer_unittest.cc b/src/google/protobuf/io/tokenizer_unittest.cc
index b14eddf..91c440c 100644
--- a/src/google/protobuf/io/tokenizer_unittest.cc
+++ b/src/google/protobuf/io/tokenizer_unittest.cc
@@ -808,8 +808,11 @@
   Tokenizer::ParseString("'\\ud852XX'", &output);
   EXPECT_EQ("\xed\xa1\x92XX", output);
   // Malformed escape: Demons may fly out of the nose.
-  Tokenizer::ParseString("\\u0", &output);
+  Tokenizer::ParseString("'\\u0'", &output);
   EXPECT_EQ("u0", output);
+  // Beyond the range of valid UTF-32 code units.
+  Tokenizer::ParseString("'\\U00110000\\U00200000\\UFFFFFFFF'", &output);
+  EXPECT_EQ("\\U00110000\\U00200000\\Uffffffff", output);
 
   // Test invalid strings that will never be tokenized as strings.
 #ifdef PROTOBUF_HAS_DEATH_TEST  // death tests do not work on Windows yet
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 b749ca9..cc53949 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 2bb3557..d5d71a0 100644
--- a/src/google/protobuf/map.h
+++ b/src/google/protobuf/map.h
@@ -76,12 +76,12 @@
 namespace internal {
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType key_wire_type,
-          WireFormatLite::FieldType value_wire_type, int default_enum_value>
+          WireFormatLite::FieldType value_wire_type>
 class MapFieldLite;
 
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType key_wire_type,
-          WireFormatLite::FieldType value_wire_type, int default_enum_value>
+          WireFormatLite::FieldType value_wire_type>
 class MapField;
 
 template <typename Key, typename T>
@@ -133,8 +133,7 @@
     }
   }
 
-#if __cplusplus >= 201103L && !defined(GOOGLE_PROTOBUF_OS_APPLE) && \
-    !defined(GOOGLE_PROTOBUF_OS_NACL) &&                            \
+#if !defined(GOOGLE_PROTOBUF_OS_APPLE) && !defined(GOOGLE_PROTOBUF_OS_NACL) && \
     !defined(GOOGLE_PROTOBUF_OS_EMSCRIPTEN)
   template <class NodeType, class... Args>
   void construct(NodeType* p, Args&&... args) {
@@ -183,7 +182,7 @@
 
  private:
   using DestructorSkippable_ = void;
-  Arena* const arena_;
+  Arena* arena_;
 };
 
 template <typename T>
@@ -252,6 +251,79 @@
 };
 #endif  // defined(__cpp_lib_string_view)
 
+template <typename Key>
+using TreeForMap =
+    std::map<KeyForTree<Key>, void*, typename TransparentSupport<Key>::less,
+             MapAllocator<std::pair<const KeyForTree<Key>, void*>>>;
+
+inline bool TableEntryIsEmpty(void* const* table, size_t b) {
+  return table[b] == nullptr;
+}
+inline bool TableEntryIsNonEmptyList(void* const* table, size_t b) {
+  return table[b] != nullptr && table[b] != table[b ^ 1];
+}
+inline bool TableEntryIsTree(void* const* table, size_t b) {
+  return !TableEntryIsEmpty(table, b) && !TableEntryIsNonEmptyList(table, b);
+}
+inline bool TableEntryIsList(void* const* table, size_t b) {
+  return !TableEntryIsTree(table, b);
+}
+
+// This captures all numeric types.
+inline size_t MapValueSpaceUsedExcludingSelfLong(bool) { return 0; }
+inline size_t MapValueSpaceUsedExcludingSelfLong(const std::string& str) {
+  return StringSpaceUsedExcludingSelfLong(str);
+}
+template <typename T,
+          typename = decltype(std::declval<const T&>().SpaceUsedLong())>
+size_t MapValueSpaceUsedExcludingSelfLong(const T& message) {
+  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>
+PROTOBUF_NOINLINE size_t SpaceUsedInTable(void** table, size_t num_buckets,
+                                          size_t num_elements,
+                                          size_t sizeof_node) {
+  size_t size = 0;
+  // The size of the table.
+  size += sizeof(void*) * num_buckets;
+  // All the nodes.
+  size += sizeof_node * num_elements;
+  // For each tree, count the overhead of the those nodes.
+  // Two buckets at a time because we only care about trees.
+  for (size_t b = 0; b < num_buckets; b += 2) {
+    if (internal::TableEntryIsTree(table, b)) {
+      using Tree = TreeForMap<Key>;
+      Tree* tree = static_cast<Tree*>(table[b]);
+      // Estimated cost of the red-black tree nodes, 3 pointers plus a
+      // bool (plus alignment, so 4 pointers).
+      size += tree->size() *
+              (sizeof(typename Tree::value_type) + sizeof(void*) * 4);
+    }
+  }
+  return size;
+}
+
+template <typename Map,
+          typename = typename std::enable_if<
+              !std::is_scalar<typename Map::key_type>::value ||
+              !std::is_scalar<typename Map::mapped_type>::value>::type>
+size_t SpaceUsedInValues(const Map* map) {
+  size_t size = 0;
+  for (const auto& v : *map) {
+    size += internal::MapValueSpaceUsedExcludingSelfLong(v.first) +
+            internal::MapValueSpaceUsedExcludingSelfLong(v.second);
+  }
+  return size;
+}
+
+inline size_t SpaceUsedInValues(const void*) { return 0; }
+
 }  // namespace internal
 
 // This is the class for Map's internal value_type. Instead of using
@@ -308,25 +380,22 @@
   using size_type = size_t;
   using hasher = typename internal::TransparentSupport<Key>::hash;
 
-  Map() : arena_(nullptr), default_enum_value_(0) { Init(); }
-  explicit Map(Arena* arena) : arena_(arena), default_enum_value_(0) { Init(); }
+  Map() : elements_(nullptr) {}
+  explicit Map(Arena* arena) : elements_(arena) {}
 
-  Map(const Map& other)
-      : arena_(nullptr), default_enum_value_(other.default_enum_value_) {
-    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);
@@ -336,22 +405,13 @@
   }
 
   template <class InputIt>
-  Map(const InputIt& first, const InputIt& last)
-      : arena_(nullptr), default_enum_value_(0) {
-    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
@@ -388,20 +448,18 @@
   //    otherwise. This avoids unnecessary 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_);
       }
@@ -421,11 +479,7 @@
     // The value is a void* pointing to Node. We use void* instead of Node* to
     // avoid code bloat. That way there is only one instantiation of the tree
     // class per key type.
-    using TreeAllocator = typename Allocator::template rebind<
-        std::pair<const internal::KeyForTree<Key>, void*>>::other;
-    using Tree = std::map<internal::KeyForTree<Key>, void*,
-                          typename internal::TransparentSupport<Key>::less,
-                          TreeAllocator>;
+    using Tree = internal::TreeForMap<Key>;
     using TreeIterator = typename Tree::iterator;
 
     static Node* NodeFromTreeIterator(TreeIterator it) {
@@ -564,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); }
@@ -613,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) {
@@ -675,6 +745,11 @@
       }
     }
 
+    size_t SpaceUsedInternal() const {
+      return internal::SpaceUsedInTable<Key>(table_, num_buckets_,
+                                             num_elements_, sizeof(Node));
+    }
+
    private:
     const_iterator find(const Key& k, TreeIterator* it) const {
       return FindHelper(k, it).first;
@@ -827,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_;
@@ -835,9 +918,9 @@
       const size_type start = index_of_first_non_null_;
       index_of_first_non_null_ = num_buckets_;
       for (size_type i = start; i < old_table_size; i++) {
-        if (TableEntryIsNonEmptyList(old_table, i)) {
+        if (internal::TableEntryIsNonEmptyList(old_table, i)) {
           TransferList(old_table, i);
-        } else if (TableEntryIsTree(old_table, i)) {
+        } else if (internal::TableEntryIsTree(old_table, i)) {
           TransferTree(old_table, i++);
         }
       }
@@ -873,29 +956,16 @@
     }
 
     bool TableEntryIsEmpty(size_type b) const {
-      return TableEntryIsEmpty(table_, b);
+      return internal::TableEntryIsEmpty(table_, b);
     }
     bool TableEntryIsNonEmptyList(size_type b) const {
-      return TableEntryIsNonEmptyList(table_, b);
+      return internal::TableEntryIsNonEmptyList(table_, b);
     }
     bool TableEntryIsTree(size_type b) const {
-      return TableEntryIsTree(table_, b);
+      return internal::TableEntryIsTree(table_, b);
     }
     bool TableEntryIsList(size_type b) const {
-      return TableEntryIsList(table_, b);
-    }
-    static bool TableEntryIsEmpty(void* const* table, size_type b) {
-      return table[b] == nullptr;
-    }
-    static bool TableEntryIsNonEmptyList(void* const* table, size_type b) {
-      return table[b] != nullptr && table[b] != table[b ^ 1];
-    }
-    static bool TableEntryIsTree(void* const* table, size_type b) {
-      return !TableEntryIsEmpty(table, b) &&
-             !TableEntryIsNonEmptyList(table, b);
-    }
-    static bool TableEntryIsList(void* const* table, size_type b) {
-      return !TableEntryIsTree(table, b);
+      return internal::TableEntryIsList(table_, b);
     }
 
     void TreeConvert(size_type b) {
@@ -1002,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;
@@ -1100,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 {
@@ -1140,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>
@@ -1178,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;
     }
@@ -1210,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) {
@@ -1218,7 +1284,7 @@
       first = erase(first);
     }
   }
-  void clear() { elements_->clear(); }
+  void clear() { elements_.clear(); }
 
   // Assign
   Map& operator=(const Map& other) {
@@ -1230,9 +1296,8 @@
   }
 
   void swap(Map& other) {
-    if (arena_ == other.arena_) {
-      std::swap(default_enum_value_, other.default_enum_value_);
-      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
@@ -1245,25 +1310,23 @@
 
   // 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(); }
 
- private:
-  // Set default enum value only for proto2 map field whose value is enum type.
-  void SetDefaultEnumValue(int default_enum_value) {
-    default_enum_value_ = default_enum_value;
+  size_t SpaceUsedExcludingSelfLong() const {
+    if (empty()) return 0;
+    return elements_.SpaceUsedInternal() + internal::SpaceUsedInValues(this);
   }
 
-  Arena* arena_;
-  int default_enum_value_;
-  InnerMap* elements_;
+ private:
+  Arena* arena() const { return elements_.arena(); }
+  InnerMap elements_;
 
   friend class Arena;
   using InternalArenaConstructable_ = void;
   using DestructorSkippable_ = void;
   template <typename Derived, typename K, typename V,
             internal::WireFormatLite::FieldType key_wire_type,
-            internal::WireFormatLite::FieldType value_wire_type,
-            int default_enum_value>
+            internal::WireFormatLite::FieldType value_wire_type>
   friend class internal::MapFieldLite;
 };
 
diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h
index 4e6a3e3..180ff0e 100644
--- a/src/google/protobuf/map_entry.h
+++ b/src/google/protobuf/map_entry.h
@@ -51,7 +51,7 @@
 namespace internal {
 template <typename Derived, typename Key, typename Value,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+          WireFormatLite::FieldType kValueFieldType>
 class MapField;
 }
 }  // namespace protobuf
@@ -86,19 +86,17 @@
 //
 // The in-memory types of primitive types can be inferred from its proto type,
 // while we need to explicitly specify the cpp type if proto type is
-// TYPE_MESSAGE to infer the in-memory type.  Moreover, default_enum_value is
-// used to initialize enum field in proto2.
+// TYPE_MESSAGE to infer the in-memory type.
 template <typename Derived, typename Key, typename Value,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-class MapEntry
-    : public MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
-                          kValueFieldType, default_enum_value> {
+          WireFormatLite::FieldType kValueFieldType>
+class MapEntry : public MapEntryImpl<Derived, Message, Key, Value,
+                                     kKeyFieldType, kValueFieldType> {
  public:
   MapEntry() : _internal_metadata_(NULL) {}
   explicit MapEntry(Arena* arena)
       : MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
-                     kValueFieldType, default_enum_value>(arena),
+                     kValueFieldType>(arena),
         _internal_metadata_(arena) {}
   ~MapEntry() {
     Message::_internal_metadata_.Delete<UnknownFieldSet>();
@@ -107,13 +105,11 @@
   typedef void InternalArenaConstructable_;
   typedef void DestructorSkippable_;
 
+  typedef typename MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
+                                kValueFieldType>::KeyTypeHandler KeyTypeHandler;
   typedef
       typename MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
-                            kValueFieldType, default_enum_value>::KeyTypeHandler
-          KeyTypeHandler;
-  typedef typename MapEntryImpl<
-      Derived, Message, Key, Value, kKeyFieldType, kValueFieldType,
-      default_enum_value>::ValueTypeHandler ValueTypeHandler;
+                            kValueFieldType>::ValueTypeHandler ValueTypeHandler;
   size_t SpaceUsedLong() const override {
     size_t size = sizeof(Derived);
     size += KeyTypeHandler::SpaceUsedInMapEntryLong(this->key_);
@@ -126,8 +122,7 @@
  private:
   friend class ::PROTOBUF_NAMESPACE_ID::Arena;
   template <typename C, typename K, typename V,
-            WireFormatLite::FieldType k_wire_type, WireFormatLite::FieldType,
-            int default_enum>
+            WireFormatLite::FieldType k_wire_type, WireFormatLite::FieldType>
   friend class internal::MapField;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry);
@@ -136,26 +131,24 @@
 // Specialization for the full runtime
 template <typename Derived, typename Key, typename Value,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-struct MapEntryHelper<MapEntry<Derived, Key, Value, kKeyFieldType,
-                               kValueFieldType, default_enum_value> >
-    : MapEntryHelper<MapEntryLite<Derived, Key, Value, kKeyFieldType,
-                                  kValueFieldType, default_enum_value> > {
+          WireFormatLite::FieldType kValueFieldType>
+struct MapEntryHelper<
+    MapEntry<Derived, Key, Value, kKeyFieldType, kValueFieldType> >
+    : MapEntryHelper<
+          MapEntryLite<Derived, Key, Value, kKeyFieldType, kValueFieldType> > {
   explicit MapEntryHelper(const MapPair<Key, Value>& map_pair)
-      : MapEntryHelper<MapEntryLite<Derived, Key, Value, kKeyFieldType,
-                                    kValueFieldType, default_enum_value> >(
+      : MapEntryHelper<
+            MapEntryLite<Derived, Key, Value, kKeyFieldType, kValueFieldType> >(
             map_pair) {}
 };
 
 template <typename Derived, typename K, typename V,
-          WireFormatLite::FieldType key, WireFormatLite::FieldType value,
-          int default_enum>
-struct DeconstructMapEntry<MapEntry<Derived, K, V, key, value, default_enum> > {
+          WireFormatLite::FieldType key, WireFormatLite::FieldType value>
+struct DeconstructMapEntry<MapEntry<Derived, K, V, key, value> > {
   typedef K Key;
   typedef V Value;
   static constexpr WireFormatLite::FieldType kKeyFieldType = key;
   static constexpr WireFormatLite::FieldType kValueFieldType = value;
-  static constexpr int default_enum_value = default_enum;
 };
 
 }  // namespace internal
diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h
index 161d08d..92cb4ac 100644
--- a/src/google/protobuf/map_entry_lite.h
+++ b/src/google/protobuf/map_entry_lite.h
@@ -55,11 +55,11 @@
 namespace internal {
 template <typename Derived, typename Key, typename Value,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+          WireFormatLite::FieldType kValueFieldType>
 class MapEntry;
 template <typename Derived, typename Key, typename Value,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+          WireFormatLite::FieldType kValueFieldType>
 class MapFieldLite;
 }  // namespace internal
 }  // namespace protobuf
@@ -93,11 +93,7 @@
 template <typename T>
 struct MoveHelper<false, false, true, T> {  // strings and similar
   static void Move(T* src, T* dest) {
-#if __cplusplus >= 201103L
     *dest = std::move(*src);
-#else
-    dest->swap(*src);
-#endif
   }
 };
 
@@ -144,7 +140,7 @@
 // the eventual code to the template code.
 template <typename Derived, typename Base, typename Key, typename Value,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+          WireFormatLite::FieldType kValueFieldType>
 class MapEntryImpl : public Base {
  public:
   typedef MapEntryFuncs<Key, Value, kKeyFieldType, kValueFieldType> Funcs;
@@ -185,19 +181,16 @@
   typedef Value EntryValueType;
   static const WireFormatLite::FieldType kEntryKeyFieldType = kKeyFieldType;
   static const WireFormatLite::FieldType kEntryValueFieldType = kValueFieldType;
-  static const int kEntryDefaultEnumValue = default_enum_value;
 
   MapEntryImpl() {
     KeyTypeHandler::Initialize(&key_, NULL);
-    ValueTypeHandler::InitializeMaybeByDefaultEnum(&value_, default_enum_value,
-                                                   NULL);
+    ValueTypeHandler::Initialize(&value_, NULL);
     _has_bits_[0] = 0;
   }
 
   explicit MapEntryImpl(Arena* arena) : Base(arena) {
     KeyTypeHandler::Initialize(&key_, arena);
-    ValueTypeHandler::InitializeMaybeByDefaultEnum(&value_, default_enum_value,
-                                                   arena);
+    ValueTypeHandler::Initialize(&value_, arena);
     _has_bits_[0] = 0;
   }
 
@@ -213,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();
@@ -325,18 +317,11 @@
  public:
   void Clear() override {
     KeyTypeHandler::Clear(&key_, Base::GetArena());
-    ValueTypeHandler::ClearMaybeByDefaultEnum(&value_, Base::GetArena(),
-                                              default_enum_value);
+    ValueTypeHandler::Clear(&value_, Base::GetArena());
     clear_has_key();
     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>
@@ -520,10 +505,10 @@
   typedef void InternalArenaConstructable_;
   typedef void DestructorSkippable_;
   template <typename C, typename K, typename V, WireFormatLite::FieldType,
-            WireFormatLite::FieldType, int>
+            WireFormatLite::FieldType>
   friend class internal::MapEntry;
   template <typename C, typename K, typename V, WireFormatLite::FieldType,
-            WireFormatLite::FieldType, int>
+            WireFormatLite::FieldType>
   friend class internal::MapFieldLite;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryImpl);
@@ -531,13 +516,12 @@
 
 template <typename T, typename Key, typename Value,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-class MapEntryLite
-    : public MapEntryImpl<T, MessageLite, Key, Value, kKeyFieldType,
-                          kValueFieldType, default_enum_value> {
+          WireFormatLite::FieldType kValueFieldType>
+class MapEntryLite : public MapEntryImpl<T, MessageLite, Key, Value,
+                                         kKeyFieldType, kValueFieldType> {
  public:
   typedef MapEntryImpl<T, MessageLite, Key, Value, kKeyFieldType,
-                       kValueFieldType, default_enum_value>
+                       kValueFieldType>
       SuperType;
   MapEntryLite() {}
   explicit MapEntryLite(Arena* arena) : SuperType(arena) {}
@@ -554,13 +538,12 @@
 struct DeconstructMapEntry;
 
 template <typename T, typename K, typename V, WireFormatLite::FieldType key,
-          WireFormatLite::FieldType value, int default_enum>
-struct DeconstructMapEntry<MapEntryLite<T, K, V, key, value, default_enum> > {
+          WireFormatLite::FieldType value>
+struct DeconstructMapEntry<MapEntryLite<T, K, V, key, value> > {
   typedef K Key;
   typedef V Value;
   static const WireFormatLite::FieldType kKeyFieldType = key;
   static const WireFormatLite::FieldType kValueFieldType = value;
-  static const int default_enum_value = default_enum;
 };
 
 // Helpers for deterministic serialization =============================
@@ -631,9 +614,9 @@
 
 template <typename T, typename Key, typename Value,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-struct MapEntryHelper<MapEntryLite<T, Key, Value, kKeyFieldType,
-                                   kValueFieldType, default_enum_value> > {
+          WireFormatLite::FieldType kValueFieldType>
+struct MapEntryHelper<
+    MapEntryLite<T, Key, Value, kKeyFieldType, kValueFieldType> > {
   // Provide utilities to parse/serialize key/value.  Provide utilities to
   // manipulate internal stored type.
   typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h
index f32b086..b0d8050 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;
@@ -425,7 +472,7 @@
 // directly.
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value = 0>
+          WireFormatLite::FieldType kValueFieldType>
 class MapField : public TypeDefinedMapFieldBase<Key, T> {
   // Provide utilities to parse/serialize key/value.  Provide utilities to
   // manipulate internal stored type.
@@ -436,8 +483,7 @@
   typedef Derived EntryType;
 
   // Define abbreviation for parent MapFieldLite
-  typedef MapFieldLite<Derived, Key, T, kKeyFieldType, kValueFieldType,
-                       default_enum_value>
+  typedef MapFieldLite<Derived, Key, T, kKeyFieldType, kValueFieldType>
       MapFieldLiteType;
 
   // Enum needs to be handled differently from other types because it has
@@ -522,10 +568,9 @@
 
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType key_wire_type,
-          WireFormatLite::FieldType value_wire_type, int default_enum_value>
+          WireFormatLite::FieldType value_wire_type>
 bool AllAreInitialized(
-    const MapField<Derived, Key, T, key_wire_type, value_wire_type,
-                   default_enum_value>& field) {
+    const MapField<Derived, Key, T, key_wire_type, value_wire_type>& field) {
   const auto& t = field.GetMap();
   for (typename Map<Key, T>::const_iterator it = t.begin(); it != t.end();
        ++it) {
@@ -536,12 +581,10 @@
 
 template <typename T, typename Key, typename Value,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-struct MapEntryToMapField<MapEntry<T, Key, Value, kKeyFieldType,
-                                   kValueFieldType, default_enum_value>> {
-  typedef MapField<T, Key, Value, kKeyFieldType, kValueFieldType,
-                   default_enum_value>
-      MapFieldType;
+          WireFormatLite::FieldType kValueFieldType>
+struct MapEntryToMapField<
+    MapEntry<T, Key, Value, kKeyFieldType, kValueFieldType>> {
+  typedef MapField<T, Key, Value, kKeyFieldType, kValueFieldType> MapFieldType;
 };
 
 class PROTOBUF_EXPORT DynamicMapField
@@ -675,8 +718,7 @@
  private:
   template <typename Derived, typename K, typename V,
             internal::WireFormatLite::FieldType key_wire_type,
-            internal::WireFormatLite::FieldType value_wire_type,
-            int default_enum_value>
+            internal::WireFormatLite::FieldType value_wire_type>
   friend class internal::MapField;
   template <typename K, typename V>
   friend class internal::TypeDefinedMapFieldBase;
@@ -778,8 +820,7 @@
   friend class internal::DynamicMapField;
   template <typename Derived, typename Key, typename T,
             internal::WireFormatLite::FieldType kKeyFieldType,
-            internal::WireFormatLite::FieldType kValueFieldType,
-            int default_enum_value>
+            internal::WireFormatLite::FieldType kValueFieldType>
   friend class internal::MapField;
 
   // reinterpret_cast from heap-allocated Map<...>::iterator*. MapIterator owns
@@ -797,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_inl.h b/src/google/protobuf/map_field_inl.h
index 7baaa5f..6b6a87e 100644
--- a/src/google/protobuf/map_field_inl.h
+++ b/src/google/protobuf/map_field_inl.h
@@ -164,18 +164,16 @@
 
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-int MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
-             default_enum_value>::size() const {
+          WireFormatLite::FieldType kValueFieldType>
+int MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::size() const {
   MapFieldBase::SyncMapWithRepeatedField();
   return static_cast<int>(impl_.GetMap().size());
 }
 
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
-              default_enum_value>::Clear() {
+          WireFormatLite::FieldType kValueFieldType>
+void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::Clear() {
   if (this->MapFieldBase::repeated_field_ != nullptr) {
     RepeatedPtrField<EntryType>* repeated_field =
         reinterpret_cast<RepeatedPtrField<EntryType>*>(
@@ -192,9 +190,9 @@
 
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
-              default_enum_value>::SetMapIteratorValue(MapIterator* map_iter)
+          WireFormatLite::FieldType kValueFieldType>
+void MapField<Derived, Key, T, kKeyFieldType,
+              kValueFieldType>::SetMapIteratorValue(MapIterator* map_iter)
     const {
   const Map<Key, T>& map = impl_.GetMap();
   typename Map<Key, T>::const_iterator iter =
@@ -206,9 +204,9 @@
 
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-bool MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
-              default_enum_value>::ContainsMapKey(const MapKey& map_key) const {
+          WireFormatLite::FieldType kValueFieldType>
+bool MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::ContainsMapKey(
+    const MapKey& map_key) const {
   const Map<Key, T>& map = impl_.GetMap();
   const Key& key = UnwrapMapKey<Key>(map_key);
   typename Map<Key, T>::const_iterator iter = map.find(key);
@@ -217,10 +215,10 @@
 
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-bool MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
-              default_enum_value>::InsertOrLookupMapValue(const MapKey& map_key,
-                                                          MapValueRef* val) {
+          WireFormatLite::FieldType kValueFieldType>
+bool MapField<Derived, Key, T, kKeyFieldType,
+              kValueFieldType>::InsertOrLookupMapValue(const MapKey& map_key,
+                                                       MapValueRef* val) {
   // Always use mutable map because users may change the map value by
   // MapValueRef.
   Map<Key, T>* map = MutableMap();
@@ -238,18 +236,18 @@
 
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-bool MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
-              default_enum_value>::DeleteMapValue(const MapKey& map_key) {
+          WireFormatLite::FieldType kValueFieldType>
+bool MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::DeleteMapValue(
+    const MapKey& map_key) {
   const Key& key = UnwrapMapKey<Key>(map_key);
   return MutableMap()->erase(key);
 }
 
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
-              default_enum_value>::MergeFrom(const MapFieldBase& other) {
+          WireFormatLite::FieldType kValueFieldType>
+void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::MergeFrom(
+    const MapFieldBase& other) {
   MapFieldBase::SyncMapWithRepeatedField();
   const MapField& other_field = static_cast<const MapField&>(other);
   other_field.SyncMapWithRepeatedField();
@@ -259,9 +257,9 @@
 
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
-              default_enum_value>::Swap(MapFieldBase* other) {
+          WireFormatLite::FieldType kValueFieldType>
+void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::Swap(
+    MapFieldBase* other) {
   MapField* other_field = down_cast<MapField*>(other);
   std::swap(this->MapFieldBase::repeated_field_, other_field->repeated_field_);
   impl_.Swap(&other_field->impl_);
@@ -274,9 +272,9 @@
 
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
-              default_enum_value>::SyncRepeatedFieldWithMapNoLock() const {
+          WireFormatLite::FieldType kValueFieldType>
+void MapField<Derived, Key, T, kKeyFieldType,
+              kValueFieldType>::SyncRepeatedFieldWithMapNoLock() const {
   if (this->MapFieldBase::repeated_field_ == NULL) {
     if (this->MapFieldBase::arena_ == NULL) {
       this->MapFieldBase::repeated_field_ = new RepeatedPtrField<Message>();
@@ -311,9 +309,9 @@
 
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
-              default_enum_value>::SyncMapWithRepeatedFieldNoLock() const {
+          WireFormatLite::FieldType kValueFieldType>
+void MapField<Derived, Key, T, kKeyFieldType,
+              kValueFieldType>::SyncMapWithRepeatedFieldNoLock() const {
   Map<Key, T>* map = const_cast<MapField*>(this)->impl_.MutableMap();
   RepeatedPtrField<EntryType>* repeated_field =
       reinterpret_cast<RepeatedPtrField<EntryType>*>(
@@ -334,20 +332,15 @@
 
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-size_t MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
-                default_enum_value>::SpaceUsedExcludingSelfNoLock() const {
+          WireFormatLite::FieldType kValueFieldType>
+size_t MapField<Derived, Key, T, kKeyFieldType,
+                kValueFieldType>::SpaceUsedExcludingSelfNoLock() const {
   size_t size = 0;
   if (this->MapFieldBase::repeated_field_ != NULL) {
     size += this->MapFieldBase::repeated_field_->SpaceUsedExcludingSelfLong();
   }
-  Map<Key, T>* map = const_cast<MapField*>(this)->impl_.MutableMap();
-  size += sizeof(*map);
-  for (typename Map<Key, T>::iterator it = map->begin(); it != map->end();
-       ++it) {
-    size += KeyTypeHandler::SpaceUsedInMapLong(it->first);
-    size += ValueTypeHandler::SpaceUsedInMapLong(it->second);
-  }
+  size += impl_.GetMap().SpaceUsedExcludingSelfLong();
+
   return size;
 }
 }  // namespace internal
diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h
index f883f4c..a47b877 100644
--- a/src/google/protobuf/map_field_lite.h
+++ b/src/google/protobuf/map_field_lite.h
@@ -54,7 +54,7 @@
 // directly.
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType key_wire_type,
-          WireFormatLite::FieldType value_wire_type, int default_enum_value = 0>
+          WireFormatLite::FieldType value_wire_type>
 class MapFieldLite {
   // Define message type for internal repeated field.
   typedef Derived EntryType;
@@ -63,9 +63,9 @@
   typedef Map<Key, T> MapType;
   typedef EntryType EntryTypeTrait;
 
-  MapFieldLite() { SetDefaultEnumValue(); }
+  MapFieldLite() {}
 
-  explicit MapFieldLite(Arena* arena) : map_(arena) { SetDefaultEnumValue(); }
+  explicit MapFieldLite(Arena* arena) : map_(arena) {}
 
   // Accessors
   const Map<Key, T>& GetMap() const { return map_; }
@@ -82,15 +82,10 @@
   }
   void Swap(MapFieldLite* other) { map_.swap(other->map_); }
 
-  // Set default enum value only for proto2 map field whose value is enum type.
-  void SetDefaultEnumValue() {
-    MutableMap()->SetDefaultEnumValue(default_enum_value);
-  }
-
   // 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.
@@ -154,10 +149,9 @@
 // We want the C++ compiler to inline this or not as it sees fit.
 template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType key_wire_type,
-          WireFormatLite::FieldType value_wire_type, int default_enum_value>
-bool AllAreInitialized(
-    const MapFieldLite<Derived, Key, T, key_wire_type, value_wire_type,
-                       default_enum_value>& field) {
+          WireFormatLite::FieldType value_wire_type>
+bool AllAreInitialized(const MapFieldLite<Derived, Key, T, key_wire_type,
+                                          value_wire_type>& field) {
   const auto& t = field.GetMap();
   for (typename Map<Key, T>::const_iterator it = t.begin(); it != t.end();
        ++it) {
@@ -171,13 +165,12 @@
 
 template <typename T, typename Key, typename Value,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-struct MapEntryToMapField<MapEntryLite<T, Key, Value, kKeyFieldType,
-                                       kValueFieldType, default_enum_value>> {
-  typedef MapFieldLite<MapEntryLite<T, Key, Value, kKeyFieldType,
-                                    kValueFieldType, default_enum_value>,
-                       Key, Value, kKeyFieldType, kValueFieldType,
-                       default_enum_value>
+          WireFormatLite::FieldType kValueFieldType>
+struct MapEntryToMapField<
+    MapEntryLite<T, Key, Value, kKeyFieldType, kValueFieldType>> {
+  typedef MapFieldLite<
+      MapEntryLite<T, Key, Value, kKeyFieldType, kValueFieldType>, Key, Value,
+      kKeyFieldType, kValueFieldType>
       MapFieldType;
 };
 
diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc
index 5ccb7b0..f05d68d 100644
--- a/src/google/protobuf/map_field_test.cc
+++ b/src/google/protobuf/map_field_test.cc
@@ -99,7 +99,7 @@
  protected:
   typedef unittest::TestMap_MapInt32Int32Entry_DoNotUse EntryType;
   typedef MapField<EntryType, int32, int32, WireFormatLite::TYPE_INT32,
-                   WireFormatLite::TYPE_INT32, false>
+                   WireFormatLite::TYPE_INT32>
       MapFieldType;
 
   MapFieldBasePrimitiveTest() {
@@ -203,7 +203,7 @@
  protected:
   typedef unittest::TestMap_MapInt32Int32Entry_DoNotUse EntryType;
   typedef MapField<EntryType, int32, int32, WireFormatLite::TYPE_INT32,
-                   WireFormatLite::TYPE_INT32, false>
+                   WireFormatLite::TYPE_INT32>
       MapFieldType;
   MapFieldStateTest() : state_(GetParam()) {
     // Build map field
diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc
index e570bc0..acd2477 100644
--- a/src/google/protobuf/map_test.cc
+++ b/src/google/protobuf/map_test.cc
@@ -980,6 +980,43 @@
   EXPECT_EQ(it1.GetKey().GetInt32Value(), it2.GetKey().GetInt32Value());
 }
 
+TEST_F(MapImplTest, SpaceUsed) {
+  constexpr size_t kMinCap = 8;
+
+  Map<int32, int32> m;
+  // 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) {
+    m[i];
+    static constexpr double kMaxLoadFactor = .75;
+    if (m.size() >= capacity * kMaxLoadFactor) {
+      capacity *= 2;
+    }
+    EXPECT_EQ(m.SpaceUsedExcludingSelfLong(),
+              sizeof(void*) * capacity +
+                  m.size() * sizeof(std::pair<std::pair<int32, int32>, void*>));
+  }
+
+  // Test string, and non-scalar keys.
+  Map<std::string, int32> m2;
+  std::string str = "Some arbitrarily large string";
+  m2[str] = 1;
+  EXPECT_EQ(m2.SpaceUsedExcludingSelfLong(),
+            sizeof(void*) * kMinCap +
+                sizeof(std::pair<std::pair<std::string, int32>, void*>) +
+                internal::StringSpaceUsedExcludingSelfLong(str));
+
+  // Test messages, and non-scalar values.
+  Map<int32, TestAllTypes> m3;
+  m3[0].set_optional_string(str);
+  EXPECT_EQ(m3.SpaceUsedExcludingSelfLong(),
+            sizeof(void*) * kMinCap +
+                sizeof(std::pair<std::pair<int32, TestAllTypes>, void*>) +
+                m3[0].SpaceUsedLong() - sizeof(m3[0]));
+}
+
 // Attempts to verify that a map with keys a and b has a random ordering. This
 // function returns true if it succeeds in observing both possible orderings.
 bool MapOrderingIsRandom(int a, int b) {
@@ -2507,6 +2544,27 @@
   EXPECT_TRUE(map_message.IsInitialized());
 }
 
+TEST(GeneratedMapFieldTest, SpaceUsed) {
+  unittest::TestRequiredMessageMap map_message;
+  const size_t initial = map_message.SpaceUsed();
+  const size_t space_used_message = unittest::TestRequired().SpaceUsed();
+
+  auto& m = *map_message.mutable_map_field();
+  constexpr int kNumValues = 100;
+  for (int i = 0; i < kNumValues; ++i) {
+    m[i];
+  }
+
+  // The exact value will depend on internal state, like collisions,
+  // so we can't predict it. But we can predict a lower bound.
+  size_t lower_bound =
+      initial + kNumValues * (space_used_message + sizeof(int32) +
+                              /* Node::next */ sizeof(void*) +
+                              /* table entry */ sizeof(void*));
+
+  EXPECT_LE(lower_bound, map_message.SpaceUsed());
+}
+
 TEST(GeneratedMapFieldTest, MessagesMustMerge) {
   unittest::TestRequiredMessageMap map_message;
 
diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h
index d54aa22..7908544 100644
--- a/src/google/protobuf/map_type_handler.h
+++ b/src/google/protobuf/map_type_handler.h
@@ -59,29 +59,6 @@
   typedef FalseType type;
 };
 
-// In proto2 Map, enum needs to be initialized to given default value, while
-// other types' default value can be inferred from the type.
-template <bool IsEnum, typename Type>
-class MapValueInitializer {
- public:
-  static inline void Initialize(Type& type, int default_enum_value);
-};
-
-template <typename Type>
-class MapValueInitializer<true, Type> {
- public:
-  static inline void Initialize(Type& value, int default_enum_value) {
-    value = static_cast<Type>(default_enum_value);
-  }
-};
-
-template <typename Type>
-class MapValueInitializer<false, Type> {
- public:
-  static inline void Initialize(Type& /* value */,
-                                int /* default_enum_value */) {}
-};
-
 template <typename Type, bool is_arena_constructable>
 class MapArenaMessageCreator {
  public:
@@ -180,25 +157,15 @@
   static inline void DeleteNoArena(const Type* x);
   static inline void Merge(const Type& from, Type** to, Arena* arena);
   static inline void Clear(Type** value, Arena* arena);
-  static inline void ClearMaybeByDefaultEnum(Type** value, Arena* arena,
-                                             int default_enum_value);
   static inline void Initialize(Type** x, Arena* arena);
 
-  static inline void InitializeMaybeByDefaultEnum(Type** x,
-                                                  int default_enum_value,
-                                                  Arena* arena);
   static inline Type* EnsureMutable(Type** value, Arena* arena);
   // SpaceUsedInMapEntry: Return bytes used by value in MapEntry, excluding
   // those already calculate in sizeof(MapField).
   static inline size_t SpaceUsedInMapEntryLong(const Type* value);
-  // Return bytes used by value in Map.
-  static inline size_t SpaceUsedInMapLong(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);
 };
@@ -235,21 +202,12 @@
     static inline void Merge(const MapEntryAccessorType& from,                \
                              TypeOnMemory* to, Arena* arena);                 \
     static inline void Clear(TypeOnMemory* value, Arena* arena);              \
-    static inline void ClearMaybeByDefaultEnum(TypeOnMemory* value,           \
-                                               Arena* arena,                  \
-                                               int default_enum);             \
     static inline size_t SpaceUsedInMapEntryLong(const TypeOnMemory& value);  \
-    static inline size_t SpaceUsedInMapLong(const TypeOnMemory& value);       \
-    static inline size_t SpaceUsedInMapLong(ConstStringParam 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);         \
-    static inline void InitializeMaybeByDefaultEnum(TypeOnMemory* value,      \
-                                                    int default_enum_value,   \
-                                                    Arena* arena);            \
     static inline MapEntryAccessorType* EnsureMutable(TypeOnMemory* value,    \
                                                       Arena* arena);          \
   };
@@ -547,23 +505,11 @@
 }
 
 template <typename Type>
-size_t MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::SpaceUsedInMapLong(
-    const Type& value) {
-  return value.SpaceUsedLong();
-}
-
-template <typename Type>
 inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Clear(
     Type** value, Arena* /* arena */) {
   if (*value != NULL) (*value)->Clear();
 }
 template <typename Type>
-inline void
-MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::ClearMaybeByDefaultEnum(
-    Type** value, Arena* /* arena */, int /* default_enum_value */) {
-  if (*value != NULL) (*value)->Clear();
-}
-template <typename Type>
 inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Merge(
     const Type& from, Type** to, Arena* /* arena */) {
   (*to)->MergeFrom(from);
@@ -576,25 +522,12 @@
 }
 
 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;
 }
 
 template <typename Type>
-inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::
-    InitializeMaybeByDefaultEnum(Type** x, int /* default_enum_value */,
-                                 Arena* /* arena */) {
-  *x = NULL;
-}
-
-template <typename Type>
 inline Type* MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::EnsureMutable(
     Type** value, Arena* arena) {
   if (*value == NULL) {
@@ -608,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>
@@ -635,29 +568,11 @@
     return sizeof(value);                                                     \
   }                                                                           \
   template <typename Type>                                                    \
-  inline size_t                                                               \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapLong( \
-      const TypeOnMemory& value) {                                            \
-    return sizeof(value);                                                     \
-  }                                                                           \
-  template <typename Type>                                                    \
-  inline size_t                                                               \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapLong( \
-      ConstStringParam value) {                                               \
-    return sizeof(std::string);                                               \
-  }                                                                           \
-  template <typename Type>                                                    \
   inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Clear(  \
       TypeOnMemory* value, Arena* arena) {                                    \
     value->ClearToEmpty(&internal::GetEmptyStringAlreadyInited(), arena);     \
   }                                                                           \
   template <typename Type>                                                    \
-  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::        \
-      ClearMaybeByDefaultEnum(TypeOnMemory* value, Arena* arena,              \
-                              int /* default_enum */) {                       \
-    Clear(value, arena);                                                      \
-  }                                                                           \
-  template <typename Type>                                                    \
   inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Merge(  \
       const MapEntryAccessorType& from, TypeOnMemory* to, Arena* arena) {     \
     to->Set(&internal::GetEmptyStringAlreadyInited(), from, arena);           \
@@ -669,21 +584,11 @@
   }                                                                           \
   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());        \
   }                                                                           \
   template <typename Type>                                                    \
-  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::        \
-      InitializeMaybeByDefaultEnum(                                           \
-          TypeOnMemory* value, int /* default_enum_value */, Arena* arena) {  \
-    Initialize(value, arena);                                                 \
-  }                                                                           \
-  template <typename Type>                                                    \
   inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType,            \
                                  Type>::MapEntryAccessorType*                 \
   MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable(      \
@@ -693,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>                                                    \
@@ -708,81 +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 size_t                                                               \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapLong( \
-      const TypeOnMemory& /* value */) {                                      \
-    return sizeof(Type);                                                      \
-  }                                                                           \
-  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>::        \
-      ClearMaybeByDefaultEnum(TypeOnMemory* value, Arena* /* arena */,        \
-                              int default_enum_value) {                       \
-    *value = static_cast<TypeOnMemory>(default_enum_value);                   \
-  }                                                                           \
-  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 void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::        \
-      InitializeMaybeByDefaultEnum(                                           \
-          TypeOnMemory* value, int default_enum_value, Arena* /* arena */) {  \
-    *value = static_cast<TypeOnMemory>(default_enum_value);                   \
-  }                                                                           \
-  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 f9422e5..c2e06cf 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/port_def.inc b/src/google/protobuf/port_def.inc
index 18fc65e..74c2518 100644
--- a/src/google/protobuf/port_def.inc
+++ b/src/google/protobuf/port_def.inc
@@ -444,6 +444,10 @@
 #undef NO
 #pragma push_macro("DEBUG")
 #undef DEBUG
+#pragma push_macro("TRUE")
+#undef TRUE
+#pragma push_macro("FALSE")
+#undef FALSE
 #endif // defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
 
 #if defined(__clang__)
diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc
index 5fea276..6b37510 100644
--- a/src/google/protobuf/port_undef.inc
+++ b/src/google/protobuf/port_undef.inc
@@ -99,6 +99,8 @@
 #pragma pop_macro("YES")
 #pragma pop_macro("NO")
 #pragma pop_macro("DEBUG")
+#pragma pop_macro("TRUE")
+#pragma pop_macro("FALSE")
 #endif // defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
 
 #if defined(__clang__)
diff --git a/src/google/protobuf/proto3_arena_unittest.cc b/src/google/protobuf/proto3_arena_unittest.cc
index 11f8b65..b253f70 100644
--- a/src/google/protobuf/proto3_arena_unittest.cc
+++ b/src/google/protobuf/proto3_arena_unittest.cc
@@ -293,6 +293,47 @@
   EXPECT_TRUE(r->GetOneofFieldDescriptor(msg, o) == nullptr);
 }
 
+// It's a regression test for b/160665543.
+TEST(Proto3OptionalTest, ClearNonOptionalMessageField) {
+  protobuf_unittest::TestProto3OptionalMessage msg;
+  msg.mutable_nested_message();
+  const google::protobuf::Descriptor* d = msg.GetDescriptor();
+  const google::protobuf::Reflection* r = msg.GetReflection();
+  const google::protobuf::FieldDescriptor* f = d->FindFieldByName("nested_message");
+  r->ClearField(&msg, f);
+}
+
+TEST(Proto3OptionalTest, ClearOptionalMessageField) {
+  protobuf_unittest::TestProto3OptionalMessage msg;
+  msg.mutable_optional_nested_message();
+  const google::protobuf::Descriptor* d = msg.GetDescriptor();
+  const google::protobuf::Reflection* r = msg.GetReflection();
+  const google::protobuf::FieldDescriptor* f =
+      d->FindFieldByName("optional_nested_message");
+  r->ClearField(&msg, f);
+}
+
+TEST(Proto3OptionalTest, SwapNonOptionalMessageField) {
+  protobuf_unittest::TestProto3OptionalMessage msg1;
+  protobuf_unittest::TestProto3OptionalMessage msg2;
+  msg1.mutable_nested_message();
+  const google::protobuf::Descriptor* d = msg1.GetDescriptor();
+  const google::protobuf::Reflection* r = msg1.GetReflection();
+  const google::protobuf::FieldDescriptor* f = d->FindFieldByName("nested_message");
+  r->SwapFields(&msg1, &msg2, {f});
+}
+
+TEST(Proto3OptionalTest, SwapOptionalMessageField) {
+  protobuf_unittest::TestProto3OptionalMessage msg1;
+  protobuf_unittest::TestProto3OptionalMessage msg2;
+  msg1.mutable_optional_nested_message();
+  const google::protobuf::Descriptor* d = msg1.GetDescriptor();
+  const google::protobuf::Reflection* r = msg1.GetReflection();
+  const google::protobuf::FieldDescriptor* f =
+      d->FindFieldByName("optional_nested_message");
+  r->SwapFields(&msg1, &msg2, {f});
+}
+
 void SetAllFieldsZero(protobuf_unittest::TestProto3Optional* msg) {
   msg->set_optional_int32(0);
   msg->set_optional_int64(0);
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 9f09bec..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 =
@@ -57,11 +56,10 @@
 const char descriptor_table_protodef_google_2fprotobuf_2fsource_5fcontext_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n$google/protobuf/source_context.proto\022\017"
   "google.protobuf\"\"\n\rSourceContext\022\021\n\tfile"
-  "_name\030\001 \001(\tB\225\001\n\023com.google.protobufB\022Sou"
-  "rceContextProtoP\001ZAgoogle.golang.org/gen"
-  "proto/protobuf/source_context;source_con"
-  "text\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTy"
-  "pesb\006proto3"
+  "_name\030\001 \001(\tB\212\001\n\023com.google.protobufB\022Sou"
+  "rceContextProtoP\001Z6google.golang.org/pro"
+  "tobuf/types/known/sourcecontextpb\242\002\003GPB\252"
+  "\002\036Google.Protobuf.WellKnownTypesb\006proto3"
   ;
 static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_deps[1] = {
 };
@@ -70,7 +68,7 @@
 };
 static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_once;
 const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto = {
-  false, false, descriptor_table_protodef_google_2fprotobuf_2fsource_5fcontext_2eproto, "google/protobuf/source_context.proto", 251,
+  false, false, descriptor_table_protodef_google_2fprotobuf_2fsource_5fcontext_2eproto, "google/protobuf/source_context.proto", 240,
   &descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_once, descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_sccs, descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_deps, 1, 0,
   schemas, file_default_instances, TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto::offsets,
   file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto, file_level_service_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto,
@@ -82,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 732c814..4722d10 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/source_context.proto b/src/google/protobuf/source_context.proto
index f3b2c96..06bfc43 100644
--- a/src/google/protobuf/source_context.proto
+++ b/src/google/protobuf/source_context.proto
@@ -37,7 +37,7 @@
 option java_outer_classname = "SourceContextProto";
 option java_multiple_files = true;
 option objc_class_prefix = "GPB";
-option go_package = "google.golang.org/genproto/protobuf/source_context;source_context";
+option go_package = "google.golang.org/protobuf/types/known/sourcecontextpb";
 
 // `SourceContext` represents information about the source of a
 // protobuf element, like the file in which it is defined.
diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc
index 027fef6..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_),
@@ -136,11 +126,10 @@
   "\000\0220\n\nlist_value\030\006 \001(\0132\032.google.protobuf."
   "ListValueH\000B\006\n\004kind\"3\n\tListValue\022&\n\006valu"
   "es\030\001 \003(\0132\026.google.protobuf.Value*\033\n\tNull"
-  "Value\022\016\n\nNULL_VALUE\020\000B\201\001\n\023com.google.pro"
-  "tobufB\013StructProtoP\001Z1github.com/golang/"
-  "protobuf/ptypes/struct;structpb\370\001\001\242\002\003GPB"
-  "\252\002\036Google.Protobuf.WellKnownTypesb\006proto"
-  "3"
+  "Value\022\016\n\nNULL_VALUE\020\000B\177\n\023com.google.prot"
+  "obufB\013StructProtoP\001Z/google.golang.org/p"
+  "rotobuf/types/known/structpb\370\001\001\242\002\003GPB\252\002\036"
+  "Google.Protobuf.WellKnownTypesb\006proto3"
   ;
 static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fstruct_2eproto_deps[1] = {
 };
@@ -149,7 +138,7 @@
 };
 static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fstruct_2eproto_once;
 const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fstruct_2eproto = {
-  false, false, descriptor_table_protodef_google_2fprotobuf_2fstruct_2eproto, "google/protobuf/struct.proto", 641,
+  false, false, descriptor_table_protodef_google_2fprotobuf_2fstruct_2eproto, "google/protobuf/struct.proto", 638,
   &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once, descriptor_table_google_2fprotobuf_2fstruct_2eproto_sccs, descriptor_table_google_2fprotobuf_2fstruct_2eproto_deps, 1, 0,
   schemas, file_default_instances, TableStruct_google_2fprotobuf_2fstruct_2eproto::offsets,
   file_level_metadata_google_2fprotobuf_2fstruct_2eproto, 4, file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto, file_level_service_descriptors_google_2fprotobuf_2fstruct_2eproto,
@@ -191,8 +180,6 @@
 
 // ===================================================================
 
-void Struct::InitAsDefaultInstance() {
-}
 class Struct::_Internal {
  public:
 };
@@ -429,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);
@@ -886,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 84605a2..315193c 100644
--- a/src/google/protobuf/struct.pb.h
+++ b/src/google/protobuf/struct.pb.h
@@ -109,14 +109,12 @@
 class Struct_FieldsEntry_DoNotUse : public ::PROTOBUF_NAMESPACE_ID::internal::MapEntry<Struct_FieldsEntry_DoNotUse, 
     std::string, PROTOBUF_NAMESPACE_ID::Value,
     ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_STRING,
-    ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE,
-    0 > {
+    ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE> {
 public:
   typedef ::PROTOBUF_NAMESPACE_ID::internal::MapEntry<Struct_FieldsEntry_DoNotUse, 
     std::string, PROTOBUF_NAMESPACE_ID::Value,
     ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_STRING,
-    ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE,
-    0 > SuperType;
+    ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE> SuperType;
   Struct_FieldsEntry_DoNotUse();
   explicit Struct_FieldsEntry_DoNotUse(::PROTOBUF_NAMESPACE_ID::Arena* arena);
   void MergeFrom(const Struct_FieldsEntry_DoNotUse& other);
@@ -174,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_);
@@ -282,8 +279,7 @@
       Struct_FieldsEntry_DoNotUse,
       std::string, PROTOBUF_NAMESPACE_ID::Value,
       ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_STRING,
-      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE,
-      0 > fields_;
+      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE> fields_;
   mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
   friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto;
 };
@@ -335,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_);
@@ -580,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_);
@@ -980,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)
@@ -1053,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/struct.proto b/src/google/protobuf/struct.proto
index ed990e3..545215c 100644
--- a/src/google/protobuf/struct.proto
+++ b/src/google/protobuf/struct.proto
@@ -34,7 +34,7 @@
 
 option csharp_namespace = "Google.Protobuf.WellKnownTypes";
 option cc_enable_arenas = true;
-option go_package = "github.com/golang/protobuf/ptypes/struct;structpb";
+option go_package = "google.golang.org/protobuf/types/known/structpb";
 option java_package = "com.google.protobuf";
 option java_outer_classname = "StructProto";
 option java_multiple_files = true;
diff --git a/src/google/protobuf/test_messages_proto3.proto b/src/google/protobuf/test_messages_proto3.proto
index a10f44d..4e409dc 100644
--- a/src/google/protobuf/test_messages_proto3.proto
+++ b/src/google/protobuf/test_messages_proto3.proto
@@ -203,6 +203,7 @@
     float oneof_float = 117;
     double oneof_double = 118;
     NestedEnum oneof_enum = 119;
+    google.protobuf.NullValue oneof_null_value = 120;
   }
 
   // Well-known types
@@ -232,6 +233,7 @@
   google.protobuf.Struct optional_struct = 304;
   google.protobuf.Any optional_any = 305;
   google.protobuf.Value optional_value = 306;
+  google.protobuf.NullValue optional_null_value = 307;
 
   repeated google.protobuf.Duration repeated_duration = 311;
   repeated google.protobuf.Timestamp repeated_timestamp = 312;
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 6ac63ed..f7ced05 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 8b27210..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 =
@@ -58,10 +57,10 @@
 const char descriptor_table_protodef_google_2fprotobuf_2ftimestamp_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n\037google/protobuf/timestamp.proto\022\017googl"
   "e.protobuf\"+\n\tTimestamp\022\017\n\007seconds\030\001 \001(\003"
-  "\022\r\n\005nanos\030\002 \001(\005B~\n\023com.google.protobufB\016"
-  "TimestampProtoP\001Z+github.com/golang/prot"
-  "obuf/ptypes/timestamp\370\001\001\242\002\003GPB\252\002\036Google."
-  "Protobuf.WellKnownTypesb\006proto3"
+  "\022\r\n\005nanos\030\002 \001(\005B\205\001\n\023com.google.protobufB"
+  "\016TimestampProtoP\001Z2google.golang.org/pro"
+  "tobuf/types/known/timestamppb\370\001\001\242\002\003GPB\252\002"
+  "\036Google.Protobuf.WellKnownTypesb\006proto3"
   ;
 static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_deps[1] = {
 };
@@ -70,7 +69,7 @@
 };
 static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_once;
 const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftimestamp_2eproto = {
-  false, false, descriptor_table_protodef_google_2fprotobuf_2ftimestamp_2eproto, "google/protobuf/timestamp.proto", 231,
+  false, false, descriptor_table_protodef_google_2fprotobuf_2ftimestamp_2eproto, "google/protobuf/timestamp.proto", 239,
   &descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_once, descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_sccs, descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_deps, 1, 0,
   schemas, file_default_instances, TableStruct_google_2fprotobuf_2ftimestamp_2eproto::offsets,
   file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2ftimestamp_2eproto, file_level_service_descriptors_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 608f8f4..da7ebe9 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 cd35786..3b2df6d 100644
--- a/src/google/protobuf/timestamp.proto
+++ b/src/google/protobuf/timestamp.proto
@@ -34,7 +34,7 @@
 
 option csharp_namespace = "Google.Protobuf.WellKnownTypes";
 option cc_enable_arenas = true;
-option go_package = "github.com/golang/protobuf/ptypes/timestamp";
+option go_package = "google.golang.org/protobuf/types/known/timestamppb";
 option java_package = "com.google.protobuf";
 option java_outer_classname = "TimestampProto";
 option java_multiple_files = true;
@@ -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 8da70ec..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 =
@@ -230,10 +225,10 @@
   "\003 \003(\0132\027.google.protobuf.Option\";\n\006Option"
   "\022\014\n\004name\030\001 \001(\t\022#\n\005value\030\002 \001(\0132\024.google.p"
   "rotobuf.Any*.\n\006Syntax\022\021\n\rSYNTAX_PROTO2\020\000"
-  "\022\021\n\rSYNTAX_PROTO3\020\001B}\n\023com.google.protob"
-  "ufB\tTypeProtoP\001Z/google.golang.org/genpr"
-  "oto/protobuf/ptype;ptype\370\001\001\242\002\003GPB\252\002\036Goog"
-  "le.Protobuf.WellKnownTypesb\006proto3"
+  "\022\021\n\rSYNTAX_PROTO3\020\001B{\n\023com.google.protob"
+  "ufB\tTypeProtoP\001Z-google.golang.org/proto"
+  "buf/types/known/typepb\370\001\001\242\002\003GPB\252\002\036Google"
+  ".Protobuf.WellKnownTypesb\006proto3"
   ;
 static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2ftype_2eproto_deps[2] = {
   &::descriptor_table_google_2fprotobuf_2fany_2eproto,
@@ -248,7 +243,7 @@
 };
 static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2ftype_2eproto_once;
 const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftype_2eproto = {
-  false, false, descriptor_table_protodef_google_2fprotobuf_2ftype_2eproto, "google/protobuf/type.proto", 1594,
+  false, false, descriptor_table_protodef_google_2fprotobuf_2ftype_2eproto, "google/protobuf/type.proto", 1592,
   &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, descriptor_table_google_2fprotobuf_2ftype_2eproto_sccs, descriptor_table_google_2fprotobuf_2ftype_2eproto_deps, 5, 2,
   schemas, file_default_instances, TableStruct_google_2fprotobuf_2ftype_2eproto::offsets,
   file_level_metadata_google_2fprotobuf_2ftype_2eproto, 5, file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto, file_level_service_descriptors_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 ce0155b..f761361 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/type.proto b/src/google/protobuf/type.proto
index e4b1d3a..d3f6a68 100644
--- a/src/google/protobuf/type.proto
+++ b/src/google/protobuf/type.proto
@@ -41,7 +41,7 @@
 option java_outer_classname = "TypeProto";
 option java_multiple_files = true;
 option objc_class_prefix = "GPB";
-option go_package = "google.golang.org/genproto/protobuf/ptype;ptype";
+option go_package = "google.golang.org/protobuf/types/known/typepb";
 
 // A protocol buffer message type.
 message Type {
@@ -113,7 +113,7 @@
     CARDINALITY_REQUIRED = 2;
     // For repeated fields.
     CARDINALITY_REPEATED = 3;
-  };
+  }
 
   // The field type.
   Kind kind = 1;
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/unittest_proto3_optional.proto b/src/google/protobuf/unittest_proto3_optional.proto
index 3c47f12..e760021 100644
--- a/src/google/protobuf/unittest_proto3_optional.proto
+++ b/src/google/protobuf/unittest_proto3_optional.proto
@@ -77,3 +77,12 @@
   int32 singular_int32 = 22;
   int64 singular_int64 = 23;
 }
+
+message TestProto3OptionalMessage {
+  message NestedMessage {
+    string s = 1;
+  }
+
+  NestedMessage nested_message = 1;
+  optional NestedMessage optional_nested_message = 2;
+}
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/datapiece.cc b/src/google/protobuf/util/internal/datapiece.cc
index 6ce7dbc..e76268a 100644
--- a/src/google/protobuf/util/internal/datapiece.cc
+++ b/src/google/protobuf/util/internal/datapiece.cc
@@ -37,6 +37,7 @@
 #include <google/protobuf/type.pb.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/util/internal/utility.h>
+#include <google/protobuf/stubs/status.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/mathutil.h>
 
diff --git a/src/google/protobuf/util/internal/field_mask_utility.cc b/src/google/protobuf/util/internal/field_mask_utility.cc
index 40e193e..0beff99 100644
--- a/src/google/protobuf/util/internal/field_mask_utility.cc
+++ b/src/google/protobuf/util/internal/field_mask_utility.cc
@@ -31,6 +31,7 @@
 #include <google/protobuf/util/internal/field_mask_utility.h>
 
 #include <google/protobuf/util/internal/utility.h>
+#include <google/protobuf/stubs/status.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/status_macros.h>
 
@@ -107,7 +108,7 @@
 }
 
 util::Status DecodeCompactFieldMaskPaths(StringPiece paths,
-                                           PathSinkCallback path_sink) {
+                                         PathSinkCallback path_sink) {
   std::stack<std::string> prefix;
   int length = paths.length();
   int previous_position = 0;
diff --git a/src/google/protobuf/util/internal/field_mask_utility.h b/src/google/protobuf/util/internal/field_mask_utility.h
index 7335af5..bc41321 100644
--- a/src/google/protobuf/util/internal/field_mask_utility.h
+++ b/src/google/protobuf/util/internal/field_mask_utility.h
@@ -38,6 +38,7 @@
 
 #include <google/protobuf/stubs/callback.h>
 #include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/status.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/status.h>
 
@@ -63,7 +64,7 @@
 // Note that we also support Apiary style FieldMask form. The above example in
 // the Apiary style will look like "a.b,a.c(d,e)".
 util::Status DecodeCompactFieldMaskPaths(StringPiece paths,
-                                           PathSinkCallback path_sink);
+                                         PathSinkCallback path_sink);
 
 }  // namespace converter
 }  // namespace util
diff --git a/src/google/protobuf/util/internal/json_objectwriter.cc b/src/google/protobuf/util/internal/json_objectwriter.cc
index a98e7ba..32ce2dc 100644
--- a/src/google/protobuf/util/internal/json_objectwriter.cc
+++ b/src/google/protobuf/util/internal/json_objectwriter.cc
@@ -148,7 +148,7 @@
   std::string base64;
 
   if (use_websafe_base64_for_bytes_)
-    WebSafeBase64EscapeWithPadding(value.ToString(), &base64);
+    WebSafeBase64EscapeWithPadding(std::string(value), &base64);
   else
     Base64Escape(value, &base64);
 
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_objectsource_test.cc b/src/google/protobuf/util/internal/protostream_objectsource_test.cc
index b2daf3a..ab27349 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource_test.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource_test.cc
@@ -49,6 +49,7 @@
 #include <google/protobuf/util/internal/constants.h>
 #include <gtest/gtest.h>
 #include <google/protobuf/stubs/casts.h>
+#include <google/protobuf/stubs/status.h>
 
 
 namespace google {
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc
index 527d5e7..817109b 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc
@@ -42,6 +42,7 @@
 #include <google/protobuf/util/internal/constants.h>
 #include <google/protobuf/util/internal/utility.h>
 #include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/status.h>
 #include <google/protobuf/stubs/time.h>
 #include <google/protobuf/stubs/map_util.h>
 #include <google/protobuf/stubs/statusor.h>
@@ -587,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
@@ -610,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/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
index 983043f..564050f 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
@@ -93,12 +93,6 @@
 }
 }  // namespace
 
-#if __cplusplus >= 201103L
-using std::get;
-#else
-using std::tr1::get;
-#endif
-
 class BaseProtoStreamObjectWriterTest
     : public ::testing::TestWithParam<testing::TypeInfoSource> {
  protected:
@@ -171,7 +165,7 @@
 
 MATCHER_P(HasObjectLocation, expected,
           "Verifies the expected object location") {
-  std::string actual = get<0>(arg).ToString();
+  std::string actual = std::get<0>(arg).ToString();
   if (actual == expected) return true;
   *result_listener << "actual location is: " << actual;
   return false;
diff --git a/src/google/protobuf/util/internal/type_info.cc b/src/google/protobuf/util/internal/type_info.cc
index e8b2103..e91afa0 100644
--- a/src/google/protobuf/util/internal/type_info.cc
+++ b/src/google/protobuf/util/internal/type_info.cc
@@ -36,6 +36,7 @@
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/type.pb.h>
 #include <google/protobuf/util/internal/utility.h>
+#include <google/protobuf/stubs/status.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/map_util.h>
 #include <google/protobuf/stubs/status.h>
diff --git a/src/google/protobuf/util/json_format_proto3.proto b/src/google/protobuf/util/json_format_proto3.proto
index b62487a..0eec9da 100644
--- a/src/google/protobuf/util/json_format_proto3.proto
+++ b/src/google/protobuf/util/json_format_proto3.proto
@@ -91,6 +91,7 @@
     bytes oneof_bytes_value = 3;
     EnumType oneof_enum_value = 4;
     MessageType oneof_message_value = 5;
+    google.protobuf.NullValue oneof_null_value = 6;
   }
 }
 
diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc
index c7d0261..9ce64b7 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 3268870..943fadf 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_lite.cc b/src/google/protobuf/wire_format_lite.cc
index 47ad0f1..dc25608 100644
--- a/src/google/protobuf/wire_format_lite.cc
+++ b/src/google/protobuf/wire_format_lite.cc
@@ -603,7 +603,6 @@
 // efficient SSE code.
 template <bool ZigZag, bool SignExtended, typename T>
 static size_t VarintSize(const T* data, const int n) {
-#if __cplusplus >= 201103L
   static_assert(sizeof(T) == 4, "This routine only works for 32 bit integers");
   // is_unsigned<T> => !ZigZag
   static_assert(
@@ -615,7 +614,6 @@
       "Cannot SignExtended unsigned types");
   static_assert(!(SignExtended && ZigZag),
                 "Cannot SignExtended and ZigZag on the same type");
-#endif
   uint32 sum = n;
   uint32 msb_sum = 0;
   for (int i = 0; i < n; i++) {
@@ -640,12 +638,10 @@
 
 template <bool ZigZag, typename T>
 static size_t VarintSize64(const T* data, const int n) {
-#if __cplusplus >= 201103L
   static_assert(sizeof(T) == 8, "This routine only works for 64 bit integers");
   // is_unsigned<T> => !ZigZag
   static_assert(!ZigZag || !std::is_unsigned<T>::value,
                 "Cannot ZigZag encode unsigned types");
-#endif
   uint64 sum = n;
   for (int i = 0; i < n; i++) {
     uint64 x = data[i];
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 be039b4..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 =
@@ -270,11 +261,11 @@
   "e\030\001 \001(\004\"\033\n\nInt32Value\022\r\n\005value\030\001 \001(\005\"\034\n\013"
   "UInt32Value\022\r\n\005value\030\001 \001(\r\"\032\n\tBoolValue\022"
   "\r\n\005value\030\001 \001(\010\"\034\n\013StringValue\022\r\n\005value\030\001"
-  " \001(\t\"\033\n\nBytesValue\022\r\n\005value\030\001 \001(\014B|\n\023com"
-  ".google.protobufB\rWrappersProtoP\001Z*githu"
-  "b.com/golang/protobuf/ptypes/wrappers\370\001\001"
-  "\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypesb"
-  "\006proto3"
+  " \001(\t\"\033\n\nBytesValue\022\r\n\005value\030\001 \001(\014B\203\001\n\023co"
+  "m.google.protobufB\rWrappersProtoP\001Z1goog"
+  "le.golang.org/protobuf/types/known/wrapp"
+  "erspb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKno"
+  "wnTypesb\006proto3"
   ;
 static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fwrappers_2eproto_deps[1] = {
 };
@@ -291,7 +282,7 @@
 };
 static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once;
 const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fwrappers_2eproto = {
-  false, false, descriptor_table_protodef_google_2fprotobuf_2fwrappers_2eproto, "google/protobuf/wrappers.proto", 447,
+  false, false, descriptor_table_protodef_google_2fprotobuf_2fwrappers_2eproto, "google/protobuf/wrappers.proto", 455,
   &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once, descriptor_table_google_2fprotobuf_2fwrappers_2eproto_sccs, descriptor_table_google_2fprotobuf_2fwrappers_2eproto_deps, 9, 0,
   schemas, file_default_instances, TableStruct_google_2fprotobuf_2fwrappers_2eproto::offsets,
   file_level_metadata_google_2fprotobuf_2fwrappers_2eproto, 9, file_level_enum_descriptors_google_2fprotobuf_2fwrappers_2eproto, file_level_service_descriptors_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 5463d66..5a092cd 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/src/google/protobuf/wrappers.proto b/src/google/protobuf/wrappers.proto
index 9ee41e3..d49dd53 100644
--- a/src/google/protobuf/wrappers.proto
+++ b/src/google/protobuf/wrappers.proto
@@ -44,7 +44,7 @@
 
 option csharp_namespace = "Google.Protobuf.WellKnownTypes";
 option cc_enable_arenas = true;
-option go_package = "github.com/golang/protobuf/ptypes/wrappers";
+option go_package = "google.golang.org/protobuf/types/known/wrapperspb";
 option java_package = "com.google.protobuf";
 option java_outer_classname = "WrappersProto";
 option java_multiple_files = true;