Merge tag 'refs/tags/sync-piper' into sync-stage
diff --git a/.github/mergeable.yml b/.github/mergeable.yml
index a827eb7..8577f08 100644
--- a/.github/mergeable.yml
+++ b/.github/mergeable.yml
@@ -11,8 +11,8 @@
                 regex: 'release notes: yes'
                 message: 'Please include release notes: yes'
             - must_include:
-                regex: '^(c#|c\+\+|cleanup|conformance tests|integration|java|javascript|go|objective-c|php|python|ruby|bazel)'
-                message: 'Please include at least a language label (e.g., c++, java, python). Or apply one of the following labels: bazel, cleanup, conformance tests, integration.'
+                regex: '^(c#|c\+\+|cleanup|conformance tests|integration|java|javascript|go|objective-c|php|python|ruby|bazel|cmake|protoc)'
+                message: 'Please include at least a language label (e.g., c++, java, python). Or apply one of the following labels: bazel, cmake, cleanup, conformance tests, integration, protoc.'
           - must_include:
               regex: 'release notes: no'
               message: 'Please include release notes: no'
diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml
index 4ef1a1b..f9795e1 100644
--- a/.github/workflows/codespell.yml
+++ b/.github/workflows/codespell.yml
@@ -13,4 +13,4 @@
         with:
           check_filenames: true
           skip: ./.git,./conformance/third_party,*.snk,*.pb,*.pb.cc,*.pb.h,./src/google/protobuf/testdata,./objectivec/Tests,./python/compatibility_tests/v2.5.0/tests/google/protobuf/internal
-          ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,fo,fundementals,hel,importd,inout,leapyear,nd,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od"
+          ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,files',fo,fundementals,hel,importd,inout,leapyear,nd,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od"
diff --git a/BUILD b/BUILD
index b4c9f5e..1124321 100644
--- a/BUILD
+++ b/BUILD
@@ -14,10 +14,10 @@
 # build configuration
 ################################################################################
 
+# TODO(yannic): Remove in 3.14.0.
 string_flag(
     name = "incompatible_use_com_google_googletest",
-    # TODO(yannic): Flip to `true` for `3.13.0`.
-    build_setting_default = "false",
+    build_setting_default = "true",
     values = ["true", "false"]
 )
 
@@ -369,7 +369,15 @@
 
 cc_proto_blacklist_test(
     name = "cc_proto_blacklist_test",
-    deps = [proto + "_cc_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()]
+    deps = [proto + "_cc_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()],
+    tags = [
+        # Exclude this target from wildcard expansion (//...). Due to
+        # https://github.com/bazelbuild/bazel/issues/10590, this test has to
+        # be nominated using the `@com_google_protobuf//` prefix. We do that,
+        # e.g., in kokoro/linux/bazel/build.sh.
+        # See also https://github.com/protocolbuffers/protobuf/pull/7096.
+        "manual",
+    ],
 )
 
 ################################################################################
@@ -757,6 +765,13 @@
     copts = COPTS + [
         "-DPYTHON_PROTO2_CPP_IMPL_V2",
     ],
+    tags = [
+        # Exclude this target from wildcard expansion (//...) because it may
+        # not even be buildable. It will be built if it is needed according
+        # to :use_fast_cpp_protos.
+        # https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes
+        "manual",
+    ],
     linkshared = 1,
     linkstatic = 1,
     deps = select({
@@ -781,6 +796,13 @@
         "python/",
         "src/",
     ],
+    tags = [
+        # Exclude this target from wildcard expansion (//...) because it may
+        # not even be buildable. It will be built if it is needed according
+        # to :use_fast_cpp_protos.
+        # https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes
+        "manual",
+    ],
     linkshared = 1,
     linkstatic = 1,
     deps = [
diff --git a/WORKSPACE b/WORKSPACE
index cb16ae8..5a767a9 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -29,13 +29,13 @@
     actual = "//util/python:python_headers",
 )
 
-# TODO(yannic): Remove in 3.13.0.
+# TODO(yannic): Remove in 3.14.0.
 bind(
     name = "gtest",
     actual = "@com_google_googletest//:gtest",
 )
 
-# TODO(yannic): Remove in 3.13.0.
+# TODO(yannic): Remove in 3.14.0.
 bind(
     name = "gtest_main",
     actual = "@com_google_googletest//:gtest_main",
diff --git a/conformance/text_format_failure_list_java.txt b/conformance/text_format_failure_list_java.txt
index 8f74bdf..71e3242 100644
--- a/conformance/text_format_failure_list_java.txt
+++ b/conformance/text_format_failure_list_java.txt
@@ -5,14 +5,6 @@
 Required.Proto3.TextFormatInput.AnyField.ProtobufOutput
 Required.Proto3.TextFormatInput.AnyField.TextFormatOutput
 
-Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput
-Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput
-Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput
-Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput
-Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput
-Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput
-Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput
-Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput
 Required.Proto3.TextFormatInput.StringFieldBadUTF8Hex
 Required.Proto3.TextFormatInput.StringFieldBadUTF8Octal
 Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput
diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
index e20a885..ff81e00 100644
--- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
+++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
@@ -41,6 +41,7 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.Buffer;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -2009,14 +2010,14 @@
       int prevPos = buffer.position();
       int prevLimit = buffer.limit();
       try {
-        buffer.position(bufferPos(begin));
-        buffer.limit(bufferPos(end));
+        ((Buffer) buffer).position(bufferPos(begin));
+        ((Buffer) buffer).limit(bufferPos(end));
         return buffer.slice();
       } catch (IllegalArgumentException e) {
         throw InvalidProtocolBufferException.truncatedMessage();
       } finally {
-        buffer.position(prevPos);
-        buffer.limit(prevLimit);
+        ((Buffer) buffer).position(prevPos);
+        ((Buffer) buffer).limit(prevLimit);
       }
     }
   }
@@ -3910,14 +3911,14 @@
       int prevPos = currentByteBuffer.position();
       int prevLimit = currentByteBuffer.limit();
       try {
-        currentByteBuffer.position(begin);
-        currentByteBuffer.limit(end);
+        ((Buffer) currentByteBuffer).position(begin);
+        ((Buffer) currentByteBuffer).limit(end);
         return currentByteBuffer.slice();
       } catch (IllegalArgumentException e) {
         throw InvalidProtocolBufferException.truncatedMessage();
       } finally {
-        currentByteBuffer.position(prevPos);
-        currentByteBuffer.limit(prevLimit);
+        ((Buffer) currentByteBuffer).position(prevPos);
+        ((Buffer) currentByteBuffer).limit(prevLimit);
       }
     }
   }
diff --git a/java/core/src/main/java/com/google/protobuf/Descriptors.java b/java/core/src/main/java/com/google/protobuf/Descriptors.java
index f27602a..c30b00d 100644
--- a/java/core/src/main/java/com/google/protobuf/Descriptors.java
+++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java
@@ -764,7 +764,10 @@
     /**
      * Finds a field by name.
      *
-     * @param name The unqualified name of the field (e.g. "foo").
+     * @param name The unqualified name of the field (e.g. "foo"). For protocol buffer messages that
+     *     follow <a
+     *     href=https://developers.google.com/protocol-buffers/docs/style#message_and_field_names>Google's
+     *     guidance on naming</a> this will be a snake case string, such as <pre>song_name</pre>.
      * @return The field's descriptor, or {@code null} if not found.
      */
     public FieldDescriptor findFieldByName(final String name) {
diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java
index 241fcbd..0a63fad 100644
--- a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java
+++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java
@@ -46,7 +46,6 @@
   @Nullable */
   static final Class<?> EXTENSION_REGISTRY_CLASS = reflectExtensionRegistry();
 
-  /* @Nullable */
   static Class<?> reflectExtensionRegistry() {
     try {
       return Class.forName(FULL_REGISTRY_CLASS_NAME);
@@ -77,7 +76,6 @@
         && EXTENSION_REGISTRY_CLASS.isAssignableFrom(registry.getClass());
   }
 
-  /* @Nullable */
   private static final ExtensionRegistryLite invokeSubclassFactory(String methodName) {
     if (EXTENSION_REGISTRY_CLASS == null) {
       return null;
diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
index 0c4b20e..caa58e1 100644
--- a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
+++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
@@ -84,10 +84,8 @@
   static final String EXTENSION_CLASS_NAME = "com.google.protobuf.Extension";
 
   private static class ExtensionClassHolder {
-    /* @Nullable */
     static final Class<?> INSTANCE = resolveExtensionClass();
 
-    /* @Nullable */
     static Class<?> resolveExtensionClass() {
       try {
         return Class.forName(EXTENSION_CLASS_NAME);
diff --git a/java/core/src/main/java/com/google/protobuf/FieldType.java b/java/core/src/main/java/com/google/protobuf/FieldType.java
index 1b8f9e5..7232753 100644
--- a/java/core/src/main/java/com/google/protobuf/FieldType.java
+++ b/java/core/src/main/java/com/google/protobuf/FieldType.java
@@ -204,7 +204,6 @@
    *
    * @return the {@link FieldType} or {@code null} if not found.
    */
-  /* @Nullable */
   public static FieldType forId(int id) {
     if (id < 0 || id >= VALUES.length) {
       return null;
@@ -228,7 +227,6 @@
    *
    * @return the generic super class/interface, or {@code null} if not found.
    */
-  /* @Nullable */
   private static Type getGenericSuperList(Class<?> clazz) {
     // First look at interfaces.
     Type[] genericInterfaces = clazz.getGenericInterfaces();
diff --git a/java/core/src/main/java/com/google/protobuf/NioByteString.java b/java/core/src/main/java/com/google/protobuf/NioByteString.java
index 64c46be..1e594ff 100644
--- a/java/core/src/main/java/com/google/protobuf/NioByteString.java
+++ b/java/core/src/main/java/com/google/protobuf/NioByteString.java
@@ -37,6 +37,7 @@
 import java.io.InvalidObjectException;
 import java.io.ObjectInputStream;
 import java.io.OutputStream;
+import java.nio.Buffer;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.InvalidMarkException;
@@ -109,7 +110,7 @@
   protected void copyToInternal(
       byte[] target, int sourceOffset, int targetOffset, int numberToCopy) {
     ByteBuffer slice = buffer.slice();
-    slice.position(sourceOffset);
+    ((Buffer) slice).position(sourceOffset);
     slice.get(target, targetOffset, numberToCopy);
   }
 
@@ -285,8 +286,8 @@
     }
 
     ByteBuffer slice = buffer.slice();
-    slice.position(beginIndex - buffer.position());
-    slice.limit(endIndex - buffer.position());
+    ((Buffer) slice).position(beginIndex - buffer.position());
+    ((Buffer) slice).limit(endIndex - buffer.position());
     return slice;
   }
 }
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 7f744dd..bbc0f8d 100644
--- a/java/core/src/main/java/com/google/protobuf/TextFormat.java
+++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java
@@ -30,6 +30,8 @@
 
 package com.google.protobuf;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
+
 import com.google.protobuf.Descriptors.Descriptor;
 import com.google.protobuf.Descriptors.EnumDescriptor;
 import com.google.protobuf.Descriptors.EnumValueDescriptor;
@@ -2375,6 +2377,73 @@
                 result[pos++] = (byte) code;
                 break;
 
+              case 'u':
+                // Unicode escape
+                ++i;
+                if (i + 3 < input.size()
+                    && isHex(input.byteAt(i))
+                    && isHex(input.byteAt(i + 1))
+                    && isHex(input.byteAt(i + 2))
+                    && isHex(input.byteAt(i + 3))) {
+                  char ch =
+                      (char)
+                          (digitValue(input.byteAt(i)) << 12
+                              | digitValue(input.byteAt(i + 1)) << 8
+                              | digitValue(input.byteAt(i + 2)) << 4
+                              | digitValue(input.byteAt(i + 3)));
+                  if (Character.isSurrogate(ch)) {
+                    throw new InvalidEscapeSequenceException(
+                        "Invalid escape sequence: '\\u' refers to a surrogate");
+                  }
+                  byte[] chUtf8 = Character.toString(ch).getBytes(UTF_8);
+                  System.arraycopy(chUtf8, 0, result, pos, chUtf8.length);
+                  pos += chUtf8.length;
+                  i += 3;
+                } else {
+                  throw new InvalidEscapeSequenceException(
+                      "Invalid escape sequence: '\\u' with too few hex chars");
+                }
+                break;
+
+              case 'U':
+                // Unicode escape
+                ++i;
+                if (i + 7 >= input.size()) {
+                  throw new InvalidEscapeSequenceException(
+                      "Invalid escape sequence: '\\U' with too few hex chars");
+                }
+                int codepoint = 0;
+                for (int offset = i; offset < i + 8; offset++) {
+                  byte b = input.byteAt(offset);
+                  if (!isHex(b)) {
+                    throw new InvalidEscapeSequenceException(
+                        "Invalid escape sequence: '\\U' with too few hex chars");
+                  }
+                  codepoint = (codepoint << 4) | digitValue(b);
+                }
+                if (!Character.isValidCodePoint(codepoint)) {
+                  throw new InvalidEscapeSequenceException(
+                      "Invalid escape sequence: '\\U"
+                          + input.substring(i, i + 8).toStringUtf8()
+                          + "' is not a valid code point value");
+                }
+                Character.UnicodeBlock unicodeBlock = Character.UnicodeBlock.of(codepoint);
+                if (unicodeBlock.equals(Character.UnicodeBlock.LOW_SURROGATES)
+                    || unicodeBlock.equals(Character.UnicodeBlock.HIGH_SURROGATES)
+                    || unicodeBlock.equals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES)) {
+                  throw new InvalidEscapeSequenceException(
+                      "Invalid escape sequence: '\\U"
+                          + input.substring(i, i + 8).toStringUtf8()
+                          + "' refers to a surrogate code unit");
+                }
+                int[] codepoints = new int[1];
+                codepoints[0] = codepoint;
+                byte[] chUtf8 = new String(codepoints, 0, 1).getBytes(UTF_8);
+                System.arraycopy(chUtf8, 0, result, pos, chUtf8.length);
+                pos += chUtf8.length;
+                i += 7;
+                break;
+
               default:
                 throw new InvalidEscapeSequenceException(
                     "Invalid escape sequence: '\\" + (char) c + '\'');
diff --git a/java/core/src/main/java/com/google/protobuf/TypeRegistry.java b/java/core/src/main/java/com/google/protobuf/TypeRegistry.java
index 47d798b..422ff1f 100644
--- a/java/core/src/main/java/com/google/protobuf/TypeRegistry.java
+++ b/java/core/src/main/java/com/google/protobuf/TypeRegistry.java
@@ -70,7 +70,6 @@
   /**
    * Find a type by its typeUrl. Returns null if it cannot be found in this {@link TypeRegistry}.
    */
-  /* @Nullable */
   public final Descriptor getDescriptorForTypeUrl(String typeUrl)
       throws InvalidProtocolBufferException {
     return find(getTypeName(typeUrl));
diff --git a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
index b435327..471238a 100644
--- a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
+++ b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
@@ -41,7 +41,6 @@
 
 /** Utility class for working with unsafe operations. */
 final class UnsafeUtil {
-  private static final Logger logger = Logger.getLogger(UnsafeUtil.class.getName());
   private static final sun.misc.Unsafe UNSAFE = getUnsafe();
   private static final Class<?> MEMORY_CLASS = Android.getMemoryClass();
   private static final boolean IS_ANDROID_64 = determineAndroidSupportByAddressSize(long.class);
@@ -363,9 +362,13 @@
 
       return true;
     } catch (Throwable e) {
-      logger.log(
-          Level.WARNING,
-          "platform method missing - proto runtime falling back to safer methods: " + e);
+      // Because log statements are fairly sparse in this class, this logger is initialized
+      // non-statically. Static initialization adds undue runtime costs to the first client to
+      // initialize this class.
+      Logger.getLogger(UnsafeUtil.class.getName())
+          .log(
+              Level.WARNING,
+              "platform method missing - proto runtime falling back to safer methods: " + e);
     }
     return false;
   }
@@ -397,9 +400,13 @@
       clazz.getMethod("copyMemory", Object.class, long.class, Object.class, long.class, long.class);
       return true;
     } catch (Throwable e) {
-      logger.log(
-          Level.WARNING,
-          "platform method missing - proto runtime falling back to safer methods: " + e);
+      // Because log statements are fairly sparse in this class, this logger is initialized
+      // non-statically. Static initialization adds undue runtime costs to the first client to
+      // initialize this class.
+      Logger.getLogger(UnsafeUtil.class.getName())
+          .log(
+              Level.WARNING,
+              "platform method missing - proto runtime falling back to safer methods: " + e);
     }
     return false;
   }
diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java
index adca1d5..9994ad0 100644
--- a/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java
+++ b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java
@@ -77,44 +77,44 @@
 
   private void copyMapValues(TestMap source, TestMap.Builder destination) {
     destination
-        .putAllInt32ToInt32Field(source.getInt32ToInt32Field())
-        .putAllInt32ToStringField(source.getInt32ToStringField())
-        .putAllInt32ToBytesField(source.getInt32ToBytesField())
-        .putAllInt32ToEnumField(source.getInt32ToEnumField())
-        .putAllInt32ToMessageField(source.getInt32ToMessageField())
-        .putAllStringToInt32Field(source.getStringToInt32Field());
+        .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap())
+        .putAllInt32ToStringField(source.getInt32ToStringFieldMap())
+        .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap())
+        .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap())
+        .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap())
+        .putAllStringToInt32Field(source.getStringToInt32FieldMap());
   }
 
   private void assertMapValuesSet(TestMap message) {
-    assertEquals(3, message.getInt32ToInt32Field().size());
-    assertEquals(11, message.getInt32ToInt32Field().get(1).intValue());
-    assertEquals(22, message.getInt32ToInt32Field().get(2).intValue());
-    assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
+    assertEquals(3, message.getInt32ToInt32FieldMap().size());
+    assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue());
+    assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue());
+    assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue());
 
-    assertEquals(3, message.getInt32ToStringField().size());
-    assertEquals("11", message.getInt32ToStringField().get(1));
-    assertEquals("22", message.getInt32ToStringField().get(2));
-    assertEquals("33", message.getInt32ToStringField().get(3));
+    assertEquals(3, message.getInt32ToStringFieldMap().size());
+    assertEquals("11", message.getInt32ToStringFieldMap().get(1));
+    assertEquals("22", message.getInt32ToStringFieldMap().get(2));
+    assertEquals("33", message.getInt32ToStringFieldMap().get(3));
 
-    assertEquals(3, message.getInt32ToBytesField().size());
-    assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1));
-    assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2));
-    assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
+    assertEquals(3, message.getInt32ToBytesFieldMap().size());
+    assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1));
+    assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2));
+    assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3));
 
-    assertEquals(3, message.getInt32ToEnumField().size());
-    assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1));
-    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2));
-    assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
+    assertEquals(3, message.getInt32ToEnumFieldMap().size());
+    assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1));
+    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2));
+    assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3));
 
-    assertEquals(3, message.getInt32ToMessageField().size());
-    assertEquals(11, message.getInt32ToMessageField().get(1).getValue());
-    assertEquals(22, message.getInt32ToMessageField().get(2).getValue());
-    assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
+    assertEquals(3, message.getInt32ToMessageFieldMap().size());
+    assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue());
+    assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue());
+    assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue());
 
-    assertEquals(3, message.getStringToInt32Field().size());
-    assertEquals(11, message.getStringToInt32Field().get("1").intValue());
-    assertEquals(22, message.getStringToInt32Field().get("2").intValue());
-    assertEquals(33, message.getStringToInt32Field().get("3").intValue());
+    assertEquals(3, message.getStringToInt32FieldMap().size());
+    assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue());
+    assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue());
+    assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue());
   }
 
   private void updateMapValues(TestMap.Builder builder) {
@@ -152,35 +152,35 @@
   }
 
   private void assertMapValuesUpdated(TestMap message) {
-    assertEquals(3, message.getInt32ToInt32Field().size());
-    assertEquals(111, message.getInt32ToInt32Field().get(1).intValue());
-    assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
-    assertEquals(44, message.getInt32ToInt32Field().get(4).intValue());
+    assertEquals(3, message.getInt32ToInt32FieldMap().size());
+    assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue());
+    assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue());
+    assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue());
 
-    assertEquals(3, message.getInt32ToStringField().size());
-    assertEquals("111", message.getInt32ToStringField().get(1));
-    assertEquals("33", message.getInt32ToStringField().get(3));
-    assertEquals("44", message.getInt32ToStringField().get(4));
+    assertEquals(3, message.getInt32ToStringFieldMap().size());
+    assertEquals("111", message.getInt32ToStringFieldMap().get(1));
+    assertEquals("33", message.getInt32ToStringFieldMap().get(3));
+    assertEquals("44", message.getInt32ToStringFieldMap().get(4));
 
-    assertEquals(3, message.getInt32ToBytesField().size());
-    assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1));
-    assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
-    assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4));
+    assertEquals(3, message.getInt32ToBytesFieldMap().size());
+    assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1));
+    assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3));
+    assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4));
 
-    assertEquals(3, message.getInt32ToEnumField().size());
-    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
-    assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
-    assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4));
+    assertEquals(3, message.getInt32ToEnumFieldMap().size());
+    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
+    assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3));
+    assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4));
 
-    assertEquals(3, message.getInt32ToMessageField().size());
-    assertEquals(111, message.getInt32ToMessageField().get(1).getValue());
-    assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
-    assertEquals(44, message.getInt32ToMessageField().get(4).getValue());
+    assertEquals(3, message.getInt32ToMessageFieldMap().size());
+    assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue());
+    assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue());
+    assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue());
 
-    assertEquals(3, message.getStringToInt32Field().size());
-    assertEquals(111, message.getStringToInt32Field().get("1").intValue());
-    assertEquals(33, message.getStringToInt32Field().get("3").intValue());
-    assertEquals(44, message.getStringToInt32Field().get("4").intValue());
+    assertEquals(3, message.getStringToInt32FieldMap().size());
+    assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue());
+    assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue());
+    assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue());
   }
 
   private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) {
@@ -206,13 +206,13 @@
     TestMap.Builder builder = TestMap.newBuilder();
     TestMap message = builder.build();
     builder.putInt32ToInt32Field(1, 2);
-    assertTrue(message.getInt32ToInt32Field().isEmpty());
+    assertTrue(message.getInt32ToInt32FieldMap().isEmpty());
     message = builder.build();
-    assertEquals(newMap(1, 2), message.getInt32ToInt32Field());
-    assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
+    assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap());
+    assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap());
     builder.putInt32ToInt32Field(2, 3);
-    assertEquals(newMap(1, 2), message.getInt32ToInt32Field());
-    assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field());
+    assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap());
+    assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap());
   }
 
   public void testGetMapIsImmutable() {
@@ -254,30 +254,31 @@
 
   public void testMutableMapLifecycle() {
     TestMap.Builder builder = TestMap.newBuilder().putInt32ToInt32Field(1, 2);
-    assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field());
-    assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
+    assertEquals(newMap(1, 2), builder.build().getInt32ToInt32FieldMap());
+    assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap());
     builder.putInt32ToInt32Field(2, 3);
-    assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field());
+    assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap());
 
     builder.putInt32ToEnumField(1, TestMap.EnumValue.BAR);
-    assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField());
-    assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField());
+    assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumFieldMap());
+    assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumFieldMap());
     builder.putInt32ToEnumField(2, TestMap.EnumValue.FOO);
     assertEquals(
-        newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), builder.getInt32ToEnumField());
+        newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO),
+        builder.getInt32ToEnumFieldMap());
 
     builder.putInt32ToStringField(1, "1");
-    assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField());
-    assertEquals(newMap(1, "1"), builder.getInt32ToStringField());
+    assertEquals(newMap(1, "1"), builder.build().getInt32ToStringFieldMap());
+    assertEquals(newMap(1, "1"), builder.getInt32ToStringFieldMap());
     builder.putInt32ToStringField(2, "2");
-    assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringField());
+    assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringFieldMap());
 
     builder.putInt32ToMessageField(1, TestMap.MessageValue.getDefaultInstance());
     assertEquals(
         newMap(1, TestMap.MessageValue.getDefaultInstance()),
-        builder.build().getInt32ToMessageField());
+        builder.build().getInt32ToMessageFieldMap());
     assertEquals(
-        newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageField());
+        newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageFieldMap());
     builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance());
     assertEquals(
         newMap(
@@ -285,7 +286,7 @@
             TestMap.MessageValue.getDefaultInstance(),
             2,
             TestMap.MessageValue.getDefaultInstance()),
-        builder.getInt32ToMessageField());
+        builder.getInt32ToMessageFieldMap());
   }
 
   public void testGettersAndSetters() throws Exception {
@@ -415,7 +416,7 @@
     } catch (InvalidProtocolBufferException expected) {
       assertTrue(expected.getUnfinishedMessage() instanceof TestMap);
       map = (TestMap) expected.getUnfinishedMessage();
-      assertTrue(map.getInt32ToMessageField().isEmpty());
+      assertTrue(map.getInt32ToMessageFieldMap().isEmpty());
     }
 
     map =
@@ -476,14 +477,14 @@
     TestMap message = TestMap.parseFrom(data);
     // Entries with unknown enum values will be stored into UnknownFieldSet so
     // there is only one entry in the map.
-    assertEquals(1, message.getInt32ToEnumField().size());
-    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
+    assertEquals(1, message.getInt32ToEnumFieldMap().size());
+    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
     // Serializing and parsing should preserve the unknown entry.
     data = message.toByteString();
     TestUnknownEnumValue messageWithUnknownEnums = TestUnknownEnumValue.parseFrom(data);
-    assertEquals(2, messageWithUnknownEnums.getInt32ToInt32Field().size());
-    assertEquals(1, messageWithUnknownEnums.getInt32ToInt32Field().get(1).intValue());
-    assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue());
+    assertEquals(2, messageWithUnknownEnums.getInt32ToInt32FieldMap().size());
+    assertEquals(1, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(1).intValue());
+    assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(2).intValue());
   }
 
   public void testIterationOrder() throws Exception {
@@ -493,7 +494,7 @@
 
     assertEquals(
         Arrays.asList("1", "2", "3"),
-        new ArrayList<String>(message.getStringToInt32Field().keySet()));
+        new ArrayList<String>(message.getStringToInt32FieldMap().keySet()));
   }
 
   private static <K, V> Map<K, V> newMap(K key1, V value1) {
@@ -513,10 +514,10 @@
     TestMap.Builder builder = TestMap.newBuilder();
     setMapValues(builder);
     TestMap message = builder.build();
-    assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap());
-    assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap());
-    assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap());
-    assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap());
+    assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap());
+    assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap());
+    assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap());
+    assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap());
   }
 
   public void testContains() {
diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
index bb70632..b995802 100644
--- a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
+++ b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
@@ -119,12 +119,12 @@
 
   private void copyMapValues(TestMap source, TestMap.Builder destination) {
     destination
-        .putAllInt32ToInt32Field(source.getInt32ToInt32Field())
-        .putAllInt32ToStringField(source.getInt32ToStringField())
-        .putAllInt32ToBytesField(source.getInt32ToBytesField())
-        .putAllInt32ToEnumField(source.getInt32ToEnumField())
-        .putAllInt32ToMessageField(source.getInt32ToMessageField())
-        .putAllStringToInt32Field(source.getStringToInt32Field());
+        .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap())
+        .putAllInt32ToStringField(source.getInt32ToStringFieldMap())
+        .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap())
+        .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap())
+        .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap())
+        .putAllStringToInt32Field(source.getStringToInt32FieldMap());
   }
 
   private void assertMapValuesSet(TestMapOrBuilder message) {
@@ -236,35 +236,35 @@
   }
 
   private void assertMapValuesUpdated(TestMap message) {
-    assertEquals(3, message.getInt32ToInt32Field().size());
-    assertEquals(111, message.getInt32ToInt32Field().get(1).intValue());
-    assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
-    assertEquals(44, message.getInt32ToInt32Field().get(4).intValue());
+    assertEquals(3, message.getInt32ToInt32FieldMap().size());
+    assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue());
+    assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue());
+    assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue());
 
-    assertEquals(3, message.getInt32ToStringField().size());
-    assertEquals("111", message.getInt32ToStringField().get(1));
-    assertEquals("33", message.getInt32ToStringField().get(3));
-    assertEquals("44", message.getInt32ToStringField().get(4));
+    assertEquals(3, message.getInt32ToStringFieldMap().size());
+    assertEquals("111", message.getInt32ToStringFieldMap().get(1));
+    assertEquals("33", message.getInt32ToStringFieldMap().get(3));
+    assertEquals("44", message.getInt32ToStringFieldMap().get(4));
 
-    assertEquals(3, message.getInt32ToBytesField().size());
-    assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1));
-    assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
-    assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4));
+    assertEquals(3, message.getInt32ToBytesFieldMap().size());
+    assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1));
+    assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3));
+    assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4));
 
-    assertEquals(3, message.getInt32ToEnumField().size());
-    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
-    assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
-    assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4));
+    assertEquals(3, message.getInt32ToEnumFieldMap().size());
+    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
+    assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3));
+    assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4));
 
-    assertEquals(3, message.getInt32ToMessageField().size());
-    assertEquals(111, message.getInt32ToMessageField().get(1).getValue());
-    assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
-    assertEquals(44, message.getInt32ToMessageField().get(4).getValue());
+    assertEquals(3, message.getInt32ToMessageFieldMap().size());
+    assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue());
+    assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue());
+    assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue());
 
-    assertEquals(3, message.getStringToInt32Field().size());
-    assertEquals(111, message.getStringToInt32Field().get("1").intValue());
-    assertEquals(33, message.getStringToInt32Field().get("3").intValue());
-    assertEquals(44, message.getStringToInt32Field().get("4").intValue());
+    assertEquals(3, message.getStringToInt32FieldMap().size());
+    assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue());
+    assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue());
+    assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue());
   }
 
   private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) {
@@ -563,7 +563,7 @@
     } catch (InvalidProtocolBufferException expected) {
       assertTrue(expected.getUnfinishedMessage() instanceof TestMap);
       map = (TestMap) expected.getUnfinishedMessage();
-      assertTrue(map.getInt32ToMessageField().isEmpty());
+      assertTrue(map.getInt32ToMessageFieldMap().isEmpty());
     }
 
     map =
@@ -698,8 +698,8 @@
     builder.clearField(f("int32_to_int32_field"));
     builder.clearField(f("int32_to_message_field"));
     message = builder.build();
-    assertEquals(0, message.getInt32ToInt32Field().size());
-    assertEquals(0, message.getInt32ToMessageField().size());
+    assertEquals(0, message.getInt32ToInt32FieldMap().size());
+    assertEquals(0, message.getInt32ToMessageFieldMap().size());
 
     // Test setField()
     setMapValues(builder, "int32_to_int32_field", mapForValues(11, 22, 33, 44));
@@ -710,10 +710,10 @@
             111, MessageValue.newBuilder().setValue(222).build(),
             333, MessageValue.newBuilder().setValue(444).build()));
     message = builder.build();
-    assertEquals(22, message.getInt32ToInt32Field().get(11).intValue());
-    assertEquals(44, message.getInt32ToInt32Field().get(33).intValue());
-    assertEquals(222, message.getInt32ToMessageField().get(111).getValue());
-    assertEquals(444, message.getInt32ToMessageField().get(333).getValue());
+    assertEquals(22, message.getInt32ToInt32FieldMap().get(11).intValue());
+    assertEquals(44, message.getInt32ToInt32FieldMap().get(33).intValue());
+    assertEquals(222, message.getInt32ToMessageFieldMap().get(111).getValue());
+    assertEquals(444, message.getInt32ToMessageFieldMap().get(333).getValue());
 
     // Test addRepeatedField
     builder.addRepeatedField(
@@ -726,8 +726,8 @@
             555,
             MessageValue.newBuilder().setValue(666).build()));
     message = builder.build();
-    assertEquals(66, message.getInt32ToInt32Field().get(55).intValue());
-    assertEquals(666, message.getInt32ToMessageField().get(555).getValue());
+    assertEquals(66, message.getInt32ToInt32FieldMap().get(55).intValue());
+    assertEquals(666, message.getInt32ToMessageFieldMap().get(555).getValue());
 
     // Test addRepeatedField (overriding existing values)
     builder.addRepeatedField(
@@ -740,8 +740,8 @@
             555,
             MessageValue.newBuilder().setValue(555).build()));
     message = builder.build();
-    assertEquals(55, message.getInt32ToInt32Field().get(55).intValue());
-    assertEquals(555, message.getInt32ToMessageField().get(555).getValue());
+    assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue());
+    assertEquals(555, message.getInt32ToMessageFieldMap().get(555).getValue());
 
     // Test setRepeatedField
     for (int i = 0; i < builder.getRepeatedFieldCount(f("int32_to_int32_field")); i++) {
@@ -755,9 +755,9 @@
       builder.setRepeatedField(f("int32_to_int32_field"), i, mapEntryBuilder.build());
     }
     message = builder.build();
-    assertEquals(11, message.getInt32ToInt32Field().get(22).intValue());
-    assertEquals(33, message.getInt32ToInt32Field().get(44).intValue());
-    assertEquals(55, message.getInt32ToInt32Field().get(55).intValue());
+    assertEquals(11, message.getInt32ToInt32FieldMap().get(22).intValue());
+    assertEquals(33, message.getInt32ToInt32FieldMap().get(44).intValue());
+    assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue());
   }
 
   // See additional coverage in TextFormatTest.java.
@@ -844,16 +844,16 @@
     TestMap message = TestMap.parseFrom(data);
     // Entries with unknown enum values will be stored into UnknownFieldSet so
     // there is only one entry in the map.
-    assertEquals(1, message.getInt32ToEnumField().size());
-    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
+    assertEquals(1, message.getInt32ToEnumFieldMap().size());
+    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
     // UnknownFieldSet should not be empty.
     assertFalse(message.getUnknownFields().asMap().isEmpty());
     // Serializing and parsing should preserve the unknown entry.
     data = message.toByteString();
     TestUnknownEnumValue messageWithUnknownEnums = TestUnknownEnumValue.parseFrom(data);
-    assertEquals(2, messageWithUnknownEnums.getInt32ToInt32Field().size());
-    assertEquals(1, messageWithUnknownEnums.getInt32ToInt32Field().get(1).intValue());
-    assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue());
+    assertEquals(2, messageWithUnknownEnums.getInt32ToInt32FieldMap().size());
+    assertEquals(1, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(1).intValue());
+    assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(2).intValue());
   }
 
   public void testRequiredMessage() throws Exception {
@@ -885,7 +885,7 @@
 
     assertEquals(
         Arrays.asList("1", "2", "3"),
-        new ArrayList<String>(message.getStringToInt32Field().keySet()));
+        new ArrayList<String>(message.getStringToInt32FieldMap().keySet()));
   }
 
   public void testContains() {
@@ -1172,9 +1172,9 @@
     setMapValuesUsingAccessors(builder);
     assertMapValuesSet(builder);
     TestMap message = builder.build();
-    assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap());
-    assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap());
-    assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap());
-    assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap());
+    assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap());
+    assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap());
+    assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap());
+    assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap());
   }
 }
diff --git a/java/core/src/test/java/com/google/protobuf/MapLiteTest.java b/java/core/src/test/java/com/google/protobuf/MapLiteTest.java
index d18fd13..40bb789 100644
--- a/java/core/src/test/java/com/google/protobuf/MapLiteTest.java
+++ b/java/core/src/test/java/com/google/protobuf/MapLiteTest.java
@@ -84,44 +84,44 @@
 
   private void copyMapValues(TestMap source, TestMap.Builder destination) {
     destination
-        .putAllInt32ToInt32Field(source.getInt32ToInt32Field())
-        .putAllInt32ToStringField(source.getInt32ToStringField())
-        .putAllInt32ToBytesField(source.getInt32ToBytesField())
-        .putAllInt32ToEnumField(source.getInt32ToEnumField())
-        .putAllInt32ToMessageField(source.getInt32ToMessageField())
-        .putAllStringToInt32Field(source.getStringToInt32Field());
+        .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap())
+        .putAllInt32ToStringField(source.getInt32ToStringFieldMap())
+        .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap())
+        .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap())
+        .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap())
+        .putAllStringToInt32Field(source.getStringToInt32FieldMap());
   }
 
   private void assertMapValuesSet(TestMap message) {
-    assertEquals(3, message.getInt32ToInt32Field().size());
-    assertEquals(11, message.getInt32ToInt32Field().get(1).intValue());
-    assertEquals(22, message.getInt32ToInt32Field().get(2).intValue());
-    assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
+    assertEquals(3, message.getInt32ToInt32FieldMap().size());
+    assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue());
+    assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue());
+    assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue());
 
-    assertEquals(3, message.getInt32ToStringField().size());
-    assertEquals("11", message.getInt32ToStringField().get(1));
-    assertEquals("22", message.getInt32ToStringField().get(2));
-    assertEquals("33", message.getInt32ToStringField().get(3));
+    assertEquals(3, message.getInt32ToStringFieldMap().size());
+    assertEquals("11", message.getInt32ToStringFieldMap().get(1));
+    assertEquals("22", message.getInt32ToStringFieldMap().get(2));
+    assertEquals("33", message.getInt32ToStringFieldMap().get(3));
 
-    assertEquals(3, message.getInt32ToBytesField().size());
-    assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1));
-    assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2));
-    assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
+    assertEquals(3, message.getInt32ToBytesFieldMap().size());
+    assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1));
+    assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2));
+    assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3));
 
-    assertEquals(3, message.getInt32ToEnumField().size());
-    assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1));
-    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2));
-    assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
+    assertEquals(3, message.getInt32ToEnumFieldMap().size());
+    assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1));
+    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2));
+    assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3));
 
-    assertEquals(3, message.getInt32ToMessageField().size());
-    assertEquals(11, message.getInt32ToMessageField().get(1).getValue());
-    assertEquals(22, message.getInt32ToMessageField().get(2).getValue());
-    assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
+    assertEquals(3, message.getInt32ToMessageFieldMap().size());
+    assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue());
+    assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue());
+    assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue());
 
-    assertEquals(3, message.getStringToInt32Field().size());
-    assertEquals(11, message.getStringToInt32Field().get("1").intValue());
-    assertEquals(22, message.getStringToInt32Field().get("2").intValue());
-    assertEquals(33, message.getStringToInt32Field().get("3").intValue());
+    assertEquals(3, message.getStringToInt32FieldMap().size());
+    assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue());
+    assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue());
+    assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue());
   }
 
   private void updateMapValues(TestMap.Builder builder) {
@@ -159,35 +159,35 @@
   }
 
   private void assertMapValuesUpdated(TestMap message) {
-    assertEquals(3, message.getInt32ToInt32Field().size());
-    assertEquals(111, message.getInt32ToInt32Field().get(1).intValue());
-    assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
-    assertEquals(44, message.getInt32ToInt32Field().get(4).intValue());
+    assertEquals(3, message.getInt32ToInt32FieldMap().size());
+    assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue());
+    assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue());
+    assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue());
 
-    assertEquals(3, message.getInt32ToStringField().size());
-    assertEquals("111", message.getInt32ToStringField().get(1));
-    assertEquals("33", message.getInt32ToStringField().get(3));
-    assertEquals("44", message.getInt32ToStringField().get(4));
+    assertEquals(3, message.getInt32ToStringFieldMap().size());
+    assertEquals("111", message.getInt32ToStringFieldMap().get(1));
+    assertEquals("33", message.getInt32ToStringFieldMap().get(3));
+    assertEquals("44", message.getInt32ToStringFieldMap().get(4));
 
-    assertEquals(3, message.getInt32ToBytesField().size());
-    assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1));
-    assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
-    assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4));
+    assertEquals(3, message.getInt32ToBytesFieldMap().size());
+    assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1));
+    assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3));
+    assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4));
 
-    assertEquals(3, message.getInt32ToEnumField().size());
-    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
-    assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
-    assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4));
+    assertEquals(3, message.getInt32ToEnumFieldMap().size());
+    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
+    assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3));
+    assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4));
 
-    assertEquals(3, message.getInt32ToMessageField().size());
-    assertEquals(111, message.getInt32ToMessageField().get(1).getValue());
-    assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
-    assertEquals(44, message.getInt32ToMessageField().get(4).getValue());
+    assertEquals(3, message.getInt32ToMessageFieldMap().size());
+    assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue());
+    assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue());
+    assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue());
 
-    assertEquals(3, message.getStringToInt32Field().size());
-    assertEquals(111, message.getStringToInt32Field().get("1").intValue());
-    assertEquals(33, message.getStringToInt32Field().get("3").intValue());
-    assertEquals(44, message.getStringToInt32Field().get("4").intValue());
+    assertEquals(3, message.getStringToInt32FieldMap().size());
+    assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue());
+    assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue());
+    assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue());
   }
 
   private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) {
@@ -213,12 +213,12 @@
     TestMap.Builder builder = TestMap.newBuilder();
     TestMap message = builder.build();
     builder.putInt32ToInt32Field(1, 2);
-    assertTrue(message.getInt32ToInt32Field().isEmpty());
-    assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
+    assertTrue(message.getInt32ToInt32FieldMap().isEmpty());
+    assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap());
     message = builder.build();
     builder.putInt32ToInt32Field(2, 3);
-    assertEquals(newMap(1, 2), message.getInt32ToInt32Field());
-    assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field());
+    assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap());
+    assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap());
   }
 
   public void testGetMapIsImmutable() {
@@ -266,30 +266,31 @@
 
   public void testMutableMapLifecycle() {
     TestMap.Builder builder = TestMap.newBuilder().putInt32ToInt32Field(1, 2);
-    assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field());
-    assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
+    assertEquals(newMap(1, 2), builder.build().getInt32ToInt32FieldMap());
+    assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap());
     builder.putInt32ToInt32Field(2, 3);
-    assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field());
+    assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap());
 
     builder.putInt32ToEnumField(1, TestMap.EnumValue.BAR);
-    assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField());
-    assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField());
+    assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumFieldMap());
+    assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumFieldMap());
     builder.putInt32ToEnumField(2, TestMap.EnumValue.FOO);
     assertEquals(
-        newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), builder.getInt32ToEnumField());
+        newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO),
+        builder.getInt32ToEnumFieldMap());
 
     builder.putInt32ToStringField(1, "1");
-    assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField());
-    assertEquals(newMap(1, "1"), builder.getInt32ToStringField());
+    assertEquals(newMap(1, "1"), builder.build().getInt32ToStringFieldMap());
+    assertEquals(newMap(1, "1"), builder.getInt32ToStringFieldMap());
     builder.putInt32ToStringField(2, "2");
-    assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringField());
+    assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringFieldMap());
 
     builder.putInt32ToMessageField(1, TestMap.MessageValue.getDefaultInstance());
     assertEquals(
         newMap(1, TestMap.MessageValue.getDefaultInstance()),
-        builder.build().getInt32ToMessageField());
+        builder.build().getInt32ToMessageFieldMap());
     assertEquals(
-        newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageField());
+        newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageFieldMap());
     builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance());
     assertEquals(
         newMap(
@@ -297,7 +298,7 @@
             TestMap.MessageValue.getDefaultInstance(),
             2,
             TestMap.MessageValue.getDefaultInstance()),
-        builder.getInt32ToMessageField());
+        builder.getInt32ToMessageFieldMap());
   }
 
   public void testGettersAndSetters() throws Exception {
@@ -342,12 +343,12 @@
     TestMap source = sourceBuilder.build();
 
     TestMap.Builder destinationBuilder = TestMap.newBuilder();
-    destinationBuilder.putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValue());
+    destinationBuilder.putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValueMap());
     TestMap destination = destinationBuilder.build();
 
-    assertEquals(0, destination.getInt32ToEnumFieldValue().get(0).intValue());
-    assertEquals(1, destination.getInt32ToEnumFieldValue().get(1).intValue());
-    assertEquals(1000, destination.getInt32ToEnumFieldValue().get(2).intValue());
+    assertEquals(0, destination.getInt32ToEnumFieldValueMap().get(0).intValue());
+    assertEquals(1, destination.getInt32ToEnumFieldValueMap().get(1).intValue());
+    assertEquals(1000, destination.getInt32ToEnumFieldValueMap().get(2).intValue());
     assertEquals(3, destination.getInt32ToEnumFieldCount());
   }
 
@@ -459,7 +460,7 @@
     } catch (InvalidProtocolBufferException expected) {
       assertTrue(expected.getUnfinishedMessage() instanceof TestMap);
       map = (TestMap) expected.getUnfinishedMessage();
-      assertTrue(map.getInt32ToMessageField().isEmpty());
+      assertTrue(map.getInt32ToMessageFieldMap().isEmpty());
     }
 
     map =
@@ -524,24 +525,24 @@
             .putInt32ToEnumFieldValue(2, 1000); // unknown value.
     TestMap message = builder.build();
 
-    assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(0));
-    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
-    assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2));
+    assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(0));
+    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
+    assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2));
 
     builder.putAllInt32ToEnumFieldValue(newMap(2, 1000)); // unknown value.
     message = builder.build();
-    assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2));
+    assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2));
 
     // Unknown enum values should be preserved after:
     //   1. Serialization and parsing.
     //   2. toBuild().
     //   3. mergeFrom().
     message = TestMap.parseFrom(message.toByteString());
-    assertEquals(1000, message.getInt32ToEnumFieldValue().get(2).intValue());
+    assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue());
     builder = message.toBuilder();
-    assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue());
+    assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue());
     builder = TestMap.newBuilder().mergeFrom(message);
-    assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue());
+    assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue());
 
     // hashCode()/equals() should take unknown enum values into account.
     builder.putAllInt32ToEnumFieldValue(newMap(2, 1001));
@@ -550,7 +551,7 @@
     assertFalse(message.equals(message2));
     // Unknown values will be converted to UNRECOGNIZED so the resulted enum map
     // should be the same.
-    assertEquals(message2.getInt32ToEnumField(), message.getInt32ToEnumField());
+    assertEquals(message2.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap());
   }
 
   public void testIterationOrder() throws Exception {
@@ -559,18 +560,18 @@
     TestMap message = builder.build();
 
     assertEquals(
-        Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32Field().keySet()));
+        Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32FieldMap().keySet()));
   }
 
   public void testGetMap() {
     TestMap.Builder builder = TestMap.newBuilder();
     setMapValues(builder);
     TestMap message = builder.build();
-    assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap());
-    assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap());
-    assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap());
-    assertEquals(message.getInt32ToEnumFieldValue(), message.getInt32ToEnumFieldValueMap());
-    assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap());
+    assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap());
+    assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap());
+    assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap());
+    assertEquals(message.getInt32ToEnumFieldValueMap(), message.getInt32ToEnumFieldValueMap());
+    assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap());
   }
 
   public void testContains() {
diff --git a/java/core/src/test/java/com/google/protobuf/MapTest.java b/java/core/src/test/java/com/google/protobuf/MapTest.java
index 9f1ebae..f3458dd 100644
--- a/java/core/src/test/java/com/google/protobuf/MapTest.java
+++ b/java/core/src/test/java/com/google/protobuf/MapTest.java
@@ -122,44 +122,44 @@
 
   private void copyMapValues(TestMap source, TestMap.Builder destination) {
     destination
-        .putAllInt32ToInt32Field(source.getInt32ToInt32Field())
-        .putAllInt32ToStringField(source.getInt32ToStringField())
-        .putAllInt32ToBytesField(source.getInt32ToBytesField())
-        .putAllInt32ToEnumField(source.getInt32ToEnumField())
-        .putAllInt32ToMessageField(source.getInt32ToMessageField())
-        .putAllStringToInt32Field(source.getStringToInt32Field());
+        .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap())
+        .putAllInt32ToStringField(source.getInt32ToStringFieldMap())
+        .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap())
+        .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap())
+        .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap())
+        .putAllStringToInt32Field(source.getStringToInt32FieldMap());
   }
 
   private void assertMapValuesSet(TestMap message) {
-    assertEquals(3, message.getInt32ToInt32Field().size());
-    assertEquals(11, message.getInt32ToInt32Field().get(1).intValue());
-    assertEquals(22, message.getInt32ToInt32Field().get(2).intValue());
-    assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
+    assertEquals(3, message.getInt32ToInt32FieldMap().size());
+    assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue());
+    assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue());
+    assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue());
 
-    assertEquals(3, message.getInt32ToStringField().size());
-    assertEquals("11", message.getInt32ToStringField().get(1));
-    assertEquals("22", message.getInt32ToStringField().get(2));
-    assertEquals("33", message.getInt32ToStringField().get(3));
+    assertEquals(3, message.getInt32ToStringFieldMap().size());
+    assertEquals("11", message.getInt32ToStringFieldMap().get(1));
+    assertEquals("22", message.getInt32ToStringFieldMap().get(2));
+    assertEquals("33", message.getInt32ToStringFieldMap().get(3));
 
-    assertEquals(3, message.getInt32ToBytesField().size());
-    assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1));
-    assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2));
-    assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
+    assertEquals(3, message.getInt32ToBytesFieldMap().size());
+    assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1));
+    assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2));
+    assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3));
 
-    assertEquals(3, message.getInt32ToEnumField().size());
-    assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1));
-    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2));
-    assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
+    assertEquals(3, message.getInt32ToEnumFieldMap().size());
+    assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1));
+    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2));
+    assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3));
 
-    assertEquals(3, message.getInt32ToMessageField().size());
-    assertEquals(11, message.getInt32ToMessageField().get(1).getValue());
-    assertEquals(22, message.getInt32ToMessageField().get(2).getValue());
-    assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
+    assertEquals(3, message.getInt32ToMessageFieldMap().size());
+    assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue());
+    assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue());
+    assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue());
 
-    assertEquals(3, message.getStringToInt32Field().size());
-    assertEquals(11, message.getStringToInt32Field().get("1").intValue());
-    assertEquals(22, message.getStringToInt32Field().get("2").intValue());
-    assertEquals(33, message.getStringToInt32Field().get("3").intValue());
+    assertEquals(3, message.getStringToInt32FieldMap().size());
+    assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue());
+    assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue());
+    assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue());
   }
 
   private void updateMapValuesUsingMutableMap(TestMap.Builder builder) {
@@ -239,35 +239,35 @@
   }
 
   private void assertMapValuesUpdated(TestMap message) {
-    assertEquals(3, message.getInt32ToInt32Field().size());
-    assertEquals(111, message.getInt32ToInt32Field().get(1).intValue());
-    assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
-    assertEquals(44, message.getInt32ToInt32Field().get(4).intValue());
+    assertEquals(3, message.getInt32ToInt32FieldMap().size());
+    assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue());
+    assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue());
+    assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue());
 
-    assertEquals(3, message.getInt32ToStringField().size());
-    assertEquals("111", message.getInt32ToStringField().get(1));
-    assertEquals("33", message.getInt32ToStringField().get(3));
-    assertEquals("44", message.getInt32ToStringField().get(4));
+    assertEquals(3, message.getInt32ToStringFieldMap().size());
+    assertEquals("111", message.getInt32ToStringFieldMap().get(1));
+    assertEquals("33", message.getInt32ToStringFieldMap().get(3));
+    assertEquals("44", message.getInt32ToStringFieldMap().get(4));
 
-    assertEquals(3, message.getInt32ToBytesField().size());
-    assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1));
-    assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
-    assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4));
+    assertEquals(3, message.getInt32ToBytesFieldMap().size());
+    assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1));
+    assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3));
+    assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4));
 
-    assertEquals(3, message.getInt32ToEnumField().size());
-    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
-    assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
-    assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4));
+    assertEquals(3, message.getInt32ToEnumFieldMap().size());
+    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
+    assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3));
+    assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4));
 
-    assertEquals(3, message.getInt32ToMessageField().size());
-    assertEquals(111, message.getInt32ToMessageField().get(1).getValue());
-    assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
-    assertEquals(44, message.getInt32ToMessageField().get(4).getValue());
+    assertEquals(3, message.getInt32ToMessageFieldMap().size());
+    assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue());
+    assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue());
+    assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue());
 
-    assertEquals(3, message.getStringToInt32Field().size());
-    assertEquals(111, message.getStringToInt32Field().get("1").intValue());
-    assertEquals(33, message.getStringToInt32Field().get("3").intValue());
-    assertEquals(44, message.getStringToInt32Field().get("4").intValue());
+    assertEquals(3, message.getStringToInt32FieldMap().size());
+    assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue());
+    assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue());
+    assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue());
   }
 
   private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) {
@@ -468,11 +468,13 @@
             .build();
 
     TestMap destination =
-        TestMap.newBuilder().putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValue()).build();
+        TestMap.newBuilder()
+            .putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValueMap())
+            .build();
 
-    assertEquals(0, destination.getInt32ToEnumFieldValue().get(0).intValue());
-    assertEquals(1, destination.getInt32ToEnumFieldValue().get(1).intValue());
-    assertEquals(1000, destination.getInt32ToEnumFieldValue().get(2).intValue());
+    assertEquals(0, destination.getInt32ToEnumFieldValueMap().get(0).intValue());
+    assertEquals(1, destination.getInt32ToEnumFieldValueMap().get(1).intValue());
+    assertEquals(1000, destination.getInt32ToEnumFieldValueMap().get(2).intValue());
     assertEquals(3, destination.getInt32ToEnumFieldCount());
   }
 
@@ -583,7 +585,7 @@
     } catch (InvalidProtocolBufferException expected) {
       assertTrue(expected.getUnfinishedMessage() instanceof TestMap);
       map = (TestMap) expected.getUnfinishedMessage();
-      assertTrue(map.getInt32ToMessageField().isEmpty());
+      assertTrue(map.getInt32ToMessageFieldMap().isEmpty());
     }
 
     map =
@@ -644,14 +646,14 @@
     TestOnChangeEventPropagation.Builder parent = TestOnChangeEventPropagation.newBuilder();
     parent.getOptionalMessageBuilder().putInt32ToInt32Field(1, 2);
     TestOnChangeEventPropagation message = parent.build();
-    assertEquals(2, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue());
+    assertEquals(2, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue());
 
     // Make a change using nested builder.
     parent.getOptionalMessageBuilder().putInt32ToInt32Field(1, 3);
 
     // Should be able to observe the change.
     message = parent.build();
-    assertEquals(3, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue());
+    assertEquals(3, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue());
 
     // Make another change using mergeFrom()
     TestMap other = TestMap.newBuilder().putInt32ToInt32Field(1, 4).build();
@@ -659,14 +661,14 @@
 
     // Should be able to observe the change.
     message = parent.build();
-    assertEquals(4, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue());
+    assertEquals(4, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue());
 
     // Make yet another change by clearing the nested builder.
     parent.getOptionalMessageBuilder().clear();
 
     // Should be able to observe the change.
     message = parent.build();
-    assertEquals(0, message.getOptionalMessage().getInt32ToInt32Field().size());
+    assertEquals(0, message.getOptionalMessage().getInt32ToInt32FieldMap().size());
   }
 
   public void testNestedBuilderOnChangeEventPropagationReflection() {
@@ -683,7 +685,7 @@
 
     // Should be able to observe the change.
     TestOnChangeEventPropagation message = parentBuilder.build();
-    assertEquals(1, message.getOptionalMessage().getInt32ToInt32Field().size());
+    assertEquals(1, message.getOptionalMessage().getInt32ToInt32FieldMap().size());
 
     // Change the entry value.
     entryBuilder.putInt32ToInt32Field(1, 4);
@@ -692,7 +694,7 @@
 
     // Should be able to observe the change.
     message = parentBuilder.build();
-    assertEquals(4, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue());
+    assertEquals(4, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue());
 
     // Clear the nested builder.
     testMapBuilder = parentBuilder.getOptionalMessageBuilder();
@@ -700,7 +702,7 @@
 
     // Should be able to observe the change.
     message = parentBuilder.build();
-    assertEquals(0, message.getOptionalMessage().getInt32ToInt32Field().size());
+    assertEquals(0, message.getOptionalMessage().getInt32ToInt32FieldMap().size());
   }
 
   // The following methods are used to test reflection API.
@@ -789,8 +791,8 @@
     builder.clearField(f("int32_to_int32_field"));
     builder.clearField(f("int32_to_message_field"));
     message = builder.build();
-    assertEquals(0, message.getInt32ToInt32Field().size());
-    assertEquals(0, message.getInt32ToMessageField().size());
+    assertEquals(0, message.getInt32ToInt32FieldMap().size());
+    assertEquals(0, message.getInt32ToMessageFieldMap().size());
 
     // Test setField()
     setMapValues(builder, "int32_to_int32_field", mapForValues(11, 22, 33, 44));
@@ -801,10 +803,10 @@
             111, MessageValue.newBuilder().setValue(222).build(),
             333, MessageValue.newBuilder().setValue(444).build()));
     message = builder.build();
-    assertEquals(22, message.getInt32ToInt32Field().get(11).intValue());
-    assertEquals(44, message.getInt32ToInt32Field().get(33).intValue());
-    assertEquals(222, message.getInt32ToMessageField().get(111).getValue());
-    assertEquals(444, message.getInt32ToMessageField().get(333).getValue());
+    assertEquals(22, message.getInt32ToInt32FieldMap().get(11).intValue());
+    assertEquals(44, message.getInt32ToInt32FieldMap().get(33).intValue());
+    assertEquals(222, message.getInt32ToMessageFieldMap().get(111).getValue());
+    assertEquals(444, message.getInt32ToMessageFieldMap().get(333).getValue());
 
     // Test addRepeatedField
     builder.addRepeatedField(
@@ -817,8 +819,8 @@
             555,
             MessageValue.newBuilder().setValue(666).build()));
     message = builder.build();
-    assertEquals(66, message.getInt32ToInt32Field().get(55).intValue());
-    assertEquals(666, message.getInt32ToMessageField().get(555).getValue());
+    assertEquals(66, message.getInt32ToInt32FieldMap().get(55).intValue());
+    assertEquals(666, message.getInt32ToMessageFieldMap().get(555).getValue());
 
     // Test addRepeatedField (overriding existing values)
     builder.addRepeatedField(
@@ -831,8 +833,8 @@
             555,
             MessageValue.newBuilder().setValue(555).build()));
     message = builder.build();
-    assertEquals(55, message.getInt32ToInt32Field().get(55).intValue());
-    assertEquals(555, message.getInt32ToMessageField().get(555).getValue());
+    assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue());
+    assertEquals(555, message.getInt32ToMessageFieldMap().get(555).getValue());
 
     // Test setRepeatedField
     for (int i = 0; i < builder.getRepeatedFieldCount(f("int32_to_int32_field")); i++) {
@@ -846,9 +848,9 @@
       builder.setRepeatedField(f("int32_to_int32_field"), i, mapEntryBuilder.build());
     }
     message = builder.build();
-    assertEquals(11, message.getInt32ToInt32Field().get(22).intValue());
-    assertEquals(33, message.getInt32ToInt32Field().get(44).intValue());
-    assertEquals(55, message.getInt32ToInt32Field().get(55).intValue());
+    assertEquals(11, message.getInt32ToInt32FieldMap().get(22).intValue());
+    assertEquals(33, message.getInt32ToInt32FieldMap().get(44).intValue());
+    assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue());
   }
 
   // See additional coverage in TextFormatTest.java.
@@ -937,21 +939,21 @@
                     2, 1000)); // unknown value.
     TestMap message = builder.build();
 
-    assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(0));
-    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
-    assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2));
-    assertEquals(1000, message.getInt32ToEnumFieldValue().get(2).intValue());
+    assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(0));
+    assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
+    assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2));
+    assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue());
 
     // Unknown enum values should be preserved after:
     //   1. Serialization and parsing.
     //   2. toBuild().
     //   3. mergeFrom().
     message = TestMap.parseFrom(message.toByteString());
-    assertEquals(1000, message.getInt32ToEnumFieldValue().get(2).intValue());
+    assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue());
     builder = message.toBuilder();
-    assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue());
+    assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue());
     builder = TestMap.newBuilder().mergeFrom(message);
-    assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue());
+    assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue());
 
     // hashCode()/equals() should take unknown enum values into account.
     builder.putAllInt32ToEnumFieldValue(newMap(2, 1001));
@@ -960,7 +962,7 @@
     assertFalse(message.equals(message2));
     // Unknown values will be converted to UNRECOGNIZED so the resulted enum map
     // should be the same.
-    assertEquals(message2.getInt32ToEnumField(), message.getInt32ToEnumField());
+    assertEquals(message2.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap());
   }
 
   public void testUnknownEnumValuesInReflectionApi() throws Exception {
@@ -991,7 +993,7 @@
 
     // Verify that enum values have been successfully updated.
     TestMap message = builder.build();
-    for (Map.Entry<Integer, Integer> entry : message.getInt32ToEnumFieldValue().entrySet()) {
+    for (Map.Entry<Integer, Integer> entry : message.getInt32ToEnumFieldValueMap().entrySet()) {
       assertEquals(data.get(entry.getKey()) + 1, entry.getValue().intValue());
     }
   }
@@ -1002,18 +1004,18 @@
     TestMap message = builder.build();
 
     assertEquals(
-        Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32Field().keySet()));
+        Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32FieldMap().keySet()));
   }
 
   public void testGetMap() {
     TestMap.Builder builder = TestMap.newBuilder();
     setMapValuesUsingAccessors(builder);
     TestMap message = builder.build();
-    assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap());
-    assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap());
-    assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap());
-    assertEquals(message.getInt32ToEnumFieldValue(), message.getInt32ToEnumFieldValueMap());
-    assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap());
+    assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap());
+    assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap());
+    assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap());
+    assertEquals(message.getInt32ToEnumFieldValueMap(), message.getInt32ToEnumFieldValueMap());
+    assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap());
   }
 
   public void testContains() {
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 e229fac..915dddf 100644
--- a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
+++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
@@ -30,6 +30,7 @@
 
 package com.google.protobuf;
 
+import static com.google.common.truth.Truth.assertThat;
 import static com.google.protobuf.TestUtil.TEST_REQUIRED_INITIALIZED;
 import static com.google.protobuf.TestUtil.TEST_REQUIRED_UNINITIALIZED;
 
@@ -866,6 +867,12 @@
     assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\341\\210\\264"));
     assertEquals("\u1234", TextFormat.unescapeText("\\xe1\\x88\\xb4"));
     assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\xe1\\x88\\xb4"));
+    assertEquals("\u1234", TextFormat.unescapeText("\\u1234"));
+    assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\u1234"));
+    assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\U00001234"));
+    assertEquals(
+        new String(new int[] {0x10437}, 0, 1), TextFormat.unescapeText("\\xf0\\x90\\x90\\xb7"));
+    assertEquals(bytes(0xf0, 0x90, 0x90, 0xb7), TextFormat.unescapeBytes("\\U00010437"));
 
     // Handling of strings with unescaped Unicode characters > 255.
     final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c";
@@ -893,6 +900,87 @@
     } catch (TextFormat.InvalidEscapeSequenceException e) {
       // success
     }
+
+    try {
+      TextFormat.unescapeText("\\u");
+      fail("Should have thrown an exception.");
+    } catch (TextFormat.InvalidEscapeSequenceException e) {
+      assertThat(e)
+          .hasMessageThat()
+          .isEqualTo("Invalid escape sequence: '\\u' with too few hex chars");
+    }
+
+    try {
+      TextFormat.unescapeText("\\ud800");
+      fail("Should have thrown an exception.");
+    } catch (TextFormat.InvalidEscapeSequenceException e) {
+      assertThat(e)
+          .hasMessageThat()
+          .isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate");
+    }
+
+    try {
+      TextFormat.unescapeText("\\ud800\\u1234");
+      fail("Should have thrown an exception.");
+    } catch (TextFormat.InvalidEscapeSequenceException e) {
+      assertThat(e)
+          .hasMessageThat()
+          .isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate");
+    }
+
+    try {
+      TextFormat.unescapeText("\\udc00");
+      fail("Should have thrown an exception.");
+    } catch (TextFormat.InvalidEscapeSequenceException e) {
+      assertThat(e)
+          .hasMessageThat()
+          .isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate");
+    }
+
+    try {
+      TextFormat.unescapeText("\\ud801\\udc37");
+      fail("Should have thrown an exception.");
+    } catch (TextFormat.InvalidEscapeSequenceException e) {
+      assertThat(e)
+          .hasMessageThat()
+          .isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate");
+    }
+
+    try {
+      TextFormat.unescapeText("\\U1234");
+      fail("Should have thrown an exception.");
+    } catch (TextFormat.InvalidEscapeSequenceException e) {
+      assertThat(e)
+          .hasMessageThat()
+          .isEqualTo("Invalid escape sequence: '\\U' with too few hex chars");
+    }
+
+    try {
+      TextFormat.unescapeText("\\U1234no more hex");
+      fail("Should have thrown an exception.");
+    } catch (TextFormat.InvalidEscapeSequenceException e) {
+      assertThat(e)
+          .hasMessageThat()
+          .isEqualTo("Invalid escape sequence: '\\U' with too few hex chars");
+    }
+
+    try {
+      TextFormat.unescapeText("\\U00110000");
+      fail("Should have thrown an exception.");
+    } catch (TextFormat.InvalidEscapeSequenceException e) {
+      assertThat(e)
+          .hasMessageThat()
+          .isEqualTo("Invalid escape sequence: '\\U00110000' is not a valid code point value");
+    }
+
+    try {
+      TextFormat.unescapeText("\\U0000d801\\U00000dc37");
+      fail("Should have thrown an exception.");
+    } catch (TextFormat.InvalidEscapeSequenceException e) {
+      assertThat(e)
+          .hasMessageThat()
+          .isEqualTo("Invalid escape sequence: '\\U0000d801' refers to a surrogate code unit");
+    }
   }
 
   public void testParseInteger() throws Exception {
diff --git a/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java b/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
index 4092b30..352376e 100644
--- a/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
+++ b/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
@@ -137,11 +137,19 @@
   }
 
   /**
-   * Remove {@code path} from the tree.
+   * Removes {@code path} from the tree.
    *
-   * <p>When removing a field path from the tree, all sub-paths will be removed. That is, after
-   * removing "foo.bar" from the tree, "foo.bar.baz" will be removed. Likewise, if the field path to
-   * remove is a non-exist sub-path, nothing will be changed.
+   * <ul>
+   *   When removing a field path from the tree:
+   *   <li>All sub-paths will be removed. That is, after removing "foo.bar" from the tree,
+   *       "foo.bar.baz" will be removed.
+   *   <li>If all children of a node has been removed, the node itself will be removed as well.
+   *       That is, if "foo" only has one child "bar" and "foo.bar" only has one child "baz",
+   *       removing "foo.bar.barz" would remove both "foo" and "foo.bar".
+   *       If "foo" has both "bar" and "qux" as children, removing "foo.bar" would leave the path
+   *       "foo.qux" intact.
+   *   <li>If the field path to remove is a non-exist sub-path, nothing will be changed.
+   * </ul>
    */
   @CanIgnoreReturnValue
   FieldMaskTree removeFieldPath(String path) {
@@ -149,23 +157,35 @@
     if (parts.isEmpty()) {
       return this;
     }
-    Node node = root;
-    for (int i = 0; i < parts.size(); i++) {
-      String key = parts.get(i);
-      if (!node.children.containsKey(key)) {
-        // Path does not exist.
-        return this;
-      }
-      if (i == parts.size() - 1) {
-        // Remove path.
-        node.children.remove(key);
-        return this;
-      }
-      node = node.children.get(key);
-    }
+    removeFieldPath(root, parts, 0);
     return this;
   }
 
+  /**
+   * Removes {@code parts} from {@code node} recursively.
+   *
+   * @return a boolean value indicating whether current {@code node} should be removed.
+   */
+  @CanIgnoreReturnValue
+  private static boolean removeFieldPath(Node node, List<String> parts, int index) {
+    String key = parts.get(index);
+
+    // Base case 1: path not match.
+    if (!node.children.containsKey(key)) {
+      return false;
+    }
+    // Base case 2: last element in parts.
+    if (index == parts.size() - 1) {
+      node.children.remove(key);
+      return node.children.isEmpty();
+    }
+    // Recursive remove sub-path.
+    if (removeFieldPath(node.children.get(key), parts, index + 1)) {
+      node.children.remove(key);
+    }
+    return node.children.isEmpty();
+  }
+
   /** Removes all field paths in {@code mask} from this tree. */
   @CanIgnoreReturnValue
   FieldMaskTree removeFromFieldMask(FieldMask mask) {
@@ -187,10 +207,8 @@
     return FieldMask.newBuilder().addAllPaths(paths).build();
   }
 
-  /**
-   * Gathers all field paths in a sub-tree.
-   */
-  private void getFieldPaths(Node node, String path, List<String> paths) {
+  /** Gathers all field paths in a sub-tree. */
+  private static void getFieldPaths(Node node, String path, List<String> paths) {
     if (node.children.isEmpty()) {
       paths.add(path);
       return;
@@ -247,10 +265,8 @@
     merge(root, "", source, destination, options);
   }
 
-  /**
-   * Merges all fields specified by a sub-tree from {@code source} to {@code destination}.
-   */
-  private void merge(
+  /** Merges all fields specified by a sub-tree from {@code source} to {@code destination}. */
+  private static void merge(
       Node node,
       String path,
       Message source,
diff --git a/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java b/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java
index 0c2f90c..c32d10a 100644
--- a/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java
+++ b/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java
@@ -276,7 +276,13 @@
     return maskTree.toFieldMask();
   }
 
-  /** Subtracts {@code secondMask} and {@code otherMasks} from {@code firstMask}. */
+  /**
+   * Subtracts {@code secondMask} and {@code otherMasks} from {@code firstMask}.
+   *
+   * <p>This method disregards proto structure. That is, if {@code firstMask} is "foo" and {@code
+   * secondMask} is "foo.bar", the response will always be "foo" without considering the internal
+   * proto structure of message "foo".
+   */
   public static FieldMask subtract(
       FieldMask firstMask, FieldMask secondMask, FieldMask... otherMasks) {
     FieldMaskTree maskTree = new FieldMaskTree(firstMask).removeFromFieldMask(secondMask);
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 cc3f5f6..4f2fe3f 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
@@ -525,7 +525,6 @@
       return types.get(name);
     }
 
-    /* @Nullable */
     Descriptor getDescriptorForTypeUrl(String typeUrl) throws InvalidProtocolBufferException {
       return find(getTypeName(typeUrl));
     }
diff --git a/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java b/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java
index 7ec37d0..c829722 100644
--- a/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java
+++ b/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java
@@ -77,25 +77,37 @@
 
   public void testRemoveFieldPath() throws Exception {
     String initialTreeString = "bar.baz,bar.quz.bar,foo";
-    FieldMaskTree tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString));
+    FieldMaskTree tree;
+
     // Empty path.
+    tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString));
     tree.removeFieldPath("");
     assertEquals(initialTreeString, tree.toString());
+
     // Non-exist sub-path of an existing leaf.
+    tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString));
     tree.removeFieldPath("foo.bar");
     assertEquals(initialTreeString, tree.toString());
+
     // Non-exist path.
+    tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString));
     tree.removeFieldPath("bar.foo");
     assertEquals(initialTreeString, tree.toString());
-    // Match an existing leaf node.
+
+    // Match an existing leaf node -> remove leaf node.
+    tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString));
     tree.removeFieldPath("foo");
     assertEquals("bar.baz,bar.quz.bar", tree.toString());
-    // Match sub-path of an existing leaf node.
+
+    // Match sub-path of an existing leaf node -> recursive removal.
+    tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString));
     tree.removeFieldPath("bar.quz.bar");
-    assertEquals("bar.baz,bar.quz", tree.toString());
-    // Match a non-leaf node.
+    assertEquals("bar.baz,foo", tree.toString());
+
+    // Match a non-leaf node -> remove all children.
+    tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString));
     tree.removeFieldPath("bar");
-    assertThat(tree.toString()).isEmpty();
+    assertEquals("foo", tree.toString());
   }
 
   public void testRemoveFromFieldMask() throws Exception {
diff --git a/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java b/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java
index 796020e..28e43a7 100644
--- a/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java
+++ b/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java
@@ -239,7 +239,7 @@
     FieldMask mask3 = FieldMaskUtil.fromString("bar.quz");
     FieldMask mask4 = FieldMaskUtil.fromString("foo,bar.baz");
     FieldMask result = FieldMaskUtil.subtract(mask1, mask2, mask3, mask4);
-    assertEquals("bar", FieldMaskUtil.toString(result));
+    assertThat(FieldMaskUtil.toString(result)).isEmpty();
   }
 
   public void testIntersection() throws Exception {
diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
index f9358e5..46d3cc4 100644
--- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
+++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
@@ -722,8 +722,8 @@
     mergeFromJson(
         "{\n" + "  int32ToInt32Map: {1: 2},\n" + "  stringToInt32Map: {hello: 3}\n" + "}", builder);
     TestMap message = builder.build();
-    assertEquals(2, message.getInt32ToInt32Map().get(1).intValue());
-    assertEquals(3, message.getStringToInt32Map().get("hello").intValue());
+    assertEquals(2, message.getInt32ToInt32MapMap().get(1).intValue());
+    assertEquals(3, message.getStringToInt32MapMap().get("hello").intValue());
   }
 
   public void testWrappers() throws Exception {
diff --git a/kokoro/linux/dockerfile/test/python27/Dockerfile b/kokoro/linux/dockerfile/test/python27/Dockerfile
index e41e49a..6b0eaf7 100644
--- a/kokoro/linux/dockerfile/test/python27/Dockerfile
+++ b/kokoro/linux/dockerfile/test/python27/Dockerfile
@@ -20,4 +20,12 @@
   parallel \
   time \
   wget \
-  && apt-get clean
+  && apt-get clean \
+  && rm -rf /var/lib/apt/lists/*
+
+# Install Python libraries.
+RUN python -m pip install --no-cache-dir --upgrade \
+  pip \
+  setuptools \
+  tox \
+  wheel
diff --git a/kokoro/linux/dockerfile/test/python35/Dockerfile b/kokoro/linux/dockerfile/test/python35/Dockerfile
index 3ea4c9e..50ee184 100644
--- a/kokoro/linux/dockerfile/test/python35/Dockerfile
+++ b/kokoro/linux/dockerfile/test/python35/Dockerfile
@@ -20,4 +20,12 @@
   parallel \
   time \
   wget \
-  && apt-get clean
+  && apt-get clean \
+  && rm -rf /var/lib/apt/lists/*
+
+# Install Python libraries.
+RUN python -m pip install --no-cache-dir --upgrade \
+  pip \
+  setuptools \
+  tox \
+  wheel
diff --git a/kokoro/linux/dockerfile/test/python36/Dockerfile b/kokoro/linux/dockerfile/test/python36/Dockerfile
index 4368460..742503e 100644
--- a/kokoro/linux/dockerfile/test/python36/Dockerfile
+++ b/kokoro/linux/dockerfile/test/python36/Dockerfile
@@ -20,4 +20,12 @@
   parallel \
   time \
   wget \
-  && apt-get clean
+  && apt-get clean \
+  && rm -rf /var/lib/apt/lists/*
+
+# Install Python libraries.
+RUN python -m pip install --no-cache-dir --upgrade \
+  pip \
+  setuptools \
+  tox \
+  wheel
diff --git a/kokoro/linux/dockerfile/test/python37/Dockerfile b/kokoro/linux/dockerfile/test/python37/Dockerfile
index c711eb8..ee108dd 100644
--- a/kokoro/linux/dockerfile/test/python37/Dockerfile
+++ b/kokoro/linux/dockerfile/test/python37/Dockerfile
@@ -20,4 +20,12 @@
   parallel \
   time \
   wget \
-  && apt-get clean
+  && apt-get clean \
+  && rm -rf /var/lib/apt/lists/*
+
+# Install Python libraries.
+RUN python -m pip install --no-cache-dir --upgrade \
+  pip \
+  setuptools \
+  tox \
+  wheel
diff --git a/kokoro/linux/dockerfile/test/python38/Dockerfile b/kokoro/linux/dockerfile/test/python38/Dockerfile
index 48a7be5..56efc9d 100644
--- a/kokoro/linux/dockerfile/test/python38/Dockerfile
+++ b/kokoro/linux/dockerfile/test/python38/Dockerfile
@@ -20,4 +20,12 @@
   parallel \
   time \
   wget \
-  && apt-get clean
+  && apt-get clean \
+  && rm -rf /var/lib/apt/lists/*
+
+# Install Python libraries.
+RUN python -m pip install --no-cache-dir --upgrade \
+  pip \
+  setuptools \
+  tox \
+  wheel
diff --git a/kokoro/linux/python27/continuous.cfg b/kokoro/linux/python27/continuous.cfg
index e2fc413..dd98469 100644
--- a/kokoro/linux/python27/continuous.cfg
+++ b/kokoro/linux/python27/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python/build.sh"
+build_file: "protobuf/kokoro/linux/python27/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python27/presubmit.cfg b/kokoro/linux/python27/presubmit.cfg
index e2fc413..dd98469 100644
--- a/kokoro/linux/python27/presubmit.cfg
+++ b/kokoro/linux/python27/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python/build.sh"
+build_file: "protobuf/kokoro/linux/python27/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python27_cpp/continuous.cfg b/kokoro/linux/python27_cpp/continuous.cfg
index b1b0e55..ace22d0 100644
--- a/kokoro/linux/python27_cpp/continuous.cfg
+++ b/kokoro/linux/python27_cpp/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
+build_file: "protobuf/kokoro/linux/python27_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python27_cpp/presubmit.cfg b/kokoro/linux/python27_cpp/presubmit.cfg
index b1b0e55..ace22d0 100644
--- a/kokoro/linux/python27_cpp/presubmit.cfg
+++ b/kokoro/linux/python27_cpp/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
+build_file: "protobuf/kokoro/linux/python27_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python35/continuous.cfg b/kokoro/linux/python35/continuous.cfg
index e2fc413..2b3e12c 100644
--- a/kokoro/linux/python35/continuous.cfg
+++ b/kokoro/linux/python35/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python/build.sh"
+build_file: "protobuf/kokoro/linux/python35/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python35/presubmit.cfg b/kokoro/linux/python35/presubmit.cfg
index e2fc413..2b3e12c 100644
--- a/kokoro/linux/python35/presubmit.cfg
+++ b/kokoro/linux/python35/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python/build.sh"
+build_file: "protobuf/kokoro/linux/python35/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python35_cpp/continuous.cfg b/kokoro/linux/python35_cpp/continuous.cfg
index b1b0e55..ad5cc86 100644
--- a/kokoro/linux/python35_cpp/continuous.cfg
+++ b/kokoro/linux/python35_cpp/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
+build_file: "protobuf/kokoro/linux/python35_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python35_cpp/presubmit.cfg b/kokoro/linux/python35_cpp/presubmit.cfg
index b1b0e55..ad5cc86 100644
--- a/kokoro/linux/python35_cpp/presubmit.cfg
+++ b/kokoro/linux/python35_cpp/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
+build_file: "protobuf/kokoro/linux/python35_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python36/continuous.cfg b/kokoro/linux/python36/continuous.cfg
index e2fc413..ee7f488 100644
--- a/kokoro/linux/python36/continuous.cfg
+++ b/kokoro/linux/python36/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python/build.sh"
+build_file: "protobuf/kokoro/linux/python36/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python36/presubmit.cfg b/kokoro/linux/python36/presubmit.cfg
index e2fc413..ee7f488 100644
--- a/kokoro/linux/python36/presubmit.cfg
+++ b/kokoro/linux/python36/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python/build.sh"
+build_file: "protobuf/kokoro/linux/python36/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python36_cpp/continuous.cfg b/kokoro/linux/python36_cpp/continuous.cfg
index b1b0e55..df9e714 100644
--- a/kokoro/linux/python36_cpp/continuous.cfg
+++ b/kokoro/linux/python36_cpp/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
+build_file: "protobuf/kokoro/linux/python36_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python36_cpp/presubmit.cfg b/kokoro/linux/python36_cpp/presubmit.cfg
index b1b0e55..df9e714 100644
--- a/kokoro/linux/python36_cpp/presubmit.cfg
+++ b/kokoro/linux/python36_cpp/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
+build_file: "protobuf/kokoro/linux/python36_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python37/continuous.cfg b/kokoro/linux/python37/continuous.cfg
index e2fc413..9fa20c1 100644
--- a/kokoro/linux/python37/continuous.cfg
+++ b/kokoro/linux/python37/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python/build.sh"
+build_file: "protobuf/kokoro/linux/python37/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python37/presubmit.cfg b/kokoro/linux/python37/presubmit.cfg
index e2fc413..9fa20c1 100644
--- a/kokoro/linux/python37/presubmit.cfg
+++ b/kokoro/linux/python37/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python/build.sh"
+build_file: "protobuf/kokoro/linux/python37/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python37_cpp/continuous.cfg b/kokoro/linux/python37_cpp/continuous.cfg
index b1b0e55..49c441f 100644
--- a/kokoro/linux/python37_cpp/continuous.cfg
+++ b/kokoro/linux/python37_cpp/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
+build_file: "protobuf/kokoro/linux/python37_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python37_cpp/presubmit.cfg b/kokoro/linux/python37_cpp/presubmit.cfg
index b1b0e55..49c441f 100644
--- a/kokoro/linux/python37_cpp/presubmit.cfg
+++ b/kokoro/linux/python37_cpp/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
+build_file: "protobuf/kokoro/linux/python37_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python38/continuous.cfg b/kokoro/linux/python38/continuous.cfg
index e2fc413..76425d2 100644
--- a/kokoro/linux/python38/continuous.cfg
+++ b/kokoro/linux/python38/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python/build.sh"
+build_file: "protobuf/kokoro/linux/python38/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python38/presubmit.cfg b/kokoro/linux/python38/presubmit.cfg
index e2fc413..76425d2 100644
--- a/kokoro/linux/python38/presubmit.cfg
+++ b/kokoro/linux/python38/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python/build.sh"
+build_file: "protobuf/kokoro/linux/python38/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python38_cpp/continuous.cfg b/kokoro/linux/python38_cpp/continuous.cfg
index b1b0e55..1e8888c 100644
--- a/kokoro/linux/python38_cpp/continuous.cfg
+++ b/kokoro/linux/python38_cpp/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
+build_file: "protobuf/kokoro/linux/python38_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/python38_cpp/presubmit.cfg b/kokoro/linux/python38_cpp/presubmit.cfg
index b1b0e55..1e8888c 100644
--- a/kokoro/linux/python38_cpp/presubmit.cfg
+++ b/kokoro/linux/python38_cpp/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
+build_file: "protobuf/kokoro/linux/python38_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/macos/php5.6_mac/build.sh b/kokoro/macos/php5.6_mac/build.sh
deleted file mode 100755
index 7487889..0000000
--- a/kokoro/macos/php5.6_mac/build.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-#
-# Build file to set up and run tests
-
-# Change to repo root
-cd $(dirname $0)/../../..
-
-# Prepare worker environment to run tests
-source kokoro/macos/prepare_build_macos_rc
-
-./tests.sh php5.6_mac
diff --git a/kokoro/macos/php5.6_mac/continuous.cfg b/kokoro/macos/php5.6_mac/continuous.cfg
deleted file mode 100644
index ff345e9..0000000
--- a/kokoro/macos/php5.6_mac/continuous.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-# Config file for running tests in Kokoro
-
-# Location of the build script in repository
-build_file: "protobuf/kokoro/macos/php5.6_mac/build.sh"
-timeout_mins: 1440
diff --git a/kokoro/macos/php5.6_mac/presubmit.cfg b/kokoro/macos/php5.6_mac/presubmit.cfg
deleted file mode 100644
index ff345e9..0000000
--- a/kokoro/macos/php5.6_mac/presubmit.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-# Config file for running tests in Kokoro
-
-# Location of the build script in repository
-build_file: "protobuf/kokoro/macos/php5.6_mac/build.sh"
-timeout_mins: 1440
diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c
index b2a0306..7cd1669 100644
--- a/php/ext/google/protobuf/message.c
+++ b/php/ext/google/protobuf/message.c
@@ -356,14 +356,14 @@
   }
 
   upb_msg_set(intern->msg, f, msgval, arena);
-#if PHP_VERSION_ID < 704000
+#if PHP_VERSION_ID < 70400
   return;
 #else
   return val;
 #endif
 
 error:
-#if PHP_VERSION_ID < 704000
+#if PHP_VERSION_ID < 70400
   return;
 #else
   return &EG(error_zval);
diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml
index 037fa90..e0d25c8 100644
--- a/php/ext/google/protobuf/package.xml
+++ b/php/ext/google/protobuf/package.xml
@@ -10,11 +10,11 @@
   <email>protobuf-opensource@google.com</email>
   <active>yes</active>
  </lead>
- <date>2020-08-14</date>
+ <date>2020-10-08</date>
  <time>14:07:59</time>
  <version>
-  <release>3.13.0</release>
-  <api>3.13.0</api>
+  <release>3.13.0.1</release>
+  <api>3.13.0.1</api>
  </version>
  <stability>
   <release>stable</release>
@@ -675,5 +675,19 @@
    <license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
    <notes>GA release.</notes>
   </release>
+  <release>
+   <version>
+    <release>3.13.0.1</release>
+    <api>3.13.0.1</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2020-10-08</date>
+   <time>14:07:59</time>
+   <license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
+   <notes>GA release.</notes>
+  </release>
  </changelog>
 </package>
diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h
index 3188fe7..195e2a7 100644
--- a/php/ext/google/protobuf/protobuf.h
+++ b/php/ext/google/protobuf/protobuf.h
@@ -56,7 +56,7 @@
 // instead of zval* and zend_string* instead of zval* for property names.
 // https://github.com/php/php-src/blob/php-8.0.0beta1/UPGRADING.INTERNALS#L37-L39
 #if PHP_VERSION_ID < 80000
-#define PROTO_VAL zval 
+#define PROTO_VAL zval
 #define PROTO_STR zval
 #define PROTO_MSG_P(obj) (Message*)Z_OBJ_P(obj)
 #define PROTO_STRVAL_P(obj) Z_STRVAL_P(obj)
@@ -69,7 +69,7 @@
 #define PROTO_STRLEN_P(obj) ZSTR_LEN(obj)
 #endif
 
-#define PHP_PROTOBUF_VERSION "3.13.0"
+#define PHP_PROTOBUF_VERSION "3.13.0.1"
 
 // ptr -> PHP object cache. This is a weak map that caches lazily-created
 // wrapper objects around upb types:
diff --git a/php/release.sh b/php/release.sh
index ec9ec0e..6b0baac 100755
--- a/php/release.sh
+++ b/php/release.sh
@@ -10,8 +10,8 @@
 
 VERSION=$1
 
-git clone git@github.com:protocolbuffers/protobuf-php.git
-git clone git@github.com:protocolbuffers/protobuf.git
+git clone https://github.com/protocolbuffers/protobuf-php.git
+git clone https://github.com/protocolbuffers/protobuf.git
 
 # Clean old files
 pushd protobuf-php
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc
index b7d7385..0301e96 100644
--- a/python/google/protobuf/pyext/message.cc
+++ b/python/google/protobuf/pyext/message.cc
@@ -809,7 +809,7 @@
     return false;
   }
 
-  string value_string(value, value_len);
+  std::string value_string(value, value_len);
   if (append) {
     reflection->AddString(message, descriptor, std::move(value_string));
   } else if (index < 0) {
diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py
index 2a9a866..c2bec1c 100644
--- a/python/google/protobuf/text_format.py
+++ b/python/google/protobuf/text_format.py
@@ -883,7 +883,8 @@
                                                   (expanded_any_end_token,))
         self._MergeField(tokenizer, expanded_any_sub_message)
       message.Pack(expanded_any_sub_message,
-                   type_url_prefix=type_url_prefix)
+                   type_url_prefix=type_url_prefix,
+                   deterministic=True)
       return
 
     if tokenizer.TryConsume('['):
diff --git a/python/protobuf_distutils/README.md b/python/protobuf_distutils/README.md
index 2989b2a..63d12b5 100644
--- a/python/protobuf_distutils/README.md
+++ b/python/protobuf_distutils/README.md
@@ -103,4 +103,19 @@
 
   By default, the protoc binary (the Protobuf compiler) is found by
   searching the environment path. To use a specific protoc binary, its
-  path can be specified.
+  path can be specified. Resolution of the `protoc` value is as follows:
+  1. If the `--protoc=VALUE` flag is passed to `generate_py_protobufs`,
+     then `VALUE` will be used.
+     For example:
+     ```shell
+     $ python setup.py generate_py_protobufs --protoc=/path/to/protoc
+     ```
+  2. Otherwise, if a value was set in the `options`, it will be used.
+     (See "Example setup.py configuration," above.)
+  3. Otherwise, if the `PROTOC` environment variable is set, it will be
+     used. For example:
+     For example:
+     ```shell
+     $ PROTOC=/path/to/protoc python setup.py generate_py_protobufs
+     ```
+  4. Otherwise, `$PATH` will be searched.
diff --git a/python/tox.ini b/python/tox.ini
index 999f8ce..56be125 100644
--- a/python/tox.ini
+++ b/python/tox.ini
@@ -14,7 +14,10 @@
 commands =
     python setup.py -q build_py
     python: python setup.py -q build
-    cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension
+    # --warnings_as_errors disabled until we update the Python C extension. See:
+    # https://github.com/protocolbuffers/protobuf/issues/7930
+    # cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension
+    cpp: python setup.py -q build --cpp_implementation --compile_static_extension
     python: python setup.py -q test -q
     cpp: python setup.py -q test -q --cpp_implementation
     python: python setup.py -q test_conformance
diff --git a/src/google/protobuf/any.h b/src/google/protobuf/any.h
index 16a68ca..e8f2cac 100644
--- a/src/google/protobuf/any.h
+++ b/src/google/protobuf/any.h
@@ -60,7 +60,8 @@
   typedef ArenaStringPtr ValueType;
  public:
   // AnyMetadata does not take ownership of "type_url" and "value".
-  AnyMetadata(UrlType* type_url, ValueType* value);
+  constexpr AnyMetadata(UrlType* type_url, ValueType* value)
+      : type_url_(type_url), value_(value) {}
 
   // Packs a message using the default type URL prefix: "type.googleapis.com".
   // The resulted type URL will be "type.googleapis.com/<message_full_name>".
diff --git a/src/google/protobuf/any_lite.cc b/src/google/protobuf/any_lite.cc
index 7501969..ffb2692 100644
--- a/src/google/protobuf/any_lite.cc
+++ b/src/google/protobuf/any_lite.cc
@@ -53,9 +53,6 @@
 const char kTypeGoogleApisComPrefix[] = "type.googleapis.com/";
 const char kTypeGoogleProdComPrefix[] = "type.googleprod.com/";
 
-AnyMetadata::AnyMetadata(UrlType* type_url, ValueType* value)
-    : type_url_(type_url), value_(value) {}
-
 void AnyMetadata::InternalPackFrom(const MessageLite& message,
                                    StringPiece type_url_prefix,
                                    StringPiece type_name) {
diff --git a/src/google/protobuf/any_test.cc b/src/google/protobuf/any_test.cc
index 0d8893f..8aeab76 100644
--- a/src/google/protobuf/any_test.cc
+++ b/src/google/protobuf/any_test.cc
@@ -33,10 +33,18 @@
 #include <gtest/gtest.h>
 
 
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
 namespace google {
 namespace protobuf {
 namespace {
 
+TEST(AnyMetadataTest, ConstInit) {
+  PROTOBUF_CONSTINIT static internal::AnyMetadata metadata(nullptr, nullptr);
+  (void)metadata;
+}
+
 TEST(AnyTest, TestPackAndUnpack) {
   protobuf_unittest::TestAny submessage;
   submessage.set_int32_value(12345);
diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc
index fce59b2..631a08e 100644
--- a/src/google/protobuf/arena.cc
+++ b/src/google/protobuf/arena.cc
@@ -47,6 +47,10 @@
 
 namespace google {
 namespace protobuf {
+
+PROTOBUF_EXPORT /*static*/ void* (*const ArenaOptions::kDefaultBlockAlloc)(
+    size_t) = &::operator new;
+
 namespace internal {
 
 const size_t ArenaImpl::kBlockHeaderSize;
@@ -54,7 +58,7 @@
 const size_t ArenaImpl::kOptionsSize;
 
 
-std::atomic<LifecycleId> ArenaImpl::lifecycle_id_generator_;
+ArenaImpl::CacheAlignedLifecycleIdGenerator ArenaImpl::lifecycle_id_generator_;
 #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
 ArenaImpl::ThreadCache& ArenaImpl::thread_cache() {
   static internal::ThreadLocalStorage<ThreadCache>* thread_cache_ =
@@ -63,12 +67,13 @@
 }
 #elif defined(PROTOBUF_USE_DLLS)
 ArenaImpl::ThreadCache& ArenaImpl::thread_cache() {
-  static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_ = {-1, NULL};
+  static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_ = {
+      0, static_cast<LifecycleIdAtomic>(-1), nullptr};
   return thread_cache_;
 }
 #else
-PROTOBUF_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = {-1,
-                                                                         NULL};
+PROTOBUF_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = {
+    0, static_cast<LifecycleIdAtomic>(-1), nullptr};
 #endif
 
 void ArenaFree(void* object, size_t size) {
@@ -122,9 +127,26 @@
 }
 
 void ArenaImpl::Init(bool record_allocs) {
+  ThreadCache& tc = thread_cache();
+  auto id = tc.next_lifecycle_id;
+  constexpr uint64 kInc = ThreadCache::kPerThreadIds * 2;
+  if (PROTOBUF_PREDICT_FALSE((id & (kInc - 1)) == 0)) {
+    if (sizeof(lifecycle_id_generator_.id) == 4) {
+      // 2^32 is dangerous low to guarantee uniqueness. If we start dolling out
+      // unique id's in ranges of kInc it's unacceptably low. In this case
+      // we increment by 1. The additional range of kPerThreadIds that are used
+      // per thread effectively pushes the overflow time from weeks to years
+      // of continuous running.
+      id = lifecycle_id_generator_.id.fetch_add(1, std::memory_order_relaxed) *
+           kInc;
+    } else {
+      id =
+          lifecycle_id_generator_.id.fetch_add(kInc, std::memory_order_relaxed);
+    }
+  }
+  tc.next_lifecycle_id = id + 2;
   // We store "record_allocs" in the low bit of lifecycle_id_.
-  auto id = lifecycle_id_generator_.fetch_add(1, std::memory_order_relaxed);
-  lifecycle_id_ = (id << 1) | (record_allocs ? 1 : 0);
+  lifecycle_id_ = id | (record_allocs ? 1 : 0);
   hint_.store(nullptr, std::memory_order_relaxed);
   threads_.store(nullptr, std::memory_order_relaxed);
   space_allocated_.store(0, std::memory_order_relaxed);
diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h
index 7c5c7d0..8ab4fc8 100644
--- a/src/google/protobuf/arena.h
+++ b/src/google/protobuf/arena.h
@@ -142,10 +142,12 @@
         max_block_size(kDefaultMaxBlockSize),
         initial_block(NULL),
         initial_block_size(0),
-        block_alloc(&::operator new),
+        block_alloc(kDefaultBlockAlloc),
         block_dealloc(&internal::ArenaFree),
         make_metrics_collector(nullptr) {}
 
+  PROTOBUF_EXPORT static void* (*const kDefaultBlockAlloc)(size_t);
+
  private:
   // If make_metrics_collector is not nullptr, it will be called at Arena init
   // time. It may return a pointer to a collector instance that will be notified
diff --git a/src/google/protobuf/arena_impl.h b/src/google/protobuf/arena_impl.h
index 56ef7e1..ec86dab 100644
--- a/src/google/protobuf/arena_impl.h
+++ b/src/google/protobuf/arena_impl.h
@@ -58,7 +58,7 @@
   return (n + 7) & static_cast<size_t>(-8);
 }
 
-using LifecycleId = int64_t;
+using LifecycleIdAtomic = uint64_t;
 
 void PROTOBUF_EXPORT ArenaFree(void* object, size_t size);
 
@@ -328,20 +328,43 @@
     ArenaMetricsCollector* metrics_collector;
   };
 
-  struct ThreadCache {
+#ifdef _MSC_VER
+#pragma warning(disable:4324)
+#endif
+  struct alignas(64) ThreadCache {
 #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
     // If we are using the ThreadLocalStorage class to store the ThreadCache,
     // then the ThreadCache's default constructor has to be responsible for
     // initializing it.
-    ThreadCache() : last_lifecycle_id_seen(-1), last_serial_arena(NULL) {}
+    ThreadCache()
+        : next_lifecycle_id(0),
+          last_lifecycle_id_seen(-1),
+          last_serial_arena(NULL) {}
 #endif
 
+    // Number of per-thread lifecycle IDs to reserve. Must be power of two.
+    // To reduce contention on a global atomic, each thread reserves a batch of
+    // IDs.  The following number is caluculated based on a stress test with
+    // ~6500 threads all frequently allocating a new arena.
+    static constexpr size_t kPerThreadIds = 256;
+    // Next lifecycle ID available to this thread. We need to reserve a new
+    // batch, if `next_lifecycle_id & (kPerThreadIds - 1) == 0`.
+    uint64 next_lifecycle_id;
     // The ThreadCache is considered valid as long as this matches the
     // lifecycle_id of the arena being used.
-    LifecycleId last_lifecycle_id_seen;
+    uint64 last_lifecycle_id_seen;
     SerialArena* last_serial_arena;
   };
-  static std::atomic<LifecycleId> lifecycle_id_generator_;
+  // Lifecycle_id can be highly contended variable in a situation of lots of
+  // arena creation. Make sure that other global variables are not sharing the
+  // cacheline.
+#ifdef _MSC_VER
+#pragma warning(disable:4324)
+#endif
+  struct alignas(64) CacheAlignedLifecycleIdGenerator {
+    std::atomic<LifecycleIdAtomic> id;
+  };
+  static CacheAlignedLifecycleIdGenerator lifecycle_id_generator_;
 #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
   // Android ndk does not support __thread keyword so we use a custom thread
   // local storage class we implemented.
@@ -430,7 +453,7 @@
 
   // Unique for each arena. Changes on Reset().
   // Least-significant-bit is 1 iff allocations should be recorded.
-  LifecycleId lifecycle_id_;
+  uint64 lifecycle_id_;
 
   Options* options_ = nullptr;
 
diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h
index e23459f..60307b2 100644
--- a/src/google/protobuf/arenastring.h
+++ b/src/google/protobuf/arenastring.h
@@ -87,22 +87,27 @@
 template <typename T>
 class TaggedPtr {
  public:
+  TaggedPtr() = default;
+  explicit constexpr TaggedPtr(const std::string* ptr)
+      : ptr_(const_cast<std::string*>(ptr)) {}
+
   void SetTagged(T* p) {
     Set(p);
-    ptr_ |= 1;
+    ptr_ = reinterpret_cast<void*>(as_int() | 1);
   }
-  void Set(T* p) { ptr_ = reinterpret_cast<uintptr_t>(p); }
-  T* Get() const { return reinterpret_cast<T*>(ptr_ & -2); }
-  bool IsTagged() const { return ptr_ & 1; }
+  void Set(T* p) { ptr_ = p; }
+  T* Get() const { return reinterpret_cast<T*>(as_int() & -2); }
+  bool IsTagged() const { return as_int() & 1; }
 
   // Returned value is only safe to dereference if IsTagged() == false.
   // It is safe to compare.
-  T* UnsafeGet() const { return reinterpret_cast<T*>(ptr_); }
+  T* UnsafeGet() const { return static_cast<T*>(ptr_); }
 
-  bool IsNull() { return ptr_ == 0; }
+  bool IsNull() { return ptr_ == nullptr; }
 
  private:
-  uintptr_t ptr_;
+  uintptr_t as_int() const { return reinterpret_cast<uintptr_t>(ptr_); }
+  void* ptr_;
 };
 
 static_assert(std::is_trivial<TaggedPtr<std::string>>::value,
@@ -165,9 +170,9 @@
 // single "cmp %reg, GLOBAL" in the resulting machine code. (Note that this also
 // requires the String tag to be 0 so we can avoid the mask before comparing.)
 struct PROTOBUF_EXPORT ArenaStringPtr {
-  // No default constructor or destructor -- we have to be POD because we go
-  // into a union when used in a oneof. Message code calls UnsafeReset() to zero
-  // the pointer when necessary instead.
+  ArenaStringPtr() = default;
+  explicit constexpr ArenaStringPtr(const std::string* default_value)
+      : tagged_ptr_(default_value) {}
 
   // Some methods below are overloaded on a `default_value` and on tags.
   // The tagged overloads help reduce code size in the callers in generated
diff --git a/src/google/protobuf/arenastring_unittest.cc b/src/google/protobuf/arenastring_unittest.cc
index 07e7c65..321b451 100644
--- a/src/google/protobuf/arenastring_unittest.cc
+++ b/src/google/protobuf/arenastring_unittest.cc
@@ -45,6 +45,9 @@
 #include <google/protobuf/stubs/strutil.h>
 
 
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
 namespace google {
 namespace protobuf {
 
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index f5d88e5..1987e08 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -47,6 +47,7 @@
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/testing/file.h>
+#include <google/protobuf/any.pb.h>
 #include <google/protobuf/compiler/mock_code_generator.h>
 #include <google/protobuf/compiler/subprocess.h>
 #include <google/protobuf/compiler/code_generator.h>
@@ -123,7 +124,7 @@
   void SwitchToTempDirectory() {
     File::ChangeWorkingDirectory(temp_directory_);
   }
-#else   // !PROTOBUF_OPENSOURCE
+#else  // !PROTOBUF_OPENSOURCE
   // TODO(teboring): Figure out how to change and get working directory in
   // google3.
 #endif  // !PROTOBUF_OPENSOURCE
@@ -681,6 +682,9 @@
       FileDescriptorProto::descriptor()->file();
   descriptor_file->CopyTo(file_descriptor_set.add_file());
 
+  FileDescriptorProto& any_proto = *file_descriptor_set.add_file();
+  google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
+
   const FileDescriptor* custom_file =
       protobuf_unittest::AggregateMessage::descriptor()->file();
   FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h
index 5b2f276..2d11f90 100644
--- a/src/google/protobuf/compiler/cpp/cpp_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_field.h
@@ -164,10 +164,6 @@
     return false;
   }
 
-  // Generate code that allocates the fields's default instance.
-  virtual void GenerateDefaultInstanceAllocator(
-      io::Printer* /*printer*/) const {}
-
   // Generate lines to serialize this field directly to the array "target",
   // which are placed within the message's SerializeWithCachedSizesToArray()
   // method. This must also advance "target" past the written bytes.
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index 1e3d2da..875beec 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -941,7 +941,6 @@
     if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) {
       continue;
     }
-    message_generators_[i]->GenerateFieldDefaultInstances(printer);
     format(
         "{\n"
         "  void* ptr = &$1$;\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index 653bd70..965d9bc 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -1899,13 +1899,6 @@
   return num_field_metadata;
 }
 
-void MessageGenerator::GenerateFieldDefaultInstances(io::Printer* printer) {
-  // Construct the default instances for all fields that need one.
-  for (auto field : FieldRange(descriptor_)) {
-    field_generators_.get(field).GenerateDefaultInstanceAllocator(printer);
-  }
-}
-
 void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
   Formatter format(printer, variables_);
   if (IsMapEntryMessage(descriptor_)) {
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h
index 0bc32b4..933386f 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message.h
@@ -82,9 +82,6 @@
 
   // Source file stuff.
 
-  // Generates code that creates default instances for fields.
-  void GenerateFieldDefaultInstances(io::Printer* printer);
-
   // Generate all non-inline methods for this class.
   void GenerateClassMethods(io::Printer* printer);
 
diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc
index 2fc7aad..bb378b8 100644
--- a/src/google/protobuf/compiler/java/java_file.cc
+++ b/src/google/protobuf/compiler/java/java_file.cc
@@ -390,6 +390,7 @@
   printer->Print("}\n");
 }
 
+
 void FileGenerator::GenerateDescriptorInitializationCodeForImmutable(
     io::Printer* printer) {
   printer->Print(
diff --git a/src/google/protobuf/compiler/java/java_file.h b/src/google/protobuf/compiler/java/java_file.h
index bb3e4a5..9f1f719 100644
--- a/src/google/protobuf/compiler/java/java_file.h
+++ b/src/google/protobuf/compiler/java/java_file.h
@@ -78,6 +78,7 @@
 
   void Generate(io::Printer* printer);
 
+
   // If we aren't putting everything into one file, this will write all the
   // files other than the outer file (i.e. one for each message, enum, and
   // service type).
diff --git a/src/google/protobuf/compiler/java/java_name_resolver.cc b/src/google/protobuf/compiler/java/java_name_resolver.cc
index d998f16..bc13dd8 100644
--- a/src/google/protobuf/compiler/java/java_name_resolver.cc
+++ b/src/google/protobuf/compiler/java/java_name_resolver.cc
@@ -160,7 +160,14 @@
 
 std::string ClassNameResolver::GetFileClassName(const FileDescriptor* file,
                                                 bool immutable) {
-  if (immutable) {
+  return GetFileClassName(file, immutable, false);
+}
+
+std::string ClassNameResolver::GetFileClassName(const FileDescriptor* file,
+                                                bool immutable, bool kotlin) {
+  if (kotlin) {
+    return GetFileImmutableClassName(file) + "Kt";
+  } else if (immutable) {
     return GetFileImmutableClassName(file);
   } else {
     return "Mutable" + GetFileImmutableClassName(file);
@@ -200,9 +207,14 @@
 
 std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor,
                                             bool immutable) {
+  return GetClassName(descriptor, immutable, false);
+}
+
+std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor,
+                                            bool immutable, bool kotlin) {
   std::string result = FileJavaPackage(descriptor, immutable);
   if (!result.empty()) result += '.';
-  result += GetFileClassName(descriptor, immutable);
+  result += GetFileClassName(descriptor, immutable, kotlin);
   return result;
 }
 
@@ -211,50 +223,79 @@
 std::string ClassNameResolver::GetClassFullName(
     const std::string& name_without_package, const FileDescriptor* file,
     bool immutable, bool is_own_file) {
+  return GetClassFullName(name_without_package, file, immutable, is_own_file,
+                          false);
+}
+
+std::string ClassNameResolver::GetClassFullName(
+    const std::string& name_without_package, const FileDescriptor* file,
+    bool immutable, bool is_own_file, bool kotlin) {
   std::string result;
   if (is_own_file) {
     result = FileJavaPackage(file, immutable);
   } else {
-    result = GetClassName(file, immutable);
+    result = GetClassName(file, immutable, kotlin);
   }
   if (!result.empty()) {
     result += '.';
   }
   result += name_without_package;
+  if (kotlin) result += "Kt";
   return result;
 }
 
 std::string ClassNameResolver::GetClassName(const Descriptor* descriptor,
                                             bool immutable) {
-  return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable),
-                          descriptor->file(), immutable,
-                          MultipleJavaFiles(descriptor->file(), immutable));
+  return GetClassName(descriptor, immutable, false);
+}
+
+std::string ClassNameResolver::GetClassName(const Descriptor* descriptor,
+                                            bool immutable, bool kotlin) {
+  return GetClassFullName(
+      ClassNameWithoutPackage(descriptor, immutable), descriptor->file(),
+      immutable, MultipleJavaFiles(descriptor->file(), immutable), kotlin);
 }
 
 std::string ClassNameResolver::GetClassName(const EnumDescriptor* descriptor,
                                             bool immutable) {
-  return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable),
-                          descriptor->file(), immutable,
-                          MultipleJavaFiles(descriptor->file(), immutable));
+  return GetClassName(descriptor, immutable, false);
+}
+
+std::string ClassNameResolver::GetClassName(const EnumDescriptor* descriptor,
+                                            bool immutable, bool kotlin) {
+  return GetClassFullName(
+      ClassNameWithoutPackage(descriptor, immutable), descriptor->file(),
+      immutable, MultipleJavaFiles(descriptor->file(), immutable), kotlin);
 }
 
 std::string ClassNameResolver::GetClassName(const ServiceDescriptor* descriptor,
                                             bool immutable) {
+  return GetClassName(descriptor, immutable, false);
+}
+
+std::string ClassNameResolver::GetClassName(const ServiceDescriptor* descriptor,
+                                            bool immutable, bool kotlin) {
   return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable),
                           descriptor->file(), immutable,
-                          IsOwnFile(descriptor, immutable));
+                          IsOwnFile(descriptor, immutable), kotlin);
 }
 
 // Get the Java Class style full name of a message.
 std::string ClassNameResolver::GetJavaClassFullName(
     const std::string& name_without_package, const FileDescriptor* file,
     bool immutable) {
+  return GetJavaClassFullName(name_without_package, file, immutable, false);
+}
+
+std::string ClassNameResolver::GetJavaClassFullName(
+    const std::string& name_without_package, const FileDescriptor* file,
+    bool immutable, bool kotlin) {
   std::string result;
   if (MultipleJavaFiles(file, immutable)) {
     result = FileJavaPackage(file, immutable);
     if (!result.empty()) result += '.';
   } else {
-    result = GetClassName(file, immutable);
+    result = GetClassName(file, immutable, kotlin);
     if (!result.empty()) result += '$';
   }
   result += StringReplace(name_without_package, ".", "$", true);
@@ -263,7 +304,12 @@
 
 std::string ClassNameResolver::GetExtensionIdentifierName(
     const FieldDescriptor* descriptor, bool immutable) {
-  return GetClassName(descriptor->containing_type(), immutable) + "." +
+  return GetExtensionIdentifierName(descriptor, immutable, false);
+}
+
+std::string ClassNameResolver::GetExtensionIdentifierName(
+    const FieldDescriptor* descriptor, bool immutable, bool kotlin) {
+  return GetClassName(descriptor->containing_type(), immutable, kotlin) + "." +
          descriptor->name();
 }
 
diff --git a/src/google/protobuf/compiler/java/java_name_resolver.h b/src/google/protobuf/compiler/java/java_name_resolver.h
index b92570c..8461df9 100644
--- a/src/google/protobuf/compiler/java/java_name_resolver.h
+++ b/src/google/protobuf/compiler/java/java_name_resolver.h
@@ -60,6 +60,8 @@
 
   // Gets the unqualified outer class name for the file.
   std::string GetFileClassName(const FileDescriptor* file, bool immutable);
+  std::string GetFileClassName(const FileDescriptor* file, bool immutable,
+                               bool kotlin);
   // Gets the unqualified immutable outer class name of a file.
   std::string GetFileImmutableClassName(const FileDescriptor* file);
   // Gets the unqualified default immutable outer class name of a file
@@ -80,9 +82,17 @@
 
   // Gets the fully-qualified class name corresponding to the given descriptor.
   std::string GetClassName(const Descriptor* descriptor, bool immutable);
+  std::string GetClassName(const Descriptor* descriptor, bool immutable,
+                           bool kotlin);
   std::string GetClassName(const EnumDescriptor* descriptor, bool immutable);
+  std::string GetClassName(const EnumDescriptor* descriptor, bool immutable,
+                           bool kotlin);
   std::string GetClassName(const ServiceDescriptor* descriptor, bool immutable);
+  std::string GetClassName(const ServiceDescriptor* descriptor, bool immutable,
+                           bool kotlin);
   std::string GetClassName(const FileDescriptor* descriptor, bool immutable);
+  std::string GetClassName(const FileDescriptor* descriptor, bool immutable,
+                           bool kotlin);
 
   template <class DescriptorType>
   std::string GetImmutableClassName(const DescriptorType* descriptor) {
@@ -96,6 +106,8 @@
   // Gets the fully qualified name of an extension identifier.
   std::string GetExtensionIdentifierName(const FieldDescriptor* descriptor,
                                          bool immutable);
+  std::string GetExtensionIdentifierName(const FieldDescriptor* descriptor,
+                                         bool immutable, bool kotlin);
 
   // Gets the fully qualified name for generated classes in Java convention.
   // Nested classes will be separated using '$' instead of '.'
@@ -109,9 +121,15 @@
   std::string GetClassFullName(const std::string& name_without_package,
                                const FileDescriptor* file, bool immutable,
                                bool is_own_file);
+  std::string GetClassFullName(const std::string& name_without_package,
+                               const FileDescriptor* file, bool immutable,
+                               bool is_own_file, bool kotlin);
   // Get the Java Class style full name of a message.
   std::string GetJavaClassFullName(const std::string& name_without_package,
                                    const FileDescriptor* file, bool immutable);
+  std::string GetJavaClassFullName(const std::string& name_without_package,
+                                   const FileDescriptor* file, bool immutable,
+                                   bool kotlin);
   // Caches the result to provide better performance.
   std::map<const FileDescriptor*, std::string>
       file_immutable_outer_class_names_;
diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc
index a702ca9..895b47d 100644
--- a/src/google/protobuf/compiler/main.cc
+++ b/src/google/protobuf/compiler/main.cc
@@ -65,6 +65,7 @@
                         "Generate Java source file.");
 
 
+
   // Proto2 Python
   python::Generator py_generator;
   cli.RegisterGenerator("--python_out", "--python_opt", &py_generator,
diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc
index 4a3a228..cbb24a5 100644
--- a/src/google/protobuf/compiler/parser_unittest.cc
+++ b/src/google/protobuf/compiler/parser_unittest.cc
@@ -41,6 +41,7 @@
 
 #include <google/protobuf/test_util2.h>
 #include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/any.pb.h>
 #include <google/protobuf/unittest_custom_options.pb.h>
 #include <google/protobuf/io/tokenizer.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
@@ -2276,6 +2277,11 @@
   FileDescriptorProto import_proto;
   import->CopyTo(&import_proto);
   ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL);
+
+  FileDescriptorProto any_import;
+  google::protobuf::Any::descriptor()->file()->CopyTo(&any_import);
+  ASSERT_TRUE(pool_.BuildFile(any_import) != nullptr);
+
   const FileDescriptor* actual = pool_.BuildFile(parsed);
   ASSERT_TRUE(actual != NULL);
   parsed.Clear();
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index d1d0828..179df8f 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -49,6 +49,7 @@
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/stringprintf.h>
 #include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/any.h>
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/tokenizer.h>
@@ -254,14 +255,14 @@
   std::string result;
   result.reserve(input.size());
 
-  for (int i = 0; i < input.size(); i++) {
-    if (input[i] == '_') {
+  for (char character : input) {
+    if (character == '_') {
       capitalize_next = true;
     } else if (capitalize_next) {
-      result.push_back(ToUpper(input[i]));
+      result.push_back(ToUpper(character));
       capitalize_next = false;
     } else {
-      result.push_back(input[i]);
+      result.push_back(character);
     }
   }
 
@@ -278,14 +279,14 @@
   std::string result;
   result.reserve(input.size());
 
-  for (int i = 0; i < input.size(); i++) {
-    if (input[i] == '_') {
+  for (char character : input) {
+    if (character == '_') {
       capitalize_next = true;
     } else if (capitalize_next) {
-      result.push_back(ToUpper(input[i]));
+      result.push_back(ToUpper(character));
       capitalize_next = false;
     } else {
-      result.push_back(input[i]);
+      result.push_back(character);
     }
   }
 
@@ -297,14 +298,14 @@
   std::string result;
   result.reserve(input.size());
 
-  for (int i = 0; i < input.size(); i++) {
-    if (input[i] == '_') {
+  for (char character : input) {
+    if (character == '_') {
       next_upper = true;
     } else {
       if (next_upper) {
-        result.push_back(ToUpper(input[i]));
+        result.push_back(ToUpper(character));
       } else {
-        result.push_back(ToLower(input[i]));
+        result.push_back(ToLower(character));
       }
       next_upper = false;
     }
@@ -318,9 +319,9 @@
  public:
   PrefixRemover(StringPiece prefix) {
     // Strip underscores and lower-case the prefix.
-    for (int i = 0; i < prefix.size(); i++) {
-      if (prefix[i] != '_') {
-        prefix_ += ascii_tolower(prefix[i]);
+    for (char character : prefix) {
+      if (character != '_') {
+        prefix_ += ascii_tolower(character);
       }
     }
   }
@@ -471,16 +472,15 @@
   const char* kOptionNames[] = {
       "FileOptions",      "MessageOptions", "FieldOptions",  "EnumOptions",
       "EnumValueOptions", "ServiceOptions", "MethodOptions", "OneofOptions"};
-  for (int i = 0; i < GOOGLE_ARRAYSIZE(kOptionNames); ++i) {
+  for (const char* option_name : kOptionNames) {
     // descriptor.proto has a different package name in opensource. We allow
     // both so the opensource protocol compiler can also compile internal
     // proto3 files with custom options. See: b/27567912
     allowed_proto3_extendees->insert(std::string("google.protobuf.") +
-                                     kOptionNames[i]);
+                                     option_name);
     // Split the word to trick the opensource processing scripts so they
     // will keep the original package name.
-    allowed_proto3_extendees->insert(std::string("proto") + "2." +
-                                     kOptionNames[i]);
+    allowed_proto3_extendees->insert(std::string("proto") + "2." + option_name);
   }
   return allowed_proto3_extendees;
 }
@@ -1571,8 +1571,7 @@
     std::vector<int> numbers;
     if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(),
                                                     &numbers)) {
-      for (int i = 0; i < numbers.size(); ++i) {
-        int number = numbers[i];
+      for (int number : numbers) {
         if (tables_->FindExtension(extendee, number) == nullptr) {
           TryFindExtensionInFallbackDatabase(extendee, number);
         }
@@ -2279,34 +2278,34 @@
   const Reflection* reflection = options.GetReflection();
   std::vector<const FieldDescriptor*> fields;
   reflection->ListFields(options, &fields);
-  for (int i = 0; i < fields.size(); i++) {
+  for (const FieldDescriptor* field : fields) {
     int count = 1;
     bool repeated = false;
-    if (fields[i]->is_repeated()) {
-      count = reflection->FieldSize(options, fields[i]);
+    if (field->is_repeated()) {
+      count = reflection->FieldSize(options, field);
       repeated = true;
     }
     for (int j = 0; j < count; j++) {
       std::string fieldval;
-      if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
         std::string tmp;
         TextFormat::Printer printer;
         printer.SetInitialIndentLevel(depth + 1);
-        printer.PrintFieldValueToString(options, fields[i], repeated ? j : -1,
+        printer.PrintFieldValueToString(options, field, repeated ? j : -1,
                                         &tmp);
         fieldval.append("{\n");
         fieldval.append(tmp);
         fieldval.append(depth * 2, ' ');
         fieldval.append("}");
       } else {
-        TextFormat::PrintFieldValueToString(options, fields[i],
-                                            repeated ? j : -1, &fieldval);
+        TextFormat::PrintFieldValueToString(options, field, repeated ? j : -1,
+                                            &fieldval);
       }
       std::string name;
-      if (fields[i]->is_extension()) {
-        name = "(." + fields[i]->full_name() + ")";
+      if (field->is_extension()) {
+        name = "(." + field->full_name() + ")";
       } else {
-        name = fields[i]->name();
+        name = field->name();
       }
       option_entries->push_back(name + " = " + fieldval);
     }
@@ -2363,9 +2362,8 @@
   std::string prefix(depth * 2, ' ');
   std::vector<std::string> all_options;
   if (RetrieveOptions(depth, options, pool, &all_options)) {
-    for (int i = 0; i < all_options.size(); i++) {
-      strings::SubstituteAndAppend(output, "$0option $1;\n", prefix,
-                                all_options[i]);
+    for (const std::string& option : all_options) {
+      strings::SubstituteAndAppend(output, "$0option $1;\n", prefix, option);
     }
   }
   return !all_options.empty();
@@ -2395,8 +2393,9 @@
   void AddPreComment(std::string* output) {
     if (have_source_loc_) {
       // Detached leading comments.
-      for (int i = 0; i < source_loc_.leading_detached_comments.size(); ++i) {
-        *output += FormatComment(source_loc_.leading_detached_comments[i]);
+      for (const std::string& leading_detached_comment :
+           source_loc_.leading_detached_comments) {
+        *output += FormatComment(leading_detached_comment);
         *output += "\n";
       }
       // Attached leading comments.
@@ -2418,8 +2417,7 @@
     StripWhitespace(&stripped_comment);
     std::vector<std::string> lines = Split(stripped_comment, "\n");
     std::string output;
-    for (int i = 0; i < lines.size(); ++i) {
-      const std::string& line = lines[i];
+    for (const std::string& line : lines) {
       strings::SubstituteAndAppend(&output, "$0// $1\n", prefix_, line);
     }
     return output;
@@ -3866,13 +3864,13 @@
 static bool ValidateQualifiedName(StringPiece name) {
   bool last_was_period = false;
 
-  for (int i = 0; i < name.size(); i++) {
+  for (char character : name) {
     // I don't trust isalnum() due to locales.  :(
-    if (('a' <= name[i] && name[i] <= 'z') ||
-        ('A' <= name[i] && name[i] <= 'Z') ||
-        ('0' <= name[i] && name[i] <= '9') || (name[i] == '_')) {
+    if (('a' <= character && character <= 'z') ||
+        ('A' <= character && character <= 'Z') ||
+        ('0' <= character && character <= '9') || (character == '_')) {
       last_was_period = false;
-    } else if (name[i] == '.') {
+    } else if (character == '.') {
       if (last_was_period) return false;
       last_was_period = true;
     } else {
@@ -4096,11 +4094,11 @@
     AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
              "Missing name.");
   } else {
-    for (int i = 0; i < name.size(); i++) {
+    for (char character : name) {
       // I don't trust isalnum() due to locales.  :(
-      if ((name[i] < 'a' || 'z' < name[i]) &&
-          (name[i] < 'A' || 'Z' < name[i]) &&
-          (name[i] < '0' || '9' < name[i]) && (name[i] != '_')) {
+      if ((character < 'a' || 'z' < character) &&
+          (character < 'A' || 'Z' < character) &&
+          (character < '0' || '9' < character) && (character != '_')) {
         AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
                  "\"" + name + "\" is not a valid identifier.");
       }
@@ -5945,12 +5943,12 @@
 
 static std::string ToLowercaseWithoutUnderscores(const std::string& name) {
   std::string result;
-  for (int i = 0; i < name.size(); ++i) {
-    if (name[i] != '_') {
-      if (name[i] >= 'A' && name[i] <= 'Z') {
-        result.push_back(name[i] - 'A' + 'a');
+  for (char character : name) {
+    if (character != '_') {
+      if (character >= 'A' && character <= 'Z') {
+        result.push_back(character - 'A' + 'a');
       } else {
-        result.push_back(name[i]);
+        result.push_back(character);
       }
     }
   }
@@ -7067,6 +7065,18 @@
  public:
   DescriptorBuilder* builder_;
 
+  const Descriptor* FindAnyType(const Message& message,
+                                const std::string& prefix,
+                                const std::string& name) const override {
+    if (prefix != internal::kTypeGoogleApisComPrefix &&
+        prefix != internal::kTypeGoogleProdComPrefix) {
+      return nullptr;
+    }
+    assert_mutex_held(builder_->pool_);
+    Symbol result = builder_->FindSymbol(name);
+    return result.type == Symbol::MESSAGE ? result.descriptor : nullptr;
+  }
+
   const FieldDescriptor* FindExtension(Message* message,
                                        const std::string& name) const override {
     assert_mutex_held(builder_->pool_);
diff --git a/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc
index 83165fb..bb6f19c 100644
--- a/src/google/protobuf/descriptor_database.cc
+++ b/src/google/protobuf/descriptor_database.cc
@@ -552,11 +552,9 @@
 
 bool EncodedDescriptorDatabase::Add(const void* encoded_file_descriptor,
                                     int size) {
-  google::protobuf::Arena arena;
-  auto* file = google::protobuf::Arena::CreateMessage<FileDescriptorProto>(&arena);
-  if (file->ParseFromArray(encoded_file_descriptor, size)) {
-    return index_->AddFile(*file,
-                           std::make_pair(encoded_file_descriptor, size));
+  FileDescriptorProto file;
+  if (file.ParseFromArray(encoded_file_descriptor, size)) {
+    return index_->AddFile(file, std::make_pair(encoded_file_descriptor, size));
   } else {
     GOOGLE_LOG(ERROR) << "Invalid file descriptor data passed to "
                   "EncodedDescriptorDatabase::Add().";
@@ -933,8 +931,8 @@
   std::vector<const FieldDescriptor*> extensions;
   pool_.FindAllExtensions(extendee, &extensions);
 
-  for (int i = 0; i < extensions.size(); ++i) {
-    output->push_back(extensions[i]->number());
+  for (const FieldDescriptor* extension : extensions) {
+    output->push_back(extension->number());
   }
 
   return true;
@@ -954,8 +952,8 @@
 
 bool MergedDescriptorDatabase::FindFileByName(const std::string& filename,
                                               FileDescriptorProto* output) {
-  for (int i = 0; i < sources_.size(); i++) {
-    if (sources_[i]->FindFileByName(filename, output)) {
+  for (DescriptorDatabase* source : sources_) {
+    if (source->FindFileByName(filename, output)) {
       return true;
     }
   }
@@ -1012,8 +1010,8 @@
   std::vector<int> results;
   bool success = false;
 
-  for (int i = 0; i < sources_.size(); i++) {
-    if (sources_[i]->FindAllExtensionNumbers(extendee_type, &results)) {
+  for (DescriptorDatabase* source : sources_) {
+    if (source->FindAllExtensionNumbers(extendee_type, &results)) {
       std::copy(results.begin(), results.end(),
                 std::insert_iterator<std::set<int> >(merged_results,
                                                      merged_results.begin()));
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
index 278b07f..331a0c5 100644
--- a/src/google/protobuf/descriptor_unittest.cc
+++ b/src/google/protobuf/descriptor_unittest.cc
@@ -38,6 +38,7 @@
 #include <memory>
 #include <vector>
 
+#include <google/protobuf/any.pb.h>
 #include <google/protobuf/compiler/importer.h>
 #include <google/protobuf/compiler/parser.h>
 #include <google/protobuf/unittest.pb.h>
@@ -287,9 +288,8 @@
         break;
     }
 
-    strings::SubstituteAndAppend(&warning_text_, "$0: $1: $2: $3\n",
-                                       filename, element_name, location_name,
-                                       message);
+    strings::SubstituteAndAppend(&warning_text_, "$0: $1: $2: $3\n", filename,
+                              element_name, location_name, message);
   }
 };
 
@@ -3148,6 +3148,11 @@
   FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
   ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
 
+  // We have to import the Any dependency.
+  FileDescriptorProto any_proto;
+  google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
+  ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
+
   protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
       &file_proto);
   ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
@@ -3206,6 +3211,10 @@
   FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
   ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
 
+  FileDescriptorProto any_proto;
+  google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
+  ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
+
   protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
       &file_proto);
   ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
@@ -3283,6 +3292,10 @@
   FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
   ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
 
+  FileDescriptorProto any_proto;
+  google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
+  ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
+
   protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
       &file_proto);
   ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
@@ -3363,6 +3376,10 @@
   FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
   ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
 
+  FileDescriptorProto any_proto;
+  google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
+  ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
+
   protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
       &file_proto);
   ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
@@ -3463,6 +3480,10 @@
                                   message_set_extension)
                 .s());
 
+  protobuf_unittest::AggregateMessageSetElement any_payload;
+  ASSERT_TRUE(file_options.any().UnpackTo(&any_payload));
+  EXPECT_EQ("EmbeddedMessageSetElement", any_payload.s());
+
   // Simple tests for all the other types of annotations
   EXPECT_EQ("MessageAnnotation",
             msg->options().GetExtension(protobuf_unittest::msgopt).s());
@@ -3485,6 +3506,10 @@
   FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
   ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
 
+  FileDescriptorProto any_proto;
+  google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
+  ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
+
   protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
       &file_proto);
   ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
@@ -7182,8 +7207,8 @@
 
   static std::string PrintSourceLocation(const SourceLocation& loc) {
     return strings::Substitute("$0:$1-$2:$3", 1 + loc.start_line,
-                                     1 + loc.start_column, 1 + loc.end_line,
-                                     1 + loc.end_column);
+                            1 + loc.start_column, 1 + loc.end_line,
+                            1 + loc.end_column);
   }
 
  private:
diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc
index 0dcabb0..bfa1c42 100644
--- a/src/google/protobuf/extension_set.cc
+++ b/src/google/protobuf/extension_set.cc
@@ -192,14 +192,6 @@
                ? NULL
                : Arena::CreateArray<KeyValue>(arena_, flat_capacity_)} {}
 
-ExtensionSet::ExtensionSet()
-    : arena_(NULL),
-      flat_capacity_(0),
-      flat_size_(0),
-      map_{flat_capacity_ == 0
-               ? NULL
-               : Arena::CreateArray<KeyValue>(arena_, flat_capacity_)} {}
-
 ExtensionSet::~ExtensionSet() {
   // Deletes all allocated extensions.
   if (arena_ == NULL) {
diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h
index b30a960..b3a6e3a 100644
--- a/src/google/protobuf/extension_set.h
+++ b/src/google/protobuf/extension_set.h
@@ -173,7 +173,7 @@
 // off to the ExtensionSet for parsing.  Etc.
 class PROTOBUF_EXPORT ExtensionSet {
  public:
-  ExtensionSet();
+  constexpr ExtensionSet();
   explicit ExtensionSet(Arena* arena);
   ~ExtensionSet();
 
@@ -850,6 +850,9 @@
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet);
 };
 
+constexpr ExtensionSet::ExtensionSet()
+    : arena_(nullptr), flat_capacity_(0), flat_size_(0), map_{nullptr} {}
+
 // These are just for convenience...
 inline void ExtensionSet::SetString(int number, FieldType type,
                                     std::string value,
diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc
index 3e6ecef..2c299c1 100644
--- a/src/google/protobuf/extension_set_unittest.cc
+++ b/src/google/protobuf/extension_set_unittest.cc
@@ -46,13 +46,15 @@
 #include <google/protobuf/dynamic_message.h>
 #include <google/protobuf/extension_set.h>
 #include <google/protobuf/wire_format.h>
-
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
 #include <google/protobuf/stubs/stl_util.h>
 
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
 
 namespace google {
 namespace protobuf {
@@ -1324,6 +1326,11 @@
   EXPECT_TRUE(msg.GetExtension(protobuf_unittest::optional_bool_extension));
 }
 
+TEST(ExtensionSetTest, ConstInit) {
+  PROTOBUF_CONSTINIT static ExtensionSet set{};
+  EXPECT_EQ(set.NumExtensions(), 0);
+}
+
 }  // namespace
 }  // namespace internal
 }  // namespace protobuf
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc
index 3ff9315..e8b19c8 100644
--- a/src/google/protobuf/generated_message_reflection.cc
+++ b/src/google/protobuf/generated_message_reflection.cc
@@ -1065,6 +1065,7 @@
           output->push_back(field);
         }
       } else if (has_bits && has_bits_indices[i] != -1) {
+        CheckInvalidAccess(schema_, field);
         // Equivalent to: HasBit(message, field)
         if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) {
           output->push_back(field);
diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc
index aaeadc7..f1f6f88 100644
--- a/src/google/protobuf/generated_message_util.cc
+++ b/src/google/protobuf/generated_message_util.cc
@@ -68,16 +68,25 @@
   static_cast<const std::string*>(s)->~basic_string();
 }
 
-ExplicitlyConstructed<std::string> fixed_address_empty_string;
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EmptyString
+    fixed_address_empty_string;  // NOLINT
 
 
+PROTOBUF_CONSTINIT std::atomic<bool> init_protobuf_defaults_state{false};
 static bool InitProtobufDefaultsImpl() {
-  fixed_address_empty_string.DefaultConstruct();
-  OnShutdownDestroyString(fixed_address_empty_string.get_mutable());
+  ::new (static_cast<void*>(&fixed_address_empty_string.value)) std::string();
+  OnShutdownDestroyString(&fixed_address_empty_string.value);
+
+  // Verify that we can indeed get the address during constant evaluation.
+  PROTOBUF_CONSTINIT static const std::string& fixed_address_empty_string_test =
+      GetEmptyStringAlreadyInited();
+  (void)fixed_address_empty_string_test;
+
+  init_protobuf_defaults_state.store(true, std::memory_order_release);
   return true;
 }
 
-void InitProtobufDefaults() {
+void InitProtobufDefaultsSlow() {
   static bool is_inited = InitProtobufDefaultsImpl();
   (void)is_inited;
 }
diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h
index 7cae4e1..bae0c1f 100644
--- a/src/google/protobuf/generated_message_util.h
+++ b/src/google/protobuf/generated_message_util.h
@@ -85,7 +85,17 @@
 }
 
 
-PROTOBUF_EXPORT void InitProtobufDefaults();
+// This fastpath inlines a single branch instead of having to make the
+// InitProtobufDefaults function call.
+// It also generates less inlined code than a function-scope static initializer.
+PROTOBUF_EXPORT extern std::atomic<bool> init_protobuf_defaults_state;
+PROTOBUF_EXPORT void InitProtobufDefaultsSlow();
+PROTOBUF_EXPORT inline void InitProtobufDefaults() {
+  if (PROTOBUF_PREDICT_FALSE(
+          !init_protobuf_defaults_state.load(std::memory_order_acquire))) {
+    InitProtobufDefaultsSlow();
+  }
+}
 
 // This used by proto1
 PROTOBUF_EXPORT inline const std::string& GetEmptyString() {
diff --git a/src/google/protobuf/has_bits.h b/src/google/protobuf/has_bits.h
index 540cac2..1144b9f 100644
--- a/src/google/protobuf/has_bits.h
+++ b/src/google/protobuf/has_bits.h
@@ -47,7 +47,7 @@
 template <size_t doublewords>
 class HasBits {
  public:
-  HasBits() PROTOBUF_ALWAYS_INLINE { Clear(); }
+  constexpr HasBits() PROTOBUF_ALWAYS_INLINE : has_bits_{} {}
 
   void Clear() PROTOBUF_ALWAYS_INLINE {
     memset(has_bits_, 0, sizeof(has_bits_));
diff --git a/src/google/protobuf/implicit_weak_message.h b/src/google/protobuf/implicit_weak_message.h
index ec028eb..bfa6a81 100644
--- a/src/google/protobuf/implicit_weak_message.h
+++ b/src/google/protobuf/implicit_weak_message.h
@@ -129,7 +129,7 @@
 template <typename T>
 struct WeakRepeatedPtrField {
   using TypeHandler = internal::ImplicitWeakTypeHandler<T>;
-  WeakRepeatedPtrField() : weak() {}
+  constexpr WeakRepeatedPtrField() : weak() {}
   explicit WeakRepeatedPtrField(Arena* arena) : weak(arena) {}
   ~WeakRepeatedPtrField() { weak.template Destroy<TypeHandler>(); }
 
diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h
index f04d048..dfc84ff 100644
--- a/src/google/protobuf/map.h
+++ b/src/google/protobuf/map.h
@@ -105,8 +105,8 @@
   using size_type = size_t;
   using difference_type = ptrdiff_t;
 
-  MapAllocator() : arena_(nullptr) {}
-  explicit MapAllocator(Arena* arena) : arena_(arena) {}
+  constexpr MapAllocator() : arena_(nullptr) {}
+  explicit constexpr MapAllocator(Arena* arena) : arena_(arena) {}
   template <typename X>
   MapAllocator(const MapAllocator<X>& allocator)  // NOLINT(runtime/explicit)
       : arena_(allocator.arena()) {}
@@ -382,7 +382,7 @@
   using size_type = size_t;
   using hasher = typename internal::TransparentSupport<Key>::hash;
 
-  Map() : elements_(nullptr) {}
+  constexpr Map() : elements_(nullptr) {}
   explicit Map(Arena* arena) : elements_(arena) {}
 
   Map(const Map& other) : Map() { insert(other.begin(), other.end()); }
@@ -450,11 +450,11 @@
   //    otherwise. This avoids unnecessary copies of string keys, for example.
   class InnerMap : private hasher {
    public:
-    explicit InnerMap(Arena* arena)
+    explicit constexpr InnerMap(Arena* arena)
         : hasher(),
           num_elements_(0),
           num_buckets_(internal::kGlobalEmptyTableSize),
-          seed_(Seed()),
+          seed_(0),
           index_of_first_non_null_(num_buckets_),
           table_(const_cast<void**>(internal::kGlobalEmptyTable)),
           alloc_(arena) {}
@@ -920,6 +920,7 @@
         // 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_);
+        seed_ = Seed();
         return;
       }
 
diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h
index 180ff0e..9e35795 100644
--- a/src/google/protobuf/map_entry.h
+++ b/src/google/protobuf/map_entry.h
@@ -93,7 +93,7 @@
 class MapEntry : public MapEntryImpl<Derived, Message, Key, Value,
                                      kKeyFieldType, kValueFieldType> {
  public:
-  MapEntry() : _internal_metadata_(NULL) {}
+  constexpr MapEntry() : _internal_metadata_() {}
   explicit MapEntry(Arena* arena)
       : MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
                      kValueFieldType>(arena),
diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h
index 92cb4ac..1caf59d 100644
--- a/src/google/protobuf/map_entry_lite.h
+++ b/src/google/protobuf/map_entry_lite.h
@@ -182,17 +182,16 @@
   static const WireFormatLite::FieldType kEntryKeyFieldType = kKeyFieldType;
   static const WireFormatLite::FieldType kEntryValueFieldType = kValueFieldType;
 
-  MapEntryImpl() {
-    KeyTypeHandler::Initialize(&key_, NULL);
-    ValueTypeHandler::Initialize(&value_, NULL);
-    _has_bits_[0] = 0;
-  }
+  constexpr MapEntryImpl()
+      : key_(KeyTypeHandler::Constinit()),
+        value_(ValueTypeHandler::Constinit()),
+        _has_bits_{} {}
 
-  explicit MapEntryImpl(Arena* arena) : Base(arena) {
-    KeyTypeHandler::Initialize(&key_, arena);
-    ValueTypeHandler::Initialize(&value_, arena);
-    _has_bits_[0] = 0;
-  }
+  explicit MapEntryImpl(Arena* arena)
+      : Base(arena),
+        key_(KeyTypeHandler::Constinit()),
+        value_(ValueTypeHandler::Constinit()),
+        _has_bits_{} {}
 
   ~MapEntryImpl() {
     if (Base::GetArena() != NULL) return;
@@ -523,7 +522,7 @@
   typedef MapEntryImpl<T, MessageLite, Key, Value, kKeyFieldType,
                        kValueFieldType>
       SuperType;
-  MapEntryLite() {}
+  constexpr MapEntryLite() {}
   explicit MapEntryLite(Arena* arena) : SuperType(arena) {}
   ~MapEntryLite() { MessageLite::_internal_metadata_.Delete<std::string>(); }
   void MergeFrom(const MapEntryLite& other) { MergeFromInternal(other); }
diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h
index f4e034c..9fbd06a 100644
--- a/src/google/protobuf/map_field.h
+++ b/src/google/protobuf/map_field.h
@@ -324,6 +324,16 @@
  public:
   MapFieldBase()
       : arena_(NULL), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) {}
+
+  // This constructor is for constant initialized global instances.
+  // It uses a linker initialized mutex, so it is not compatible with regular
+  // runtime instances.
+  // Except in MSVC, where we can't have a constinit mutex.
+  explicit PROTOBUF_MAYBE_CONSTEXPR MapFieldBase(ConstantInitialized)
+      : arena_(nullptr),
+        repeated_field_(nullptr),
+        mutex_(GOOGLE_PROTOBUF_LINKER_INITIALIZED),
+        state_(STATE_MODIFIED_MAP) {}
   explicit MapFieldBase(Arena* arena)
       : arena_(arena), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) {
     // Mutex's destructor needs to be called explicitly to release resources
@@ -466,6 +476,12 @@
 class TypeDefinedMapFieldBase : public MapFieldBase {
  public:
   TypeDefinedMapFieldBase() {}
+
+  // This constructor is for constant initialized global instances.
+  // It uses a linker initialized mutex, so it is not compatible with regular
+  // runtime instances.
+  explicit constexpr TypeDefinedMapFieldBase(ConstantInitialized tag)
+      : MapFieldBase(tag) {}
   explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {}
   ~TypeDefinedMapFieldBase() override {}
   void MapBegin(MapIterator* map_iter) const override;
@@ -521,6 +537,12 @@
   typedef Map<Key, T> MapType;
 
   MapField() {}
+
+  // This constructor is for constant initialized global instances.
+  // It uses a linker initialized mutex, so it is not compatible with regular
+  // runtime instances.
+  explicit constexpr MapField(ConstantInitialized tag)
+      : TypeDefinedMapFieldBase<Key, T>(tag), impl_() {}
   explicit MapField(Arena* arena)
       : TypeDefinedMapFieldBase<Key, T>(arena), impl_(arena) {}
 
diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h
index a47b877..665cb0e 100644
--- a/src/google/protobuf/map_field_lite.h
+++ b/src/google/protobuf/map_field_lite.h
@@ -63,7 +63,7 @@
   typedef Map<Key, T> MapType;
   typedef EntryType EntryTypeTrait;
 
-  MapFieldLite() {}
+  constexpr MapFieldLite() {}
 
   explicit MapFieldLite(Arena* arena) : map_(arena) {}
 
diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc
index 39544a3..f6274c0 100644
--- a/src/google/protobuf/map_field_test.cc
+++ b/src/google/protobuf/map_field_test.cc
@@ -45,6 +45,9 @@
 #include <google/protobuf/repeated_field.h>
 #include <gtest/gtest.h>
 
+// Must be included last.
+#include <google/protobuf/port_def.inc>
+
 namespace google {
 namespace protobuf {
 
@@ -478,6 +481,22 @@
   }
 }
 
+class MyMapField
+    : public MapField<unittest::TestMap_MapInt32Int32Entry_DoNotUse, int32,
+                      int32, internal::WireFormatLite::TYPE_INT32,
+                      internal::WireFormatLite::TYPE_INT32> {
+ public:
+  constexpr MyMapField()
+      : MyMapField::MapField(internal::ConstantInitialized{}) {}
+};
+
+TEST(MapFieldTest, ConstInit) {
+  // This tests that `MapField` and all its base classes can be constant
+  // initialized.
+  PROTOBUF_CONSTINIT static MyMapField field;  // NOLINT
+  EXPECT_EQ(field.size(), 0);
+}
+
 
 }  // namespace internal
 }  // namespace protobuf
diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc
index f2a5b93..9c53b51 100644
--- a/src/google/protobuf/map_test.cc
+++ b/src/google/protobuf/map_test.cc
@@ -80,6 +80,7 @@
 #include <google/protobuf/stubs/substitute.h>
 
 
+// Must be included last.
 #include <google/protobuf/port_def.inc>
 
 namespace google {
@@ -1180,6 +1181,11 @@
   TestTransparent(std::cref(abc), std::cref(lkj));
 }
 
+TEST_F(MapImplTest, ConstInit) {
+  PROTOBUF_CONSTINIT static Map<int, int> map;  // NOLINT
+  EXPECT_TRUE(map.empty());
+}
+
 // Map Field Reflection Test ========================================
 
 static int Func(int i, int j) { return i * j; }
@@ -2047,6 +2053,39 @@
   EXPECT_FALSE(message.IsInitialized());
 }
 
+class MyMapEntry
+    : public internal::MapEntry<MyMapEntry, ::google::protobuf::int32, ::google::protobuf::int32,
+                                internal::WireFormatLite::TYPE_INT32,
+                                internal::WireFormatLite::TYPE_INT32> {
+ public:
+  constexpr MyMapEntry() {}
+  MyMapEntry(Arena*) { std::abort(); }
+  Metadata GetMetadata() const override { std::abort(); }
+  static bool ValidateKey(void*) { return true; }
+  static bool ValidateValue(void*) { return true; }
+};
+
+class MyMapEntryLite
+    : public internal::MapEntryLite<MyMapEntryLite, ::google::protobuf::int32, ::google::protobuf::int32,
+                                    internal::WireFormatLite::TYPE_INT32,
+                                    internal::WireFormatLite::TYPE_INT32> {
+ public:
+  constexpr MyMapEntryLite() {}
+  explicit MyMapEntryLite(Arena*) { std::abort(); }
+  static bool ValidateKey(void*) { return true; }
+  static bool ValidateValue(void*) { return true; }
+};
+
+TEST(MapEntryTest, ConstInit) {
+  // This verifies that `MapEntry`, `MapEntryLite` and `MapEntryImpl` can be
+  // constant initialized.
+  PROTOBUF_CONSTINIT static MyMapEntry entry{};
+  EXPECT_NE(entry.SpaceUsed(), 0);
+
+  PROTOBUF_CONSTINIT static MyMapEntryLite entry_lite{};  // NOLINT
+  EXPECT_TRUE(entry_lite.IsInitialized());
+}
+
 // Generated Message Test ===========================================
 
 TEST(GeneratedMapFieldTest, Accessors) {
diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h
index 9c1a594..8b8fd14 100644
--- a/src/google/protobuf/map_type_handler.h
+++ b/src/google/protobuf/map_type_handler.h
@@ -157,7 +157,7 @@
   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 Initialize(Type** x, Arena* arena);
+  static constexpr TypeOnMemory Constinit();
 
   static inline Type* EnsureMutable(Type** value, Arena* arena);
   // SpaceUsedInMapEntry: Return bytes used by value in MapEntry, excluding
@@ -207,7 +207,7 @@
         const TypeOnMemory& value);                                           \
     static inline bool IsInitialized(const TypeOnMemory& value);              \
     static void DeleteNoArena(TypeOnMemory& value);                           \
-    static inline void Initialize(TypeOnMemory* value, Arena* arena);         \
+    static constexpr TypeOnMemory Constinit();                                \
     static inline MapEntryAccessorType* EnsureMutable(TypeOnMemory* value,    \
                                                       Arena* arena);          \
   };
@@ -522,9 +522,9 @@
 }
 
 template <typename Type>
-inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Initialize(
-    Type** x, Arena* /* arena */) {
-  *x = NULL;
+constexpr auto MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Constinit()
+    -> TypeOnMemory {
+  return nullptr;
 }
 
 template <typename Type>
@@ -583,10 +583,10 @@
     value.DestroyNoArena(&internal::GetEmptyStringAlreadyInited());           \
   }                                                                           \
   template <typename Type>                                                    \
-  inline void                                                                 \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Initialize(         \
-      TypeOnMemory* value, Arena* /* arena */) {                              \
-    value->UnsafeSetDefault(&internal::GetEmptyStringAlreadyInited());        \
+  constexpr auto                                                              \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Constinit()         \
+      ->TypeOnMemory {                                                        \
+    return TypeOnMemory(&internal::GetEmptyStringAlreadyInited());            \
   }                                                                           \
   template <typename Type>                                                    \
   inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType,            \
@@ -640,10 +640,10 @@
   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;                                                              \
+  constexpr auto                                                             \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Constinit()        \
+      ->TypeOnMemory {                                                       \
+    return 0;                                                                \
   }                                                                          \
   template <typename Type>                                                   \
   inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType,           \
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc
index ccf09ee..6e1e25e 100644
--- a/src/google/protobuf/message.cc
+++ b/src/google/protobuf/message.cc
@@ -162,7 +162,7 @@
   return GetReflection()->SpaceUsedLong(*this);
 }
 
-size_t Message::GetInvariantPerBuild(size_t salt) {
+uint64 Message::GetInvariantPerBuild(uint64 salt) {
   return salt;
 }
 
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index fca4dd5..feb9a8f 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -231,7 +231,7 @@
 // the internal library are allowed to create subclasses.
 class PROTOBUF_EXPORT Message : public MessageLite {
  public:
-  inline Message() {}
+  constexpr Message() = default;
 
   // Basic Operations ------------------------------------------------
 
@@ -367,7 +367,7 @@
 
 
  protected:
-  static size_t GetInvariantPerBuild(size_t salt);
+  static uint64 GetInvariantPerBuild(uint64 salt);
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message);
diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h
index 1cce5d9..a76c16e 100644
--- a/src/google/protobuf/message_lite.h
+++ b/src/google/protobuf/message_lite.h
@@ -74,6 +74,12 @@
 }  // namespace io
 namespace internal {
 
+// Tag type used to invoke the constinit constructor overload of some classes.
+// Such constructors are internal implementation details of the library.
+struct ConstantInitialized {
+  explicit ConstantInitialized() = default;
+};
+
 // See parse_context.h for explanation
 class ParseContext;
 
@@ -145,14 +151,27 @@
   } union_;
 };
 
+PROTOBUF_DISABLE_MSVC_UNION_WARNING
+// We need a publicly accessible `value` object to allow constexpr
+// support in C++11.
+// A constexpr accessor does not work portably.
+union EmptyString {
+  constexpr EmptyString() : dummy{} {}
+  ~EmptyString() {}
+
+  // We need a dummy object for constant initialization.
+  std::false_type dummy;
+  std::string value;
+};
+PROTOBUF_ENABLE_MSVC_UNION_WARNING
+
 // Default empty string object. Don't use this directly. Instead, call
 // GetEmptyString() to get the reference.
-PROTOBUF_EXPORT extern ExplicitlyConstructed<std::string>
-    fixed_address_empty_string;
+PROTOBUF_EXPORT extern EmptyString fixed_address_empty_string;
 
 
-PROTOBUF_EXPORT inline const std::string& GetEmptyStringAlreadyInited() {
-  return fixed_address_empty_string.get();
+PROTOBUF_EXPORT constexpr const std::string& GetEmptyStringAlreadyInited() {
+  return fixed_address_empty_string.value;
 }
 
 PROTOBUF_EXPORT size_t StringSpaceUsedExcludingSelfLong(const std::string& str);
@@ -187,7 +206,7 @@
 // the internal library are allowed to create subclasses.
 class PROTOBUF_EXPORT MessageLite {
  public:
-  inline MessageLite() {}
+  constexpr MessageLite() = default;
   virtual ~MessageLite() = default;
 
   // Basic Operations ------------------------------------------------
diff --git a/src/google/protobuf/metadata_lite.h b/src/google/protobuf/metadata_lite.h
index 781a1f5..ec5f923 100644
--- a/src/google/protobuf/metadata_lite.h
+++ b/src/google/protobuf/metadata_lite.h
@@ -58,7 +58,7 @@
 // pointer.
 class InternalMetadata {
  public:
-  InternalMetadata() : ptr_(nullptr) {}
+  constexpr InternalMetadata() : ptr_(nullptr) {}
   explicit InternalMetadata(Arena* arena) : ptr_(arena) {}
 
   template <typename T>
diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc
index d879a86..8b39d69 100644
--- a/src/google/protobuf/port_def.inc
+++ b/src/google/protobuf/port_def.inc
@@ -139,6 +139,21 @@
 #ifdef PROTOBUF_FINAL
 #error PROTOBUF_FINAL was previously defined
 #endif
+#ifdef PROTOBUF_DISABLE_MSVC_UNION_WARNING
+#error PROTOBUF_DISABLE_MSVC_UNION_WARNING was previously defined
+#endif
+#ifdef PROTOBUF_ENABLE_MSVC_UNION_WARNING
+#error PROTOBUF_ENABLE_MSVC_UNION_WARNING was previously defined
+#endif
+#ifdef PROTOBUF_CONSTINIT
+#error PROTOBUF_CONSTINIT was previously defined
+#endif
+#ifdef PROTOBUF_MAYBE_CONSTEXPR
+#error PROTOBUF_MAYBE_CONSTEXPR was previously defined
+#endif
+#ifdef PROTOBUF_ATTRIBUTE_NO_DESTROY
+#error PROTOBUF_ATTRIBUTE_NO_DESTROY was previously defined
+#endif
 
 
 #define PROTOBUF_NAMESPACE "google::protobuf"
@@ -428,6 +443,10 @@
 #undef min
 #pragma push_macro("max")
 #undef max
+#pragma push_macro("NEAR")
+#undef NEAR
+#pragma push_macro("NO_DATA")
+#undef NO_DATA
 #pragma push_macro("REASON_UNKNOWN")
 #undef REASON_UNKNOWN
 #pragma push_macro("SERVICE_DISABLED")
@@ -443,10 +462,6 @@
 #if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
 // Don't let Objective-C Macros interfere with proto identifiers with the same 
 // name.
-#pragma push_macro("YES")
-#undef YES
-#pragma push_macro("NO")
-#undef NO
 #pragma push_macro("DEBUG")
 #undef DEBUG
 #pragma push_macro("TRUE")
@@ -533,3 +548,59 @@
 // This experiment is purely for the purpose of gathering data. All code guarded
 // by this flag is supposed to be removed after this experiment.
 // #define PROTOBUF_MESSAGE_OWNED_ARENA_EXPERIMENT
+
+#if defined(__cpp_constinit)
+#define PROTOBUF_CONSTINIT constinit
+#elif defined(__has_cpp_attribute)
+#if __has_cpp_attribute(clang::require_constant_initialization)
+#define PROTOBUF_CONSTINIT [[clang::require_constant_initialization]]
+#endif
+#endif
+#ifndef PROTOBUF_CONSTINIT
+#define PROTOBUF_CONSTINIT
+#endif
+
+// Some constructors can't be constexpr under MSVC, but given that MSVC will not
+// do constant initialization of globals anyway we can omit `constexpr` from
+// them. These constructors are marked with PROTOBUF_MAYBE_CONSTEXPR
+#if defined(_MSC_VER)
+#define PROTOBUF_MAYBE_CONSTEXPR
+#else
+#define PROTOBUF_MAYBE_CONSTEXPR constexpr
+#endif
+
+#if _MSC_VER
+#define PROTOBUF_DISABLE_MSVC_UNION_WARNING \
+  __pragma(warning(push)) \
+  __pragma(warning(disable : 4582)) \
+  __pragma(warning(disable : 4583))
+
+#define PROTOBUF_ENABLE_MSVC_UNION_WARNING \
+  __pragma(warning(pop))
+#else
+#define PROTOBUF_DISABLE_MSVC_UNION_WARNING
+#define PROTOBUF_ENABLE_MSVC_UNION_WARNING
+#endif
+
+#if defined(__cpp_constinit)
+#define PROTOBUF_CONSTINIT constinit
+#elif defined(__has_cpp_attribute)
+#if __has_cpp_attribute(clang::require_constant_initialization)
+#define PROTOBUF_CONSTINIT [[clang::require_constant_initialization]]
+#endif
+#endif
+#ifndef PROTOBUF_CONSTINIT
+#define PROTOBUF_CONSTINIT
+#endif
+
+// Some globals with an empty non-trivial destructor are annotated with
+// no_destroy for performance reasons. It reduces the cost of these globals in
+// non-opt mode and under sanitizers.
+#if defined(__has_cpp_attribute)
+#if __has_cpp_attribute(clang::no_destroy)
+#define PROTOBUF_ATTRIBUTE_NO_DESTROY [[clang::no_destroy]]
+#endif
+#endif
+#if !defined(PROTOBUF_ATTRIBUTE_NO_DESTROY)
+#define PROTOBUF_ATTRIBUTE_NO_DESTROY
+#endif
diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc
index fd080a4..d141428 100644
--- a/src/google/protobuf/port_undef.inc
+++ b/src/google/protobuf/port_undef.inc
@@ -72,6 +72,11 @@
 #undef PROTOBUF_FINAL
 #undef PROTOBUF_THREAD_LOCAL
 #undef PROTOBUF_MESSAGE_OWNED_ARENA_EXPERIMENT
+#undef PROTOBUF_DISABLE_MSVC_UNION_WARNING
+#undef PROTOBUF_ENABLE_MSVC_UNION_WARNING
+#undef PROTOBUF_CONSTINIT
+#undef PROTOBUF_MAYBE_CONSTEXPR
+#undef PROTOBUF_ATTRIBUTE_NO_DESTROY
 
 // Restore macro that may have been #undef'd in port_def.inc.
 #ifdef _MSC_VER
@@ -88,6 +93,8 @@
 #pragma pop_macro("OPTIONAL")
 #pragma pop_macro("min")
 #pragma pop_macro("max")
+#pragma pop_macro("NEAR")
+#pragma pop_macro("NO_DATA")
 #pragma pop_macro("NO_ERROR")
 #pragma pop_macro("REASON_UNKNOWN")
 #pragma pop_macro("SERVICE_DISABLED")
@@ -97,8 +104,6 @@
 #endif
 
 #if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
-#pragma pop_macro("YES")
-#pragma pop_macro("NO")
 #pragma pop_macro("DEBUG")
 #pragma pop_macro("TRUE")
 #pragma pop_macro("FALSE")
diff --git a/src/google/protobuf/reflection_ops.cc b/src/google/protobuf/reflection_ops.cc
index c913ea0..29fc5db 100644
--- a/src/google/protobuf/reflection_ops.cc
+++ b/src/google/protobuf/reflection_ops.cc
@@ -85,9 +85,7 @@
 
   std::vector<const FieldDescriptor*> fields;
   from_reflection->ListFieldsOmitStripped(from, &fields);
-  for (int i = 0; i < fields.size(); i++) {
-    const FieldDescriptor* field = fields[i];
-
+  for (const FieldDescriptor* field : fields) {
     if (field->is_repeated()) {
       // Use map reflection if both are in map status and have the
       // same map type to avoid sync with repeated field.
@@ -180,8 +178,8 @@
 
   std::vector<const FieldDescriptor*> fields;
   reflection->ListFieldsOmitStripped(*message, &fields);
-  for (int i = 0; i < fields.size(); i++) {
-    reflection->ClearField(message, fields[i]);
+  for (const FieldDescriptor* field : fields) {
+    reflection->ClearField(message, field);
   }
 
   reflection->MutableUnknownFields(message)->Clear();
@@ -270,8 +268,7 @@
   // Should be safe to skip stripped fields because required fields are not
   // stripped.
   reflection->ListFieldsOmitStripped(message, &fields);
-  for (int i = 0; i < fields.size(); i++) {
-    const FieldDescriptor* field = fields[i];
+  for (const FieldDescriptor* field : fields) {
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
 
       if (field->is_map()) {
@@ -329,8 +326,7 @@
   // messages present.
   std::vector<const FieldDescriptor*> fields;
   reflection->ListFields(*message, &fields);
-  for (int i = 0; i < fields.size(); i++) {
-    const FieldDescriptor* field = fields[i];
+  for (const FieldDescriptor* field : fields) {
     // Skip over non-message fields.
     if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
       continue;
@@ -401,8 +397,7 @@
   // Check sub-messages.
   std::vector<const FieldDescriptor*> fields;
   reflection->ListFieldsOmitStripped(message, &fields);
-  for (int i = 0; i < fields.size(); i++) {
-    const FieldDescriptor* field = fields[i];
+  for (const FieldDescriptor* field : fields) {
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
 
       if (field->is_repeated()) {
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index c1c4774..26d5847 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -169,7 +169,7 @@
       "We only support types that have an alignment smaller than Arena");
 
  public:
-  RepeatedField();
+  constexpr RepeatedField();
   explicit RepeatedField(Arena* arena);
   RepeatedField(const RepeatedField& other);
   template <typename Iter>
@@ -577,7 +577,7 @@
 //   };
 class PROTOBUF_EXPORT RepeatedPtrFieldBase {
  protected:
-  RepeatedPtrFieldBase();
+  constexpr RepeatedPtrFieldBase();
   explicit RepeatedPtrFieldBase(Arena* arena);
   ~RepeatedPtrFieldBase() {
 #ifndef NDEBUG
@@ -920,7 +920,7 @@
 template <typename Element>
 class RepeatedPtrField final : private internal::RepeatedPtrFieldBase {
  public:
-  RepeatedPtrField();
+  constexpr RepeatedPtrField();
   explicit RepeatedPtrField(Arena* arena);
 
   RepeatedPtrField(const RepeatedPtrField& other);
@@ -1180,7 +1180,7 @@
 // implementation ====================================================
 
 template <typename Element>
-inline RepeatedField<Element>::RepeatedField()
+constexpr RepeatedField<Element>::RepeatedField()
     : current_size_(0), total_size_(0), arena_or_elements_(nullptr) {}
 
 template <typename Element>
@@ -1647,7 +1647,7 @@
 
 namespace internal {
 
-inline RepeatedPtrFieldBase::RepeatedPtrFieldBase()
+constexpr RepeatedPtrFieldBase::RepeatedPtrFieldBase()
     : arena_(NULL), current_size_(0), total_size_(0), rep_(NULL) {}
 
 inline RepeatedPtrFieldBase::RepeatedPtrFieldBase(Arena* arena)
@@ -2090,7 +2090,8 @@
     : public internal::StringTypeHandler {};
 
 template <typename Element>
-inline RepeatedPtrField<Element>::RepeatedPtrField() : RepeatedPtrFieldBase() {}
+constexpr RepeatedPtrField<Element>::RepeatedPtrField()
+    : RepeatedPtrFieldBase() {}
 
 template <typename Element>
 inline RepeatedPtrField<Element>::RepeatedPtrField(Arena* arena)
diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc
index 8de9504..4072f47 100644
--- a/src/google/protobuf/repeated_field_unittest.cc
+++ b/src/google/protobuf/repeated_field_unittest.cc
@@ -65,6 +65,11 @@
 using ::protobuf_unittest::TestAllTypes;
 using ::testing::ElementsAre;
 
+TEST(RepeatedField, ConstInit) {
+  PROTOBUF_CONSTINIT static RepeatedField<int> field{};  // NOLINT
+  EXPECT_TRUE(field.empty());
+}
+
 // Test operations on a small RepeatedField.
 TEST(RepeatedField, Small) {
   RepeatedField<int> field;
@@ -827,6 +832,11 @@
 // RepeatedPtrField tests.  These pretty much just mirror the RepeatedField
 // tests above.
 
+TEST(RepeatedPtrField, ConstInit) {
+  PROTOBUF_CONSTINIT static RepeatedPtrField<std::string> field{};  // NOLINT
+  EXPECT_TRUE(field.empty());
+}
+
 TEST(RepeatedPtrField, Small) {
   RepeatedPtrField<std::string> field;
 
diff --git a/src/google/protobuf/stubs/bytestream.h b/src/google/protobuf/stubs/bytestream.h
index 0193301..c7a48de 100644
--- a/src/google/protobuf/stubs/bytestream.h
+++ b/src/google/protobuf/stubs/bytestream.h
@@ -256,11 +256,11 @@
 //
 class PROTOBUF_EXPORT StringByteSink : public ByteSink {
  public:
-  explicit StringByteSink(string* dest) : dest_(dest) {}
+  explicit StringByteSink(std::string* dest) : dest_(dest) {}
   virtual void Append(const char* data, size_t n) override;
 
  private:
-  string* dest_;
+  std::string* dest_;
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringByteSink);
 };
 
diff --git a/src/google/protobuf/stubs/bytestream_unittest.cc b/src/google/protobuf/stubs/bytestream_unittest.cc
index 06f114a..cb11825 100644
--- a/src/google/protobuf/stubs/bytestream_unittest.cc
+++ b/src/google/protobuf/stubs/bytestream_unittest.cc
@@ -64,7 +64,7 @@
 TEST(ByteSourceTest, CopyTo) {
   StringPiece data("Hello world!");
   MockByteSource source(data, 3);
-  string str;
+  std::string str;
   StringByteSink sink(&str);
 
   source.CopyTo(&sink, data.size());
@@ -75,7 +75,7 @@
   StringPiece data("Hello world!");
   MockByteSource source(data, 3);
   source.Skip(1);
-  string str;
+  std::string str;
   StringByteSink sink(&str);
 
   source.CopyTo(&sink, data.size() - 2);
@@ -92,7 +92,7 @@
   EXPECT_EQ(5, limit_source.Available());
 
   {
-    string str;
+    std::string str;
     StringByteSink sink(&str);
     limit_source.CopyTo(&sink, limit_source.Available());
     EXPECT_EQ("ello ", str);
@@ -101,7 +101,7 @@
   }
 
   {
-    string str;
+    std::string str;
     StringByteSink sink(&str);
     source.CopyTo(&sink, source.Available());
     EXPECT_EQ("world!", str);
@@ -112,7 +112,7 @@
 TEST(ByteSourceTest, CopyToStringByteSink) {
   StringPiece data("Hello world!");
   MockByteSource source(data, 3);
-  string str;
+  std::string str;
   StringByteSink sink(&str);
   source.CopyTo(&sink, data.size());
   EXPECT_EQ(data, str);
@@ -121,7 +121,7 @@
 // Verify that ByteSink is subclassable and Flush() overridable.
 class FlushingByteSink : public StringByteSink {
  public:
-  explicit FlushingByteSink(string* dest) : StringByteSink(dest) {}
+  explicit FlushingByteSink(std::string* dest) : StringByteSink(dest) {}
   virtual void Flush() { Append("z", 1); }
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FlushingByteSink);
@@ -134,7 +134,7 @@
 }
 
 TEST(ByteSinkTest, Flush) {
-  string str;
+  std::string str;
   FlushingByteSink f_sink(&str);
   WriteAndFlush(&f_sink);
   EXPECT_STREQ("abcz", str.c_str());
diff --git a/src/google/protobuf/stubs/callback.h b/src/google/protobuf/stubs/callback.h
index b7a3a82..43d546d 100644
--- a/src/google/protobuf/stubs/callback.h
+++ b/src/google/protobuf/stubs/callback.h
@@ -62,12 +62,12 @@
 // Note that NewCallback() is a bit touchy regarding argument types.  Generally,
 // the values you provide for the parameter bindings must exactly match the
 // types accepted by the callback function.  For example:
-//   void Foo(string s);
+//   void Foo(std::string s);
 //   NewCallback(&Foo, "foo");          // WON'T WORK:  const char* != string
-//   NewCallback(&Foo, string("foo"));  // WORKS
+//   NewCallback(&Foo, std::string("foo"));  // WORKS
 // Also note that the arguments cannot be references:
-//   void Foo(const string& s);
-//   string my_str;
+//   void Foo(const std::string& s);
+//   std::string my_str;
 //   NewCallback(&Foo, my_str);  // WON'T WORK:  Can't use references.
 // However, correctly-typed pointers will work just fine.
 class PROTOBUF_EXPORT Closure {
diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc
index 30802b1..bc150f5 100644
--- a/src/google/protobuf/stubs/common.cc
+++ b/src/google/protobuf/stubs/common.cc
@@ -96,7 +96,7 @@
   }
 }
 
-string VersionString(int version) {
+std::string VersionString(int version) {
   int major = version / 1000000;
   int minor = (version / 1000) % 1000;
   int micro = version % 1000;
@@ -127,7 +127,7 @@
 
 #if defined(__ANDROID__)
 inline void DefaultLogHandler(LogLevel level, const char* filename, int line,
-                              const string& message) {
+                              const std::string& message) {
   if (level < GOOGLE_PROTOBUF_MIN_LOG_LEVEL) {
     return;
   }
@@ -162,7 +162,7 @@
 
 #else
 void DefaultLogHandler(LogLevel level, const char* filename, int line,
-                       const string& message) {
+                       const std::string& message) {
   if (level < GOOGLE_PROTOBUF_MIN_LOG_LEVEL) {
     return;
   }
@@ -177,14 +177,14 @@
 #endif
 
 void NullLogHandler(LogLevel /* level */, const char* /* filename */,
-                    int /* line */, const string& /* message */) {
+                    int /* line */, const std::string& /* message */) {
   // Nothing.
 }
 
 static LogHandler* log_handler_ = &DefaultLogHandler;
 static std::atomic<int> log_silencer_count_ = ATOMIC_VAR_INIT(0);
 
-LogMessage& LogMessage::operator<<(const string& value) {
+LogMessage& LogMessage::operator<<(const std::string& value) {
   message_ += value;
   return *this;
 }
diff --git a/src/google/protobuf/stubs/common_unittest.cc b/src/google/protobuf/stubs/common_unittest.cc
index 5852458..c55e452 100644
--- a/src/google/protobuf/stubs/common_unittest.cc
+++ b/src/google/protobuf/stubs/common_unittest.cc
@@ -53,7 +53,7 @@
   // Verify that the version string specified in config.h matches the one
   // in common.h.  The config.h version is a string which may have a suffix
   // like "beta" or "rc1", so we remove that.
-  string version = PACKAGE_VERSION;
+  std::string version = PACKAGE_VERSION;
   int pos = 0;
   while (pos < version.size() &&
          (ascii_isdigit(version[pos]) || version[pos] == '.')) {
@@ -77,10 +77,10 @@
   EXPECT_EQ(0, kuint64max + 1);
 }
 
-std::vector<string> captured_messages_;
+std::vector<std::string> captured_messages_;
 
 void CaptureLog(LogLevel level, const char* filename, int line,
-                const string& message) {
+                const std::string& message) {
   captured_messages_.push_back(
     strings::Substitute("$0 $1:$2: $3",
       implicit_cast<int>(level), filename, line, message));
@@ -93,7 +93,7 @@
   GOOGLE_LOG(WARNING) << "A warning.";
   GOOGLE_LOG(ERROR  ) << "An error.";
 
-  string text = GetCapturedTestStderr();
+  std::string text = GetCapturedTestStderr();
   EXPECT_EQ(
     "[libprotobuf INFO " __FILE__ ":" + SimpleItoa(line + 1) + "] A message.\n"
     "[libprotobuf WARNING " __FILE__ ":" + SimpleItoa(line + 2) + "] A warning.\n"
@@ -111,7 +111,7 @@
 
   EXPECT_TRUE(SetLogHandler(old_handler) == nullptr);
 
-  string text = GetCapturedTestStderr();
+  std::string text = GetCapturedTestStderr();
   EXPECT_EQ("", text);
 }
 
@@ -167,10 +167,10 @@
   static void SetA123Function() { current_instance_->a_ = 123; }
 
   void SetAMethod(int a)         { a_ = a; }
-  void SetCMethod(string c)      { c_ = c; }
+  void SetCMethod(std::string c) { c_ = c; }
 
   static void SetAFunction(int a)         { current_instance_->a_ = a; }
-  static void SetCFunction(string c)      { current_instance_->c_ = c; }
+  static void SetCFunction(std::string c) { current_instance_->c_ = c; }
 
   void SetABMethod(int a, const char* b)  { a_ = a; b_ = b; }
   static void SetABFunction(int a, const char* b) {
@@ -192,7 +192,7 @@
 
   int a_;
   const char* b_;
-  string c_;
+  std::string c_;
   Closure* permanent_closure_;
 
   static ClosureTest* current_instance_;
@@ -231,15 +231,15 @@
 }
 
 TEST_F(ClosureTest, TestClosureFunction1String) {
-  Closure* closure = NewCallback(&SetCFunction, string("test"));
+  Closure* closure = NewCallback(&SetCFunction, std::string("test"));
   EXPECT_NE("test", c_);
   closure->Run();
   EXPECT_EQ("test", c_);
 }
 
 TEST_F(ClosureTest, TestClosureMethod1String) {
-  Closure* closure = NewCallback(current_instance_,
-                                 &ClosureTest::SetCMethod, string("test"));
+  Closure* closure = NewCallback(current_instance_, &ClosureTest::SetCMethod,
+                                 std::string("test"));
   EXPECT_NE("test", c_);
   closure->Run();
   EXPECT_EQ("test", c_);
diff --git a/src/google/protobuf/stubs/status.cc b/src/google/protobuf/stubs/status.cc
index 2bfbe0b..03b37c3 100644
--- a/src/google/protobuf/stubs/status.cc
+++ b/src/google/protobuf/stubs/status.cc
@@ -38,7 +38,7 @@
 namespace protobuf {
 namespace util {
 namespace error {
-inline string CodeEnumToString(error::Code code) {
+inline std::string CodeEnumToString(error::Code code) {
   switch (code) {
     case OK:
       return "OK";
@@ -111,7 +111,7 @@
       error_message_ == x.error_message_;
 }
 
-string Status::ToString() const {
+std::string Status::ToString() const {
   if (error_code_ == error::OK) {
     return "OK";
   } else {
diff --git a/src/google/protobuf/stubs/status.h b/src/google/protobuf/stubs/status.h
index 04ecc63..bededad 100644
--- a/src/google/protobuf/stubs/status.h
+++ b/src/google/protobuf/stubs/status.h
@@ -106,11 +106,11 @@
   }
 
   // Return a combination of the error code name and message.
-  string ToString() const;
+  std::string ToString() const;
 
  private:
   error::Code error_code_;
-  string error_message_;
+  std::string error_message_;
 };
 
 // Prints a human-readable representation of 'x' to 'os'.
diff --git a/src/google/protobuf/stubs/status_test.cc b/src/google/protobuf/stubs/status_test.cc
index 9a18778..8f4398c 100644
--- a/src/google/protobuf/stubs/status_test.cc
+++ b/src/google/protobuf/stubs/status_test.cc
@@ -101,7 +101,7 @@
   util::Status a(util::error::UNKNOWN, "message");
   util::Status b;
   a = b;
-  ASSERT_EQ(string("OK"), a.ToString());
+  ASSERT_EQ(std::string("OK"), a.ToString());
   ASSERT_TRUE(b.ok());
   ASSERT_TRUE(a.ok());
 }
diff --git a/src/google/protobuf/stubs/stl_util.h b/src/google/protobuf/stubs/stl_util.h
index aa81eb6..d01f9ec 100644
--- a/src/google/protobuf/stubs/stl_util.h
+++ b/src/google/protobuf/stubs/stl_util.h
@@ -44,7 +44,7 @@
 // improve performance.  However, since it's totally non-portable it has no
 // place in open source code.  Feel free to fill this function in with your
 // own disgusting hack if you want the perf boost.
-inline void STLStringResizeUninitialized(string* s, size_t new_size) {
+inline void STLStringResizeUninitialized(std::string* s, size_t new_size) {
   s->resize(new_size);
 }
 
@@ -60,7 +60,7 @@
 // (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530)
 // proposes this as the method. According to Matt Austern, this should
 // already work on all current implementations.
-inline char* string_as_array(string* str) {
+inline char* string_as_array(std::string* str) {
   // DO NOT USE const_cast<char*>(str->data())! See the unittest for why.
   return str->empty() ? nullptr : &*str->begin();
 }
diff --git a/src/google/protobuf/stubs/stringpiece_unittest.cc b/src/google/protobuf/stubs/stringpiece_unittest.cc
index d9a32d0..846e1ae 100644
--- a/src/google/protobuf/stubs/stringpiece_unittest.cc
+++ b/src/google/protobuf/stubs/stringpiece_unittest.cc
@@ -87,7 +87,7 @@
 #if defined(HAS_GLOBAL_STRING)
   {
     // ::string
-    string bonjour = "bonjour";
+    std::string bonjour = "bonjour";
     StringPiece s40(bonjour);
     EXPECT_TRUE(s40.data() == bonjour.data());
     EXPECT_EQ(7, s40.length());
@@ -100,9 +100,9 @@
 }
 
 TEST(StringPiece, STLComparator) {
-  string s1("foo");
-  string s2("bar");
-  string s3("baz");
+  std::string s1("foo");
+  std::string s2("bar");
+  std::string s3("baz");
 
   StringPiece p1(s1);
   StringPiece p2(s2);
@@ -207,13 +207,13 @@
   COMPARE(true, >, "b",  "aa");
   COMPARE(true, >, "bb", "aa");
 
-  string x;
+  std::string x;
   for (int i = 0; i < 256; i++) {
     x += 'a';
-    string y = x;
+    std::string y = x;
     COMPARE(true, ==, x, y);
     for (int j = 0; j < i; j++) {
-      string z = x;
+      std::string z = x;
       z[j] = 'b';       // Differs in position 'j'
       COMPARE(false, ==, x, z);
       COMPARE(true, <, x, z);
@@ -240,7 +240,7 @@
   const StringPiece c("xyz");
   const StringPiece d("foobar");
   const StringPiece e;
-  string temp("123");
+  std::string temp("123");
   temp += '\0';
   temp += "456";
   const StringPiece f(temp);
@@ -315,7 +315,7 @@
   EXPECT_TRUE(d.data() == nullptr);
   EXPECT_TRUE(d.begin() == d.end());
 
-  EXPECT_EQ(StringPiece::npos, string::npos);
+  EXPECT_EQ(StringPiece::npos, std::string::npos);
 
   EXPECT_EQ(a.find(b), 0);
   EXPECT_EQ(a.find(b, 1), StringPiece::npos);
@@ -336,15 +336,15 @@
   EXPECT_EQ(d.find(b, 4), StringPiece::npos);
   EXPECT_EQ(e.find(b, 7), StringPiece::npos);
 
-  size_t empty_search_pos = string().find(string());
+  size_t empty_search_pos = std::string().find(std::string());
   EXPECT_EQ(d.find(d), empty_search_pos);
   EXPECT_EQ(d.find(e), empty_search_pos);
   EXPECT_EQ(e.find(d), empty_search_pos);
   EXPECT_EQ(e.find(e), empty_search_pos);
-  EXPECT_EQ(d.find(d, 4), string().find(string(), 4));
-  EXPECT_EQ(d.find(e, 4), string().find(string(), 4));
-  EXPECT_EQ(e.find(d, 4), string().find(string(), 4));
-  EXPECT_EQ(e.find(e, 4), string().find(string(), 4));
+  EXPECT_EQ(d.find(d, 4), std::string().find(std::string(), 4));
+  EXPECT_EQ(d.find(e, 4), std::string().find(std::string(), 4));
+  EXPECT_EQ(e.find(d, 4), std::string().find(std::string(), 4));
+  EXPECT_EQ(e.find(e, 4), std::string().find(std::string(), 4));
 
   EXPECT_EQ(a.find('a'), 0);
   EXPECT_EQ(a.find('c'), 2);
@@ -376,8 +376,8 @@
   EXPECT_EQ(a.rfind(c, 0), StringPiece::npos);
   EXPECT_EQ(b.rfind(c), StringPiece::npos);
   EXPECT_EQ(b.rfind(c, 0), StringPiece::npos);
-  EXPECT_EQ(a.rfind(d), a.as_string().rfind(string()));
-  EXPECT_EQ(a.rfind(e), a.as_string().rfind(string()));
+  EXPECT_EQ(a.rfind(d), a.as_string().rfind(std::string()));
+  EXPECT_EQ(a.rfind(e), a.as_string().rfind(std::string()));
   EXPECT_EQ(a.rfind(d, 12), 12);
   EXPECT_EQ(a.rfind(e, 17), 17);
   EXPECT_EQ(a.rfind(g), StringPiece::npos);
@@ -386,14 +386,14 @@
   EXPECT_EQ(d.rfind(b, 4), StringPiece::npos);
   EXPECT_EQ(e.rfind(b, 7), StringPiece::npos);
   // empty string nonsense
-  EXPECT_EQ(d.rfind(d, 4), string().rfind(string()));
-  EXPECT_EQ(e.rfind(d, 7), string().rfind(string()));
-  EXPECT_EQ(d.rfind(e, 4), string().rfind(string()));
-  EXPECT_EQ(e.rfind(e, 7), string().rfind(string()));
-  EXPECT_EQ(d.rfind(d), string().rfind(string()));
-  EXPECT_EQ(e.rfind(d), string().rfind(string()));
-  EXPECT_EQ(d.rfind(e), string().rfind(string()));
-  EXPECT_EQ(e.rfind(e), string().rfind(string()));
+  EXPECT_EQ(d.rfind(d, 4), std::string().rfind(std::string()));
+  EXPECT_EQ(e.rfind(d, 7), std::string().rfind(std::string()));
+  EXPECT_EQ(d.rfind(e, 4), std::string().rfind(std::string()));
+  EXPECT_EQ(e.rfind(e, 7), std::string().rfind(std::string()));
+  EXPECT_EQ(d.rfind(d), std::string().rfind(std::string()));
+  EXPECT_EQ(e.rfind(d), std::string().rfind(std::string()));
+  EXPECT_EQ(d.rfind(e), std::string().rfind(std::string()));
+  EXPECT_EQ(e.rfind(e), std::string().rfind(std::string()));
 
   EXPECT_EQ(g.rfind('o'), 8);
   EXPECT_EQ(g.rfind('q'), StringPiece::npos);
@@ -566,7 +566,7 @@
   // empty string nonsense
   EXPECT_EQ(StringPiece(d, 0, 99), e);
   // Verify that they work taking an actual string, not just a StringPiece.
-  string a2 = a.as_string();
+  std::string a2 = a.as_string();
   EXPECT_EQ(StringPiece(a2, 0, 3), b);
   EXPECT_EQ(StringPiece(a2, 23), c);
   EXPECT_EQ(StringPiece(a2, 23, 3), c);
@@ -577,12 +577,12 @@
 
 TEST(StringPiece, Custom) {
   StringPiece a("foobar");
-  string s1("123");
+  std::string s1("123");
   s1 += '\0';
   s1 += "456";
   StringPiece b(s1);
   StringPiece e;
-  string s2;
+  std::string s2;
 
   // CopyToString
   a.CopyToString(&s2);
@@ -666,16 +666,16 @@
   EXPECT_NE(c, a);
 
   // as_string
-  string s3(a.as_string().c_str(), 7);
+  std::string s3(a.as_string().c_str(), 7);
   EXPECT_EQ(c, s3);
-  string s4(e.as_string());
+  std::string s4(e.as_string());
   EXPECT_TRUE(s4.empty());
 
   // ToString
   {
-    string s5(a.ToString().c_str(), 7);
+    std::string s5(a.ToString().c_str(), 7);
     EXPECT_EQ(c, s5);
-    string s6(e.ToString());
+    std::string s6(e.ToString());
     EXPECT_TRUE(s6.empty());
   }
 
@@ -747,12 +747,12 @@
 }
 
 TEST(ComparisonOpsTest, StringCompareNotAmbiguous) {
-  EXPECT_EQ("hello", string("hello"));
-  EXPECT_LT("hello", string("world"));
+  EXPECT_EQ("hello", std::string("hello"));
+  EXPECT_LT("hello", std::string("world"));
 }
 
 TEST(ComparisonOpsTest, HeterogenousStringPieceEquals) {
-  EXPECT_EQ(StringPiece("hello"), string("hello"));
+  EXPECT_EQ(StringPiece("hello"), std::string("hello"));
   EXPECT_EQ("hello", StringPiece("hello"));
 }
 
diff --git a/src/google/protobuf/stubs/stringprintf.cc b/src/google/protobuf/stubs/stringprintf.cc
index e6019fc..2603164 100644
--- a/src/google/protobuf/stubs/stringprintf.cc
+++ b/src/google/protobuf/stubs/stringprintf.cc
@@ -54,7 +54,7 @@
 enum { IS_COMPILER_MSVC = 0 };
 #endif
 
-void StringAppendV(string* dst, const char* format, va_list ap) {
+void StringAppendV(std::string* dst, const char* format, va_list ap) {
   // First try with a small fixed size buffer
   static const int kSpaceLength = 1024;
   char space[kSpaceLength];
@@ -105,17 +105,16 @@
   delete[] buf;
 }
 
-
-string StringPrintf(const char* format, ...) {
+std::string StringPrintf(const char* format, ...) {
   va_list ap;
   va_start(ap, format);
-  string result;
+  std::string result;
   StringAppendV(&result, format, ap);
   va_end(ap);
   return result;
 }
 
-const string& SStringPrintf(string* dst, const char* format, ...) {
+const std::string& SStringPrintf(std::string* dst, const char* format, ...) {
   va_list ap;
   va_start(ap, format);
   dst->clear();
@@ -124,7 +123,7 @@
   return *dst;
 }
 
-void StringAppendF(string* dst, const char* format, ...) {
+void StringAppendF(std::string* dst, const char* format, ...) {
   va_list ap;
   va_start(ap, format);
   StringAppendV(dst, format, ap);
@@ -139,7 +138,8 @@
 // and we can fix the problem or protect against an attack.
 static const char string_printf_empty_block[256] = { '\0' };
 
-string StringPrintfVector(const char* format, const std::vector<string>& v) {
+std::string StringPrintfVector(const char* format,
+                               const std::vector<std::string>& v) {
   GOOGLE_CHECK_LE(v.size(), kStringPrintfVectorMaxArgs)
       << "StringPrintfVector currently only supports up to "
       << kStringPrintfVectorMaxArgs << " arguments. "
diff --git a/src/google/protobuf/stubs/stringprintf.h b/src/google/protobuf/stubs/stringprintf.h
index 253d736..e3858be 100644
--- a/src/google/protobuf/stubs/stringprintf.h
+++ b/src/google/protobuf/stubs/stringprintf.h
@@ -52,18 +52,20 @@
 namespace protobuf {
 
 // Return a C++ string
-PROTOBUF_EXPORT extern string StringPrintf(const char* format, ...);
+PROTOBUF_EXPORT extern std::string StringPrintf(const char* format, ...);
 
 // Store result into a supplied string and return it
-PROTOBUF_EXPORT extern const string& SStringPrintf(string* dst,
-                                                   const char* format, ...);
+PROTOBUF_EXPORT extern const std::string& SStringPrintf(std::string* dst,
+                                                        const char* format,
+                                                        ...);
 
 // Append result to a supplied string
-PROTOBUF_EXPORT extern void StringAppendF(string* dst, const char* format, ...);
+PROTOBUF_EXPORT extern void StringAppendF(std::string* dst, const char* format,
+                                          ...);
 
 // Lower-level routine that takes a va_list and appends to a specified
 // string.  All other routines are just convenience wrappers around it.
-PROTOBUF_EXPORT extern void StringAppendV(string* dst, const char* format,
+PROTOBUF_EXPORT extern void StringAppendV(std::string* dst, const char* format,
                                           va_list ap);
 
 // The max arguments supported by StringPrintfVector
@@ -72,8 +74,8 @@
 // You can use this version when all your arguments are strings, but
 // you don't know how many arguments you'll have at compile time.
 // StringPrintfVector will LOG(FATAL) if v.size() > kStringPrintfVectorMaxArgs
-PROTOBUF_EXPORT extern string StringPrintfVector(const char* format,
-                                                 const std::vector<string>& v);
+PROTOBUF_EXPORT extern std::string StringPrintfVector(
+    const char* format, const std::vector<std::string>& v);
 
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/stubs/stringprintf_unittest.cc b/src/google/protobuf/stubs/stringprintf_unittest.cc
index 7fcbf50..37172a9 100644
--- a/src/google/protobuf/stubs/stringprintf_unittest.cc
+++ b/src/google/protobuf/stubs/stringprintf_unittest.cc
@@ -49,7 +49,7 @@
   // so we do not allow them in google3.
   EXPECT_EQ("", StringPrintf(""));
 #endif
-  EXPECT_EQ("", StringPrintf("%s", string().c_str()));
+  EXPECT_EQ("", StringPrintf("%s", std::string().c_str()));
   EXPECT_EQ("", StringPrintf("%s", ""));
 }
 
@@ -61,26 +61,26 @@
 }
 
 TEST(StringAppendFTest, Empty) {
-  string value("Hello");
+  std::string value("Hello");
   const char* empty = "";
   StringAppendF(&value, "%s", empty);
   EXPECT_EQ("Hello", value);
 }
 
 TEST(StringAppendFTest, EmptyString) {
-  string value("Hello");
+  std::string value("Hello");
   StringAppendF(&value, "%s", "");
   EXPECT_EQ("Hello", value);
 }
 
 TEST(StringAppendFTest, String) {
-  string value("Hello");
+  std::string value("Hello");
   StringAppendF(&value, " %s", "World");
   EXPECT_EQ("Hello World", value);
 }
 
 TEST(StringAppendFTest, Int) {
-  string value("Hello");
+  std::string value("Hello");
   StringAppendF(&value, " %d", 123);
   EXPECT_EQ("Hello 123", value);
 }
@@ -96,7 +96,7 @@
   setlocale(LC_CTYPE, "en_US.utf8");
 
   const char kInvalidCodePoint[] = "\375\067s";
-  string value = StringPrintf("%.*s", 3, kInvalidCodePoint);
+  std::string value = StringPrintf("%.*s", 3, kInvalidCodePoint);
 
   // In some versions of glibc (e.g. eglibc-2.11.1, aka GRTEv2), snprintf
   // returns error given an invalid codepoint. Other versions
@@ -122,7 +122,7 @@
   // No multibyte handling, but the string contains funny chars.
   char* old_locale = setlocale(LC_CTYPE, nullptr);
   setlocale(LC_CTYPE, "POSIX");
-  string value = StringPrintf("%.*s", 3, "\375\067s");
+  std::string value = StringPrintf("%.*s", 3, "\375\067s");
   setlocale(LC_CTYPE, old_locale);
   EXPECT_EQ("\375\067s", value);
 }
@@ -132,7 +132,7 @@
   // something significantly larger than what people are normally
   // printing in their badly written PLOG() statements.
   errno = ECHILD;
-  string value = StringPrintf("Hello, %s!", "World");
+  std::string value = StringPrintf("Hello, %s!", "World");
   EXPECT_EQ(ECHILD, errno);
 }
 
@@ -142,7 +142,7 @@
   char* buf = new char[n+1];
   memset(buf, ' ', n);
   buf[n] = 0;
-  string value = StringPrintf("%s", buf);
+  std::string value = StringPrintf("%s", buf);
   EXPECT_EQ(buf, value);
   delete[] buf;
 }
diff --git a/src/google/protobuf/stubs/structurally_valid_unittest.cc b/src/google/protobuf/stubs/structurally_valid_unittest.cc
index eec07a8..ebd9c42 100644
--- a/src/google/protobuf/stubs/structurally_valid_unittest.cc
+++ b/src/google/protobuf/stubs/structurally_valid_unittest.cc
@@ -43,7 +43,8 @@
   // On GCC, this string can be written as:
   //   "abcd 1234 - \u2014\u2013\u2212"
   // MSVC seems to interpret \u differently.
-  string valid_str("abcd 1234 - \342\200\224\342\200\223\342\210\222 - xyz789");
+  std::string valid_str(
+      "abcd 1234 - \342\200\224\342\200\223\342\210\222 - xyz789");
   EXPECT_TRUE(IsStructurallyValidUTF8(valid_str.data(),
                                       valid_str.size()));
   // Additional check for pointer alignment
@@ -54,7 +55,7 @@
 }
 
 TEST(StructurallyValidTest, InvalidUTF8String) {
-  const string invalid_str("abcd\xA0\xB0\xA0\xB0\xA0\xB0 - xyz789");
+  const std::string invalid_str("abcd\xA0\xB0\xA0\xB0\xA0\xB0 - xyz789");
   EXPECT_FALSE(IsStructurallyValidUTF8(invalid_str.data(),
                                        invalid_str.size()));
   // Additional check for pointer alignment
diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc
index 2722594..2ecdb2b 100644
--- a/src/google/protobuf/stubs/strutil.cc
+++ b/src/google/protobuf/stubs/strutil.cc
@@ -84,7 +84,7 @@
 //    Replaces any occurrence of the character 'remove' (or the characters
 //    in 'remove') with the character 'replacewith'.
 // ----------------------------------------------------------------------
-void ReplaceCharacters(string *s, const char *remove, char replacewith) {
+void ReplaceCharacters(std::string *s, const char *remove, char replacewith) {
   const char *str_start = s->c_str();
   const char *str = str_start;
   for (str = strpbrk(str, remove);
@@ -94,7 +94,7 @@
   }
 }
 
-void StripWhitespace(string* str) {
+void StripWhitespace(std::string *str) {
   int str_length = str->length();
 
   // Strip off leading whitespace.
@@ -118,7 +118,7 @@
     --last;
   }
   if (last != (str_length - 1) && last >= 0) {
-    str->erase(last + 1, string::npos);
+    str->erase(last + 1, std::string::npos);
   }
 }
 
@@ -129,19 +129,19 @@
 //    it only replaces the first instance of "old."
 // ----------------------------------------------------------------------
 
-void StringReplace(const string& s, const string& oldsub,
-                   const string& newsub, bool replace_all,
-                   string* res) {
+void StringReplace(const std::string &s, const std::string &oldsub,
+                   const std::string &newsub, bool replace_all,
+                   std::string *res) {
   if (oldsub.empty()) {
     res->append(s);  // if empty, append the given string.
     return;
   }
 
-  string::size_type start_pos = 0;
-  string::size_type pos;
+  std::string::size_type start_pos = 0;
+  std::string::size_type pos;
   do {
     pos = s.find(oldsub, start_pos);
-    if (pos == string::npos) {
+    if (pos == std::string::npos) {
       break;
     }
     res->append(s, start_pos, pos - start_pos);
@@ -160,9 +160,9 @@
 //    happened or not.
 // ----------------------------------------------------------------------
 
-string StringReplace(const string& s, const string& oldsub,
-                     const string& newsub, bool replace_all) {
-  string ret;
+std::string StringReplace(const std::string &s, const std::string &oldsub,
+                          const std::string &newsub, bool replace_all) {
+  std::string ret;
   StringReplace(s, oldsub, newsub, replace_all, &ret);
   return ret;
 }
@@ -195,11 +195,11 @@
     return;
   }
 
-  string::size_type begin_index, end_index;
+  std::string::size_type begin_index, end_index;
   begin_index = full.find_first_not_of(delim);
-  while (begin_index != string::npos) {
+  while (begin_index != std::string::npos) {
     end_index = full.find_first_of(delim, begin_index);
-    if (end_index == string::npos) {
+    if (end_index == std::string::npos) {
       *result++ = std::string(full.substr(begin_index));
       return;
     }
@@ -210,8 +210,8 @@
 }
 
 void SplitStringUsing(StringPiece full, const char *delim,
-                      std::vector<string> *result) {
-  std::back_insert_iterator< std::vector<string> > it(*result);
+                      std::vector<std::string> *result) {
+  std::back_insert_iterator<std::vector<std::string> > it(*result);
   SplitStringToIteratorUsing(full, delim, it);
 }
 
@@ -230,12 +230,12 @@
 static inline void SplitStringToIteratorAllowEmpty(StringPiece full,
                                                    const char *delim,
                                                    int pieces, ITR &result) {
-  string::size_type begin_index, end_index;
+  std::string::size_type begin_index, end_index;
   begin_index = 0;
 
   for (int i = 0; (i < pieces-1) || (pieces == 0); i++) {
     end_index = full.find_first_of(delim, begin_index);
-    if (end_index == string::npos) {
+    if (end_index == std::string::npos) {
       *result++ = std::string(full.substr(begin_index));
       return;
     }
@@ -247,8 +247,8 @@
 }
 
 void SplitStringAllowEmpty(StringPiece full, const char *delim,
-                           std::vector<string> *result) {
-  std::back_insert_iterator<std::vector<string> > it(*result);
+                           std::vector<std::string> *result) {
+  std::back_insert_iterator<std::vector<std::string> > it(*result);
   SplitStringToIteratorAllowEmpty(full, delim, 0, it);
 }
 
@@ -259,10 +259,8 @@
 //
 // ----------------------------------------------------------------------
 template <class ITERATOR>
-static void JoinStringsIterator(const ITERATOR& start,
-                                const ITERATOR& end,
-                                const char* delim,
-                                string* result) {
+static void JoinStringsIterator(const ITERATOR &start, const ITERATOR &end,
+                                const char *delim, std::string *result) {
   GOOGLE_CHECK(result != nullptr);
   result->clear();
   int delim_length = strlen(delim);
@@ -286,9 +284,8 @@
   }
 }
 
-void JoinStrings(const std::vector<string>& components,
-                 const char* delim,
-                 string * result) {
+void JoinStrings(const std::vector<std::string> &components, const char *delim,
+                 std::string *result) {
   JoinStringsIterator(components.begin(), components.end(), delim, result);
 }
 
@@ -314,8 +311,8 @@
   return UnescapeCEscapeSequences(source, dest, nullptr);
 }
 
-int UnescapeCEscapeSequences(const char* source, char* dest,
-                             std::vector<string> *errors) {
+int UnescapeCEscapeSequences(const char *source, char *dest,
+                             std::vector<std::string> *errors) {
   GOOGLE_DCHECK(errors == nullptr) << "Error reporting not implemented.";
 
   char* d = dest;
@@ -370,8 +367,10 @@
           while (isxdigit(p[1]))  // arbitrarily many hex digits
             ch = (ch << 4) + hex_digit_to_int(*++p);
           if (ch > 0xFF)
-            LOG_STRING(ERROR, errors) << "Value of " <<
-              "\\" << string(hex_start, p+1-hex_start) << " exceeds 8 bits";
+            LOG_STRING(ERROR, errors)
+                << "Value of "
+                << "\\" << std::string(hex_start, p + 1 - hex_start)
+                << " exceeds 8 bits";
           *d++ = ch;
           break;
         }
@@ -386,7 +385,7 @@
             } else {
               LOG_STRING(ERROR, errors)
                 << "\\u must be followed by 4 hex digits: \\"
-                <<  string(hex_start, p+1-hex_start);
+                <<  std::string(hex_start, p+1-hex_start);
               break;
             }
           }
@@ -405,7 +404,7 @@
               if (newrune > 0x10FFFF) {
                 LOG_STRING(ERROR, errors)
                   << "Value of \\"
-                  << string(hex_start, p + 1 - hex_start)
+                  << std::string(hex_start, p + 1 - hex_start)
                   << " exceeds Unicode limit (0x10FFFF)";
                 break;
               } else {
@@ -414,7 +413,7 @@
             } else {
               LOG_STRING(ERROR, errors)
                 << "\\U must be followed by 8 hex digits: \\"
-                <<  string(hex_start, p+1-hex_start);
+                <<  std::string(hex_start, p+1-hex_start);
               break;
             }
           }
@@ -446,12 +445,12 @@
 //    In the first and second calls, the length of dest is returned. In the
 //    the third call, the new string is returned.
 // ----------------------------------------------------------------------
-int UnescapeCEscapeString(const string& src, string* dest) {
+int UnescapeCEscapeString(const std::string &src, std::string *dest) {
   return UnescapeCEscapeString(src, dest, nullptr);
 }
 
-int UnescapeCEscapeString(const string& src, string* dest,
-                          std::vector<string> *errors) {
+int UnescapeCEscapeString(const std::string &src, std::string *dest,
+                          std::vector<std::string> *errors) {
   std::unique_ptr<char[]> unescaped(new char[src.size() + 1]);
   int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), errors);
   GOOGLE_CHECK(dest);
@@ -459,10 +458,10 @@
   return len;
 }
 
-string UnescapeCEscapeString(const string& src) {
+std::string UnescapeCEscapeString(const std::string &src) {
   std::unique_ptr<char[]> unescaped(new char[src.size() + 1]);
   int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), nullptr);
-  return string(unescaped.get(), len);
+  return std::string(unescaped.get(), len);
 }
 
 // ----------------------------------------------------------------------
@@ -559,7 +558,7 @@
 // the required space using a lookup table, and also does not do any special
 // handling for Hex or UTF-8 characters.
 // ----------------------------------------------------------------------
-void CEscapeAndAppend(StringPiece src, string* dest) {
+void CEscapeAndAppend(StringPiece src, std::string *dest) {
   size_t escaped_len = CEscapedLength(src);
   if (escaped_len == src.size()) {
     dest->append(src.data(), src.size());
@@ -593,30 +592,30 @@
   }
 }
 
-string CEscape(const string& src) {
-  string dest;
+std::string CEscape(const std::string &src) {
+  std::string dest;
   CEscapeAndAppend(src, &dest);
   return dest;
 }
 
 namespace strings {
 
-string Utf8SafeCEscape(const string& src) {
+std::string Utf8SafeCEscape(const std::string &src) {
   const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
   std::unique_ptr<char[]> dest(new char[dest_length]);
   const int len = CEscapeInternal(src.data(), src.size(),
                                   dest.get(), dest_length, false, true);
   GOOGLE_DCHECK_GE(len, 0);
-  return string(dest.get(), len);
+  return std::string(dest.get(), len);
 }
 
-string CHexEscape(const string& src) {
+std::string CHexEscape(const std::string &src) {
   const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
   std::unique_ptr<char[]> dest(new char[dest_length]);
   const int len = CEscapeInternal(src.data(), src.size(),
                                   dest.get(), dest_length, true, false);
   GOOGLE_DCHECK_GE(len, 0);
-  return string(dest.get(), len);
+  return std::string(dest.get(), len);
 }
 
 }  // namespace strings
@@ -664,8 +663,8 @@
   return static_cast<uint32>(result);
 }
 
-inline bool safe_parse_sign(string* text  /*inout*/,
-                            bool* negative_ptr  /*output*/) {
+inline bool safe_parse_sign(std::string *text /*inout*/,
+                            bool *negative_ptr /*output*/) {
   const char* start = text->data();
   const char* end = start + text->size();
 
@@ -692,9 +691,8 @@
   return true;
 }
 
-template<typename IntType>
-bool safe_parse_positive_int(
-    string text, IntType* value_p) {
+template <typename IntType>
+bool safe_parse_positive_int(std::string text, IntType *value_p) {
   int base = 10;
   IntType value = 0;
   const IntType vmax = std::numeric_limits<IntType>::max();
@@ -726,9 +724,8 @@
   return true;
 }
 
-template<typename IntType>
-bool safe_parse_negative_int(
-    const string& text, IntType* value_p) {
+template <typename IntType>
+bool safe_parse_negative_int(const std::string &text, IntType *value_p) {
   int base = 10;
   IntType value = 0;
   const IntType vmin = std::numeric_limits<IntType>::min();
@@ -767,8 +764,8 @@
   return true;
 }
 
-template<typename IntType>
-bool safe_int_internal(string text, IntType* value_p) {
+template <typename IntType>
+bool safe_int_internal(std::string text, IntType *value_p) {
   *value_p = 0;
   bool negative;
   if (!safe_parse_sign(&text, &negative)) {
@@ -781,8 +778,8 @@
   }
 }
 
-template<typename IntType>
-bool safe_uint_internal(string text, IntType* value_p) {
+template <typename IntType>
+bool safe_uint_internal(std::string text, IntType *value_p) {
   *value_p = 0;
   bool negative;
   if (!safe_parse_sign(&text, &negative) || negative) {
@@ -1116,46 +1113,46 @@
 //    Return value: string
 // ----------------------------------------------------------------------
 
-string SimpleItoa(int i) {
+std::string SimpleItoa(int i) {
   char buffer[kFastToBufferSize];
   return (sizeof(i) == 4) ?
     FastInt32ToBuffer(i, buffer) :
     FastInt64ToBuffer(i, buffer);
 }
 
-string SimpleItoa(unsigned int i) {
+std::string SimpleItoa(unsigned int i) {
   char buffer[kFastToBufferSize];
-  return string(buffer, (sizeof(i) == 4) ?
-    FastUInt32ToBufferLeft(i, buffer) :
-    FastUInt64ToBufferLeft(i, buffer));
+  return std::string(buffer, (sizeof(i) == 4)
+                                 ? FastUInt32ToBufferLeft(i, buffer)
+                                 : FastUInt64ToBufferLeft(i, buffer));
 }
 
-string SimpleItoa(long i) {
+std::string SimpleItoa(long i) {
   char buffer[kFastToBufferSize];
   return (sizeof(i) == 4) ?
     FastInt32ToBuffer(i, buffer) :
     FastInt64ToBuffer(i, buffer);
 }
 
-string SimpleItoa(unsigned long i) {
+std::string SimpleItoa(unsigned long i) {
   char buffer[kFastToBufferSize];
-  return string(buffer, (sizeof(i) == 4) ?
-    FastUInt32ToBufferLeft(i, buffer) :
-    FastUInt64ToBufferLeft(i, buffer));
+  return std::string(buffer, (sizeof(i) == 4)
+                                 ? FastUInt32ToBufferLeft(i, buffer)
+                                 : FastUInt64ToBufferLeft(i, buffer));
 }
 
-string SimpleItoa(long long i) {
+std::string SimpleItoa(long long i) {
   char buffer[kFastToBufferSize];
   return (sizeof(i) == 4) ?
     FastInt32ToBuffer(i, buffer) :
     FastInt64ToBuffer(i, buffer);
 }
 
-string SimpleItoa(unsigned long long i) {
+std::string SimpleItoa(unsigned long long i) {
   char buffer[kFastToBufferSize];
-  return string(buffer, (sizeof(i) == 4) ?
-    FastUInt32ToBufferLeft(i, buffer) :
-    FastUInt64ToBufferLeft(i, buffer));
+  return std::string(buffer, (sizeof(i) == 4)
+                                 ? FastUInt32ToBufferLeft(i, buffer)
+                                 : FastUInt64ToBufferLeft(i, buffer));
 }
 
 // ----------------------------------------------------------------------
@@ -1199,12 +1196,12 @@
 //    implementation.
 // ----------------------------------------------------------------------
 
-string SimpleDtoa(double value) {
+std::string SimpleDtoa(double value) {
   char buffer[kDoubleToBufferSize];
   return DoubleToBuffer(value, buffer);
 }
 
-string SimpleFtoa(float value) {
+std::string SimpleFtoa(float value) {
   char buffer[kFloatToBufferSize];
   return FloatToBuffer(value, buffer);
 }
@@ -1344,19 +1341,19 @@
   return *str != '\0' && *endptr == '\0';
 }
 
-bool safe_strto32(const string& str, int32* value) {
+bool safe_strto32(const std::string &str, int32 *value) {
   return safe_int_internal(str, value);
 }
 
-bool safe_strtou32(const string& str, uint32* value) {
+bool safe_strtou32(const std::string &str, uint32 *value) {
   return safe_uint_internal(str, value);
 }
 
-bool safe_strto64(const string& str, int64* value) {
+bool safe_strto64(const std::string &str, int64 *value) {
   return safe_int_internal(str, value);
 }
 
-bool safe_strtou64(const string& str, uint64* value) {
+bool safe_strtou64(const std::string &str, uint64 *value) {
   return safe_uint_internal(str, value);
 }
 
@@ -1472,8 +1469,8 @@
   return out;
 }
 
-string StrCat(const AlphaNum &a, const AlphaNum &b) {
-  string result;
+std::string StrCat(const AlphaNum &a, const AlphaNum &b) {
+  std::string result;
   result.resize(a.size() + b.size());
   char *const begin = &*result.begin();
   char *out = Append2(begin, a, b);
@@ -1481,8 +1478,8 @@
   return result;
 }
 
-string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) {
-  string result;
+std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) {
+  std::string result;
   result.resize(a.size() + b.size() + c.size());
   char *const begin = &*result.begin();
   char *out = Append2(begin, a, b);
@@ -1491,9 +1488,9 @@
   return result;
 }
 
-string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
-              const AlphaNum &d) {
-  string result;
+std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+                   const AlphaNum &d) {
+  std::string result;
   result.resize(a.size() + b.size() + c.size() + d.size());
   char *const begin = &*result.begin();
   char *out = Append4(begin, a, b, c, d);
@@ -1501,9 +1498,9 @@
   return result;
 }
 
-string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
-              const AlphaNum &d, const AlphaNum &e) {
-  string result;
+std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+                   const AlphaNum &d, const AlphaNum &e) {
+  std::string result;
   result.resize(a.size() + b.size() + c.size() + d.size() + e.size());
   char *const begin = &*result.begin();
   char *out = Append4(begin, a, b, c, d);
@@ -1512,9 +1509,9 @@
   return result;
 }
 
-string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
-              const AlphaNum &d, const AlphaNum &e, const AlphaNum &f) {
-  string result;
+std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+                   const AlphaNum &d, const AlphaNum &e, const AlphaNum &f) {
+  std::string result;
   result.resize(a.size() + b.size() + c.size() + d.size() + e.size() +
                 f.size());
   char *const begin = &*result.begin();
@@ -1524,10 +1521,10 @@
   return result;
 }
 
-string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
-              const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
-              const AlphaNum &g) {
-  string result;
+std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+                   const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
+                   const AlphaNum &g) {
+  std::string result;
   result.resize(a.size() + b.size() + c.size() + d.size() + e.size() +
                 f.size() + g.size());
   char *const begin = &*result.begin();
@@ -1538,10 +1535,10 @@
   return result;
 }
 
-string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
-              const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
-              const AlphaNum &g, const AlphaNum &h) {
-  string result;
+std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+                   const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
+                   const AlphaNum &g, const AlphaNum &h) {
+  std::string result;
   result.resize(a.size() + b.size() + c.size() + d.size() + e.size() +
                 f.size() + g.size() + h.size());
   char *const begin = &*result.begin();
@@ -1551,10 +1548,10 @@
   return result;
 }
 
-string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
-              const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
-              const AlphaNum &g, const AlphaNum &h, const AlphaNum &i) {
-  string result;
+std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+                   const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
+                   const AlphaNum &g, const AlphaNum &h, const AlphaNum &i) {
+  std::string result;
   result.resize(a.size() + b.size() + c.size() + d.size() + e.size() +
                 f.size() + g.size() + h.size() + i.size());
   char *const begin = &*result.begin();
@@ -1573,27 +1570,27 @@
     GOOGLE_DCHECK_GT(uintptr_t((src).data() - (dest).data()), \
                      uintptr_t((dest).size()))
 
-void StrAppend(string *result, const AlphaNum &a) {
+void StrAppend(std::string *result, const AlphaNum &a) {
   GOOGLE_DCHECK_NO_OVERLAP(*result, a);
   result->append(a.data(), a.size());
 }
 
-void StrAppend(string *result, const AlphaNum &a, const AlphaNum &b) {
+void StrAppend(std::string *result, const AlphaNum &a, const AlphaNum &b) {
   GOOGLE_DCHECK_NO_OVERLAP(*result, a);
   GOOGLE_DCHECK_NO_OVERLAP(*result, b);
-  string::size_type old_size = result->size();
+  std::string::size_type old_size = result->size();
   result->resize(old_size + a.size() + b.size());
   char *const begin = &*result->begin();
   char *out = Append2(begin + old_size, a, b);
   GOOGLE_DCHECK_EQ(out, begin + result->size());
 }
 
-void StrAppend(string *result,
-               const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) {
+void StrAppend(std::string *result, const AlphaNum &a, const AlphaNum &b,
+               const AlphaNum &c) {
   GOOGLE_DCHECK_NO_OVERLAP(*result, a);
   GOOGLE_DCHECK_NO_OVERLAP(*result, b);
   GOOGLE_DCHECK_NO_OVERLAP(*result, c);
-  string::size_type old_size = result->size();
+  std::string::size_type old_size = result->size();
   result->resize(old_size + a.size() + b.size() + c.size());
   char *const begin = &*result->begin();
   char *out = Append2(begin + old_size, a, b);
@@ -1601,32 +1598,29 @@
   GOOGLE_DCHECK_EQ(out, begin + result->size());
 }
 
-void StrAppend(string *result,
-               const AlphaNum &a, const AlphaNum &b,
+void StrAppend(std::string *result, const AlphaNum &a, const AlphaNum &b,
                const AlphaNum &c, const AlphaNum &d) {
   GOOGLE_DCHECK_NO_OVERLAP(*result, a);
   GOOGLE_DCHECK_NO_OVERLAP(*result, b);
   GOOGLE_DCHECK_NO_OVERLAP(*result, c);
   GOOGLE_DCHECK_NO_OVERLAP(*result, d);
-  string::size_type old_size = result->size();
+  std::string::size_type old_size = result->size();
   result->resize(old_size + a.size() + b.size() + c.size() + d.size());
   char *const begin = &*result->begin();
   char *out = Append4(begin + old_size, a, b, c, d);
   GOOGLE_DCHECK_EQ(out, begin + result->size());
 }
 
-int GlobalReplaceSubstring(const string& substring,
-                           const string& replacement,
-                           string* s) {
+int GlobalReplaceSubstring(const std::string &substring,
+                           const std::string &replacement, std::string *s) {
   GOOGLE_CHECK(s != nullptr);
   if (s->empty() || substring.empty())
     return 0;
-  string tmp;
+  std::string tmp;
   int num_replacements = 0;
   int pos = 0;
   for (int match_pos = s->find(substring.data(), pos, substring.length());
-       match_pos != string::npos;
-       pos = match_pos + substring.length(),
+       match_pos != std::string::npos; pos = match_pos + substring.length(),
            match_pos = s->find(substring.data(), pos, substring.length())) {
     ++num_replacements;
     // Append the original content before the match.
@@ -2057,8 +2051,8 @@
   return Base64UnescapeInternal(src, szsrc, dest, szdest, kUnWebSafeBase64);
 }
 
-static bool Base64UnescapeInternal(const char* src, int slen, string* dest,
-                                   const signed char* unbase64) {
+static bool Base64UnescapeInternal(const char *src, int slen, std::string *dest,
+                                   const signed char *unbase64) {
   // Determine the size of the output string.  Base64 encodes every 3 bytes into
   // 4 characters.  any leftover chars are added directly for good measure.
   // This is documented in the base64 RFC: http://tools.ietf.org/html/rfc3548
@@ -2082,11 +2076,11 @@
   return true;
 }
 
-bool Base64Unescape(StringPiece src, string* dest) {
+bool Base64Unescape(StringPiece src, std::string *dest) {
   return Base64UnescapeInternal(src.data(), src.size(), dest, kUnBase64);
 }
 
-bool WebSafeBase64Unescape(StringPiece src, string* dest) {
+bool WebSafeBase64Unescape(StringPiece src, std::string *dest) {
   return Base64UnescapeInternal(src.data(), src.size(), dest, kUnWebSafeBase64);
 }
 
@@ -2205,9 +2199,9 @@
                               kWebSafeBase64Chars, do_padding);
 }
 
-void Base64EscapeInternal(const unsigned char* src, int szsrc,
-                          string* dest, bool do_padding,
-                          const char* base64_chars) {
+void Base64EscapeInternal(const unsigned char *src, int szsrc,
+                          std::string *dest, bool do_padding,
+                          const char *base64_chars) {
   const int calc_escaped_size =
     CalculateBase64EscapedLen(szsrc, do_padding);
   dest->resize(calc_escaped_size);
@@ -2220,27 +2214,27 @@
   dest->erase(escaped_len);
 }
 
-void Base64Escape(const unsigned char *src, int szsrc,
-                  string* dest, bool do_padding) {
+void Base64Escape(const unsigned char *src, int szsrc, std::string *dest,
+                  bool do_padding) {
   Base64EscapeInternal(src, szsrc, dest, do_padding, kBase64Chars);
 }
 
-void WebSafeBase64Escape(const unsigned char *src, int szsrc,
-                         string *dest, bool do_padding) {
+void WebSafeBase64Escape(const unsigned char *src, int szsrc, std::string *dest,
+                         bool do_padding) {
   Base64EscapeInternal(src, szsrc, dest, do_padding, kWebSafeBase64Chars);
 }
 
-void Base64Escape(StringPiece src, string* dest) {
+void Base64Escape(StringPiece src, std::string *dest) {
   Base64Escape(reinterpret_cast<const unsigned char*>(src.data()),
                src.size(), dest, true);
 }
 
-void WebSafeBase64Escape(StringPiece src, string* dest) {
+void WebSafeBase64Escape(StringPiece src, std::string *dest) {
   WebSafeBase64Escape(reinterpret_cast<const unsigned char*>(src.data()),
                       src.size(), dest, false);
 }
 
-void WebSafeBase64EscapeWithPadding(StringPiece src, string* dest) {
+void WebSafeBase64EscapeWithPadding(StringPiece src, std::string *dest) {
   WebSafeBase64Escape(reinterpret_cast<const unsigned char*>(src.data()),
                       src.size(), dest, true);
 }
@@ -2336,19 +2330,19 @@
 //       (1) determines the presence of LF (first one is ok)
 //       (2) if yes, removes any CR, else convert every CR to LF
 
-void CleanStringLineEndings(const string &src, string *dst,
+void CleanStringLineEndings(const std::string &src, std::string *dst,
                             bool auto_end_last_line) {
   if (dst->empty()) {
     dst->append(src);
     CleanStringLineEndings(dst, auto_end_last_line);
   } else {
-    string tmp = src;
+    std::string tmp = src;
     CleanStringLineEndings(&tmp, auto_end_last_line);
     dst->append(tmp);
   }
 }
 
-void CleanStringLineEndings(string *str, bool auto_end_last_line) {
+void CleanStringLineEndings(std::string *str, bool auto_end_last_line) {
   ptrdiff_t output_pos = 0;
   bool r_seen = false;
   ptrdiff_t len = str->size();
@@ -2379,7 +2373,7 @@
         continue;
       }
     }
-    string::const_reference in = p[input_pos];
+    std::string::const_reference in = p[input_pos];
     if (in == '\r') {
       if (r_seen) p[output_pos++] = '\n';
       r_seen = true;
diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h
index c070a05..8ce81f2 100644
--- a/src/google/protobuf/stubs/strutil.h
+++ b/src/google/protobuf/stubs/strutil.h
@@ -118,7 +118,8 @@
          memcmp(str.data(), prefix.data(), prefix.size()) == 0;
 }
 
-inline string StripPrefixString(const string& str, const string& prefix) {
+inline std::string StripPrefixString(const std::string& str,
+                                     const std::string& prefix) {
   if (HasPrefixString(str, prefix)) {
     return str.substr(prefix.size());
   } else {
@@ -140,7 +141,8 @@
                 suffix.size()) == 0;
 }
 
-inline string StripSuffixString(const string& str, const string& suffix) {
+inline std::string StripSuffixString(const std::string& str,
+                                     const std::string& suffix) {
   if (HasSuffixString(str, suffix)) {
     return str.substr(0, str.size() - suffix.size());
   } else {
@@ -157,10 +159,10 @@
 // StripWhitespace
 //    Removes whitespaces from both ends of the given string.
 // ----------------------------------------------------------------------
-PROTOBUF_EXPORT void ReplaceCharacters(string* s, const char* remove,
+PROTOBUF_EXPORT void ReplaceCharacters(std::string* s, const char* remove,
                                        char replacewith);
 
-PROTOBUF_EXPORT void StripWhitespace(string* s);
+PROTOBUF_EXPORT void StripWhitespace(std::string* s);
 
 // ----------------------------------------------------------------------
 // LowerString()
@@ -172,26 +174,26 @@
 //    strings.
 // ----------------------------------------------------------------------
 
-inline void LowerString(string * s) {
-  string::iterator end = s->end();
-  for (string::iterator i = s->begin(); i != end; ++i) {
+inline void LowerString(std::string* s) {
+  std::string::iterator end = s->end();
+  for (std::string::iterator i = s->begin(); i != end; ++i) {
     // tolower() changes based on locale.  We don't want this!
     if ('A' <= *i && *i <= 'Z') *i += 'a' - 'A';
   }
 }
 
-inline void UpperString(string * s) {
-  string::iterator end = s->end();
-  for (string::iterator i = s->begin(); i != end; ++i) {
+inline void UpperString(std::string* s) {
+  std::string::iterator end = s->end();
+  for (std::string::iterator i = s->begin(); i != end; ++i) {
     // toupper() changes based on locale.  We don't want this!
     if ('a' <= *i && *i <= 'z') *i += 'A' - 'a';
   }
 }
 
-inline void ToUpper(string* s) { UpperString(s); }
+inline void ToUpper(std::string* s) { UpperString(s); }
 
-inline string ToUpper(const string& s) {
-  string out = s;
+inline std::string ToUpper(const std::string& s) {
+  std::string out = s;
   UpperString(&out);
   return out;
 }
@@ -204,8 +206,10 @@
 //    happened or not.
 // ----------------------------------------------------------------------
 
-PROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub,
-                                     const string& newsub, bool replace_all);
+PROTOBUF_EXPORT std::string StringReplace(const std::string& s,
+                                          const std::string& oldsub,
+                                          const std::string& newsub,
+                                          bool replace_all);
 
 // ----------------------------------------------------------------------
 // SplitStringUsing()
@@ -214,7 +218,7 @@
 //    over all of them.
 // ----------------------------------------------------------------------
 PROTOBUF_EXPORT void SplitStringUsing(StringPiece full, const char* delim,
-                                      std::vector<string>* res);
+                                      std::vector<std::string>* res);
 
 // Split a string using one or more byte delimiters, presented
 // as a nul-terminated c string. Append the components to 'result'.
@@ -225,15 +229,15 @@
 // If "full" is the empty string, yields an empty string as the only value.
 // ----------------------------------------------------------------------
 PROTOBUF_EXPORT void SplitStringAllowEmpty(StringPiece full, const char* delim,
-                                           std::vector<string>* result);
+                                           std::vector<std::string>* result);
 
 // ----------------------------------------------------------------------
 // Split()
 //    Split a string using a character delimiter.
 // ----------------------------------------------------------------------
-inline std::vector<string> Split(StringPiece full, const char* delim,
-                                 bool skip_empty = true) {
-  std::vector<string> result;
+inline std::vector<std::string> Split(StringPiece full, const char* delim,
+                                      bool skip_empty = true) {
+  std::vector<std::string> result;
   if (skip_empty) {
     SplitStringUsing(full, delim, &result);
   } else {
@@ -250,12 +254,12 @@
 //    another takes a pointer to the target string. In the latter case the
 //    target string is cleared and overwritten.
 // ----------------------------------------------------------------------
-PROTOBUF_EXPORT void JoinStrings(const std::vector<string>& components,
-                                 const char* delim, string* result);
+PROTOBUF_EXPORT void JoinStrings(const std::vector<std::string>& components,
+                                 const char* delim, std::string* result);
 
-inline string JoinStrings(const std::vector<string>& components,
-                          const char* delim) {
-  string result;
+inline std::string JoinStrings(const std::vector<std::string>& components,
+                               const char* delim) {
+  std::string result;
   JoinStrings(components, delim, &result);
   return result;
 }
@@ -293,7 +297,7 @@
 
 PROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest);
 PROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest,
-                                             std::vector<string>* errors);
+                                             std::vector<std::string>* errors);
 
 // ----------------------------------------------------------------------
 // UnescapeCEscapeString()
@@ -310,10 +314,12 @@
 //    the third call, the new string is returned.
 // ----------------------------------------------------------------------
 
-PROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest);
-PROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest,
-                                          std::vector<string>* errors);
-PROTOBUF_EXPORT string UnescapeCEscapeString(const string& src);
+PROTOBUF_EXPORT int UnescapeCEscapeString(const std::string& src,
+                                          std::string* dest);
+PROTOBUF_EXPORT int UnescapeCEscapeString(const std::string& src,
+                                          std::string* dest,
+                                          std::vector<std::string>* errors);
+PROTOBUF_EXPORT std::string UnescapeCEscapeString(const std::string& src);
 
 // ----------------------------------------------------------------------
 // CEscape()
@@ -322,21 +328,21 @@
 //
 //    Escaped chars: \n, \r, \t, ", ', \, and !isprint().
 // ----------------------------------------------------------------------
-PROTOBUF_EXPORT string CEscape(const string& src);
+PROTOBUF_EXPORT std::string CEscape(const std::string& src);
 
 // ----------------------------------------------------------------------
 // CEscapeAndAppend()
 //    Escapes 'src' using C-style escape sequences, and appends the escaped
 //    string to 'dest'.
 // ----------------------------------------------------------------------
-PROTOBUF_EXPORT void CEscapeAndAppend(StringPiece src, string* dest);
+PROTOBUF_EXPORT void CEscapeAndAppend(StringPiece src, std::string* dest);
 
 namespace strings {
 // Like CEscape() but does not escape bytes with the upper bit set.
-PROTOBUF_EXPORT string Utf8SafeCEscape(const string& src);
+PROTOBUF_EXPORT std::string Utf8SafeCEscape(const std::string& src);
 
 // Like CEscape() but uses hex (\x) escapes instead of octals.
-PROTOBUF_EXPORT string CHexEscape(const string& src);
+PROTOBUF_EXPORT std::string CHexEscape(const std::string& src);
 }  // namespace strings
 
 // ----------------------------------------------------------------------
@@ -393,31 +399,31 @@
 // ----------------------------------------------------------------------
 PROTOBUF_EXPORT bool safe_strtob(StringPiece str, bool* value);
 
-PROTOBUF_EXPORT bool safe_strto32(const string& str, int32* value);
-PROTOBUF_EXPORT bool safe_strtou32(const string& str, uint32* value);
+PROTOBUF_EXPORT bool safe_strto32(const std::string& str, int32* value);
+PROTOBUF_EXPORT bool safe_strtou32(const std::string& str, uint32* value);
 inline bool safe_strto32(const char* str, int32* value) {
-  return safe_strto32(string(str), value);
+  return safe_strto32(std::string(str), value);
 }
 inline bool safe_strto32(StringPiece str, int32* value) {
   return safe_strto32(str.ToString(), value);
 }
 inline bool safe_strtou32(const char* str, uint32* value) {
-  return safe_strtou32(string(str), value);
+  return safe_strtou32(std::string(str), value);
 }
 inline bool safe_strtou32(StringPiece str, uint32* value) {
   return safe_strtou32(str.ToString(), value);
 }
 
-PROTOBUF_EXPORT bool safe_strto64(const string& str, int64* value);
-PROTOBUF_EXPORT bool safe_strtou64(const string& str, uint64* value);
+PROTOBUF_EXPORT bool safe_strto64(const std::string& str, int64* value);
+PROTOBUF_EXPORT bool safe_strtou64(const std::string& str, uint64* value);
 inline bool safe_strto64(const char* str, int64* value) {
-  return safe_strto64(string(str), value);
+  return safe_strto64(std::string(str), value);
 }
 inline bool safe_strto64(StringPiece str, int64* value) {
   return safe_strto64(str.ToString(), value);
 }
 inline bool safe_strtou64(const char* str, uint64* value) {
-  return safe_strtou64(string(str), value);
+  return safe_strtou64(std::string(str), value);
 }
 inline bool safe_strtou64(StringPiece str, uint64* value) {
   return safe_strtou64(str.ToString(), value);
@@ -425,10 +431,10 @@
 
 PROTOBUF_EXPORT bool safe_strtof(const char* str, float* value);
 PROTOBUF_EXPORT bool safe_strtod(const char* str, double* value);
-inline bool safe_strtof(const string& str, float* value) {
+inline bool safe_strtof(const std::string& str, float* value) {
   return safe_strtof(str.c_str(), value);
 }
-inline bool safe_strtod(const string& str, double* value) {
+inline bool safe_strtod(const std::string& str, double* value) {
   return safe_strtod(str.c_str(), value);
 }
 inline bool safe_strtof(StringPiece str, float* value) {
@@ -521,9 +527,7 @@
   return buffer;
 }
 
-inline string SimpleBtoa(bool value) {
-  return value ? "true" : "false";
-}
+inline std::string SimpleBtoa(bool value) { return value ? "true" : "false"; }
 
 // ----------------------------------------------------------------------
 // SimpleItoa()
@@ -531,12 +535,12 @@
 //
 //    Return value: string
 // ----------------------------------------------------------------------
-PROTOBUF_EXPORT string SimpleItoa(int i);
-PROTOBUF_EXPORT string SimpleItoa(unsigned int i);
-PROTOBUF_EXPORT string SimpleItoa(long i);
-PROTOBUF_EXPORT string SimpleItoa(unsigned long i);
-PROTOBUF_EXPORT string SimpleItoa(long long i);
-PROTOBUF_EXPORT string SimpleItoa(unsigned long long i);
+PROTOBUF_EXPORT std::string SimpleItoa(int i);
+PROTOBUF_EXPORT std::string SimpleItoa(unsigned int i);
+PROTOBUF_EXPORT std::string SimpleItoa(long i);
+PROTOBUF_EXPORT std::string SimpleItoa(unsigned long i);
+PROTOBUF_EXPORT std::string SimpleItoa(long long i);
+PROTOBUF_EXPORT std::string SimpleItoa(unsigned long long i);
 
 // ----------------------------------------------------------------------
 // SimpleDtoa()
@@ -557,8 +561,8 @@
 //
 //    Return value: string
 // ----------------------------------------------------------------------
-PROTOBUF_EXPORT string SimpleDtoa(double value);
-PROTOBUF_EXPORT string SimpleFtoa(float value);
+PROTOBUF_EXPORT std::string SimpleDtoa(double value);
+PROTOBUF_EXPORT std::string SimpleFtoa(float value);
 
 PROTOBUF_EXPORT char* DoubleToBuffer(double i, char* buffer);
 PROTOBUF_EXPORT char* FloatToBuffer(float i, char* buffer);
@@ -654,7 +658,7 @@
   // TODO: Add a string_ref constructor, eventually
   // AlphaNum(const StringPiece &pc) : piece(pc) {}
 
-  AlphaNum(const string& str)
+  AlphaNum(const std::string& str)
       : piece_data_(str.data()), piece_size_(str.size()) {}
 
   AlphaNum(StringPiece str)
@@ -702,32 +706,34 @@
 //    be a reference into str.
 // ----------------------------------------------------------------------
 
-PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b);
-PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b,
-                              const AlphaNum& c);
-PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b,
-                              const AlphaNum& c, const AlphaNum& d);
-PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b,
-                              const AlphaNum& c, const AlphaNum& d,
-                              const AlphaNum& e);
-PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b,
-                              const AlphaNum& c, const AlphaNum& d,
-                              const AlphaNum& e, const AlphaNum& f);
-PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b,
-                              const AlphaNum& c, const AlphaNum& d,
-                              const AlphaNum& e, const AlphaNum& f,
-                              const AlphaNum& g);
-PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b,
-                              const AlphaNum& c, const AlphaNum& d,
-                              const AlphaNum& e, const AlphaNum& f,
-                              const AlphaNum& g, const AlphaNum& h);
-PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b,
-                              const AlphaNum& c, const AlphaNum& d,
-                              const AlphaNum& e, const AlphaNum& f,
-                              const AlphaNum& g, const AlphaNum& h,
-                              const AlphaNum& i);
+PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b);
+PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b,
+                                   const AlphaNum& c);
+PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b,
+                                   const AlphaNum& c, const AlphaNum& d);
+PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b,
+                                   const AlphaNum& c, const AlphaNum& d,
+                                   const AlphaNum& e);
+PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b,
+                                   const AlphaNum& c, const AlphaNum& d,
+                                   const AlphaNum& e, const AlphaNum& f);
+PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b,
+                                   const AlphaNum& c, const AlphaNum& d,
+                                   const AlphaNum& e, const AlphaNum& f,
+                                   const AlphaNum& g);
+PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b,
+                                   const AlphaNum& c, const AlphaNum& d,
+                                   const AlphaNum& e, const AlphaNum& f,
+                                   const AlphaNum& g, const AlphaNum& h);
+PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b,
+                                   const AlphaNum& c, const AlphaNum& d,
+                                   const AlphaNum& e, const AlphaNum& f,
+                                   const AlphaNum& g, const AlphaNum& h,
+                                   const AlphaNum& i);
 
-inline string StrCat(const AlphaNum& a) { return string(a.data(), a.size()); }
+inline std::string StrCat(const AlphaNum& a) {
+  return std::string(a.data(), a.size());
+}
 
 // ----------------------------------------------------------------------
 // StrAppend()
@@ -750,12 +756,12 @@
 //    worked around as consecutive calls to StrAppend are quite efficient.
 // ----------------------------------------------------------------------
 
-PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a);
-PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a,
+PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a);
+PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a,
                                const AlphaNum& b);
-PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a,
+PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a,
                                const AlphaNum& b, const AlphaNum& c);
-PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a,
+PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a,
                                const AlphaNum& b, const AlphaNum& c,
                                const AlphaNum& d);
 
@@ -765,8 +771,8 @@
 //    the C-string "delim" as a separator between components.
 // ----------------------------------------------------------------------
 template <typename Iterator>
-void Join(Iterator start, Iterator end,
-          const char* delim, string* result) {
+void Join(Iterator start, Iterator end, const char* delim,
+          std::string* result) {
   for (Iterator it = start; it != end; ++it) {
     if (it != start) {
       result->append(delim);
@@ -776,9 +782,8 @@
 }
 
 template <typename Range>
-string Join(const Range& components,
-            const char* delim) {
-  string result;
+std::string Join(const Range& components, const char* delim) {
+  std::string result;
   Join(components.begin(), components.end(), delim, &result);
   return result;
 }
@@ -787,7 +792,7 @@
 // ToHex()
 //    Return a lower-case hex string representation of the given integer.
 // ----------------------------------------------------------------------
-PROTOBUF_EXPORT string ToHex(uint64 num);
+PROTOBUF_EXPORT std::string ToHex(uint64 num);
 
 // ----------------------------------------------------------------------
 // GlobalReplaceSubstring()
@@ -796,9 +801,9 @@
 //
 //    NOTE: The string pieces must not overlap s.
 // ----------------------------------------------------------------------
-PROTOBUF_EXPORT int GlobalReplaceSubstring(const string& substring,
-                                           const string& replacement,
-                                           string* s);
+PROTOBUF_EXPORT int GlobalReplaceSubstring(const std::string& substring,
+                                           const std::string& replacement,
+                                           std::string* s);
 
 // ----------------------------------------------------------------------
 // Base64Unescape()
@@ -806,7 +811,7 @@
 //    writes it to "dest". If src contains invalid characters, dest is cleared
 //    and the function returns false. Returns true on success.
 // ----------------------------------------------------------------------
-PROTOBUF_EXPORT bool Base64Unescape(StringPiece src, string* dest);
+PROTOBUF_EXPORT bool Base64Unescape(StringPiece src, std::string* dest);
 
 // ----------------------------------------------------------------------
 // WebSafeBase64Unescape()
@@ -821,7 +826,7 @@
 // ----------------------------------------------------------------------
 PROTOBUF_EXPORT int WebSafeBase64Unescape(const char* src, int slen, char* dest,
                                           int szdest);
-PROTOBUF_EXPORT bool WebSafeBase64Unescape(StringPiece src, string* dest);
+PROTOBUF_EXPORT bool WebSafeBase64Unescape(StringPiece src, std::string* dest);
 
 // Return the length to use for the output buffer given to the base64 escape
 // routines. Make sure to use the same value for do_padding in both.
@@ -849,17 +854,17 @@
                                         char* dest, int szdest,
                                         bool do_padding);
 // Encode src into dest with padding.
-PROTOBUF_EXPORT void Base64Escape(StringPiece src, string* dest);
+PROTOBUF_EXPORT void Base64Escape(StringPiece src, std::string* dest);
 // Encode src into dest web-safely without padding.
-PROTOBUF_EXPORT void WebSafeBase64Escape(StringPiece src, string* dest);
+PROTOBUF_EXPORT void WebSafeBase64Escape(StringPiece src, std::string* dest);
 // Encode src into dest web-safely with padding.
 PROTOBUF_EXPORT void WebSafeBase64EscapeWithPadding(StringPiece src,
-                                                    string* dest);
+                                                    std::string* dest);
 
 PROTOBUF_EXPORT void Base64Escape(const unsigned char* src, int szsrc,
-                                  string* dest, bool do_padding);
+                                  std::string* dest, bool do_padding);
 PROTOBUF_EXPORT void WebSafeBase64Escape(const unsigned char* src, int szsrc,
-                                         string* dest, bool do_padding);
+                                         std::string* dest, bool do_padding);
 
 inline bool IsValidCodePoint(uint32 code_point) {
   return code_point < 0xD800 ||
@@ -915,11 +920,12 @@
 //
 //       (1) determines the presence of LF (first one is ok)
 //       (2) if yes, removes any CR, else convert every CR to LF
-PROTOBUF_EXPORT void CleanStringLineEndings(const string& src, string* dst,
+PROTOBUF_EXPORT void CleanStringLineEndings(const std::string& src,
+                                            std::string* dst,
                                             bool auto_end_last_line);
 
 // Same as above, but transforms the argument in place.
-PROTOBUF_EXPORT void CleanStringLineEndings(string* str,
+PROTOBUF_EXPORT void CleanStringLineEndings(std::string* str,
                                             bool auto_end_last_line);
 
 namespace strings {
diff --git a/src/google/protobuf/stubs/strutil_unittest.cc b/src/google/protobuf/stubs/strutil_unittest.cc
index 141d263..fc9a63f 100644
--- a/src/google/protobuf/stubs/strutil_unittest.cc
+++ b/src/google/protobuf/stubs/strutil_unittest.cc
@@ -52,7 +52,7 @@
   // Remember the old locale.
   char* old_locale_cstr = setlocale(LC_NUMERIC, nullptr);
   ASSERT_TRUE(old_locale_cstr != nullptr);
-  string old_locale = old_locale_cstr;
+  std::string old_locale = old_locale_cstr;
 
   // Set the locale to "C".
   ASSERT_TRUE(setlocale(LC_NUMERIC, "C") != nullptr);
@@ -442,7 +442,7 @@
     char decode_buffer[100];
     int decode_length;
     int cypher_length;
-    string decode_str;
+    std::string decode_str;
 
     const unsigned char* unsigned_plaintext =
       reinterpret_cast<const unsigned char*>(base64_tests[i].plaintext);
@@ -491,13 +491,13 @@
     EXPECT_EQ(plaintext, decode_str);
 
     // Let's try with a pre-populated string.
-    string encoded("this junk should be ignored");
-    Base64Escape(string(base64_tests[i].plaintext,
-                        base64_tests[i].plain_length),
-                 &encoded);
-    EXPECT_EQ(encoded, string(encode_buffer, cypher_length));
+    std::string encoded("this junk should be ignored");
+    Base64Escape(
+        std::string(base64_tests[i].plaintext, base64_tests[i].plain_length),
+        &encoded);
+    EXPECT_EQ(encoded, std::string(encode_buffer, cypher_length));
 
-    string decoded("this junk should be ignored");
+    std::string decoded("this junk should be ignored");
     EXPECT_TRUE(Base64Unescape(
         StringPiece(encode_buffer, cypher_length), &decoded));
     EXPECT_EQ(decoded.size(), base64_tests[i].plain_length);
@@ -514,7 +514,7 @@
 
       // Try chopping off the equals sign(s) entirely.  The decoder
       // should still be okay with this.
-      string decoded2("this junk should also be ignored");
+      std::string decoded2("this junk should also be ignored");
       *first_equals = '\0';
       EXPECT_TRUE(Base64Unescape(
           StringPiece(encode_buffer, first_equals - encode_buffer), &decoded2));
@@ -730,7 +730,7 @@
     EXPECT_STREQ(encode_buffer, websafe);
 
     // Let's try the (other) string version of the encoder
-    string plain(base64_tests[i].plaintext, base64_tests[i].plain_length);
+    std::string plain(base64_tests[i].plaintext, base64_tests[i].plain_length);
     encoded = "this junk should be ignored";
     WebSafeBase64Escape(plain, &encoded);
     EXPECT_EQ(encoded.size(), cypher_length);
@@ -798,7 +798,7 @@
   // Verify the behavior when decoding bad data
   {
     const char* bad_data = "ab-/";
-    string buf;
+    std::string buf;
     EXPECT_FALSE(Base64Unescape(StringPiece(bad_data), &buf));
     EXPECT_TRUE(!WebSafeBase64Unescape(bad_data, &buf));
     EXPECT_TRUE(buf.empty());
@@ -819,7 +819,7 @@
   const size_t size = 10;
   const intptr_t intptr = -12;
   const uintptr_t uintptr = 13;
-  string answer;
+  std::string answer;
   answer = StrCat(s, us);
   EXPECT_EQ(answer, "-12");
   answer = StrCat(i, ui);
@@ -836,12 +836,13 @@
   EXPECT_EQ(answer, "130");
 }
 
-class ReplaceChars : public ::testing::TestWithParam<
-                         std::tuple<string, string, const char*, char>> {};
+class ReplaceChars
+    : public ::testing::TestWithParam<
+          std::tuple<std::string, std::string, const char*, char>> {};
 
 TEST_P(ReplaceChars, ReplacesAllOccurencesOfAnyCharInReplaceWithAReplaceChar) {
-  string expected = std::get<0>(GetParam());
-  string string_to_replace_in = std::get<1>(GetParam());
+  std::string expected = std::get<0>(GetParam());
+  std::string string_to_replace_in = std::get<1>(GetParam());
   const char* what_to_replace = std::get<2>(GetParam());
   char replacement = std::get<3>(GetParam());
   ReplaceCharacters(&string_to_replace_in, what_to_replace, replacement);
@@ -864,11 +865,12 @@
         std::make_tuple("qvvvvvng v T", "queueing a T", "aeiou",
                         'v')));  // replace all voewls
 
-class StripWs : public ::testing::TestWithParam<std::tuple<string, string>> {};
+class StripWs
+    : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {};
 
 TEST_P(StripWs, AlwaysStripsLeadingAndTrailingWhitespace) {
-  string expected = std::get<0>(GetParam());
-  string string_to_strip = std::get<1>(GetParam());
+  std::string expected = std::get<0>(GetParam());
+  std::string string_to_strip = std::get<1>(GetParam());
   StripWhitespace(&string_to_strip);
   ASSERT_EQ(expected, string_to_strip);
 }
diff --git a/src/google/protobuf/stubs/substitute.cc b/src/google/protobuf/stubs/substitute.cc
index a36f2f0..9210741 100644
--- a/src/google/protobuf/stubs/substitute.cc
+++ b/src/google/protobuf/stubs/substitute.cc
@@ -52,26 +52,24 @@
   return count;
 }
 
-string Substitute(
-    const char* format,
-    const SubstituteArg& arg0, const SubstituteArg& arg1,
-    const SubstituteArg& arg2, const SubstituteArg& arg3,
-    const SubstituteArg& arg4, const SubstituteArg& arg5,
-    const SubstituteArg& arg6, const SubstituteArg& arg7,
-    const SubstituteArg& arg8, const SubstituteArg& arg9) {
-  string result;
+std::string Substitute(const char* format, const SubstituteArg& arg0,
+                       const SubstituteArg& arg1, const SubstituteArg& arg2,
+                       const SubstituteArg& arg3, const SubstituteArg& arg4,
+                       const SubstituteArg& arg5, const SubstituteArg& arg6,
+                       const SubstituteArg& arg7, const SubstituteArg& arg8,
+                       const SubstituteArg& arg9) {
+  std::string result;
   SubstituteAndAppend(&result, format, arg0, arg1, arg2, arg3, arg4,
                                        arg5, arg6, arg7, arg8, arg9);
   return result;
 }
 
-void SubstituteAndAppend(
-    string* output, const char* format,
-    const SubstituteArg& arg0, const SubstituteArg& arg1,
-    const SubstituteArg& arg2, const SubstituteArg& arg3,
-    const SubstituteArg& arg4, const SubstituteArg& arg5,
-    const SubstituteArg& arg6, const SubstituteArg& arg7,
-    const SubstituteArg& arg8, const SubstituteArg& arg9) {
+void SubstituteAndAppend(std::string* output, const char* format,
+                         const SubstituteArg& arg0, const SubstituteArg& arg1,
+                         const SubstituteArg& arg2, const SubstituteArg& arg3,
+                         const SubstituteArg& arg4, const SubstituteArg& arg5,
+                         const SubstituteArg& arg6, const SubstituteArg& arg7,
+                         const SubstituteArg& arg8, const SubstituteArg& arg9) {
   const SubstituteArg* const args_array[] = {
     &arg0, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8, &arg9, nullptr
   };
diff --git a/src/google/protobuf/stubs/substitute.h b/src/google/protobuf/stubs/substitute.h
index 267dead..d4e72e1 100644
--- a/src/google/protobuf/stubs/substitute.h
+++ b/src/google/protobuf/stubs/substitute.h
@@ -90,8 +90,8 @@
  public:
   inline SubstituteArg(const char* value)
     : text_(value), size_(strlen(text_)) {}
-  inline SubstituteArg(const string& value)
-    : text_(value.data()), size_(value.size()) {}
+  inline SubstituteArg(const std::string& value)
+      : text_(value.data()), size_(value.size()) {}
 
   // Indicates that no argument was given.
   inline explicit SubstituteArg()
@@ -139,21 +139,21 @@
 
 }  // namespace internal
 
-PROTOBUF_EXPORT string
-Substitute(const char* format,
-           const internal::SubstituteArg& arg0 = internal::SubstituteArg(),
-           const internal::SubstituteArg& arg1 = internal::SubstituteArg(),
-           const internal::SubstituteArg& arg2 = internal::SubstituteArg(),
-           const internal::SubstituteArg& arg3 = internal::SubstituteArg(),
-           const internal::SubstituteArg& arg4 = internal::SubstituteArg(),
-           const internal::SubstituteArg& arg5 = internal::SubstituteArg(),
-           const internal::SubstituteArg& arg6 = internal::SubstituteArg(),
-           const internal::SubstituteArg& arg7 = internal::SubstituteArg(),
-           const internal::SubstituteArg& arg8 = internal::SubstituteArg(),
-           const internal::SubstituteArg& arg9 = internal::SubstituteArg());
+PROTOBUF_EXPORT std::string Substitute(
+    const char* format,
+    const internal::SubstituteArg& arg0 = internal::SubstituteArg(),
+    const internal::SubstituteArg& arg1 = internal::SubstituteArg(),
+    const internal::SubstituteArg& arg2 = internal::SubstituteArg(),
+    const internal::SubstituteArg& arg3 = internal::SubstituteArg(),
+    const internal::SubstituteArg& arg4 = internal::SubstituteArg(),
+    const internal::SubstituteArg& arg5 = internal::SubstituteArg(),
+    const internal::SubstituteArg& arg6 = internal::SubstituteArg(),
+    const internal::SubstituteArg& arg7 = internal::SubstituteArg(),
+    const internal::SubstituteArg& arg8 = internal::SubstituteArg(),
+    const internal::SubstituteArg& arg9 = internal::SubstituteArg());
 
 PROTOBUF_EXPORT void SubstituteAndAppend(
-    string* output, const char* format,
+    std::string* output, const char* format,
     const internal::SubstituteArg& arg0 = internal::SubstituteArg(),
     const internal::SubstituteArg& arg1 = internal::SubstituteArg(),
     const internal::SubstituteArg& arg2 = internal::SubstituteArg(),
diff --git a/src/google/protobuf/stubs/time.cc b/src/google/protobuf/stubs/time.cc
index 64f3ceb..922be76 100644
--- a/src/google/protobuf/stubs/time.cc
+++ b/src/google/protobuf/stubs/time.cc
@@ -130,7 +130,7 @@
 
 // Format nanoseconds with either 3, 6, or 9 digits depending on the required
 // precision to represent the exact value.
-string FormatNanos(int32 nanos) {
+std::string FormatNanos(int32 nanos) {
   if (nanos % kNanosPerMillisecond == 0) {
     return StringPrintf("%03d", nanos / kNanosPerMillisecond);
   } else if (nanos % kNanosPerMicrosecond == 0) {
@@ -268,21 +268,21 @@
   *nanos = 0;
 }
 
-string FormatTime(int64 seconds, int32 nanos) {
+std::string FormatTime(int64 seconds, int32 nanos) {
   DateTime time;
   if (nanos < 0 || nanos > 999999999 || !SecondsToDateTime(seconds, &time)) {
     return "InvalidTime";
   }
-  string result = StringPrintf("%04d-%02d-%02dT%02d:%02d:%02d",
-                               time.year, time.month, time.day,
-                               time.hour, time.minute, time.second);
+  std::string result =
+      StringPrintf("%04d-%02d-%02dT%02d:%02d:%02d", time.year, time.month,
+                   time.day, time.hour, time.minute, time.second);
   if (nanos != 0) {
     result += "." + FormatNanos(nanos);
   }
   return result + "Z";
 }
 
-bool ParseTime(const string& value, int64* seconds, int32* nanos) {
+bool ParseTime(const std::string& value, int64* seconds, int32* nanos) {
   DateTime time;
   const char* data = value.c_str();
   // We only accept:
diff --git a/src/google/protobuf/stubs/time.h b/src/google/protobuf/stubs/time.h
index b52f3f9..b061176 100644
--- a/src/google/protobuf/stubs/time.h
+++ b/src/google/protobuf/stubs/time.h
@@ -65,10 +65,10 @@
 // value.
 //
 // Note that "nanos" must in the range of [0, 999999999].
-string PROTOBUF_EXPORT FormatTime(int64 seconds, int32 nanos);
+std::string PROTOBUF_EXPORT FormatTime(int64 seconds, int32 nanos);
 // Parses a time string. This method accepts RFC3339 date/time string with UTC
 // offset. For example, "2015-05-20T13:29:35.120-08:00".
-bool PROTOBUF_EXPORT ParseTime(const string& value, int64* seconds,
+bool PROTOBUF_EXPORT ParseTime(const std::string& value, int64* seconds,
                                int32* nanos);
 
 }  // namespace internal
diff --git a/src/google/protobuf/testing/file.cc b/src/google/protobuf/testing/file.cc
index 7d3708e..7b62887 100644
--- a/src/google/protobuf/testing/file.cc
+++ b/src/google/protobuf/testing/file.cc
@@ -66,11 +66,12 @@
 using google::protobuf::io::win32::stat;
 #endif
 
-bool File::Exists(const string& name) {
+bool File::Exists(const std::string& name) {
   return access(name.c_str(), F_OK) == 0;
 }
 
-bool File::ReadFileToString(const string& name, string* output, bool text_mode) {
+bool File::ReadFileToString(const std::string& name, std::string* output,
+                            bool text_mode) {
   char buffer[1024];
   FILE* file = fopen(name.c_str(), text_mode ? "rt" : "rb");
   if (file == NULL) return false;
@@ -86,11 +87,12 @@
   return error == 0;
 }
 
-void File::ReadFileToStringOrDie(const string& name, string* output) {
+void File::ReadFileToStringOrDie(const std::string& name, std::string* output) {
   GOOGLE_CHECK(ReadFileToString(name, output)) << "Could not read: " << name;
 }
 
-bool File::WriteStringToFile(const string& contents, const string& name) {
+bool File::WriteStringToFile(const std::string& contents,
+                             const std::string& name) {
   FILE* file = fopen(name.c_str(), "wb");
   if (file == NULL) {
     GOOGLE_LOG(ERROR) << "fopen(" << name << ", \"wb\"): " << strerror(errno);
@@ -109,7 +111,8 @@
   return true;
 }
 
-void File::WriteStringToFileOrDie(const string& contents, const string& name) {
+void File::WriteStringToFileOrDie(const std::string& contents,
+                                  const std::string& name) {
   FILE* file = fopen(name.c_str(), "wb");
   GOOGLE_CHECK(file != NULL)
       << "fopen(" << name << ", \"wb\"): " << strerror(errno);
@@ -120,21 +123,21 @@
       << "fclose(" << name << "): " << strerror(errno);
 }
 
-bool File::CreateDir(const string& name, int mode) {
+bool File::CreateDir(const std::string& name, int mode) {
   if (!name.empty()) {
     GOOGLE_CHECK_OK(name[name.size() - 1] != '.');
   }
   return mkdir(name.c_str(), mode) == 0;
 }
 
-bool File::RecursivelyCreateDir(const string& path, int mode) {
+bool File::RecursivelyCreateDir(const std::string& path, int mode) {
   if (CreateDir(path, mode)) return true;
 
   if (Exists(path)) return false;
 
   // Try creating the parent.
-  string::size_type slashpos = path.find_last_of('/');
-  if (slashpos == string::npos) {
+  std::string::size_type slashpos = path.find_last_of('/');
+  if (slashpos == std::string::npos) {
     // No parent given.
     return false;
   }
@@ -143,8 +146,8 @@
          CreateDir(path, mode);
 }
 
-void File::DeleteRecursively(const string& name,
-                             void* dummy1, void* dummy2) {
+void File::DeleteRecursively(const std::string& name, void* dummy1,
+                             void* dummy2) {
   if (name.empty()) return;
 
   // We don't care too much about error checking here since this is only used
@@ -162,9 +165,9 @@
   }
 
   do {
-    string entry_name = find_data.cFileName;
+    std::string entry_name = find_data.cFileName;
     if (entry_name != "." && entry_name != "..") {
-      string path = name + "/" + entry_name;
+      std::string path = name + "/" + entry_name;
       if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
         DeleteRecursively(path, NULL, NULL);
         RemoveDirectoryA(path.c_str());
@@ -188,7 +191,7 @@
       while (true) {
         struct dirent* entry = readdir(dir);
         if (entry == NULL) break;
-        string entry_name = entry->d_name;
+        std::string entry_name = entry->d_name;
         if (entry_name != "." && entry_name != "..") {
           DeleteRecursively(name + "/" + entry_name, NULL, NULL);
         }
@@ -204,7 +207,7 @@
 #endif
 }
 
-bool File::ChangeWorkingDirectory(const string& new_working_directory) {
+bool File::ChangeWorkingDirectory(const std::string& new_working_directory) {
   return chdir(new_working_directory.c_str()) == 0;
 }
 
diff --git a/src/google/protobuf/testing/file.h b/src/google/protobuf/testing/file.h
index 4598996..f18f685 100644
--- a/src/google/protobuf/testing/file.h
+++ b/src/google/protobuf/testing/file.h
@@ -46,52 +46,54 @@
 class File {
  public:
   // Check if the file exists.
-  static bool Exists(const string& name);
+  static bool Exists(const std::string& name);
 
   // Read an entire file to a string.  Return true if successful, false
   // otherwise.
-  static bool ReadFileToString(const string& name, string* output, bool text_mode = false);
+  static bool ReadFileToString(const std::string& name, std::string* output,
+                               bool text_mode = false);
 
   // Same as above, but crash on failure.
-  static void ReadFileToStringOrDie(const string& name, string* output);
+  static void ReadFileToStringOrDie(const std::string& name,
+                                    std::string* output);
 
   // Create a file and write a string to it.
-  static bool WriteStringToFile(const string& contents,
-                                const string& name);
+  static bool WriteStringToFile(const std::string& contents,
+                                const std::string& name);
 
   // Same as above, but crash on failure.
-  static void WriteStringToFileOrDie(const string& contents,
-                                     const string& name);
+  static void WriteStringToFileOrDie(const std::string& contents,
+                                     const std::string& name);
 
   // Create a directory.
-  static bool CreateDir(const string& name, int mode);
+  static bool CreateDir(const std::string& name, int mode);
 
   // Create a directory and all parent directories if necessary.
-  static bool RecursivelyCreateDir(const string& path, int mode);
+  static bool RecursivelyCreateDir(const std::string& path, int mode);
 
   // If "name" is a file, we delete it.  If it is a directory, we
   // call DeleteRecursively() for each file or directory (other than
   // dot and double-dot) within it, and then delete the directory itself.
   // The "dummy" parameters have a meaning in the original version of this
   // method but they are not used anywhere in protocol buffers.
-  static void DeleteRecursively(const string& name,
-                                void* dummy1, void* dummy2);
+  static void DeleteRecursively(const std::string& name, void* dummy1,
+                                void* dummy2);
 
   // Change working directory to given directory.
-  static bool ChangeWorkingDirectory(const string& new_working_directory);
+  static bool ChangeWorkingDirectory(const std::string& new_working_directory);
 
-  static bool GetContents(
-      const string& name, string* output, bool /*is_default*/) {
+  static bool GetContents(const std::string& name, std::string* output,
+                          bool /*is_default*/) {
     return ReadFileToString(name, output);
   }
 
-  static bool GetContentsAsText(
-      const string& name, string* output, bool /*is_default*/) {
+  static bool GetContentsAsText(const std::string& name, std::string* output,
+                                bool /*is_default*/) {
     return ReadFileToString(name, output, true);
   }
 
-  static bool SetContents(
-      const string& name, const string& contents, bool /*is_default*/) {
+  static bool SetContents(const std::string& name, const std::string& contents,
+                          bool /*is_default*/) {
     return WriteStringToFile(contents, name);
   }
 
diff --git a/src/google/protobuf/testing/googletest.cc b/src/google/protobuf/testing/googletest.cc
index 1856971..88343f9 100644
--- a/src/google/protobuf/testing/googletest.cc
+++ b/src/google/protobuf/testing/googletest.cc
@@ -70,7 +70,7 @@
 #endif
 #endif
 
-string TestSourceDir() {
+std::string TestSourceDir() {
 #ifndef GOOGLE_THIRD_PARTY_PROTOBUF
 #ifdef GOOGLE_PROTOBUF_TEST_SOURCE_PATH
   return GOOGLE_PROTOBUF_TEST_SOURCE_PATH;
@@ -84,7 +84,7 @@
 #endif  // _MSC_VER
 
   // Look for the "src" directory.
-  string prefix = ".";
+  std::string prefix = ".";
 
   // Keep looking further up the directory tree until we find
   // src/.../descriptor.cc. It is important to look for a particular file,
@@ -107,12 +107,12 @@
 
 namespace {
 
-string GetTemporaryDirectoryName() {
+std::string GetTemporaryDirectoryName() {
   // Tests run under Bazel "should not" use /tmp. Bazel sets this environment
   // variable for tests to use instead.
   char *from_environment = getenv("TEST_TMPDIR");
   if (from_environment != NULL && from_environment[0] != '\0') {
-    return string(from_environment) + "/protobuf_tmpdir";
+    return std::string(from_environment) + "/protobuf_tmpdir";
   }
 
   // tmpnam() is generally not considered safe but we're only using it for
@@ -121,7 +121,7 @@
   char b[L_tmpnam + 1];     // HPUX multithread return 0 if s is 0
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-  string result = tmpnam(b);
+  std::string result = tmpnam(b);
 #pragma GCC diagnostic pop
 #ifdef _WIN32
   // Avoid a trailing dot by changing it to an underscore. On Win32 the names of
@@ -166,7 +166,7 @@
     }
   }
 
-  string GetTempDir() {
+  std::string GetTempDir() {
     if (name_.empty()) {
       name_ = GetTemporaryDirectoryName();
       GOOGLE_CHECK(mkdir(name_.c_str(), 0777) == 0) << strerror(errno);
@@ -179,21 +179,19 @@
   }
 
  private:
-  string name_;
+  std::string name_;
 };
 
 TempDirDeleter temp_dir_deleter_;
 
 }  // namespace
 
-string TestTempDir() {
-  return temp_dir_deleter_.GetTempDir();
-}
+std::string TestTempDir() { return temp_dir_deleter_.GetTempDir(); }
 
 // TODO(kenton):  Share duplicated code below.  Too busy/lazy for now.
 
-static string stdout_capture_filename_;
-static string stderr_capture_filename_;
+static std::string stdout_capture_filename_;
+static std::string stderr_capture_filename_;
 static int original_stdout_ = -1;
 static int original_stderr_ = -1;
 
@@ -227,14 +225,14 @@
   close(fd);
 }
 
-string GetCapturedTestStdout() {
+std::string GetCapturedTestStdout() {
   GOOGLE_CHECK_NE(original_stdout_, -1) << "Not capturing.";
 
   close(1);
   dup2(original_stdout_, 1);
   original_stdout_ = -1;
 
-  string result;
+  std::string result;
   File::ReadFileToStringOrDie(stdout_capture_filename_, &result);
 
   remove(stdout_capture_filename_.c_str());
@@ -242,14 +240,14 @@
   return result;
 }
 
-string GetCapturedTestStderr() {
+std::string GetCapturedTestStderr() {
   GOOGLE_CHECK_NE(original_stderr_, -1) << "Not capturing.";
 
   close(2);
   dup2(original_stderr_, 2);
   original_stderr_ = -1;
 
-  string result;
+  std::string result;
   File::ReadFileToStringOrDie(stderr_capture_filename_, &result);
 
   remove(stderr_capture_filename_.c_str());
@@ -270,14 +268,14 @@
   active_log_ = NULL;
 }
 
-const std::vector<string>& ScopedMemoryLog::GetMessages(LogLevel level) {
+const std::vector<std::string>& ScopedMemoryLog::GetMessages(LogLevel level) {
   GOOGLE_CHECK(level == ERROR ||
                level == WARNING);
   return messages_[level];
 }
 
-void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename,
-                                int line, const string& message) {
+void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename, int line,
+                                const std::string& message) {
   GOOGLE_CHECK(active_log_ != NULL);
   if (level == ERROR || level == WARNING) {
     active_log_->messages_[level].push_back(message);
diff --git a/src/google/protobuf/testing/googletest.h b/src/google/protobuf/testing/googletest.h
index 4e0cb83..6a0c694 100644
--- a/src/google/protobuf/testing/googletest.h
+++ b/src/google/protobuf/testing/googletest.h
@@ -49,19 +49,19 @@
 namespace protobuf {
 
 // When running unittests, get the directory containing the source code.
-string TestSourceDir();
+std::string TestSourceDir();
 
 // When running unittests, get a directory where temporary files may be
 // placed.
-string TestTempDir();
+std::string TestTempDir();
 
 // Capture all text written to stdout or stderr.
 void CaptureTestStdout();
 void CaptureTestStderr();
 
 // Stop capturing stdout or stderr and return the text captured.
-string GetCapturedTestStdout();
-string GetCapturedTestStderr();
+std::string GetCapturedTestStdout();
+std::string GetCapturedTestStderr();
 
 // For use with ScopedMemoryLog::GetMessages().  Inside Google the LogLevel
 // constants don't have the LOGLEVEL_ prefix, so the code that used
@@ -84,14 +84,14 @@
   virtual ~ScopedMemoryLog();
 
   // Fetches all messages with the given severity level.
-  const std::vector<string>& GetMessages(LogLevel error);
+  const std::vector<std::string>& GetMessages(LogLevel error);
 
  private:
-  std::map<LogLevel, std::vector<string> > messages_;
+  std::map<LogLevel, std::vector<std::string> > messages_;
   LogHandler* old_handler_;
 
   static void HandleLog(LogLevel level, const char* filename, int line,
-                        const string& message);
+                        const std::string& message);
 
   static ScopedMemoryLog* active_log_;
 
diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc
index 323b0e0..f47d4e8 100644
--- a/src/google/protobuf/text_format.cc
+++ b/src/google/protobuf/text_format.cc
@@ -2052,8 +2052,8 @@
   if (print_message_fields_in_index_order_) {
     std::sort(fields.begin(), fields.end(), FieldIndexSorter());
   }
-  for (int i = 0; i < fields.size(); i++) {
-    PrintField(message, reflection, fields[i], generator);
+  for (const FieldDescriptor* field : fields) {
+    PrintField(message, reflection, field, generator);
   }
   if (!hide_unknown_fields_) {
     PrintUnknownFields(reflection->GetUnknownFields(message), generator,
@@ -2312,8 +2312,8 @@
   }
 
   if (need_release) {
-    for (int j = 0; j < sorted_map_field.size(); ++j) {
-      delete sorted_map_field[j];
+    for (const Message* message_to_delete : sorted_map_field) {
+      delete message_to_delete;
     }
   }
 }
diff --git a/src/google/protobuf/unittest_custom_options.proto b/src/google/protobuf/unittest_custom_options.proto
index 50bb996..f774c76 100644
--- a/src/google/protobuf/unittest_custom_options.proto
+++ b/src/google/protobuf/unittest_custom_options.proto
@@ -45,6 +45,7 @@
 // A custom file option (defined below).
 option (file_opt1) = 9876543210;
 
+import "google/protobuf/any.proto";
 import "google/protobuf/descriptor.proto";
 
 // We don't put this in a package within proto2 because we need to make sure
@@ -329,6 +330,9 @@
 
   // An embedded message set
   optional AggregateMessageSet mset = 5;
+
+  // An any
+  optional google.protobuf.Any any = 6;
 }
 
 // Allow Aggregate to be used as an option at all possible locations
@@ -376,6 +380,12 @@
       s: 'EmbeddedMessageSetElement'
     }
   }
+
+  any {
+    [type.googleapis.com/protobuf_unittest.AggregateMessageSetElement] {
+      s: 'EmbeddedMessageSetElement'
+    }
+  }
 };
 
 message AggregateMessage {
diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc
index 451209c..f40a577 100644
--- a/src/google/protobuf/unknown_field_set.cc
+++ b/src/google/protobuf/unknown_field_set.cc
@@ -108,8 +108,7 @@
 
   size_t total_size = sizeof(fields_) + sizeof(UnknownField) * fields_.size();
 
-  for (int i = 0; i < fields_.size(); i++) {
-    const UnknownField& field = (fields_)[i];
+  for (const UnknownField& field : fields_) {
     switch (field.type()) {
       case UnknownField::TYPE_LENGTH_DELIMITED:
         total_size += sizeof(*field.data_.length_delimited_.string_value) +
diff --git a/src/google/protobuf/util/internal/proto_writer.cc b/src/google/protobuf/util/internal/proto_writer.cc
index 240db51..24a7142 100644
--- a/src/google/protobuf/util/internal/proto_writer.cc
+++ b/src/google/protobuf/util/internal/proto_writer.cc
@@ -69,6 +69,7 @@
       ignore_unknown_enum_values_(false),
       use_lower_camel_for_enums_(false),
       case_insensitive_enum_parsing_(true),
+      use_json_name_in_missing_fields_(false),
       element_(nullptr),
       size_insert_(),
       output_(output),
@@ -90,6 +91,7 @@
       ignore_unknown_enum_values_(false),
       use_lower_camel_for_enums_(false),
       case_insensitive_enum_parsing_(true),
+      use_json_name_in_missing_fields_(false),
       element_(nullptr),
       size_insert_(),
       output_(output),
@@ -618,26 +620,12 @@
   // Pushing a ProtoElement and then pop it off at the end for 2 purposes:
   // error location reporting and required field accounting.
   //
-  // For proto3, since there is no required field tracking, we only need to push
-  // ProtoElement for error cases.
+  // For proto3, since there is no required field tracking, we only need to
+  // push ProtoElement for error cases.
   if (!element_->proto3()) {
     element_.reset(new ProtoElement(element_.release(), &field, type, false));
   }
 
-  if (field.kind() == google::protobuf::Field::TYPE_UNKNOWN ||
-      field.kind() == google::protobuf::Field::TYPE_MESSAGE) {
-    // Push a ProtoElement for location reporting purposes.
-    if (element_->proto3()) {
-      element_.reset(new ProtoElement(element_.release(), &field, type, false));
-    }
-    InvalidValue(field.type_url().empty()
-                     ? google::protobuf::Field_Kind_Name(field.kind())
-                     : field.type_url(),
-                 data.ValueAsStringOrDefault(""));
-    element_.reset(element()->pop());
-    return this;
-  }
-
   switch (field.kind()) {
     case google::protobuf::Field::TYPE_INT32: {
       status = WriteInt32(field.number(), data, stream_.get());
@@ -706,9 +694,9 @@
           case_insensitive_enum_parsing_, ignore_unknown_enum_values_);
       break;
     }
-    default:  // TYPE_GROUP or TYPE_MESSAGE
+    default:  // TYPE_GROUP, TYPE_MESSAGE, TYPE_UNKNOWN.
       status = util::Status(util::error::INVALID_ARGUMENT,
-                            data.ToString().value());
+                            data.ValueAsStringOrDefault(""));
   }
 
   if (!status.ok()) {
@@ -716,7 +704,9 @@
     if (element_->proto3()) {
       element_.reset(new ProtoElement(element_.release(), &field, type, false));
     }
-    InvalidValue(google::protobuf::Field_Kind_Name(field.kind()),
+    InvalidValue(field.type_url().empty()
+                     ? google::protobuf::Field_Kind_Name(field.kind())
+                     : field.type_url(),
                  status.message());
     element_.reset(element()->pop());
     return this;
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
index 564050f..211b7bc 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
@@ -1000,7 +1000,10 @@
   Proto3Message expected;
   EXPECT_CALL(
       listener_,
-      InvalidValue(_, StringPiece("TYPE_ENUM"),
+      InvalidValue(_,
+                   StringPiece(
+                       "type.googleapis.com/"
+                       "proto_util_converter.testing.Proto3Message.NestedEnum"),
                    StringPiece("\"someunknownvalueyouwillneverknow\"")))
       .With(Args<0>(HasObjectLocation("enum_value")));
   ow_->StartObject("")
diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc
index 1388e9d..12cbf94 100644
--- a/src/google/protobuf/util/message_differencer.cc
+++ b/src/google/protobuf/util/message_differencer.cc
@@ -112,8 +112,8 @@
       : message_differencer_(message_differencer),
         key_field_paths_(key_field_paths) {
     GOOGLE_CHECK(!key_field_paths_.empty());
-    for (int i = 0; i < key_field_paths_.size(); ++i) {
-      GOOGLE_CHECK(!key_field_paths_[i].empty());
+    for (const auto& path : key_field_paths_) {
+      GOOGLE_CHECK(!path.empty());
     }
   }
   MultipleFieldsMapKeyComparator(MessageDifferencer* message_differencer,
@@ -125,9 +125,8 @@
   }
   bool IsMatch(const Message& message1, const Message& message2,
                const std::vector<SpecificField>& parent_fields) const override {
-    for (int i = 0; i < key_field_paths_.size(); ++i) {
-      if (!IsMatchInternal(message1, message2, parent_fields,
-                           key_field_paths_[i], 0)) {
+    for (const auto& path : key_field_paths_) {
+      if (!IsMatchInternal(message1, message2, parent_fields, path, 0)) {
         return false;
       }
     }
@@ -276,11 +275,11 @@
           MatchIndicesPostProcessorForSmartList) {}
 
 MessageDifferencer::~MessageDifferencer() {
-  for (int i = 0; i < owned_key_comparators_.size(); ++i) {
-    delete owned_key_comparators_[i];
+  for (MapKeyComparator* comparator : owned_key_comparators_) {
+    delete comparator;
   }
-  for (int i = 0; i < ignore_criteria_.size(); ++i) {
-    delete ignore_criteria_[i];
+  for (IgnoreCriteria* criteria : ignore_criteria_) {
+    delete criteria;
   }
 }
 
@@ -380,9 +379,9 @@
     const FieldDescriptor* field,
     const std::vector<const FieldDescriptor*>& key_fields) {
   std::vector<std::vector<const FieldDescriptor*> > key_field_paths;
-  for (int i = 0; i < key_fields.size(); ++i) {
+  for (const FieldDescriptor* key_filed : key_fields) {
     std::vector<const FieldDescriptor*> key_field_path;
-    key_field_path.push_back(key_fields[i]);
+    key_field_path.push_back(key_filed);
     key_field_paths.push_back(key_field_path);
   }
   TreatAsMapWithMultipleFieldPathsAsKey(field, key_field_paths);
@@ -395,9 +394,7 @@
       << "Field must be repeated: " << field->full_name();
   GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, field->cpp_type())
       << "Field has to be message type.  Field name is: " << field->full_name();
-  for (int i = 0; i < key_field_paths.size(); ++i) {
-    const std::vector<const FieldDescriptor*>& key_field_path =
-        key_field_paths[i];
+  for (const auto& key_field_path : key_field_paths) {
     for (int j = 0; j < key_field_path.size(); ++j) {
       const FieldDescriptor* parent_field =
           j == 0 ? field : key_field_path[j - 1];
@@ -1236,10 +1233,11 @@
 
 bool MessageDifferencer::CheckPathChanged(
     const std::vector<SpecificField>& field_path) {
-  for (int i = 0; i < field_path.size(); ++i) {
+  for (const SpecificField& specific_field : field_path) {
     // Don't check indexes for map entries -- maps are unordered.
-    if (field_path[i].field != NULL && field_path[i].field->is_map()) continue;
-    if (field_path[i].index != field_path[i].new_index) return true;
+    if (specific_field.field != nullptr && specific_field.field->is_map())
+      continue;
+    if (specific_field.index != specific_field.new_index) return true;
   }
   return false;
 }
@@ -1286,9 +1284,8 @@
   if (ignored_fields_.find(field) != ignored_fields_.end()) {
     return true;
   }
-  for (int i = 0; i < ignore_criteria_.size(); ++i) {
-    if (ignore_criteria_[i]->IsIgnored(message1, message2, field,
-                                       parent_fields)) {
+  for (IgnoreCriteria* criteria : ignore_criteria_) {
+    if (criteria->IsIgnored(message1, message2, field, parent_fields)) {
       return true;
     }
   }
@@ -1299,9 +1296,9 @@
     const Message& message1, const Message& message2,
     const SpecificField& field,
     const std::vector<SpecificField>& parent_fields) {
-  for (int i = 0; i < ignore_criteria_.size(); ++i) {
-    if (ignore_criteria_[i]->IsUnknownFieldIgnored(message1, message2, field,
-                                                   parent_fields)) {
+  for (IgnoreCriteria* criteria : ignore_criteria_) {
+    if (criteria->IsUnknownFieldIgnored(message1, message2, field,
+                                        parent_fields)) {
       return true;
     }
   }
diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc
index 2f40d21..2f5908e 100644
--- a/src/google/protobuf/wire_format.cc
+++ b/src/google/protobuf/wire_format.cc
@@ -1462,8 +1462,8 @@
     message_reflection->ListFields(message, &fields);
   }
 
-  for (int i = 0; i < fields.size(); i++) {
-    our_size += FieldByteSize(fields[i], message);
+  for (const FieldDescriptor* field : fields) {
+    our_size += FieldByteSize(field, message);
   }
 
   if (descriptor->options().message_set_wire_format()) {
diff --git a/tests.sh b/tests.sh
index 8b499d0..5113e4a 100755
--- a/tests.sh
+++ b/tests.sh
@@ -316,7 +316,7 @@
   else
     envlist=py\{27,36\}-python
   fi
-  tox -e $envlist
+  python -m tox -e $envlist
   cd ..
 }
 
@@ -324,7 +324,7 @@
   internal_build_cpp
   cd python
   envlist=$1
-  tox -e $envlist
+  python -m tox -e $envlist
   cd ..
 }
 
@@ -467,45 +467,6 @@
   internal_build_cpp
 }
 
-build_php5.5() {
-  use_php 5.5
-
-  pushd php
-  rm -rf vendor
-  composer update
-  composer test
-  popd
-  (cd conformance && make test_php)
-}
-
-build_php5.6() {
-  use_php 5.6
-  pushd php
-  rm -rf vendor
-  composer update
-  composer test
-  popd
-  (cd conformance && make test_php)
-}
-
-build_php5.6_mac() {
-  # Install PHP
-  curl -s https://php-osx.liip.ch/install.sh | bash -s 5.6
-  PHP_FOLDER=`find /usr/local -type d -name "php5-5.6*"`  # The folder name may change upon time
-  test ! -z "$PHP_FOLDER"
-  export PATH="$PHP_FOLDER/bin:$PATH"
-
-  internal_build_cpp
-
-  # Run pure-PHP tests only.
-  pushd php
-  rm -rf vendor
-  composer update
-  composer test
-  popd
-  (cd conformance && make test_php)
-}
-
 build_php7.0() {
   use_php 7.0
   pushd php
@@ -747,8 +708,6 @@
 }
 
 build_php_all_32() {
-  build_php5.5
-  build_php5.6
   build_php7.0
   build_php7.1
   build_php7.4
@@ -803,8 +762,6 @@
             ruby27 |
             jruby |
             ruby_all |
-            php5.5   |
-            php5.6   |
             php7.0   |
             php7.0_c |
             php_compatibility |