Merge remote-tracking branch 'github/alpha-2-fix'

Change-Id: I4c5186b8451713fda38e60dc3f828da6196c7a5e
diff --git a/.gitignore b/.gitignore
index 2ccf83f..cb0347f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,6 +39,7 @@
 *.lo
 *.la
 src/.libs
+*.so
 
 .dirstamp
 
diff --git a/configure.ac b/configure.ac
index b5eb939..14351a8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -12,7 +12,7 @@
 # In the SVN trunk, the version should always be the next anticipated release
 # version with the "-pre" suffix.  (We used to use "-SNAPSHOT" but this pushed
 # the size of one file name in the dist tarfile over the 99-char limit.)
-AC_INIT([Protocol Buffers],[3.0.0-alpha-2],[protobuf@googlegroups.com],[protobuf])
+AC_INIT([Protocol Buffers],[3.0.0-alpha-3-pre],[protobuf@googlegroups.com],[protobuf])
 
 AM_MAINTAINER_MODE([enable])
 
diff --git a/generate_descriptor_proto.sh b/generate_descriptor_proto.sh
index 07219dc..b25a3c6 100755
--- a/generate_descriptor_proto.sh
+++ b/generate_descriptor_proto.sh
@@ -27,7 +27,39 @@
 fi
 
 cd src
-make $@ protoc &&
-  ./protoc --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:. google/protobuf/descriptor.proto && \
-  ./protoc --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:. google/protobuf/compiler/plugin.proto
+CORE_PROTO_IS_CORRECT=0
+while [ $CORE_PROTO_IS_CORRECT -ne 1 ]
+do
+  CORE_PROTO_IS_CORRECT=1
+  cp google/protobuf/descriptor.pb.h google/protobuf/descriptor.pb.h.tmp
+  cp google/protobuf/descriptor.pb.cc google/protobuf/descriptor.pb.cc.tmp
+  cp google/protobuf/compiler/plugin.pb.h google/protobuf/compiler/plugin.pb.h.tmp
+  cp google/protobuf/compiler/plugin.pb.cc google/protobuf/compiler/plugin.pb.cc.tmp
+
+  make $@ protoc &&
+    ./protoc --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:. google/protobuf/descriptor.proto && \
+    ./protoc --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:. google/protobuf/compiler/plugin.proto
+
+  diff google/protobuf/descriptor.pb.h google/protobuf/descriptor.pb.h.tmp > /dev/null
+  if test $? -ne 0; then
+    CORE_PROTO_IS_CORRECT=0
+  fi
+  diff google/protobuf/descriptor.pb.cc google/protobuf/descriptor.pb.cc.tmp > /dev/null
+  if test $? -ne 0; then
+    CORE_PROTO_IS_CORRECT=0
+  fi
+  diff google/protobuf/compiler/plugin.pb.h google/protobuf/compiler/plugin.pb.h.tmp > /dev/null
+  if test $? -ne 0; then
+    CORE_PROTO_IS_CORRECT=0
+  fi
+  diff google/protobuf/compiler/plugin.pb.cc google/protobuf/compiler/plugin.pb.cc.tmp > /dev/null
+  if test $? -ne 0; then
+    CORE_PROTO_IS_CORRECT=0
+  fi
+
+  rm google/protobuf/descriptor.pb.h.tmp
+  rm google/protobuf/descriptor.pb.cc.tmp
+  rm google/protobuf/compiler/plugin.pb.h.tmp
+  rm google/protobuf/compiler/plugin.pb.cc.tmp
+done
 cd ..
diff --git a/java/pom.xml b/java/pom.xml
index d409566..3eb7a70 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -10,7 +10,7 @@
   </parent>
   <groupId>com.google.protobuf</groupId>
   <artifactId>protobuf-java</artifactId>
-  <version>3.0.0-alpha-2</version>
+  <version>3.0.0-alpha-3-pre</version>
   <packaging>bundle</packaging>
   <name>Protocol Buffer Java API</name>
   <description>
@@ -152,7 +152,7 @@
           <instructions>
             <Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL>
             <Bundle-SymbolicName>com.google.protobuf</Bundle-SymbolicName>
-            <Export-Package>com.google.protobuf;version=3.0.0-alpha-2</Export-Package>
+            <Export-Package>com.google.protobuf;version=3.0.0-alpha-3-pre</Export-Package>
           </instructions>
         </configuration>
       </plugin>
diff --git a/java/src/main/java/com/google/protobuf/AbstractMessage.java b/java/src/main/java/com/google/protobuf/AbstractMessage.java
index 6de4cae..cc89173 100644
--- a/java/src/main/java/com/google/protobuf/AbstractMessage.java
+++ b/java/src/main/java/com/google/protobuf/AbstractMessage.java
@@ -83,10 +83,10 @@
   }
 
   public void writeTo(final CodedOutputStream output) throws IOException {
-    MessageReflection.writeMessageTo(this, output, false);
+    MessageReflection.writeMessageTo(this, getAllFields(), output, false);
   }
 
-  private int memoizedSize = -1;
+  protected int memoizedSize = -1;
 
   public int getSerializedSize() {
     int size = memoizedSize;
@@ -94,7 +94,7 @@
       return size;
     }
 
-    memoizedSize = MessageReflection.getSerializedSize(this);
+    memoizedSize = MessageReflection.getSerializedSize(this, getAllFields());
     return memoizedSize;
   }
 
diff --git a/java/src/main/java/com/google/protobuf/BoundedByteString.java b/java/src/main/java/com/google/protobuf/BoundedByteString.java
index 8cb6f46..b4c3fb1 100644
--- a/java/src/main/java/com/google/protobuf/BoundedByteString.java
+++ b/java/src/main/java/com/google/protobuf/BoundedByteString.java
@@ -30,8 +30,8 @@
 
 package com.google.protobuf;
 
-import java.io.InvalidObjectException;
 import java.io.IOException;
+import java.io.InvalidObjectException;
 import java.io.ObjectInputStream;
 import java.util.NoSuchElementException;
 
diff --git a/java/src/main/java/com/google/protobuf/ByteString.java b/java/src/main/java/com/google/protobuf/ByteString.java
index cff1ee5..9b0a524 100644
--- a/java/src/main/java/com/google/protobuf/ByteString.java
+++ b/java/src/main/java/com/google/protobuf/ByteString.java
@@ -76,6 +76,9 @@
   static final int MIN_READ_FROM_CHUNK_SIZE = 0x100;  // 256b
   static final int MAX_READ_FROM_CHUNK_SIZE = 0x2000;  // 8k
 
+  // Defined by java.nio.charset.Charset
+  protected static final String UTF_8 = "UTF-8";
+
   /**
    * Empty {@code ByteString}.
    */
@@ -267,7 +270,7 @@
    */
   public static ByteString copyFromUtf8(String text) {
     try {
-      return new LiteralByteString(text.getBytes("UTF-8"));
+      return new LiteralByteString(text.getBytes(UTF_8));
     } catch (UnsupportedEncodingException e) {
       throw new RuntimeException("UTF-8 not supported?", e);
     }
@@ -622,7 +625,7 @@
    */
   public String toStringUtf8() {
     try {
-      return toString("UTF-8");
+      return toString(UTF_8);
     } catch (UnsupportedEncodingException e) {
       throw new RuntimeException("UTF-8 not supported?", e);
     }
diff --git a/java/src/main/java/com/google/protobuf/Descriptors.java b/java/src/main/java/com/google/protobuf/Descriptors.java
index d65e8b4..806f46c 100644
--- a/java/src/main/java/com/google/protobuf/Descriptors.java
+++ b/java/src/main/java/com/google/protobuf/Descriptors.java
@@ -897,7 +897,7 @@
       return (type == Type.STRING) && (getFile().getOptions().getJavaStringCheckUtf8());
     }
 
-    boolean isMapField() {
+    public boolean isMapField() {
       return getType() == Type.MESSAGE && isRepeated()
           && getMessageType().getOptions().getMapEntry();
     }
diff --git a/java/src/main/java/com/google/protobuf/DynamicMessage.java b/java/src/main/java/com/google/protobuf/DynamicMessage.java
index 9c5e6c6..3ea1b68 100644
--- a/java/src/main/java/com/google/protobuf/DynamicMessage.java
+++ b/java/src/main/java/com/google/protobuf/DynamicMessage.java
@@ -35,8 +35,8 @@
 import com.google.protobuf.Descriptors.FieldDescriptor;
 import com.google.protobuf.Descriptors.OneofDescriptor;
 
-import java.io.InputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -600,9 +600,12 @@
       }
       // TODO(xiaofeng): Re-enable this check after Orgstore is fixed to not
       // set incorrect EnumValueDescriptors.
-      // if (field.getEnumType() != ((EnumValueDescriptor) value).getType()) {
-      //   throw new IllegalArgumentException(
-      //     "EnumValueDescriptor doesn't match Enum Field.");
+      // EnumDescriptor fieldType = field.getEnumType();
+      // EnumDescriptor fieldValueType = ((EnumValueDescriptor) value).getType();
+      // if (fieldType != fieldValueType) {
+      //  throw new IllegalArgumentException(String.format(
+      //      "EnumDescriptor %s of field doesn't match EnumDescriptor %s of field value",
+      //      fieldType.getFullName(), fieldValueType.getFullName()));
       // }
     }
 
diff --git a/java/src/main/java/com/google/protobuf/FieldSet.java b/java/src/main/java/com/google/protobuf/FieldSet.java
index ff9b5bc..47924b6 100644
--- a/java/src/main/java/com/google/protobuf/FieldSet.java
+++ b/java/src/main/java/com/google/protobuf/FieldSet.java
@@ -553,42 +553,13 @@
       CodedInputStream input,
       final WireFormat.FieldType type,
       boolean checkUtf8) throws IOException {
-    switch (type) {
-      case DOUBLE  : return input.readDouble  ();
-      case FLOAT   : return input.readFloat   ();
-      case INT64   : return input.readInt64   ();
-      case UINT64  : return input.readUInt64  ();
-      case INT32   : return input.readInt32   ();
-      case FIXED64 : return input.readFixed64 ();
-      case FIXED32 : return input.readFixed32 ();
-      case BOOL    : return input.readBool    ();
-      case STRING  : if (checkUtf8) {
-                       return input.readStringRequireUtf8();
-                     } else {
-                       return input.readString();
-                     }
-      case BYTES   : return input.readBytes   ();
-      case UINT32  : return input.readUInt32  ();
-      case SFIXED32: return input.readSFixed32();
-      case SFIXED64: return input.readSFixed64();
-      case SINT32  : return input.readSInt32  ();
-      case SINT64  : return input.readSInt64  ();
-
-      case GROUP:
-        throw new IllegalArgumentException(
-          "readPrimitiveField() cannot handle nested groups.");
-      case MESSAGE:
-        throw new IllegalArgumentException(
-          "readPrimitiveField() cannot handle embedded messages.");
-      case ENUM:
-        // We don't handle enums because we don't know what to do if the
-        // value is not recognized.
-        throw new IllegalArgumentException(
-          "readPrimitiveField() cannot handle enums.");
+    if (checkUtf8) {
+      return WireFormat.readPrimitiveField(input, type,
+          WireFormat.Utf8Validation.STRICT);
+    } else {
+      return WireFormat.readPrimitiveField(input, type,
+          WireFormat.Utf8Validation.LOOSE);
     }
-
-    throw new RuntimeException(
-      "There is no way to get here, but the compiler thinks otherwise.");
   }
 
 
@@ -685,9 +656,15 @@
       case FIXED64 : output.writeFixed64NoTag ((Long       ) value); break;
       case FIXED32 : output.writeFixed32NoTag ((Integer    ) value); break;
       case BOOL    : output.writeBoolNoTag    ((Boolean    ) value); break;
-      case STRING  : output.writeStringNoTag  ((String     ) value); break;
       case GROUP   : output.writeGroupNoTag   ((MessageLite) value); break;
       case MESSAGE : output.writeMessageNoTag ((MessageLite) value); break;
+      case STRING:
+        if (value instanceof ByteString) {
+          output.writeBytesNoTag((ByteString) value);
+        } else {
+          output.writeStringNoTag((String) value);
+        }
+        break;
       case BYTES:
         if (value instanceof ByteString) {
           output.writeBytesNoTag((ByteString) value);
@@ -843,7 +820,6 @@
       case FIXED64 : return CodedOutputStream.computeFixed64SizeNoTag ((Long       )value);
       case FIXED32 : return CodedOutputStream.computeFixed32SizeNoTag ((Integer    )value);
       case BOOL    : return CodedOutputStream.computeBoolSizeNoTag    ((Boolean    )value);
-      case STRING  : return CodedOutputStream.computeStringSizeNoTag  ((String     )value);
       case GROUP   : return CodedOutputStream.computeGroupSizeNoTag   ((MessageLite)value);
       case BYTES   :
         if (value instanceof ByteString) {
@@ -851,6 +827,12 @@
         } else {
           return CodedOutputStream.computeByteArraySizeNoTag((byte[]) value);
         }
+      case STRING  :
+        if (value instanceof ByteString) {
+          return CodedOutputStream.computeBytesSizeNoTag((ByteString) value);
+        } else {
+          return CodedOutputStream.computeStringSizeNoTag((String) value);
+        }
       case UINT32  : return CodedOutputStream.computeUInt32SizeNoTag  ((Integer    )value);
       case SFIXED32: return CodedOutputStream.computeSFixed32SizeNoTag((Integer    )value);
       case SFIXED64: return CodedOutputStream.computeSFixed64SizeNoTag((Long       )value);
diff --git a/java/src/main/java/com/google/protobuf/GeneratedMessage.java b/java/src/main/java/com/google/protobuf/GeneratedMessage.java
index d8510cb..9457d99 100644
--- a/java/src/main/java/com/google/protobuf/GeneratedMessage.java
+++ b/java/src/main/java/com/google/protobuf/GeneratedMessage.java
@@ -109,8 +109,15 @@
     return internalGetFieldAccessorTable().descriptor;
   }
 
-  /** Internal helper which returns a mutable map. */
-  private Map<FieldDescriptor, Object> getAllFieldsMutable() {
+  /**
+   * Internal helper to return a modifiable map containing all the fields.
+   * The returned Map is modifialbe so that the caller can add additional
+   * extension fields to implement {@link #getAllFields()}.
+   *
+   * @param getBytesForString whether to generate ByteString for string fields
+   */
+  private Map<FieldDescriptor, Object> getAllFieldsMutable(
+      boolean getBytesForString) {
     final TreeMap<FieldDescriptor, Object> result =
       new TreeMap<FieldDescriptor, Object>();
     final Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
@@ -122,7 +129,12 @@
         }
       } else {
         if (hasField(field)) {
-          result.put(field, getField(field));
+          if (getBytesForString
+              && field.getJavaType() == FieldDescriptor.JavaType.STRING) {
+            result.put(field, getFieldRaw(field));
+          } else {
+            result.put(field, getField(field));
+          }
         }
       }
     }
@@ -161,7 +173,23 @@
 
   //@Override (Java 1.6 override semantics, but we must support 1.5)
   public Map<FieldDescriptor, Object> getAllFields() {
-    return Collections.unmodifiableMap(getAllFieldsMutable());
+    return Collections.unmodifiableMap(
+        getAllFieldsMutable(/* getBytesForString = */ false));
+  }
+
+  /**
+   * Returns a collection of all the fields in this message which are set
+   * and their corresponding values.  A singular ("required" or "optional")
+   * field is set iff hasField() returns true for that field.  A "repeated"
+   * field is set iff getRepeatedFieldCount() is greater than zero.  The
+   * values are exactly what would be returned by calling
+   * {@link #getFieldRaw(Descriptors.FieldDescriptor)} for each field.  The map
+   * is guaranteed to be a sorted map, so iterating over it will return fields
+   * in order by field number.
+   */
+  Map<FieldDescriptor, Object> getAllFieldsRaw() {
+    return Collections.unmodifiableMap(
+        getAllFieldsMutable(/* getBytesForString = */ true));
   }
 
   //@Override (Java 1.6 override semantics, but we must support 1.5)
@@ -184,6 +212,18 @@
     return internalGetFieldAccessorTable().getField(field).get(this);
   }
 
+  /**
+   * Obtains the value of the given field, or the default value if it is
+   * not set.  For primitive fields, the boxed primitive value is returned.
+   * For enum fields, the EnumValueDescriptor for the value is returned. For
+   * embedded message fields, the sub-message is returned.  For repeated
+   * fields, a java.util.List is returned. For present string fields, a
+   * ByteString is returned representing the bytes that the field contains.
+   */
+  Object getFieldRaw(final FieldDescriptor field) {
+    return internalGetFieldAccessorTable().getField(field).getRaw(this);
+  }
+
   //@Override (Java 1.6 override semantics, but we must support 1.5)
   public int getRepeatedFieldCount(final FieldDescriptor field) {
     return internalGetFieldAccessorTable().getField(field)
@@ -214,6 +254,24 @@
     return unknownFields.mergeFieldFrom(tag, input);
   }
 
+  @Override
+  public void writeTo(final CodedOutputStream output) throws IOException {
+    MessageReflection.writeMessageTo(this, getAllFieldsRaw(), output, false);
+  }
+
+  @Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) {
+      return size;
+    }
+
+    memoizedSize = MessageReflection.getSerializedSize(
+        this, getAllFieldsRaw());
+    return memoizedSize;
+  }
+
+
 
   /**
    * Used by parsing constructors in generated classes.
@@ -563,6 +621,15 @@
       throw new RuntimeException(
           "No map fields found in " + getClass().getName());
     }
+
+    /** Like {@link internalGetMapField} but return a mutable version. */
+    @SuppressWarnings({"unused", "rawtypes"})
+    protected MapField internalGetMutableMapField(int fieldNumber) {
+      // Note that we can't use descriptor names here because this method will
+      // be called when descriptor is being initialized.
+      throw new RuntimeException(
+          "No map fields found in " + getClass().getName());
+    }
   }
 
   // =================================================================
@@ -825,7 +892,16 @@
 
     @Override
     public Map<FieldDescriptor, Object> getAllFields() {
-      final Map<FieldDescriptor, Object> result = super.getAllFieldsMutable();
+      final Map<FieldDescriptor, Object> result =
+          super.getAllFieldsMutable(/* getBytesForString = */ false);
+      result.putAll(getExtensionFields());
+      return Collections.unmodifiableMap(result);
+    }
+
+    @Override
+    public Map<FieldDescriptor, Object> getAllFieldsRaw() {
+      final Map<FieldDescriptor, Object> result =
+          super.getAllFieldsMutable(/* getBytesForString = */ false);
       result.putAll(getExtensionFields());
       return Collections.unmodifiableMap(result);
     }
@@ -1761,6 +1837,10 @@
               fields[i] = new SingularEnumFieldAccessor(
                   field, camelCaseNames[i], messageClass, builderClass,
                   containingOneofCamelCaseName);
+            } else if (field.getJavaType() == FieldDescriptor.JavaType.STRING) {
+              fields[i] = new SingularStringFieldAccessor(
+                  field, camelCaseNames[i], messageClass, builderClass,
+                  containingOneofCamelCaseName);
             } else {
               fields[i] = new SingularFieldAccessor(
                   field, camelCaseNames[i], messageClass, builderClass,
@@ -1817,9 +1897,13 @@
     private interface FieldAccessor {
       Object get(GeneratedMessage message);
       Object get(GeneratedMessage.Builder builder);
+      Object getRaw(GeneratedMessage message);
+      Object getRaw(GeneratedMessage.Builder builder);
       void set(Builder builder, Object value);
       Object getRepeated(GeneratedMessage message, int index);
       Object getRepeated(GeneratedMessage.Builder builder, int index);
+      Object getRepeatedRaw(GeneratedMessage message, int index);
+      Object getRepeatedRaw(GeneratedMessage.Builder builder, int index);
       void setRepeated(Builder builder,
                        int index, Object value);
       void addRepeated(Builder builder, Object value);
@@ -1949,6 +2033,12 @@
       public Object get(GeneratedMessage.Builder builder) {
         return invokeOrDie(getMethodBuilder, builder);
       }
+      public Object getRaw(final GeneratedMessage message) {
+        return get(message);
+      }
+      public Object getRaw(GeneratedMessage.Builder builder) {
+        return get(builder);
+      }
       public void set(final Builder builder, final Object value) {
         invokeOrDie(setMethod, builder, value);
       }
@@ -1957,12 +2047,22 @@
         throw new UnsupportedOperationException(
           "getRepeatedField() called on a singular field.");
       }
+      public Object getRepeatedRaw(final GeneratedMessage message,
+                                final int index) {
+        throw new UnsupportedOperationException(
+          "getRepeatedFieldRaw() called on a singular field.");
+      }
       public Object getRepeated(GeneratedMessage.Builder builder, int index) {
         throw new UnsupportedOperationException(
           "getRepeatedField() called on a singular field.");
       }
-      public void setRepeated(final Builder builder,
-                              final int index, final Object value) {
+      public Object getRepeatedRaw(GeneratedMessage.Builder builder,
+          int index) {
+        throw new UnsupportedOperationException(
+          "getRepeatedFieldRaw() called on a singular field.");
+      }
+      public void setRepeated(final Builder builder, final int index,
+          final Object value) {
         throw new UnsupportedOperationException(
           "setRepeatedField() called on a singular field.");
       }
@@ -2058,6 +2158,12 @@
       public Object get(GeneratedMessage.Builder builder) {
         return invokeOrDie(getMethodBuilder, builder);
       }
+      public Object getRaw(final GeneratedMessage message) {
+        return get(message);
+      }
+      public Object getRaw(GeneratedMessage.Builder builder) {
+        return get(builder);
+      }
       public void set(final Builder builder, final Object value) {
         // Add all the elements individually.  This serves two purposes:
         // 1) Verifies that each element has the correct type.
@@ -2075,6 +2181,13 @@
       public Object getRepeated(GeneratedMessage.Builder builder, int index) {
         return invokeOrDie(getRepeatedMethodBuilder, builder, index);
       }
+      public Object getRepeatedRaw(GeneratedMessage message, int index) {
+        return getRepeated(message, index);
+      }
+      public Object getRepeatedRaw(GeneratedMessage.Builder builder,
+          int index) {
+        return getRepeated(builder, index);
+      }
       public void setRepeated(final Builder builder,
                               final int index, final Object value) {
         invokeOrDie(setRepeatedMethod, builder, index, value);
@@ -2139,6 +2252,12 @@
         return (MapField<?, ?>) builder.internalGetMapField(field.getNumber());
       }
 
+      private MapField<?, ?> getMutableMapField(
+          GeneratedMessage.Builder builder) {
+        return (MapField<?, ?>) builder.internalGetMutableMapField(
+            field.getNumber());
+      }
+
       public Object get(GeneratedMessage message) {
         List result = new ArrayList();
         for (int i = 0; i < getRepeatedCount(message); i++) {
@@ -2155,6 +2274,14 @@
         return Collections.unmodifiableList(result);
       }
 
+      public Object getRaw(GeneratedMessage message) {
+        return get(message);
+      }
+
+      public Object getRaw(GeneratedMessage.Builder builder) {
+        return get(builder);
+      }
+
       public void set(Builder builder, Object value) {
         clear(builder);
         for (Object entry : (List) value) {
@@ -2170,14 +2297,20 @@
         return getMapField(builder).getList().get(index);
       }
 
+      public Object getRepeatedRaw(GeneratedMessage message, int index) {
+        return getRepeated(message, index);
+      }
+
+      public Object getRepeatedRaw(Builder builder, int index) {
+        return getRepeated(builder, index);
+      }
+
       public void setRepeated(Builder builder, int index, Object value) {
-        builder.onChanged();
-        getMapField(builder).getMutableList().set(index, (Message) value);
+        getMutableMapField(builder).getMutableList().set(index, (Message) value);
       }
 
       public void addRepeated(Builder builder, Object value) {
-        builder.onChanged();
-        getMapField(builder).getMutableList().add((Message) value);
+        getMutableMapField(builder).getMutableList().add((Message) value);
       }
 
       public boolean has(GeneratedMessage message) {
@@ -2199,8 +2332,7 @@
       }
 
       public void clear(Builder builder) {
-        builder.onChanged();
-        getMapField(builder).getMutableList().clear();
+        getMutableMapField(builder).getMutableList().clear();
       }
 
       public com.google.protobuf.Message.Builder newBuilder() {
@@ -2391,6 +2523,60 @@
 
     // ---------------------------------------------------------------
 
+    /**
+     * Field accessor for string fields.
+     *
+     * <p>This class makes getFooBytes() and setFooBytes() available for
+     * reflection API so that reflection based serialize/parse functions can
+     * access the raw bytes of the field to preserve non-UTF8 bytes in the
+     * string.
+     *
+     * <p>This ensures the serialize/parse round-trip safety, which is important
+     * for servers which forward messages.
+     */
+    private static final class SingularStringFieldAccessor
+        extends SingularFieldAccessor {
+      SingularStringFieldAccessor(
+          final FieldDescriptor descriptor, final String camelCaseName,
+          final Class<? extends GeneratedMessage> messageClass,
+          final Class<? extends Builder> builderClass,
+          final String containingOneofCamelCaseName) {
+        super(descriptor, camelCaseName, messageClass, builderClass,
+            containingOneofCamelCaseName);
+        getBytesMethod = getMethodOrDie(messageClass,
+            "get" + camelCaseName + "Bytes");
+        getBytesMethodBuilder = getMethodOrDie(builderClass,
+            "get" + camelCaseName + "Bytes");
+        setBytesMethodBuilder = getMethodOrDie(builderClass,
+            "set" + camelCaseName + "Bytes", ByteString.class);
+      }
+
+      private final Method getBytesMethod;
+      private final Method getBytesMethodBuilder;
+      private final Method setBytesMethodBuilder;
+
+      @Override
+      public Object getRaw(final GeneratedMessage message) {
+        return invokeOrDie(getBytesMethod, message);
+      }
+
+      @Override
+      public Object getRaw(GeneratedMessage.Builder builder) {
+        return invokeOrDie(getBytesMethodBuilder, builder);
+      }
+
+      @Override
+      public void set(GeneratedMessage.Builder builder, Object value) {
+        if (value instanceof ByteString) {
+          invokeOrDie(setBytesMethodBuilder, builder, value);
+        } else {
+          super.set(builder, value);
+        }
+      }
+    }
+
+    // ---------------------------------------------------------------
+
     private static final class SingularMessageFieldAccessor
         extends SingularFieldAccessor {
       SingularMessageFieldAccessor(
diff --git a/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
index 4d25c07..6839c9d 100644
--- a/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
+++ b/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
@@ -42,22 +42,58 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Lite version of {@link GeneratedMessage}.
  *
  * @author kenton@google.com Kenton Varda
  */
-public abstract class GeneratedMessageLite extends AbstractMessageLite
-    implements Serializable {
+public abstract class GeneratedMessageLite<
+    MessageType extends GeneratedMessageLite<MessageType, BuilderType>,
+    BuilderType extends GeneratedMessageLite.Builder<MessageType, BuilderType>> 
+        extends AbstractMessageLite
+        implements Serializable {
+  
+  /**
+   * Holds all the {@link PrototypeHolder}s for loaded classes.
+   */
+  // TODO(dweis): Consider different concurrency values.
+  // TODO(dweis): This will prevent garbage collection of the class loader.
+  //     Ideally we'd use something like ClassValue but that's Java 7 only.
+  private static final Map<Class<?>, PrototypeHolder<?, ?>> PROTOTYPE_MAP =
+      new ConcurrentHashMap<Class<?>, PrototypeHolder<?, ?>>();
+  
+  // For use by generated code only.
+  protected static <
+      MessageType extends GeneratedMessageLite<MessageType, BuilderType>,
+      BuilderType extends GeneratedMessageLite.Builder<
+          MessageType, BuilderType>> void onLoad(Class<MessageType> clazz,
+              PrototypeHolder<MessageType, BuilderType> protoTypeHolder) {
+    PROTOTYPE_MAP.put(clazz, protoTypeHolder);
+  }
+
   private static final long serialVersionUID = 1L;
 
   /** For use by generated code only.  */
   protected UnknownFieldSetLite unknownFields;
   
-  public Parser<? extends MessageLite> getParserForType() {
-    throw new UnsupportedOperationException(
-        "This is supposed to be overridden by subclasses.");
+  @SuppressWarnings("unchecked") // Guaranteed by runtime.
+  public final Parser<MessageType> getParserForType() {
+    return (Parser<MessageType>) PROTOTYPE_MAP
+        .get(getClass()).getParserForType();
+  }
+
+  @SuppressWarnings("unchecked") // Guaranteed by runtime.
+  public final MessageType getDefaultInstanceForType() {
+    return (MessageType) PROTOTYPE_MAP
+        .get(getClass()).getDefaultInstanceForType();
+  }
+
+  @SuppressWarnings("unchecked") // Guaranteed by runtime.
+  public final BuilderType newBuilderForType() {
+    return (BuilderType) PROTOTYPE_MAP
+        .get(getClass()).newBuilderForType();
   }
 
   /**
@@ -73,10 +109,17 @@
     return unknownFields.mergeFieldFrom(tag, input);
   }
 
+  // The default behavior. If a message has required fields in its subtree, the
+  // generated code will override.
+  public boolean isInitialized() {
+    return true;
+  }
+
   @SuppressWarnings("unchecked")
-  public abstract static class Builder<MessageType extends GeneratedMessageLite,
-                                       BuilderType extends Builder>
-      extends AbstractMessageLite.Builder<BuilderType> {
+  public abstract static class Builder<
+      MessageType extends GeneratedMessageLite<MessageType, BuilderType>,
+      BuilderType extends Builder<MessageType, BuilderType>>
+          extends AbstractMessageLite.Builder<BuilderType> {
 
     private final MessageType defaultInstance;
 
@@ -88,6 +131,12 @@
       this.defaultInstance = defaultInstance;
     }
 
+    // The default behavior. If a message has required fields in its subtree,
+    // the generated code will override.
+    public boolean isInitialized() {
+      return true;
+    }
+
     //@Override (Java 1.6 override semantics, but we must support 1.5)
     public BuilderType clear() {
       unknownFields = UnknownFieldSetLite.getDefaultInstance();
@@ -174,7 +223,9 @@
    * Lite equivalent of {@link com.google.protobuf.GeneratedMessage.ExtendableMessageOrBuilder}.
    */
   public interface ExtendableMessageOrBuilder<
-      MessageType extends ExtendableMessage> extends MessageLiteOrBuilder {
+      MessageType extends ExtendableMessage<MessageType, BuilderType>,
+      BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
+          extends MessageLiteOrBuilder {
 
     /** Check if a singular extension is present. */
     <Type> boolean hasExtension(
@@ -197,16 +248,30 @@
    * Lite equivalent of {@link GeneratedMessage.ExtendableMessage}.
    */
   public abstract static class ExtendableMessage<
-        MessageType extends ExtendableMessage<MessageType>>
-      extends GeneratedMessageLite
-      implements ExtendableMessageOrBuilder<MessageType> {
+        MessageType extends ExtendableMessage<MessageType, BuilderType>,
+        BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
+            extends GeneratedMessageLite<MessageType, BuilderType>
+            implements ExtendableMessageOrBuilder<MessageType, BuilderType> {
 
     /**
      * Represents the set of extensions on this message. For use by generated
      * code only.
      */
     protected FieldSet<ExtensionDescriptor> extensions = FieldSet.newFieldSet();
-    
+
+    // -1 => not memoized, 0 => false, 1 => true.
+    private byte memoizedIsInitialized = -1;
+
+    // The default behavior. If a message has required fields in its subtree,
+    // the generated code will override.
+    public boolean isInitialized() {
+      if (memoizedIsInitialized == -1) {
+        memoizedIsInitialized = (byte) (extensions.isInitialized() ? 1 : 0);
+      }
+
+      return memoizedIsInitialized == 1;
+    }
+
     private void verifyExtensionContainingType(
         final GeneratedExtension<MessageType, ?> extension) {
       if (extension.getContainingTypeDefaultInstance() !=
@@ -349,10 +414,10 @@
    */
   @SuppressWarnings("unchecked")
   public abstract static class ExtendableBuilder<
-        MessageType extends ExtendableMessage<MessageType>,
+        MessageType extends ExtendableMessage<MessageType, BuilderType>,
         BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
       extends Builder<MessageType, BuilderType>
-      implements ExtendableMessageOrBuilder<MessageType> {
+      implements ExtendableMessageOrBuilder<MessageType, BuilderType> {
     protected ExtendableBuilder(MessageType defaultInstance) {
       super(defaultInstance);
     }
@@ -360,6 +425,12 @@
     private FieldSet<ExtensionDescriptor> extensions = FieldSet.emptySet();
     private boolean extensionsIsMutable;
 
+    // The default behavior. If a message has required fields in its subtree,
+    // the generated code will override.
+    public boolean isInitialized() {
+      return extensions.isInitialized();
+    }
+
     // For immutable message conversion.
     void internalSetExtensionSet(FieldSet<ExtensionDescriptor> extensions) {
       this.extensions = extensions;
@@ -991,7 +1062,10 @@
    * Checks that the {@link Extension} is Lite and returns it as a
    * {@link GeneratedExtension}.
    */
-  private static <MessageType extends ExtendableMessage<MessageType>, T>
+  private static <
+      MessageType extends ExtendableMessage<MessageType, BuilderType>,
+      BuilderType extends ExtendableBuilder<MessageType, BuilderType>,
+      T>
     GeneratedExtension<MessageType, T> checkIsLite(
         ExtensionLite<MessageType, T> extension) {
     if (!extension.isLite()) {
@@ -1000,4 +1074,43 @@
     
     return (GeneratedExtension<MessageType, T>) extension;
   }
+  
+  /**
+   * Represents the state needed to implement *ForType methods. Generated code
+   * must provide a static singleton instance by adding it with
+   * {@link GeneratedMessageLite#onLoad(Class, PrototypeHolder)} on class load.
+   * <ul>
+   * <li>{@link #getDefaultInstanceForType()}
+   * <li>{@link #getParserForType()}
+   * <li>{@link #newBuilderForType()}
+   * </ul>
+   * This allows us to trade three generated methods for a static Map.
+   */
+  protected static class PrototypeHolder<
+      MessageType extends GeneratedMessageLite<MessageType, BuilderType>,
+      BuilderType extends GeneratedMessageLite.Builder<
+          MessageType, BuilderType>> {
+    
+    private final MessageType defaultInstance;
+    private final Parser<MessageType> parser;
+    
+    public PrototypeHolder(
+        MessageType defaultInstance, Parser<MessageType> parser) {
+      this.defaultInstance = defaultInstance;
+      this.parser = parser;
+    }
+    
+    public MessageType getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    public Parser<MessageType> getParserForType() {
+      return parser;
+    }
+
+    @SuppressWarnings("unchecked") // Guaranteed by runtime.
+    public BuilderType newBuilderForType() {
+      return (BuilderType) defaultInstance.toBuilder();
+    }
+  }
 }
diff --git a/java/src/main/java/com/google/protobuf/LazyFieldLite.java b/java/src/main/java/com/google/protobuf/LazyFieldLite.java
index 1fc80e8..eea1fe3 100644
--- a/java/src/main/java/com/google/protobuf/LazyFieldLite.java
+++ b/java/src/main/java/com/google/protobuf/LazyFieldLite.java
@@ -30,8 +30,6 @@
 
 package com.google.protobuf;
 
-import java.io.IOException;
-
 /**
  * LazyFieldLite encapsulates the logic of lazily parsing message fields. It stores
  * the message in a ByteString initially and then parse it on-demand.
@@ -44,40 +42,102 @@
  * @author xiangl@google.com (Xiang Li)
  */
 public class LazyFieldLite {
-  private ByteString bytes;
-  private ExtensionRegistryLite extensionRegistry;
-  private volatile boolean isDirty = false;
+  private static final ExtensionRegistryLite EMPTY_REGISTRY =
+      ExtensionRegistryLite.getEmptyRegistry();
 
+  /**
+   * A delayed-parsed version of the bytes. When this is non-null then {@code extensionRegistry } is
+   * also non-null and {@code value} and {@code memoizedBytes} are null.
+   */
+  private ByteString delayedBytes;
+
+  /**
+   * An {@code ExtensionRegistryLite} for parsing bytes. It is non-null on a best-effort basis. It
+   * is only guaranteed to be non-null if this message was initialized using bytes and an
+   * {@code ExtensionRegistry}. If it directly had a value set then it will be null, unless it has
+   * been merged with another {@code LazyFieldLite} that had an {@code ExtensionRegistry}.
+   */
+  private ExtensionRegistryLite extensionRegistry;
+
+  /**
+   * The parsed value. When this is non-null then {@code delayedBytes} will be null.
+   */
   protected volatile MessageLite value;
 
+  /**
+   * The memoized bytes for {@code value}. Will be null when {@code value} is null.
+   */
+  private volatile ByteString memoizedBytes;
+
+  /**
+   * Constructs a LazyFieldLite with bytes that will be parsed lazily.
+   */
   public LazyFieldLite(ExtensionRegistryLite extensionRegistry, ByteString bytes) {
+    checkArguments(extensionRegistry, bytes);
     this.extensionRegistry = extensionRegistry;
-    this.bytes = bytes;
+    this.delayedBytes = bytes;
   }
 
+  /**
+   * Constructs a LazyFieldLite with no contents, and no ability to parse extensions.
+   */
   public LazyFieldLite() {
   }
 
+  /**
+   * Constructs a LazyFieldLite instance with a value. The LazyFieldLite may not be able to parse
+   * the extensions in the value as it has no ExtensionRegistry.
+   */
   public static LazyFieldLite fromValue(MessageLite value) {
     LazyFieldLite lf = new LazyFieldLite();
     lf.setValue(value);
     return lf;
   }
 
+  /**
+   * Determines whether this LazyFieldLite instance represents the default instance of this type.
+   */
   public boolean containsDefaultInstance() {
-    return value == null && bytes == null;
-  }
-
-  public void clear() {
-    bytes = null;
-    value = null;
-    extensionRegistry = null;
-    isDirty = true;
+    return memoizedBytes == ByteString.EMPTY
+        || value == null && (delayedBytes == null || delayedBytes == ByteString.EMPTY);
   }
 
   /**
-   * Returns message instance. At first time, serialized data is parsed by
-   * {@code defaultInstance.getParserForType()}.
+   * Clears the value state of this instance.
+   *
+   * <p>LazyField is not thread-safe for write access. Synchronizations are needed
+   * under read/write situations.
+   */
+  public void clear() {
+    // Don't clear the ExtensionRegistry. It might prove useful later on when merging in another
+    // value, but there is no guarantee that it will contain all extensions that were directly set
+    // on the values that need to be merged.
+    delayedBytes = null;
+    value = null;
+    memoizedBytes = null;
+  }
+
+  /**
+   * Overrides the contents of this LazyField.
+   *
+   * <p>LazyField is not thread-safe for write access. Synchronizations are needed
+   * under read/write situations.
+   */
+  public void set(LazyFieldLite other) {
+    this.delayedBytes = other.delayedBytes;
+    this.value = other.value;
+    this.memoizedBytes = other.memoizedBytes;
+    // If the other LazyFieldLite was created by directly setting the value rather than first by
+    // parsing, then it will not have an extensionRegistry. In this case we hold on to the existing
+    // extensionRegistry, which has no guarantees that it has all the extensions that will be
+    // directly set on the value.
+    if (other.extensionRegistry != null) {
+      this.extensionRegistry = other.extensionRegistry;
+    }
+  }
+
+  /**
+   * Returns message instance. It may do some thread-safe delayed parsing of bytes.
    *
    * @param defaultInstance its message's default instance. It's also used to get parser for the
    * message type.
@@ -88,38 +148,109 @@
   }
 
   /**
-   * LazyField is not thread-safe for write access. Synchronizations are needed
+   * Sets the value of the instance and returns the old value without delay parsing anything.
+   *
+   * <p>LazyField is not thread-safe for write access. Synchronizations are needed
    * under read/write situations.
    */
   public MessageLite setValue(MessageLite value) {
     MessageLite originalValue = this.value;
+    this.delayedBytes = null;
+    this.memoizedBytes = null;
     this.value = value;
-    bytes = null;
-    isDirty = true;
     return originalValue;
   }
 
-  public void merge(LazyFieldLite value) {
-    if (value.containsDefaultInstance()) {
+  /**
+   * Merges another instance's contents. In some cases may drop some extensions if both fields
+   * contain data. If the other field has an {@code ExtensionRegistry} but this does not, then this
+   * field will copy over that {@code ExtensionRegistry}.
+   *
+   * <p>LazyField is not thread-safe for write access. Synchronizations are needed
+   * under read/write situations.
+   */
+  public void merge(LazyFieldLite other) {
+    if (other.containsDefaultInstance()) {
       return;
     }
 
-    if (bytes == null) {
-      this.bytes = value.bytes;
-    } else {
-      this.bytes.concat(value.toByteString());
+    if (this.containsDefaultInstance()) {
+      set(other);
+      return;
     }
-    isDirty = false;
+
+    // If the other field has an extension registry but this does not, copy over the other extension
+    // registry.
+    if (this.extensionRegistry == null) {
+      this.extensionRegistry = other.extensionRegistry;
+    }
+
+    // In the case that both of them are not parsed we simply concatenate the bytes to save time. In
+    // the (probably rare) case that they have different extension registries there is a chance that
+    // some of the extensions may be dropped, but the tradeoff of making this operation fast seems
+    // to outway the benefits of combining the extension registries, which is not normally done for
+    // lite protos anyways.
+    if (this.delayedBytes != null && other.delayedBytes != null) {
+      this.delayedBytes = this.delayedBytes.concat(other.delayedBytes);
+      return;
+    }
+
+    // At least one is parsed and both contain data. We won't drop any extensions here directly, but
+    // in the case that the extension registries are not the same then we might in the future if we
+    // need to serialze and parse a message again.
+    if (this.value == null && other.value != null) {
+      setValue(mergeValueAndBytes(other.value, this.delayedBytes, this.extensionRegistry));
+      return;
+    } else if (this.value != null && other.value == null) {
+      setValue(mergeValueAndBytes(this.value, other.delayedBytes, other.extensionRegistry));
+      return;
+    }
+
+    // At this point we have two fully parsed messages. We can't merge directly from one to the
+    // other because only generated builder code contains methods to mergeFrom another parsed
+    // message. We have to serialize one instance and then merge the bytes into the other. This may
+    // drop extensions from one of the messages if one of the values had an extension set on it
+    // directly.
+    //
+    // To mitigate this we prefer serializing a message that has an extension registry, and
+    // therefore a chance that all extensions set on it are in that registry.
+    //
+    // NOTE: The check for other.extensionRegistry not being null must come first because at this
+    // point in time if other.extensionRegistry is not null then this.extensionRegistry will not be
+    // null either.
+    if (other.extensionRegistry != null) {
+      setValue(mergeValueAndBytes(this.value, other.toByteString(), other.extensionRegistry));
+      return;
+    } else if (this.extensionRegistry != null) {
+      setValue(mergeValueAndBytes(other.value, this.toByteString(), this.extensionRegistry));
+      return;
+    } else {
+      // All extensions from the other message will be dropped because we have no registry.
+      setValue(mergeValueAndBytes(this.value, other.toByteString(), EMPTY_REGISTRY));
+      return;
+    }
   }
 
+  private static MessageLite mergeValueAndBytes(
+      MessageLite value, ByteString otherBytes, ExtensionRegistryLite extensionRegistry) {
+    try {
+      return value.toBuilder().mergeFrom(otherBytes, extensionRegistry).build();
+    } catch (InvalidProtocolBufferException e) {
+      // Nothing is logged and no exceptions are thrown. Clients will be unaware that a proto
+      // was invalid.
+      return value;
+    }
+  }
+
+  /**
+   * Sets this field with bytes to delay-parse.
+   */
   public void setByteString(ByteString bytes, ExtensionRegistryLite extensionRegistry) {
-    this.bytes = bytes;
+    checkArguments(extensionRegistry, bytes);
+    this.delayedBytes = bytes;
     this.extensionRegistry = extensionRegistry;
-    isDirty = false;
-  }
-
-  public ExtensionRegistryLite getExtensionRegistry() {
-    return extensionRegistry;
+    this.value = null;
+    this.memoizedBytes = null;
   }
 
   /**
@@ -128,30 +259,43 @@
    * parsed. Be careful when using this method.
    */
   public int getSerializedSize() {
-    if (isDirty) {
+    if (delayedBytes != null) {
+      return delayedBytes.size();
+    } else if (memoizedBytes != null) {
+      return memoizedBytes.size();
+    } else if (value != null) {
       return value.getSerializedSize();
+    } else {
+      return 0;
     }
-    return bytes.size();
   }
 
+  /**
+   * Returns a BytesString for this field in a thread-safe way.
+   */
   public ByteString toByteString() {
-    if (!isDirty) {
-      return bytes;
+    if (delayedBytes != null) {
+      return delayedBytes;
+    }
+    if (memoizedBytes != null) {
+      return memoizedBytes;
     }
     synchronized (this) {
-      if (!isDirty) {
-        return bytes;
+      if (memoizedBytes != null) {
+        return memoizedBytes;
       }
       if (value == null) {
-        bytes = ByteString.EMPTY;
+        memoizedBytes = ByteString.EMPTY;
       } else {
-        bytes = value.toByteString();
+        memoizedBytes = value.toByteString();
       }
-      isDirty = false;
-      return bytes;
+      return memoizedBytes;
     }
   }
 
+  /**
+   * Might lazily parse the bytes that were previously passed in. Is thread-safe.
+   */
   protected void ensureInitialized(MessageLite defaultInstance) {
     if (value != null) {
       return;
@@ -161,16 +305,35 @@
         return;
       }
       try {
-        if (bytes != null) {
-          value = defaultInstance.getParserForType()
-              .parseFrom(bytes, extensionRegistry);
+        if (delayedBytes != null) {
+          // The extensionRegistry shouldn't be null here since we have delayedBytes.
+          MessageLite parsedValue = defaultInstance.getParserForType()
+              .parseFrom(delayedBytes, extensionRegistry);
+          this.value = parsedValue;
+          this.memoizedBytes = delayedBytes;
+          this.delayedBytes = null;
         } else {
-          value = defaultInstance;
+          this.value = defaultInstance;
+          this.memoizedBytes = ByteString.EMPTY;
+          this.delayedBytes = null;
         }
-      } catch (IOException e) {
-        // TODO(xiangl): Refactory the API to support the exception thrown from
-        // lazily load messages.
+      } catch (InvalidProtocolBufferException e) {
+        // Nothing is logged and no exceptions are thrown. Clients will be unaware that this proto
+        // was invalid.
+        this.value = defaultInstance;
+        this.memoizedBytes = ByteString.EMPTY;
+        this.delayedBytes = null;
       }
     }
   }
+
+
+  private static void checkArguments(ExtensionRegistryLite extensionRegistry, ByteString bytes) {
+    if (extensionRegistry == null) {
+      throw new NullPointerException("found null ExtensionRegistry");
+    }
+    if (bytes == null) {
+      throw new NullPointerException("found null ByteString");
+    }
+  }
 }
diff --git a/java/src/main/java/com/google/protobuf/LiteralByteString.java b/java/src/main/java/com/google/protobuf/LiteralByteString.java
index 767b9f3..6893ddf 100644
--- a/java/src/main/java/com/google/protobuf/LiteralByteString.java
+++ b/java/src/main/java/com/google/protobuf/LiteralByteString.java
@@ -154,7 +154,11 @@
   @Override
   public String toString(String charsetName)
       throws UnsupportedEncodingException {
-    return new String(bytes, getOffsetIntoBytes(), size(), charsetName);
+    // Optimize for empty strings, but ensure we don't silently ignore invalid
+    // encodings.
+    return size() == 0 && UTF_8.equals(charsetName)
+        ? ""
+        : new String(bytes, getOffsetIntoBytes(), size(), charsetName);
   }
 
   // =================================================================
diff --git a/java/src/main/java/com/google/protobuf/Message.java b/java/src/main/java/com/google/protobuf/Message.java
index 5c75b58..fa0265e 100644
--- a/java/src/main/java/com/google/protobuf/Message.java
+++ b/java/src/main/java/com/google/protobuf/Message.java
@@ -163,7 +163,7 @@
      * field builder, which will then be nested into its parent builder.
      * <p>
      * NOTE: implementations that do not support nested builders will throw
-     * <code>UnsupportedException</code>.
+     * <code>UnsupportedOperationException</code>.
      */
     Builder getFieldBuilder(Descriptors.FieldDescriptor field);
 
@@ -181,7 +181,7 @@
      * field builder, which will then be nested into its parent builder.
      * <p>
      * NOTE: implementations that do not support nested builders will throw
-     * <code>UnsupportedException</code>.
+     * <code>UnsupportedOperationException</code>.
      */
     Builder getRepeatedFieldBuilder(Descriptors.FieldDescriptor field,
                                     int index);
diff --git a/java/src/main/java/com/google/protobuf/MessageReflection.java b/java/src/main/java/com/google/protobuf/MessageReflection.java
index 06e3c99..de4bfd3 100644
--- a/java/src/main/java/com/google/protobuf/MessageReflection.java
+++ b/java/src/main/java/com/google/protobuf/MessageReflection.java
@@ -45,13 +45,14 @@
  */
 class MessageReflection {
 
-  static void writeMessageTo(Message message, CodedOutputStream output,
+  static void writeMessageTo(
+      Message message,
+      Map<FieldDescriptor, Object> fields,
+      CodedOutputStream output,
       boolean alwaysWriteRequiredFields)
       throws IOException {
     final boolean isMessageSet =
         message.getDescriptorForType().getOptions().getMessageSetWireFormat();
-
-    Map<FieldDescriptor, Object> fields = message.getAllFields();
     if (alwaysWriteRequiredFields) {
       fields = new TreeMap<FieldDescriptor, Object>(fields);
       for (final FieldDescriptor field :
@@ -82,13 +83,15 @@
     }
   }
 
-  static int getSerializedSize(Message message) {
+  static int getSerializedSize(
+      Message message,
+      Map<FieldDescriptor, Object> fields) {
     int size = 0;
     final boolean isMessageSet =
         message.getDescriptorForType().getOptions().getMessageSetWireFormat();
 
     for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
-        message.getAllFields().entrySet()) {
+        fields.entrySet()) {
       final Descriptors.FieldDescriptor field = entry.getKey();
       final Object value = entry.getValue();
       if (isMessageSet && field.isExtension() &&
@@ -340,14 +343,12 @@
         ByteString bytes, ExtensionRegistryLite registry,
         Descriptors.FieldDescriptor descriptor, Message defaultInstance)
         throws IOException;
-    
+
     /**
-     * Read a primitive field from input. Note that builders and mutable
-     * messages may use different Java types to represent a primtive field.
+     * Returns the UTF8 validation level for the field.
      */
-    Object readPrimitiveField(
-        CodedInputStream input, WireFormat.FieldType type,
-        boolean checkUtf8) throws IOException;
+    WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor
+        descriptor);
 
     /**
      * Returns a new merge target for a sub-field. When defaultInstance is
@@ -513,11 +514,18 @@
         return new BuilderAdapter(builder.newBuilderForField(field));
       }
     }
-    
-    public Object readPrimitiveField(
-        CodedInputStream input, WireFormat.FieldType type,
-        boolean checkUtf8) throws IOException {
-      return FieldSet.readPrimitiveField(input, type, checkUtf8);
+
+    public WireFormat.Utf8Validation
+        getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
+      if (descriptor.needsUtf8Check()) {
+        return WireFormat.Utf8Validation.STRICT;
+      }
+      // TODO(liujisi): support lazy strings for repeated fields.
+      if (!descriptor.isRepeated()
+          && builder instanceof GeneratedMessage.Builder) {
+        return WireFormat.Utf8Validation.LAZY;
+      }
+      return WireFormat.Utf8Validation.LOOSE;
     }
 
     public Object finish() {
@@ -651,11 +659,14 @@
       throw new UnsupportedOperationException(
           "newMergeTargetForField() called on FieldSet object");
     }
-    
-    public Object readPrimitiveField(
-        CodedInputStream input, WireFormat.FieldType type,
-        boolean checkUtf8) throws IOException {
-      return FieldSet.readPrimitiveField(input, type, checkUtf8);
+
+    public WireFormat.Utf8Validation
+        getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
+      if (descriptor.needsUtf8Check()) {
+        return WireFormat.Utf8Validation.STRICT;
+      }
+      // TODO(liujisi): support lazy strings for ExtesnsionSet.
+      return WireFormat.Utf8Validation.LOOSE;
     }
 
     public Object finish() {
@@ -767,8 +778,8 @@
         }
       } else {
         while (input.getBytesUntilLimit() > 0) {
-          final Object value =
-              target.readPrimitiveField(input, field.getLiteType(), field.needsUtf8Check());
+          final Object value = WireFormat.readPrimitiveField(
+              input, field.getLiteType(), target.getUtf8Validation(field));
           target.addRepeatedField(field, value);
         }
       }
@@ -801,7 +812,8 @@
           }
           break;
         default:
-          value = target.readPrimitiveField(input, field.getLiteType(), field.needsUtf8Check());
+          value = WireFormat.readPrimitiveField(
+              input, field.getLiteType(), target.getUtf8Validation(field));
           break;
       }
 
diff --git a/java/src/main/java/com/google/protobuf/Parser.java b/java/src/main/java/com/google/protobuf/Parser.java
index f636014..227c02b 100644
--- a/java/src/main/java/com/google/protobuf/Parser.java
+++ b/java/src/main/java/com/google/protobuf/Parser.java
@@ -227,8 +227,8 @@
    * {@link MessageLite#writeDelimitedTo(java.io.OutputStream)} to write
    * messages in this format.
    *
-   * @return True if successful, or false if the stream is at EOF when the
-   *         method starts. Any other error (including reaching EOF during
+   * @return Parsed message if successful, or null if the stream is at EOF when
+   *         the method starts. Any other error (including reaching EOF during
    *         parsing) will cause an exception to be thrown.
    */
   public MessageType parseDelimitedFrom(InputStream input)
diff --git a/java/src/main/java/com/google/protobuf/RopeByteString.java b/java/src/main/java/com/google/protobuf/RopeByteString.java
index fa23c9d..168bcce 100644
--- a/java/src/main/java/com/google/protobuf/RopeByteString.java
+++ b/java/src/main/java/com/google/protobuf/RopeByteString.java
@@ -30,9 +30,9 @@
 
 package com.google.protobuf;
 
-import java.io.InvalidObjectException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InvalidObjectException;
 import java.io.ObjectInputStream;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
@@ -420,7 +420,11 @@
   @Override
   public String toString(String charsetName)
       throws UnsupportedEncodingException {
-    return new String(toByteArray(), charsetName);
+    // Optimize for empty strings, but ensure we don't silently ignore invalid
+    // encodings.
+    return size() == 0 && UTF_8.equals(charsetName)
+        ? ""
+        : new String(toByteArray(), charsetName);
   }
 
   // =================================================================
diff --git a/java/src/main/java/com/google/protobuf/TextFormat.java b/java/src/main/java/com/google/protobuf/TextFormat.java
index 4f6756e..dd2b460 100644
--- a/java/src/main/java/com/google/protobuf/TextFormat.java
+++ b/java/src/main/java/com/google/protobuf/TextFormat.java
@@ -409,9 +409,9 @@
 
         case STRING:
           generator.print("\"");
-          generator.print(escapeNonAscii ?
-              escapeText((String) value) :
-              escapeDoubleQuotesAndBackslashes((String) value)
+          generator.print(escapeNonAscii
+              ? escapeText((String) value)
+              : escapeDoubleQuotesAndBackslashes((String) value)
                   .replace("\n", "\\n"));
           generator.print("\"");
           break;
@@ -730,8 +730,8 @@
       }
 
       final char c = currentToken.charAt(0);
-      return ('0' <= c && c <= '9') ||
-             c == '-' || c == '+';
+      return ('0' <= c && c <= '9')
+          || c == '-' || c == '+';
     }
 
     /**
@@ -749,10 +749,10 @@
     public String consumeIdentifier() throws ParseException {
       for (int i = 0; i < currentToken.length(); i++) {
         final char c = currentToken.charAt(i);
-        if (('a' <= c && c <= 'z') ||
-            ('A' <= c && c <= 'Z') ||
-            ('0' <= c && c <= '9') ||
-            (c == '_') || (c == '.')) {
+        if (('a' <= c && c <= 'z')
+            || ('A' <= c && c <= 'Z')
+            || ('0' <= c && c <= '9')
+            || (c == '_') || (c == '.')) {
           // OK
         } else {
           throw parseException(
@@ -941,14 +941,14 @@
      * Otherwise, throw a {@link ParseException}.
      */
     public boolean consumeBoolean() throws ParseException {
-      if (currentToken.equals("true") ||
-          currentToken.equals("t") ||
-          currentToken.equals("1")) {
+      if (currentToken.equals("true")
+          || currentToken.equals("t")
+          || currentToken.equals("1")) {
         nextToken();
         return true;
-      } else if (currentToken.equals("false") ||
-                 currentToken.equals("f") ||
-                 currentToken.equals("0")) {
+      } else if (currentToken.equals("false")
+          || currentToken.equals("f")
+          || currentToken.equals("0")) {
         nextToken();
         return false;
       } else {
@@ -999,14 +999,15 @@
      */
     private void consumeByteString(List<ByteString> list)
         throws ParseException {
-      final char quote = currentToken.length() > 0 ? currentToken.charAt(0)
-                                                   : '\0';
+      final char quote = currentToken.length() > 0
+          ? currentToken.charAt(0)
+          : '\0';
       if (quote != '\"' && quote != '\'') {
         throw parseException("Expected string.");
       }
 
-      if (currentToken.length() < 2 ||
-          currentToken.charAt(currentToken.length() - 1) != quote) {
+      if (currentToken.length() < 2
+          || currentToken.charAt(currentToken.length() - 1) != quote) {
         throw parseException("String missing ending quote.");
       }
 
@@ -1340,8 +1341,8 @@
         } else {
           if (extension.descriptor.getContainingType() != type) {
             throw tokenizer.parseExceptionPreviousToken(
-              "Extension \"" + name + "\" does not extend message type \"" +
-              type.getFullName() + "\".");
+              "Extension \"" + name + "\" does not extend message type \""
+              + type.getFullName() + "\".");
           }
           field = extension.descriptor;
         }
@@ -1365,20 +1366,20 @@
           }
         }
         // Again, special-case group names as described above.
-        if (field != null && field.getType() == FieldDescriptor.Type.GROUP &&
-            !field.getMessageType().getName().equals(name)) {
+        if (field != null && field.getType() == FieldDescriptor.Type.GROUP
+            && !field.getMessageType().getName().equals(name)) {
           field = null;
         }
 
         if (field == null) {
           if (!allowUnknownFields) {
             throw tokenizer.parseExceptionPreviousToken(
-              "Message type \"" + type.getFullName() +
-              "\" has no field named \"" + name + "\".");
+              "Message type \"" + type.getFullName()
+              + "\" has no field named \"" + name + "\".");
           } else {
             logger.warning(
-              "Message type \"" + type.getFullName() +
-              "\" has no field named \"" + name + "\".");
+              "Message type \"" + type.getFullName()
+              + "\" has no field named \"" + name + "\".");
           }
         }
       }
@@ -1391,8 +1392,9 @@
         // start with "{" or "<" which indicates the beginning of a message body.
         // If there is no ":" or there is a "{" or "<" after ":", this field has
         // to be a message or the input is ill-formed.
-        if (tokenizer.tryConsume(":") && !tokenizer.lookingAt("{") &&
-            !tokenizer.lookingAt("<")) {
+        if (tokenizer.tryConsume(":")
+            && !tokenizer.lookingAt("{")
+            && !tokenizer.lookingAt("<")) {
           skipFieldValue(tokenizer);
         } else {
           skipFieldMessage(tokenizer);
@@ -1516,16 +1518,16 @@
               value = enumType.findValueByNumber(number);
               if (value == null) {
                 throw tokenizer.parseExceptionPreviousToken(
-                  "Enum type \"" + enumType.getFullName() +
-                  "\" has no value with number " + number + '.');
+                  "Enum type \"" + enumType.getFullName()
+                  + "\" has no value with number " + number + '.');
               }
             } else {
               final String id = tokenizer.consumeIdentifier();
               value = enumType.findValueByName(id);
               if (value == null) {
                 throw tokenizer.parseExceptionPreviousToken(
-                  "Enum type \"" + enumType.getFullName() +
-                  "\" has no value named \"" + id + "\".");
+                  "Enum type \"" + enumType.getFullName()
+                  + "\" has no value named \"" + id + "\".");
               }
             }
 
@@ -1578,8 +1580,9 @@
       // start with "{" or "<" which indicates the beginning of a message body.
       // If there is no ":" or there is a "{" or "<" after ":", this field has
       // to be a message or the input is ill-formed.
-      if (tokenizer.tryConsume(":") && !tokenizer.lookingAt("<") &&
-          !tokenizer.lookingAt("{")) {
+      if (tokenizer.tryConsume(":")
+          && !tokenizer.lookingAt("<")
+          && !tokenizer.lookingAt("{")) {
         skipFieldValue(tokenizer);
       } else {
         skipFieldMessage(tokenizer);
@@ -1617,11 +1620,11 @@
         while (tokenizer.tryConsumeString()) {}
         return;
       }
-      if (!tokenizer.tryConsumeIdentifier() &&  // includes enum & boolean
-          !tokenizer.tryConsumeInt64() &&       // includes int32
-          !tokenizer.tryConsumeUInt64() &&      // includes uint32
-          !tokenizer.tryConsumeDouble() &&
-          !tokenizer.tryConsumeFloat()) {
+      if (!tokenizer.tryConsumeIdentifier()   // includes enum & boolean
+          && !tokenizer.tryConsumeInt64()     // includes int32
+          && !tokenizer.tryConsumeUInt64()    // includes uint32
+          && !tokenizer.tryConsumeDouble()
+          && !tokenizer.tryConsumeFloat()) {
         throw tokenizer.parseException(
             "Invalid field value: " + tokenizer.currentToken);
       }
@@ -1647,19 +1650,19 @@
    * which no defined short-hand escape sequence is defined will be escaped
    * using 3-digit octal sequences.
    */
-  private static String escapeBytes(final ByteSequence input) {
+  public static String escapeBytes(final ByteSequence input) {
     final StringBuilder builder = new StringBuilder(input.size());
     for (int i = 0; i < input.size(); i++) {
       final byte b = input.byteAt(i);
       switch (b) {
         // Java does not recognize \a or \v, apparently.
-        case 0x07: builder.append("\\a" ); break;
-        case '\b': builder.append("\\b" ); break;
-        case '\f': builder.append("\\f" ); break;
-        case '\n': builder.append("\\n" ); break;
-        case '\r': builder.append("\\r" ); break;
-        case '\t': builder.append("\\t" ); break;
-        case 0x0b: builder.append("\\v" ); break;
+        case 0x07: builder.append("\\a"); break;
+        case '\b': builder.append("\\b"); break;
+        case '\f': builder.append("\\f"); break;
+        case '\n': builder.append("\\n"); break;
+        case '\r': builder.append("\\r"); break;
+        case '\t': builder.append("\\t"); break;
+        case 0x0b: builder.append("\\v"); break;
         case '\\': builder.append("\\\\"); break;
         case '\'': builder.append("\\\'"); break;
         case '"' : builder.append("\\\""); break;
@@ -1688,11 +1691,13 @@
    * which no defined short-hand escape sequence is defined will be escaped
    * using 3-digit octal sequences.
    */
-  static String escapeBytes(final ByteString input) {
+  public static String escapeBytes(final ByteString input) {
     return escapeBytes(new ByteSequence() {
+      @Override
       public int size() {
         return input.size();
       }
+      @Override
       public byte byteAt(int offset) {
         return input.byteAt(offset);
       }
@@ -1702,11 +1707,13 @@
   /**
    * Like {@link #escapeBytes(ByteString)}, but used for byte array.
    */
-  static String escapeBytes(final byte[] input) {
+  public static String escapeBytes(final byte[] input) {
     return escapeBytes(new ByteSequence() {
+      @Override
       public int size() {
         return input.length;
       }
+      @Override
       public byte byteAt(int offset) {
         return input[offset];
       }
@@ -1749,7 +1756,7 @@
               code = code * 8 + digitValue(input.byteAt(i));
             }
             // TODO: Check that 0 <= code && code <= 0xFF.
-            result[pos++] = (byte)code;
+            result[pos++] = (byte) code;
           } else {
             switch (c) {
               case 'a' : result[pos++] = 0x07; break;
@@ -1777,12 +1784,12 @@
                   ++i;
                   code = code * 16 + digitValue(input.byteAt(i));
                 }
-                result[pos++] = (byte)code;
+                result[pos++] = (byte) code;
                 break;
 
               default:
                 throw new InvalidEscapeSequenceException(
-                    "Invalid escape sequence: '\\" + (char)c + '\'');
+                    "Invalid escape sequence: '\\" + (char) c + '\'');
             }
           }
         } else {
@@ -1841,9 +1848,9 @@
 
   /** Is this a hex digit? */
   private static boolean isHex(final byte c) {
-    return ('0' <= c && c <= '9') ||
-           ('a' <= c && c <= 'f') ||
-           ('A' <= c && c <= 'F');
+    return ('0' <= c && c <= '9')
+        || ('a' <= c && c <= 'f')
+        || ('A' <= c && c <= 'F');
   }
 
   /**
diff --git a/java/src/main/java/com/google/protobuf/WireFormat.java b/java/src/main/java/com/google/protobuf/WireFormat.java
index eba2528..ba83b66 100644
--- a/java/src/main/java/com/google/protobuf/WireFormat.java
+++ b/java/src/main/java/com/google/protobuf/WireFormat.java
@@ -30,6 +30,8 @@
 
 package com.google.protobuf;
 
+import java.io.IOException;
+
 /**
  * This class is used internally by the Protocol Buffer library and generated
  * message implementations.  It is public only because those generated messages
@@ -160,4 +162,84 @@
     makeTag(MESSAGE_SET_TYPE_ID, WIRETYPE_VARINT);
   static final int MESSAGE_SET_MESSAGE_TAG =
     makeTag(MESSAGE_SET_MESSAGE, WIRETYPE_LENGTH_DELIMITED);
+
+  /**
+   * Validation level for handling incoming string field data which potentially
+   * contain non-UTF8 bytes.
+   */
+  enum Utf8Validation {
+    /** Eagerly parses to String; silently accepts invalid UTF8 bytes. */
+    LOOSE {
+      Object readString(CodedInputStream input) throws IOException {
+        return input.readString();
+      }
+    },
+    /** Eagerly parses to String; throws an IOException on invalid bytes. */
+    STRICT {
+      Object readString(CodedInputStream input) throws IOException {
+        return input.readStringRequireUtf8();
+      }
+    },
+    /** Keep data as ByteString; validation/conversion to String is lazy. */
+    LAZY {
+      Object readString(CodedInputStream input) throws IOException {
+        return input.readBytes();
+      }
+    };
+
+    /** Read a string field from the input with the proper UTF8 validation. */
+    abstract Object readString(CodedInputStream input) throws IOException;
+  }
+
+  /**
+   * Read a field of any primitive type for immutable messages from a
+   * CodedInputStream. Enums, groups, and embedded messages are not handled by
+   * this method.
+   *
+   * @param input The stream from which to read.
+   * @param type Declared type of the field.
+   * @param utf8Validation Different string UTF8 validation level for handling
+   *                       string fields.
+   * @return An object representing the field's value, of the exact
+   *         type which would be returned by
+   *         {@link Message#getField(Descriptors.FieldDescriptor)} for
+   *         this field.
+   */
+  static Object readPrimitiveField(
+      CodedInputStream input,
+      FieldType type,
+      Utf8Validation utf8Validation) throws IOException {
+    switch (type) {
+      case DOUBLE  : return input.readDouble  ();
+      case FLOAT   : return input.readFloat   ();
+      case INT64   : return input.readInt64   ();
+      case UINT64  : return input.readUInt64  ();
+      case INT32   : return input.readInt32   ();
+      case FIXED64 : return input.readFixed64 ();
+      case FIXED32 : return input.readFixed32 ();
+      case BOOL    : return input.readBool    ();
+      case BYTES   : return input.readBytes   ();
+      case UINT32  : return input.readUInt32  ();
+      case SFIXED32: return input.readSFixed32();
+      case SFIXED64: return input.readSFixed64();
+      case SINT32  : return input.readSInt32  ();
+      case SINT64  : return input.readSInt64  ();
+
+      case STRING  : return utf8Validation.readString(input);
+      case GROUP:
+        throw new IllegalArgumentException(
+          "readPrimitiveField() cannot handle nested groups.");
+      case MESSAGE:
+        throw new IllegalArgumentException(
+          "readPrimitiveField() cannot handle embedded messages.");
+      case ENUM:
+        // We don't handle enums because we don't know what to do if the
+        // value is not recognized.
+        throw new IllegalArgumentException(
+          "readPrimitiveField() cannot handle enums.");
+    }
+
+    throw new RuntimeException(
+      "There is no way to get here, but the compiler thinks otherwise.");
+  }
 }
diff --git a/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
index 2d101ba..2bd8d1a 100644
--- a/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
+++ b/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
@@ -58,8 +58,8 @@
 import protobuf_unittest.UnittestProto.ForeignMessageOrBuilder;
 import protobuf_unittest.UnittestProto.NestedTestAllTypes;
 import protobuf_unittest.UnittestProto.TestAllExtensions;
-import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage;
 import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage;
 import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
 import protobuf_unittest.UnittestProto.TestExtremeDefaultValues;
 import protobuf_unittest.UnittestProto.TestOneof2;
diff --git a/java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java b/java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java
index e67c6d2..211b569 100644
--- a/java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java
+++ b/java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java
@@ -30,6 +30,9 @@
 
 package com.google.protobuf;
 
+import static protobuf_unittest.UnittestProto.optionalInt32Extension;
+import static protobuf_unittest.UnittestProto.optionalInt64Extension;
+
 import protobuf_unittest.UnittestProto.TestAllExtensions;
 import protobuf_unittest.UnittestProto.TestAllTypes;
 
@@ -111,12 +114,146 @@
     assertNotEqual(message.toByteString(), lazyField.toByteString());
   }
 
+  public void testMergeExtensions() throws Exception {
+    TestAllExtensions message = TestUtil.getAllExtensionsSet();
+    LazyFieldLite original = createLazyFieldLiteFromMessage(message);
+    LazyFieldLite merged = new LazyFieldLite();
+    merged.merge(original);
+    TestAllExtensions value = (TestAllExtensions) merged.getValue(
+        TestAllExtensions.getDefaultInstance());
+    assertEquals(message, value);
+  }
+
+  public void testEmptyLazyField() throws Exception {
+    LazyFieldLite field = new LazyFieldLite();
+    assertEquals(0, field.getSerializedSize());
+    assertEquals(ByteString.EMPTY, field.toByteString());
+  }
+
+  public void testInvalidProto() throws Exception {
+    // Silently fails and uses the default instance.
+    LazyFieldLite field = new LazyFieldLite(
+        TestUtil.getExtensionRegistry(), ByteString.copyFromUtf8("invalid"));
+    assertEquals(
+        TestAllTypes.getDefaultInstance(), field.getValue(TestAllTypes.getDefaultInstance()));
+    assertEquals(0, field.getSerializedSize());
+    assertEquals(ByteString.EMPTY, field.toByteString());
+  }
+
+  public void testMergeBeforeParsing() throws Exception {
+    TestAllTypes message1 = TestAllTypes.newBuilder().setOptionalInt32(1).build();
+    LazyFieldLite field1 = createLazyFieldLiteFromMessage(message1);
+    TestAllTypes message2 = TestAllTypes.newBuilder().setOptionalInt64(2).build();
+    LazyFieldLite field2 = createLazyFieldLiteFromMessage(message2);
+
+    field1.merge(field2);
+    TestAllTypes expected =
+        TestAllTypes.newBuilder().setOptionalInt32(1).setOptionalInt64(2).build();
+    assertEquals(expected, field1.getValue(TestAllTypes.getDefaultInstance()));
+  }
+
+  public void testMergeOneNotParsed() throws Exception {
+    // Test a few different paths that involve one message that was not parsed.
+    TestAllTypes message1 = TestAllTypes.newBuilder().setOptionalInt32(1).build();
+    TestAllTypes message2 = TestAllTypes.newBuilder().setOptionalInt64(2).build();
+    TestAllTypes expected =
+        TestAllTypes.newBuilder().setOptionalInt32(1).setOptionalInt64(2).build();
+
+    LazyFieldLite field1 = LazyFieldLite.fromValue(message1);
+    field1.getValue(TestAllTypes.getDefaultInstance());  // Force parsing.
+    LazyFieldLite field2 = createLazyFieldLiteFromMessage(message2);
+    field1.merge(field2);
+    assertEquals(expected, field1.getValue(TestAllTypes.getDefaultInstance()));
+
+    // Now reverse which one is parsed first.
+    field1 = LazyFieldLite.fromValue(message1);
+    field2 = createLazyFieldLiteFromMessage(message2);
+    field2.getValue(TestAllTypes.getDefaultInstance());  // Force parsing.
+    field1.merge(field2);
+    assertEquals(expected, field1.getValue(TestAllTypes.getDefaultInstance()));
+  }
+
+  public void testMergeInvalid() throws Exception {
+    // Test a few different paths that involve one message that was not parsed.
+    TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt32(1).build();
+    LazyFieldLite valid = LazyFieldLite.fromValue(message);
+    LazyFieldLite invalid = new LazyFieldLite(
+        TestUtil.getExtensionRegistry(), ByteString.copyFromUtf8("invalid"));
+    invalid.merge(valid);
+
+    // We swallow the exception and just use the set field.
+    assertEquals(message, invalid.getValue(TestAllTypes.getDefaultInstance()));
+  }
+
+  public void testMergeKeepsExtensionsWhenPossible() throws Exception {
+    // In this test we attempt to only use the empty registry, which will strip out all extensions
+    // when serializing and then parsing. We verify that each code path will attempt to not
+    // serialize and parse a message that was set directly without going through the
+    // extensionRegistry.
+    TestAllExtensions messageWithExtensions =
+        TestAllExtensions.newBuilder().setExtension(optionalInt32Extension, 42).build();
+    TestAllExtensions emptyMessage = TestAllExtensions.newBuilder().build();
+
+    ExtensionRegistryLite emptyRegistry = ExtensionRegistryLite.getEmptyRegistry();
+
+    LazyFieldLite field = LazyFieldLite.fromValue(messageWithExtensions);
+    field.merge(createLazyFieldLiteFromMessage(emptyRegistry, emptyMessage));
+    assertEquals(messageWithExtensions, field.getValue(TestAllExtensions.getDefaultInstance()));
+
+    // Now reverse the order of the merging.
+    field = createLazyFieldLiteFromMessage(emptyRegistry, emptyMessage);
+    field.merge(LazyFieldLite.fromValue(messageWithExtensions));
+    assertEquals(messageWithExtensions, field.getValue(TestAllExtensions.getDefaultInstance()));
+
+    // Now try parsing the empty field first.
+    field = LazyFieldLite.fromValue(messageWithExtensions);
+    LazyFieldLite other = createLazyFieldLiteFromMessage(emptyRegistry, emptyMessage);
+    other.getValue(TestAllExtensions.getDefaultInstance());  // Force parsing.
+    field.merge(other);
+    assertEquals(messageWithExtensions, field.getValue(TestAllExtensions.getDefaultInstance()));
+
+    // And again reverse.
+    field = createLazyFieldLiteFromMessage(emptyRegistry, emptyMessage);
+    field.getValue(TestAllExtensions.getDefaultInstance());  // Force parsing.
+    other = LazyFieldLite.fromValue(messageWithExtensions);
+    field.merge(other);
+    assertEquals(messageWithExtensions, field.getValue(TestAllExtensions.getDefaultInstance()));
+  }
+
+  public void testMergeMightLoseExtensions() throws Exception {
+    // Test that we don't know about the extensions when parsing.
+    TestAllExtensions message1 =
+        TestAllExtensions.newBuilder().setExtension(optionalInt32Extension, 1).build();
+    TestAllExtensions message2 =
+        TestAllExtensions.newBuilder().setExtension(optionalInt64Extension, 2L).build();
+
+    LazyFieldLite field = LazyFieldLite.fromValue(message1);
+    field.merge(LazyFieldLite.fromValue(message2));
+
+    // We lose the extensions from message 2 because we have to serialize it and then parse it
+    // again, using the empty registry this time.
+    TestAllExtensions value =
+        (TestAllExtensions) field.getValue(TestAllExtensions.getDefaultInstance());
+    assertTrue(value.hasExtension(optionalInt32Extension));
+    assertEquals(Integer.valueOf(1), value.getExtension(optionalInt32Extension));
+    assertFalse(value.hasExtension(optionalInt64Extension));
+
+    // The field is still there, it is just unknown.
+    assertTrue(value.getUnknownFields()
+        .hasField(optionalInt64Extension.getDescriptor().getNumber()));
+  }
+
 
   // Help methods.
 
   private LazyFieldLite createLazyFieldLiteFromMessage(MessageLite message) {
+    return createLazyFieldLiteFromMessage(TestUtil.getExtensionRegistry(), message);
+  }
+
+  private LazyFieldLite createLazyFieldLiteFromMessage(
+      ExtensionRegistryLite extensionRegistry, MessageLite message) {
     ByteString bytes = message.toByteString();
-    return new LazyFieldLite(TestUtil.getExtensionRegistry(), bytes);
+    return new LazyFieldLite(extensionRegistry, bytes);
   }
 
   private void changeValue(LazyFieldLite lazyField) {
diff --git a/java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java b/java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java
index 9de794f..afe0fff 100644
--- a/java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java
+++ b/java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java
@@ -30,6 +30,7 @@
 
 package com.google.protobuf;
 
+import protobuf_unittest.LazyFieldsLite.LazyExtension;
 import protobuf_unittest.LazyFieldsLite.LazyInnerMessageLite;
 import protobuf_unittest.LazyFieldsLite.LazyMessageLite;
 import protobuf_unittest.LazyFieldsLite.LazyNestedInnerMessageLite;
@@ -285,4 +286,22 @@
 
     assertEquals(bytes, deserialized.toByteString());
   }
+
+  public void testExtensions() throws Exception {
+    LazyInnerMessageLite.Builder innerBuilder = LazyInnerMessageLite.newBuilder();
+    innerBuilder.setExtension(
+        LazyExtension.extension, LazyExtension.newBuilder()
+        .setName("name").build());
+    assertTrue(innerBuilder.hasExtension(LazyExtension.extension));
+    assertEquals("name", innerBuilder.getExtension(LazyExtension.extension).getName());
+
+    LazyInnerMessageLite innerMessage = innerBuilder.build();
+    assertTrue(innerMessage.hasExtension(LazyExtension.extension));
+    assertEquals("name", innerMessage.getExtension(LazyExtension.extension).getName());
+
+    LazyMessageLite lite = LazyMessageLite.newBuilder()
+        .setInner(innerMessage).build();
+    assertTrue(lite.getInner().hasExtension(LazyExtension.extension));
+    assertEquals("name", lite.getInner().getExtension(LazyExtension.extension).getName());
+  }
 }
diff --git a/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java b/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java
index ff39ca3..046832d 100644
--- a/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java
+++ b/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java
@@ -289,7 +289,6 @@
     assertEquals("Output.reset() resets the output", 0, output.size());
     assertEquals("Output.reset() resets the output",
         ByteString.EMPTY, output.toByteString());
-    
   }
 
   public void testToString() throws UnsupportedEncodingException {
@@ -299,6 +298,27 @@
     assertEquals(classUnderTest + " unicode must match", testString, roundTripString);
   }
 
+  public void testToString_returnsCanonicalEmptyString() throws UnsupportedEncodingException{
+    assertSame(classUnderTest + " must be the same string references",
+        ByteString.EMPTY.toString(UTF_8), new LiteralByteString(new byte[]{}).toString(UTF_8));
+  }
+
+  public void testToString_raisesException() throws UnsupportedEncodingException{
+    try {
+      ByteString.EMPTY.toString("invalid");
+      fail("Should have thrown an exception.");
+    } catch (UnsupportedEncodingException expected) {
+      // This is success
+    }
+
+    try {
+      new LiteralByteString(referenceBytes).toString("invalid");
+      fail("Should have thrown an exception.");
+    } catch (UnsupportedEncodingException expected) {
+      // This is success
+    }
+  }
+
   public void testEquals() {
     assertEquals(classUnderTest + " must not equal null", false, stringUnderTest.equals(null));
     assertEquals(classUnderTest + " must equal self", stringUnderTest, stringUnderTest);
@@ -311,7 +331,7 @@
 
     byte[] mungedBytes = new byte[referenceBytes.length];
     System.arraycopy(referenceBytes, 0, mungedBytes, 0, referenceBytes.length);
-    mungedBytes[mungedBytes.length - 5] ^= 0xFF;
+    mungedBytes[mungedBytes.length - 5] = (byte) (mungedBytes[mungedBytes.length - 5] ^ 0xFF);
     assertFalse(classUnderTest + " must not equal every string with the same length",
         stringUnderTest.equals(new LiteralByteString(mungedBytes)));
   }
diff --git a/java/src/test/java/com/google/protobuf/MapForProto2Test.java b/java/src/test/java/com/google/protobuf/MapForProto2Test.java
index 33ba715..78cba1b 100644
--- a/java/src/test/java/com/google/protobuf/MapForProto2Test.java
+++ b/java/src/test/java/com/google/protobuf/MapForProto2Test.java
@@ -34,6 +34,7 @@
 import map_test.MapForProto2TestProto.TestMap;
 import map_test.MapForProto2TestProto.TestMap.MessageValue;
 import map_test.MapForProto2TestProto.TestMap.MessageWithRequiredFields;
+import map_test.MapForProto2TestProto.TestRecursiveMap;
 import map_test.MapForProto2TestProto.TestUnknownEnumValue;
 
 import junit.framework.TestCase;
@@ -499,4 +500,17 @@
     message = builder.build();
     assertTrue(message.isInitialized());
   }
+
+  public void testRecursiveMap() throws Exception {
+    TestRecursiveMap.Builder builder = TestRecursiveMap.newBuilder();
+    builder.getMutableRecursiveMapField().put(
+        1, TestRecursiveMap.newBuilder().setValue(2).build());
+    builder.getMutableRecursiveMapField().put(
+        3, TestRecursiveMap.newBuilder().setValue(4).build());
+    ByteString data = builder.build().toByteString();
+
+    TestRecursiveMap message = TestRecursiveMap.parseFrom(data);
+    assertEquals(2, message.getRecursiveMapField().get(1).getValue());
+    assertEquals(4, message.getRecursiveMapField().get(3).getValue());
+  }
 }
diff --git a/java/src/test/java/com/google/protobuf/MapTest.java b/java/src/test/java/com/google/protobuf/MapTest.java
index 6a1e907..b8e67b7 100644
--- a/java/src/test/java/com/google/protobuf/MapTest.java
+++ b/java/src/test/java/com/google/protobuf/MapTest.java
@@ -269,7 +269,6 @@
     assertFalse(m2.equals(m1));
   }
 
-
   public void testNestedBuilderOnChangeEventPropagation() {
     TestOnChangeEventPropagation.Builder parent =
         TestOnChangeEventPropagation.newBuilder();
diff --git a/java/src/test/java/com/google/protobuf/RopeByteStringTest.java b/java/src/test/java/com/google/protobuf/RopeByteStringTest.java
index b397019..0f2344d 100644
--- a/java/src/test/java/com/google/protobuf/RopeByteStringTest.java
+++ b/java/src/test/java/com/google/protobuf/RopeByteStringTest.java
@@ -118,6 +118,34 @@
         flatString.hashCode(), unicode.hashCode());
   }
 
+  @Override
+  public void testToString_returnsCanonicalEmptyString() throws UnsupportedEncodingException {
+    RopeByteString ropeByteString =
+        RopeByteString.newInstanceForTest(ByteString.EMPTY, ByteString.EMPTY);
+    assertSame(classUnderTest + " must be the same string references",
+        ByteString.EMPTY.toString(UTF_8), ropeByteString.toString(UTF_8));
+  }
+
+  public void testToString_raisesException() throws UnsupportedEncodingException{
+    try {
+      ByteString byteString =
+          RopeByteString.newInstanceForTest(ByteString.EMPTY, ByteString.EMPTY);
+      byteString.toString("invalid");
+      fail("Should have thrown an exception.");
+    } catch (UnsupportedEncodingException expected) {
+      // This is success
+    }
+
+    try {
+      ByteString byteString = RopeByteString.concatenate(ByteString.copyFromUtf8("foo"),
+          ByteString.copyFromUtf8("bar"));
+      byteString.toString("invalid");
+      fail("Should have thrown an exception.");
+    } catch (UnsupportedEncodingException expected) {
+      // This is success
+    }
+  }
+
   public void testJavaSerialization() throws Exception {
     ByteArrayOutputStream out = new ByteArrayOutputStream();
     ObjectOutputStream oos = new ObjectOutputStream(out);
diff --git a/java/src/test/java/com/google/protobuf/lazy_fields_lite.proto b/java/src/test/java/com/google/protobuf/lazy_fields_lite.proto
index 015dc26..5580f72 100644
--- a/java/src/test/java/com/google/protobuf/lazy_fields_lite.proto
+++ b/java/src/test/java/com/google/protobuf/lazy_fields_lite.proto
@@ -54,6 +54,15 @@
   optional int32 num = 1;
   optional int32 num_with_default = 2 [default = 42];
   optional LazyNestedInnerMessageLite nested = 3 [lazy = true];
+
+  extensions 1000 to max;
+}
+
+message LazyExtension {
+  extend LazyInnerMessageLite {
+    optional LazyExtension extension = 1000;
+  }
+  optional string name = 1;
 }
 
 message LazyNestedInnerMessageLite {
diff --git a/java/src/test/java/com/google/protobuf/map_for_proto2_lite_test.proto b/java/src/test/java/com/google/protobuf/map_for_proto2_lite_test.proto
index a1fe856..d5418f2 100644
--- a/java/src/test/java/com/google/protobuf/map_for_proto2_lite_test.proto
+++ b/java/src/test/java/com/google/protobuf/map_for_proto2_lite_test.proto
@@ -63,6 +63,13 @@
   // parsing behavior of TestMap regarding unknown enum values.
   map<int32, int32> int32_to_int32_field = 4;
 }
+
+// Test that the maps initialization code works correctly when the map field
+// references the containing message.
+message TestRecursiveMap {
+  optional int32 value = 1;
+  map<int32, TestRecursiveMap> recursive_map_field = 2;
+}
 package map_for_proto2_lite_test;
 option java_package = "map_lite_test";
 option optimize_for = LITE_RUNTIME;
diff --git a/java/src/test/java/com/google/protobuf/map_for_proto2_test.proto b/java/src/test/java/com/google/protobuf/map_for_proto2_test.proto
index a0ec7ac..a9be516 100644
--- a/java/src/test/java/com/google/protobuf/map_for_proto2_test.proto
+++ b/java/src/test/java/com/google/protobuf/map_for_proto2_test.proto
@@ -65,3 +65,10 @@
   // parsing behavior of TestMap regarding unknown enum values.
   map<int32, int32> int32_to_int32_field = 4;
 }
+
+// Test that the maps initialization code works correctly when the map field
+// references the containing message.
+message TestRecursiveMap {
+  optional int32 value = 1;
+  map<int32, TestRecursiveMap> recursive_map_field = 2;
+}
diff --git a/java/src/test/java/com/google/protobuf/map_test.proto b/java/src/test/java/com/google/protobuf/map_test.proto
index 105ee3f..bf692c2 100644
--- a/java/src/test/java/com/google/protobuf/map_test.proto
+++ b/java/src/test/java/com/google/protobuf/map_test.proto
@@ -36,6 +36,7 @@
 option java_outer_classname = "MapTestProto";
 option java_generate_equals_and_hash = true;
 
+
 message TestMap {
   message MessageValue {
     optional int32 value = 1;
diff --git a/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto b/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto
index 67035fd..dc08261 100644
--- a/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto
+++ b/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto
@@ -45,6 +45,7 @@
 option java_outer_classname = "TestBadIdentifiersProto";
 option java_generate_equals_and_hash = true;
 
+
 message TestMessage {
   optional string cached_size = 1;
   optional string serialized_size = 2;
diff --git a/javanano/pom.xml b/javanano/pom.xml
index 50056cd..53dd666 100644
--- a/javanano/pom.xml
+++ b/javanano/pom.xml
@@ -10,7 +10,7 @@
   </parent>
   <groupId>com.google.protobuf.nano</groupId>
   <artifactId>protobuf-javanano</artifactId>
-  <version>3.0.0-alpha-2</version>
+  <version>3.0.0-alpha-3-pre</version>
   <packaging>bundle</packaging>
   <name>Protocol Buffer JavaNano API</name>
   <description>
@@ -156,7 +156,7 @@
           <instructions>
             <Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL>
             <Bundle-SymbolicName>com.google.protobuf</Bundle-SymbolicName>
-            <Export-Package>com.google.protobuf;version=3.0.0-alpha-2</Export-Package>
+            <Export-Package>com.google.protobuf;version=3.0.0-alpha-3-pre</Export-Package>
           </instructions>
         </configuration>
       </plugin>
diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py
index d1af74b..ef8c9c5 100755
--- a/python/google/protobuf/__init__.py
+++ b/python/google/protobuf/__init__.py
@@ -32,4 +32,4 @@
 #
 # Copyright 2007 Google Inc. All Rights Reserved.
 
-__version__ = '3.0.0-alpha-2'
+__version__ = '3.0.0-alpha-3-pre'
diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py
index 4d4de51..ed1298a 100755
--- a/python/google/protobuf/internal/message_test.py
+++ b/python/google/protobuf/internal/message_test.py
@@ -51,10 +51,10 @@
 import unittest
 
 from google.apputils import basetest
+from google.protobuf.internal import _parameterized
 from google.protobuf import unittest_pb2
 from google.protobuf import unittest_proto3_arena_pb2
 from google.protobuf.internal import api_implementation
-from google.protobuf.internal import _parameterized
 from google.protobuf.internal import test_util
 from google.protobuf import message
 
@@ -982,6 +982,7 @@
     # This is still an incomplete proto - so serializing should fail
     self.assertRaises(message.EncodeError, unpickled_message.SerializeToString)
 
+
   # TODO(haberman): this isn't really a proto2-specific test except that this
   # message has a required field in it.  Should probably be factored out so
   # that we can test the other parts with proto3.
diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py
index b307620..7d5813f 100755
--- a/python/google/protobuf/internal/text_format_test.py
+++ b/python/google/protobuf/internal/text_format_test.py
@@ -37,12 +37,12 @@
 import re
 
 from google.apputils import basetest
+from google.protobuf.internal import _parameterized
 
 from google.protobuf import unittest_mset_pb2
 from google.protobuf import unittest_pb2
 from google.protobuf import unittest_proto3_arena_pb2
 from google.protobuf.internal import api_implementation
-from google.protobuf.internal import _parameterized
 from google.protobuf.internal import test_util
 from google.protobuf import text_format
 
diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc
index 6890cd0..e77d0bb 100644
--- a/python/google/protobuf/pyext/descriptor.cc
+++ b/python/google/protobuf/pyext/descriptor.cc
@@ -298,8 +298,9 @@
 
 PyTypeObject PyBaseDescriptor_Type = {
   PyVarObject_HEAD_INIT(&PyType_Type, 0)
-  "google.protobuf.internal."
-    "_message.DescriptorBase",          // tp_name
+  // Keep the fully qualified _message symbol in a line for opensource.
+  "google.protobuf.internal._message."
+  "DescriptorBase",                     // tp_name
   sizeof(PyBaseDescriptor),             // tp_basicsize
   0,                                    // tp_itemsize
   (destructor)Dealloc,                  // tp_dealloc
@@ -551,8 +552,9 @@
 
 PyTypeObject PyMessageDescriptor_Type = {
   PyVarObject_HEAD_INIT(&PyType_Type, 0)
-  C("google.protobuf.internal."
-    "_message.MessageDescriptor"),      // tp_name
+  // Keep the fully qualified _message symbol in a line for opensource.
+  C("google.protobuf.internal._message."
+    "MessageDescriptor"),      // tp_name
   sizeof(PyBaseDescriptor),             // tp_basicsize
   0,                                    // tp_itemsize
   0,                                    // tp_dealloc
@@ -979,8 +981,9 @@
 
 PyTypeObject PyEnumDescriptor_Type = {
   PyVarObject_HEAD_INIT(&PyType_Type, 0)
-  C("google.protobuf.internal."
-    "_message.EnumDescriptor"),         // tp_name
+  // Keep the fully qualified _message symbol in a line for opensource.
+  C("google.protobuf.internal._message."
+    "EnumDescriptor"),                  // tp_name
   sizeof(PyBaseDescriptor),             // tp_basicsize
   0,                                    // tp_itemsize
   0,                                    // tp_dealloc
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc
index c48f94c..a2b357b 100644
--- a/python/google/protobuf/pyext/message.cc
+++ b/python/google/protobuf/pyext/message.cc
@@ -2304,8 +2304,9 @@
 
 PyTypeObject CMessage_Type = {
   PyVarObject_HEAD_INIT(&PyType_Type, 0)
-  "google.protobuf."
-  "pyext._message.CMessage",           // tp_name
+  // Keep the fully qualified _message symbol in a line for opensource.
+  "google.protobuf.pyext._message."
+  "CMessage",                          // tp_name
   sizeof(CMessage),                    // tp_basicsize
   0,                                   //  tp_itemsize
   (destructor)cmessage::Dealloc,       //  tp_dealloc
diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc
index abc859d..0fe98e7 100644
--- a/python/google/protobuf/pyext/repeated_composite_container.cc
+++ b/python/google/protobuf/pyext/repeated_composite_container.cc
@@ -732,9 +732,10 @@
 
 PyTypeObject RepeatedCompositeContainer_Type = {
   PyVarObject_HEAD_INIT(&PyType_Type, 0)
-  "google.protobuf.pyext."
-  "_message.RepeatedCompositeContainer",  // tp_name
-  sizeof(RepeatedCompositeContainer),     // tp_basicsize
+  // Keep the fully qualified _message symbol in a line for opensource.
+  "google.protobuf.pyext._message."
+  "RepeatedCompositeContainer",        // tp_name
+  sizeof(RepeatedCompositeContainer),  // tp_basicsize
   0,                                   //  tp_itemsize
   (destructor)repeated_composite_container::Dealloc,  //  tp_dealloc
   0,                                   //  tp_print
diff --git a/python/google/protobuf/pyext/repeated_scalar_container.cc b/python/google/protobuf/pyext/repeated_scalar_container.cc
index 1747459..110a4c8 100644
--- a/python/google/protobuf/pyext/repeated_scalar_container.cc
+++ b/python/google/protobuf/pyext/repeated_scalar_container.cc
@@ -769,8 +769,9 @@
 
 PyTypeObject RepeatedScalarContainer_Type = {
   PyVarObject_HEAD_INIT(&PyType_Type, 0)
-  "google.protobuf."
-  "pyext._message.RepeatedScalarContainer",  // tp_name
+  // Keep the fully qualified _message symbol in a line for opensource.
+  "google.protobuf.pyext._message."
+  "RepeatedScalarContainer",           // tp_name
   sizeof(RepeatedScalarContainer),     // tp_basicsize
   0,                                   //  tp_itemsize
   (destructor)repeated_scalar_container::Dealloc,  //  tp_dealloc
diff --git a/python/setup.py b/python/setup.py
index c6ff745..b97fdae 100755
--- a/python/setup.py
+++ b/python/setup.py
@@ -150,7 +150,7 @@
     os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
 
   setup(name = 'protobuf',
-        version = '3.0.0-alpha-2',
+        version = '3.0.0-alpha-3-pre',
         packages = [ 'google' ],
         namespace_packages = [ 'google' ],
         google_test_dir = "google/protobuf/internal",
diff --git a/ruby/README.md b/ruby/README.md
index 84f4a77..8331d28 100644
--- a/ruby/README.md
+++ b/ruby/README.md
@@ -72,3 +72,27 @@
 This gem includes the upb parsing and serialization library as a single-file
 amalgamation. It is up-to-date with upb git commit
 `535bc2fe2f2b467f59347ffc9449e11e47791257`.
+
+Version Number Scheme
+---------------------
+
+We are using a version number scheme that is a hybrid of Protocol Buffers'
+overall version number and some Ruby-specific rules. Gem does not allow
+re-uploads of a gem with the same version number, so we add a sequence number
+("upload version") to the version. We also format alphabetical tags (alpha,
+pre, ...) slightly differently, and we avoid hyphens. In more detail:
+
+* First, we determine the prefix: a Protocol Buffers version "3.0.0-alpha-2"
+  becomes "3.0.0.alpha.2". When we release 3.0.0, this prefix will be simply
+  "3.0.0".
+* We then append the upload version: "3.0.0.alpha.2.0" or "3.0.0.0". If we need
+  to upload a new version of the gem to fix an issue, the version becomes
+  "3.0.0.alpha.2.1" or "3.0.0.1".
+* If we are working on a prerelease version, we append a prerelease tag:
+  "3.0.0.alpha.3.0.pre". The prerelease tag comes at the end so that when
+  version numbers are sorted, any prerelease builds are ordered between the
+  prior version and current version.
+
+These rules are designed to work with the sorting rules for
+[Gem::Version](http://ruby-doc.org/stdlib-2.0/libdoc/rubygems/rdoc/Gem/Version.html):
+release numbers should sort in actual release order.
diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec
index e294751..371009b 100644
--- a/ruby/google-protobuf.gemspec
+++ b/ruby/google-protobuf.gemspec
@@ -7,7 +7,7 @@
 
 Gem::Specification.new do |s|
   s.name        = "google-protobuf"
-  s.version     = "3.0.0.alpha.2.0"
+  s.version     = "3.0.0.alpha.3.0.pre"
   s.licenses    = ["BSD"]
   s.summary     = "Protocol Buffers"
   s.description = "Protocol Buffers are Google's data interchange format."
diff --git a/src/Makefile.am b/src/Makefile.am
index 14756ff..f84cd7f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -84,10 +84,13 @@
   google/protobuf/dynamic_message.h                             \
   google/protobuf/extension_set.h                               \
   google/protobuf/generated_enum_reflection.h                   \
+  google/protobuf/generated_enum_util.h                         \
   google/protobuf/generated_message_reflection.h                \
   google/protobuf/generated_message_util.h                      \
   google/protobuf/map_entry.h                                   \
+  google/protobuf/map_entry_lite.h                              \
   google/protobuf/map_field.h                                   \
+  google/protobuf/map_field_lite.h                              \
   google/protobuf/map_field_inl.h                               \
   google/protobuf/map.h                                         \
   google/protobuf/map_type_handler.h                            \
@@ -316,6 +319,7 @@
   google/protobuf/unittest_no_generic_services.proto           \
   google/protobuf/unittest_optimize_for.proto                  \
   google/protobuf/unittest_preserve_unknown_enum.proto         \
+  google/protobuf/unittest_preserve_unknown_enum2.proto        \
   google/protobuf/unittest_proto3_arena.proto                  \
   google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
 
@@ -342,6 +346,8 @@
   google/protobuf/unittest_enormous_descriptor.proto
 
 protoc_lite_outputs =                                          \
+  google/protobuf/map_lite_unittest.pb.cc                      \
+  google/protobuf/map_lite_unittest.pb.h                       \
   google/protobuf/unittest_lite.pb.cc                          \
   google/protobuf/unittest_lite.pb.h                           \
   google/protobuf/unittest_import_lite.pb.cc                   \
@@ -351,8 +357,6 @@
 
 protoc_outputs =                                               \
   $(protoc_lite_outputs)                                       \
-  google/protobuf/map_lite_unittest.pb.cc                      \
-  google/protobuf/map_lite_unittest.pb.h                       \
   google/protobuf/map_proto2_unittest.pb.cc                    \
   google/protobuf/map_proto2_unittest.pb.h                     \
   google/protobuf/map_unittest.pb.cc                           \
@@ -389,12 +393,14 @@
   google/protobuf/unittest_optimize_for.pb.h                   \
   google/protobuf/unittest_preserve_unknown_enum.pb.cc         \
   google/protobuf/unittest_preserve_unknown_enum.pb.h          \
+  google/protobuf/unittest_preserve_unknown_enum2.pb.cc        \
+  google/protobuf/unittest_preserve_unknown_enum2.pb.h         \
   google/protobuf/unittest_proto3_arena.pb.cc                  \
   google/protobuf/unittest_proto3_arena.pb.h                   \
   google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc  \
   google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h
 
-BUILT_SOURCES = $(public_config) $(protoc_outputs) 
+BUILT_SOURCES = $(public_config) $(protoc_outputs)
 
 if USE_EXTERNAL_PROTOC
 
@@ -416,8 +422,11 @@
 $(protoc_outputs): unittest_proto_middleman
 
 COMMON_TEST_SOURCES =                                          \
+  google/protobuf/arena_test_util.cc                           \
+  google/protobuf/arena_test_util.h                            \
   google/protobuf/map_test_util.cc                             \
   google/protobuf/map_test_util.h                              \
+  google/protobuf/map_test_util_impl.h                         \
   google/protobuf/test_util.cc                                 \
   google/protobuf/test_util.h                                  \
   google/protobuf/testing/googletest.cc                        \
@@ -503,8 +512,12 @@
 protobuf_lite_test_CXXFLAGS = $(NO_OPT_CXXFLAGS)
 protobuf_lite_test_SOURCES =                                           \
   google/protobuf/lite_unittest.cc                                     \
+  google/protobuf/map_lite_test_util.cc                                \
+  google/protobuf/map_lite_test_util.h                                 \
   google/protobuf/test_util_lite.cc                                    \
   google/protobuf/test_util_lite.h
+  # TODO(teboring) add the file back and make the test build.
+  # google/protobuf/map_lite_test.cc
 nodist_protobuf_lite_test_SOURCES = $(protoc_lite_outputs)
 
 # Test plugin binary.
diff --git a/src/google/protobuf/any.proto b/src/google/protobuf/any.proto
new file mode 100644
index 0000000..bf2aa0a
--- /dev/null
+++ b/src/google/protobuf/any.proto
@@ -0,0 +1,98 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+syntax = "proto3";
+
+package google.protobuf;
+
+option java_generate_equals_and_hash = true;
+option java_multiple_files = true;
+option java_outer_classname = "AnyProto";
+option java_package = "com.google.protobuf";
+
+
+// `Any` contains an arbitrary serialized message along with a URL
+// that describes the type of the serialized message.
+//
+//
+//
+// # JSON
+// The JSON representation of an `Any` value uses the regular
+// representation of the deserialized, embedded message, with an
+// additional field `@type` which contains the type URL. Example:
+//
+//     package google.profile;
+//     message Person {
+//       string first_name = 1;
+//       string last_name = 2;
+//     }
+//
+//     {
+//       "@type": "type.googleapis.com/google.profile.Person",
+//       "firstName": <string>,
+//       "lastName": <string>
+//     }
+//
+// If the embedded message type is well-known and has a custom JSON
+// representation, that representation will be embedded adding a field
+// `value` which holds the custom JSON in addition to the the `@type`
+// field. Example (for message [google.protobuf.Duration][google.protobuf.Duration]):
+//
+//     {
+//       "@type": "type.googleapis.com/google.protobuf.Duration",
+//       "value": "1.212s"
+//     }
+//
+message Any {
+  // A URL/resource name whose content describes the type of the
+  // serialized message.
+  //
+  // For URLs which use the schema `http`, `https`, or no schema, the
+  // following restrictions and interpretations apply:
+  //
+  // * If no schema is provided, https is assumed.
+  // * The last segment of the URL's path must represent the fully
+  //   qualified name of the type (as in `path/google.protobuf.Duration`).
+  // * An HTTP GET on the URL must yield a [google.protobuf.Type][google.protobuf.Type]
+  //   value in binary format, or produce an error.
+  // * Applications are allowed to cache lookup results based on the
+  //   URL, or have them precompiled into a binary to avoid any
+  //   lookup. Therefore, binary compatibility need to be preserved
+  //   on changes to types. (Use versioned type names to manage
+  //   breaking changes.)
+  //
+  // Schemas other than `http`, `https` (or the empty schema) might be
+  // used with implementation specific semantics.
+  //
+  //
+  string type_url = 1;
+
+  // Must be valid serialized data of the above specified type.
+  bytes value = 2;
+}
diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc
old mode 100644
new mode 100755
index 1853678..bda3741
--- a/src/google/protobuf/arena.cc
+++ b/src/google/protobuf/arena.cc
@@ -47,35 +47,53 @@
 GOOGLE_THREAD_LOCAL Arena::ThreadCache Arena::thread_cache_ = { -1, NULL };
 #endif
 
-void Arena::Init(const ArenaOptions& options) {
+void Arena::Init() {
   lifecycle_id_ = lifecycle_id_generator_.GetNext();
-  start_block_size_ = options.start_block_size;
-  max_block_size_ = options.max_block_size;
-  block_alloc = options.block_alloc;
-  block_dealloc = options.block_dealloc;
   blocks_ = 0;
   hint_ = 0;
   owns_first_block_ = true;
   cleanup_list_ = 0;
 
-  if (options.initial_block != NULL && options.initial_block_size > 0) {
+  if (options_.initial_block != NULL && options_.initial_block_size > 0) {
     // Add first unowned block to list.
-    Block* first_block = reinterpret_cast<Block*>(options.initial_block);
-    first_block->size = options.initial_block_size;
+    Block* first_block = reinterpret_cast<Block*>(options_.initial_block);
+    first_block->size = options_.initial_block_size;
     first_block->pos = kHeaderSize;
     first_block->next = NULL;
     first_block->owner = &first_block->owner;
     AddBlock(first_block);
     owns_first_block_ = false;
   }
+
+  // Call the initialization hook
+  if (options_.on_arena_init != NULL) {
+    hooks_cookie_ = options_.on_arena_init(this);
+  } else {
+    hooks_cookie_ = NULL;
+  }
+}
+
+Arena::~Arena() {
+  uint64 space_allocated = Reset();
+
+  // Call the destruction hook
+  if (options_.on_arena_destruction != NULL) {
+    options_.on_arena_destruction(this, hooks_cookie_, space_allocated);
+  }
 }
 
 uint64 Arena::Reset() {
   CleanupList();
-  uint64 space_used = FreeBlocks();
+  uint64 space_allocated = FreeBlocks();
   // Invalidate any ThreadCaches pointing to any blocks we just destroyed.
   lifecycle_id_ = lifecycle_id_generator_.GetNext();
-  return space_used;
+
+  // Call the reset hook
+  if (options_.on_arena_reset != NULL) {
+    options_.on_arena_reset(this, hooks_cookie_, space_allocated);
+  }
+
+  return space_allocated;
 }
 
 Arena::Block* Arena::NewBlock(void* me, Block* my_last_block, size_t n,
@@ -93,7 +111,7 @@
     size = kHeaderSize + n;
   }
 
-  Block* b = reinterpret_cast<Block*>(block_alloc(size));
+  Block* b = reinterpret_cast<Block*>(options_.block_alloc(size));
   b->pos = kHeaderSize + n;
   b->size = size;
   if (b->avail() == 0) {
@@ -184,7 +202,7 @@
     google::protobuf::internal::NoBarrier_Store(&hint_, reinterpret_cast<google::protobuf::internal::AtomicWord>(b));
     return AllocFromBlock(b, n);
   }
-  b = NewBlock(me, b, n, start_block_size_, max_block_size_);
+  b = NewBlock(me, b, n, options_.start_block_size, options_.max_block_size);
   AddBlock(b);
   if (b->owner == me) {  // If this block can be reused (see NewBlock()).
     SetThreadCacheBlock(b);
@@ -192,29 +210,38 @@
   return reinterpret_cast<char*>(b) + kHeaderSize;
 }
 
+uint64 Arena::SpaceAllocated() const {
+  uint64 space_allocated = 0;
+  Block* b = reinterpret_cast<Block*>(google::protobuf::internal::NoBarrier_Load(&blocks_));
+  while (b != NULL) {
+    space_allocated += (b->size);
+    b = b->next;
+  }
+  return space_allocated;
+}
+
 uint64 Arena::SpaceUsed() const {
   uint64 space_used = 0;
   Block* b = reinterpret_cast<Block*>(google::protobuf::internal::NoBarrier_Load(&blocks_));
   while (b != NULL) {
-    space_used += (b->size);
+    space_used += (b->pos - kHeaderSize);
     b = b->next;
   }
   return space_used;
 }
 
-
 uint64 Arena::FreeBlocks() {
-  uint64 space_used = 0;
+  uint64 space_allocated = 0;
   Block* b = reinterpret_cast<Block*>(google::protobuf::internal::NoBarrier_Load(&blocks_));
   Block* first_block = NULL;
   while (b != NULL) {
-    space_used += (b->size);
+    space_allocated += (b->size);
     Block* next = b->next;
     if (next != NULL) {
-      block_dealloc(b, b->size);
+      options_.block_dealloc(b, b->size);
     } else {
       if (owns_first_block_) {
-        block_dealloc(b, b->size);
+        options_.block_dealloc(b, b->size);
       } else {
         // User passed in the first block, skip free'ing the memory.
         first_block = b;
@@ -231,7 +258,7 @@
     first_block->owner = &first_block->owner;
     AddBlock(first_block);
   }
-  return space_used;
+  return space_allocated;
 }
 
 void Arena::CleanupList() {
diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h
index 4f9e39e..bb15e80 100644
--- a/src/google/protobuf/arena.h
+++ b/src/google/protobuf/arena.h
@@ -34,9 +34,11 @@
 #ifndef GOOGLE_PROTOBUF_ARENA_H__
 #define GOOGLE_PROTOBUF_ARENA_H__
 
-#include <google/protobuf/stubs/common.h>
+#include <typeinfo>
+
 #include <google/protobuf/stubs/atomic_sequence_num.h>
 #include <google/protobuf/stubs/atomicops.h>
+#include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/type_traits.h>
 
 namespace google {
@@ -89,19 +91,44 @@
 
   // A function pointer to an alloc method that returns memory blocks of size
   // requested. By default, it contains a ptr to the malloc function.
+  //
+  // NOTE: block_alloc and dealloc functions are expected to behave like
+  // malloc and free, including Asan poisoning.
   void* (*block_alloc)(size_t);
   // A function pointer to a dealloc method that takes ownership of the blocks
   // from the arena. By default, it contains a ptr to a wrapper function that
   // calls free.
   void (*block_dealloc)(void*, size_t);
 
+  // Hooks for adding external functionality such as user-specific metrics
+  // collection, specific debugging abilities, etc.
+  // Init hook may return a pointer to a cookie to be stored in the arena.
+  // reset and destruction hooks will then be called with the same cookie
+  // pointer. This allows us to save an external object per arena instance and
+  // use it on the other hooks (Note: It is just as legal for init to return
+  // NULL and not use the cookie feature).
+  // on_arena_reset and on_arena_destruction also receive the space used in
+  // the arena just before the reset.
+  void* (*on_arena_init)(Arena* arena);
+  void (*on_arena_reset)(Arena* arena, void* cookie, uint64 space_used);
+  void (*on_arena_destruction)(Arena* arena, void* cookie, uint64 space_used);
+
+  // type_name is promised to be a static string - its lifetime extends to
+  // match program's lifetime.
+  void (*on_arena_allocation)(const char* type_name, uint64 alloc_size,
+      Arena* arena, void* cookie);
+
   ArenaOptions()
       : start_block_size(kDefaultStartBlockSize),
         max_block_size(kDefaultMaxBlockSize),
         initial_block(NULL),
         initial_block_size(0),
         block_alloc(&malloc),
-        block_dealloc(&internal::arena_free) {}
+        block_dealloc(&internal::arena_free),
+        on_arena_init(NULL),
+        on_arena_reset(NULL),
+        on_arena_destruction(NULL),
+        on_arena_allocation(NULL) {}
 
  private:
   // Constants define default starting block size and max block size for
@@ -123,23 +150,21 @@
  public:
   // Arena constructor taking custom options. See ArenaOptions below for
   // descriptions of the options available.
-  explicit Arena(const ArenaOptions& options) {
-    Init(options);
+  explicit Arena(const ArenaOptions& options) : options_(options) {
+    Init();
   }
 
   // Default constructor with sensible default options, tuned for average
   // use-cases.
   Arena() {
-    Init(ArenaOptions());
+    Init();
   }
 
   // Destructor deletes all owned heap allocated objects, and destructs objects
   // that have non-trivial destructors, except for proto2 message objects whose
   // destructors can be skipped. Also, frees all blocks except the initial block
   // if it was passed in.
-  ~Arena() {
-    Reset();
-  }
+  ~Arena();
 
   // API to create proto2 message objects on the arena. If the arena passed in
   // is NULL, then a heap allocated object is returned. Type T must be a message
@@ -195,6 +220,40 @@
     }
   }
 
+  // Version of the above with three constructor arguments for the created
+  // object.
+  template <typename T, typename Arg1, typename Arg2, typename Arg3>
+  GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena,
+                                           const Arg1& arg1, const Arg2& arg2,
+                                           const Arg3& arg3) {
+    if (arena == NULL) {
+      return new T(arg1, arg2, arg3);
+    } else {
+      return arena->CreateInternal<T>(SkipDeleteList<T>(static_cast<T*>(0)),
+                                      arg1,
+                                      arg2,
+                                      arg3);
+    }
+  }
+
+  // Version of the above with four constructor arguments for the created
+  // object.
+  template <typename T, typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4>
+  GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena,
+                                           const Arg1& arg1, const Arg2& arg2,
+                                           const Arg3& arg3, const Arg4& arg4) {
+    if (arena == NULL) {
+      return new T(arg1, arg2, arg3, arg4);
+    } else {
+      return arena->CreateInternal<T>(SkipDeleteList<T>(static_cast<T*>(0)),
+                                      arg1,
+                                      arg2,
+                                      arg3,
+                                      arg4);
+    }
+  }
+
   // Create an array of object type T on the arena. Type T must have a trivial
   // constructor, as it will not be invoked when created on the arena.
   template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
@@ -202,8 +261,7 @@
     if (arena == NULL) {
       return new T[num_elements];
     } else {
-      return static_cast<T*>(
-          arena->AllocateAligned(num_elements * sizeof(T)));
+      return arena->CreateInternalRawArray<T>(num_elements);
     }
   }
 
@@ -211,6 +269,8 @@
   // of the underlying blocks. The total space used may not include the new
   // blocks that are allocated by this arena from other threads concurrently
   // with the call to this method.
+  uint64 SpaceAllocated() const GOOGLE_ATTRIBUTE_NOINLINE;
+  // As above, but does not include any free space in underlying blocks.
   uint64 SpaceUsed() const GOOGLE_ATTRIBUTE_NOINLINE;
 
   // Frees all storage allocated by this arena after calling destructors
@@ -253,7 +313,7 @@
   // latter is a virtual call, while this method is a templated call that
   // resolves at compile-time.
   template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
-  static inline ::google::protobuf::Arena* GetArena(T* value) {
+  static inline ::google::protobuf::Arena* GetArena(const T* value) {
     return GetArenaInternal(value, static_cast<T*>(0));
   }
 
@@ -295,9 +355,6 @@
     // data follows
   };
 
-  void* (*block_alloc)(size_t);  // Allocates a free block of a particular size.
-  void (*block_dealloc)(void*, size_t);  // Deallocates the given block.
-
   template<typename Type> friend class ::google::protobuf::internal::GenericTypeHandler;
   friend class MockArena;              // For unit-testing.
   friend class internal::ArenaString;  // For AllocateAligned.
@@ -354,6 +411,13 @@
     return Create<T>(arena);
   }
 
+  // Just allocate the required size for the given type assuming the
+  // type has a trivial constructor.
+  template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
+  inline T* CreateInternalRawArray(uint32 num_elements) {
+    return static_cast<T*>(AllocateAligned(sizeof(T) * num_elements));
+  }
+
   template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   inline T* CreateInternal(
       bool skip_explicit_ownership) {
@@ -384,12 +448,57 @@
     return t;
   }
 
+  template <typename T, typename Arg1, typename Arg2, typename Arg3>
+  GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline T* CreateInternal(bool skip_explicit_ownership,
+                                                   const Arg1& arg1,
+                                                   const Arg2& arg2,
+                                                   const Arg3& arg3) {
+    T* t = new (AllocateAligned(sizeof(T))) T(arg1, arg2, arg3);
+    if (!skip_explicit_ownership) {
+      AddListNode(t, &internal::arena_destruct_object<T>);
+    }
+    return t;
+  }
+
+  template <typename T, typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4>
+  GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline T* CreateInternal(bool skip_explicit_ownership,
+                                                   const Arg1& arg1,
+                                                   const Arg2& arg2,
+                                                   const Arg3& arg3,
+                                                   const Arg4& arg4) {
+    T* t = new (AllocateAligned(sizeof(T))) T(arg1, arg2, arg3, arg4);
+    if (!skip_explicit_ownership) {
+      AddListNode(t, &internal::arena_destruct_object<T>);
+    }
+    return t;
+  }
+
   template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   inline T* CreateMessageInternal(typename T::InternalArenaConstructable_*) {
     return CreateInternal<T, Arena*>(SkipDeleteList<T>(static_cast<T*>(0)),
                                      this);
   }
 
+  // CreateInArenaStorage is used to implement map field. Without it,
+  // google::protobuf::Map need to call generated message's protected arena constructor,
+  // which needs to declare google::protobuf::Map as friend of generated message.
+  template <typename T>
+  static void CreateInArenaStorage(T* ptr, Arena* arena) {
+    CreateInArenaStorageInternal(ptr, arena, is_arena_constructable<T>::value);
+  }
+  template <typename T>
+  static void CreateInArenaStorageInternal(
+      T* ptr, Arena* arena, google::protobuf::internal::true_type) {
+    new (ptr) T(arena);
+  }
+
+  template <typename T>
+  static void CreateInArenaStorageInternal(
+      T* ptr, Arena* arena, google::protobuf::internal::false_type) {
+    new (ptr) T;
+  }
+
   // These implement Own(), which registers an object for deletion (destructor
   // call and operator delete()). The second parameter has type 'true_type' if T
   // is a subtype of ::google::protobuf::Message and 'false_type' otherwise. Collapsing
@@ -412,20 +521,20 @@
   // InternalArenaConstructable_ tags can be associated with an arena, and such
   // objects must implement a GetArenaNoVirtual() method.
   template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
-  static inline ::google::protobuf::Arena* GetArenaInternal(T* value,
+  static inline ::google::protobuf::Arena* GetArenaInternal(const T* value,
       typename T::InternalArenaConstructable_*) {
     return value->GetArenaNoVirtual();
   }
 
   template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
-  static inline ::google::protobuf::Arena* GetArenaInternal(T* value, ...) {
+  static inline ::google::protobuf::Arena* GetArenaInternal(const T* value, ...) {
     return NULL;
   }
 
 
   void* AllocateAligned(size_t size);
 
-  void Init(const ArenaOptions& options);
+  void Init();
 
   // Free all blocks and return the total space used which is the sums of sizes
   // of the all the allocated blocks.
@@ -446,8 +555,6 @@
   }
 
   int64 lifecycle_id_;  // Unique for each arena. Changes on Reset().
-  size_t start_block_size_;  // Starting block size of the arena.
-  size_t max_block_size_;    // Max block size of the arena.
 
   google::protobuf::internal::AtomicWord blocks_;  // Head of linked list of all allocated blocks
   google::protobuf::internal::AtomicWord hint_;    // Fast thread-local block access
@@ -472,6 +579,15 @@
   Block* NewBlock(void* me, Block* my_last_block, size_t n,
                   size_t start_block_size, size_t max_block_size);
   static void* AllocFromBlock(Block* b, size_t n);
+  template <typename Key, typename T>
+  friend class Map;
+
+  // The arena may save a cookie it receives from the external on_init hook
+  // and then use it when calling the on_reset and on_destruction hooks.
+  void* hooks_cookie_;
+
+  ArenaOptions options_;
+
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Arena);
 };
 
diff --git a/src/google/protobuf/arena_test_util.cc b/src/google/protobuf/arena_test_util.cc
new file mode 100644
index 0000000..21f55c6
--- /dev/null
+++ b/src/google/protobuf/arena_test_util.cc
@@ -0,0 +1,49 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/arena_test_util.h>
+
+
+#define EXPECT_EQ GOOGLE_CHECK_EQ
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+NoHeapChecker::~NoHeapChecker() {
+  capture_alloc.Unhook();
+  EXPECT_EQ(0, capture_alloc.alloc_count());
+  EXPECT_EQ(0, capture_alloc.free_count());
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/arena_test_util.h b/src/google/protobuf/arena_test_util.h
new file mode 100644
index 0000000..7db7a90
--- /dev/null
+++ b/src/google/protobuf/arena_test_util.h
@@ -0,0 +1,59 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_ARENA_TEST_UTIL_H__
+#define GOOGLE_PROTOBUF_ARENA_TEST_UTIL_H__
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+class NoHeapChecker {
+ public:
+  NoHeapChecker() {
+    capture_alloc.Hook();
+  }
+  ~NoHeapChecker();
+ private:
+  class NewDeleteCapture {
+   public:
+    // TOOD(xiaofeng): Implement this for opensource protobuf.
+    void Hook() {}
+    void Unhook() {}
+    int alloc_count() { return 0; }
+    int free_count() { return 0; }
+  } capture_alloc;
+};
+
+}  // namespace internal
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_ARENA_TEST_UTIL_H__
diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc
index 390141a..d9b198e 100644
--- a/src/google/protobuf/arena_unittest.cc
+++ b/src/google/protobuf/arena_unittest.cc
@@ -30,6 +30,8 @@
 
 #include <google/protobuf/arena.h>
 
+#include <stdint.h>
+
 #include <algorithm>
 #include <cstring>
 #include <memory>
@@ -40,6 +42,7 @@
 #include <vector>
 
 #include <google/protobuf/stubs/common.h>
+#include <google/protobuf/arena_test_util.h>
 #include <google/protobuf/test_util.h>
 #include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/unittest_arena.pb.h>
@@ -91,6 +94,37 @@
  private:
   Notifier* notifier_;
 };
+
+// A simple class that does not allow copying and so cannot be used as a
+// parameter type without "const &".
+class PleaseDontCopyMe {
+ public:
+  explicit PleaseDontCopyMe(int value) : value_(value) {}
+
+  int value() const { return value_; }
+
+ private:
+  int value_;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PleaseDontCopyMe);
+};
+
+// A class that takes four different types as constructor arguments.
+class MustBeConstructedWithOneThroughFour {
+ public:
+  MustBeConstructedWithOneThroughFour(
+      int one, const char* two, const string& three,
+      const PleaseDontCopyMe* four)
+      : one_(one), two_(two), three_(three), four_(four) {}
+
+  int one_;
+  const char* const two_;
+  string three_;
+  const PleaseDontCopyMe* four_;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MustBeConstructedWithOneThroughFour);
+};
+
 }  // namespace
 
 TEST(ArenaTest, ArenaConstructable) {
@@ -122,6 +156,20 @@
   EXPECT_EQ(2, notifier.GetCount());
 }
 
+TEST(ArenaTest, CreateWithManyConstructorArguments) {
+  Arena arena;
+  const string three("3");
+  const PleaseDontCopyMe four(4);
+  const MustBeConstructedWithOneThroughFour* new_object =
+      Arena::Create<MustBeConstructedWithOneThroughFour>(
+          &arena, 1, "2", three, &four);
+  EXPECT_TRUE(new_object != NULL);
+  ASSERT_EQ(1, new_object->one_);
+  ASSERT_STREQ("2", new_object->two_);
+  ASSERT_EQ("3", new_object->three_);
+  ASSERT_EQ(4, new_object->four_->value());
+}
+
 TEST(ArenaTest, InitialBlockTooSmall) {
   // Construct a small (64 byte) initial block of memory to be used by the
   // arena allocator; then, allocate an object which will not fit in the
@@ -380,6 +428,7 @@
   delete nested_string;
 }
 
+#ifndef GOOGLE_PROTOBUF_NO_RTTI
 TEST(ArenaTest, ReleaseFromArenaMessageUsingReflectionMakesCopy) {
   TestAllTypes::NestedMessage* nested_msg = NULL;
   // Note: no string: reflection API only supports releasing submessages.
@@ -396,6 +445,7 @@
   EXPECT_EQ(42, nested_msg->bb());
   delete nested_msg;
 }
+#endif  // !GOOGLE_PROTOBUF_NO_RTTI
 
 TEST(ArenaTest, UnsafeArenaReleaseDoesNotMakeCopy) {
   Arena arena;
@@ -671,6 +721,57 @@
   }
 }
 
+TEST(ArenaTest, UnsafeArenaRelease) {
+  Arena arena;
+  TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
+
+  string* s = new string("test string");
+  message->unsafe_arena_set_allocated_optional_string(s);
+  EXPECT_TRUE(message->has_optional_string());
+  EXPECT_EQ("test string", message->optional_string());
+  s = message->unsafe_arena_release_optional_string();
+  EXPECT_FALSE(message->has_optional_string());
+  delete s;
+
+  s = new string("test string");
+  message->unsafe_arena_set_allocated_oneof_string(s);
+  EXPECT_TRUE(message->has_oneof_string());
+  EXPECT_EQ("test string", message->oneof_string());
+  s = message->unsafe_arena_release_oneof_string();
+  EXPECT_FALSE(message->has_oneof_string());
+  delete s;
+}
+
+TEST(ArenaTest, ArenaOneofReflection) {
+  Arena arena;
+  TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
+  const Descriptor* desc = message->GetDescriptor();
+  const Reflection* refl = message->GetReflection();
+
+  const FieldDescriptor* string_field = desc->FindFieldByName(
+      "oneof_string");
+  const FieldDescriptor* msg_field = desc->FindFieldByName(
+      "oneof_nested_message");
+  const OneofDescriptor* oneof = desc->FindOneofByName(
+      "oneof_field");
+
+  refl->SetString(message, string_field, "Test value");
+  EXPECT_TRUE(refl->HasOneof(*message, oneof));
+  refl->ClearOneof(message, oneof);
+  EXPECT_FALSE(refl->HasOneof(*message, oneof));
+
+  Message* submsg = refl->MutableMessage(message, msg_field);
+  EXPECT_TRUE(refl->HasOneof(*message, oneof));
+  refl->ClearOneof(message, oneof);
+  EXPECT_FALSE(refl->HasOneof(*message, oneof));
+  refl->MutableMessage(message, msg_field);
+  EXPECT_TRUE(refl->HasOneof(*message, oneof));
+  submsg = refl->ReleaseMessage(message, msg_field);
+  EXPECT_FALSE(refl->HasOneof(*message, oneof));
+  EXPECT_TRUE(submsg->GetArena() == NULL);
+  delete submsg;
+}
+
 namespace {
 void TestSwapRepeatedField(Arena* arena1, Arena* arena2) {
   // Test "safe" (copying) semantics for direct Swap() on RepeatedPtrField
@@ -746,27 +847,6 @@
       protobuf_unittest::optional_nested_message_extension)->set_bb(42);
 }
 
-class NoHeapChecker {
- public:
-  NoHeapChecker() {
-    capture_alloc.Hook();
-  }
-  ~NoHeapChecker() {
-    capture_alloc.Unhook();
-    EXPECT_EQ(0, capture_alloc.alloc_count());
-    EXPECT_EQ(0, capture_alloc.free_count());
-  }
- private:
-  class NewDeleteCapture {
-   public:
-    // TOOD(xiaofeng): Implement this for opensource protobuf.
-    void Hook() {}
-    void Unhook() {}
-    int alloc_count() { return 0; }
-    int free_count() { return 0; }
-  } capture_alloc;
-};
-
 TEST(ArenaTest, RepeatedFieldOnArena) {
   // Preallocate an initial arena block to avoid mallocs during hooked region.
   std::vector<char> arena_block(1024 * 1024);
@@ -776,7 +856,7 @@
   Arena arena(options);
 
   {
-    NoHeapChecker no_heap;
+    internal::NoHeapChecker no_heap;
 
     // Fill some repeated fields on the arena to test for leaks. Also verify no
     // memory allocations.
@@ -846,6 +926,7 @@
 }
 
 
+#ifndef GOOGLE_PROTOBUF_NO_RTTI
 TEST(ArenaTest, MutableMessageReflection) {
   Arena arena;
   TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
@@ -869,6 +950,7 @@
   EXPECT_EQ(submessage_expected, submessage);
   EXPECT_EQ(&arena, submessage->GetArena());
 }
+#endif  // !GOOGLE_PROTOBUF_NO_RTTI
 
 
 namespace {
@@ -911,7 +993,7 @@
   arena.Reset();
 }
 
-
+#ifndef GOOGLE_PROTOBUF_NO_RTTI
 // Test construction on an arena via generic MessageLite interface. We should be
 // able to successfully deserialize on the arena without incurring heap
 // allocations, i.e., everything should still be arena-allocation-aware.
@@ -921,8 +1003,7 @@
   options.initial_block = &arena_block[0];
   options.initial_block_size = arena_block.size();
   Arena arena(options);
-  const google::protobuf::MessageLite* prototype =
-      &TestAllTypes::default_instance();
+  const google::protobuf::MessageLite* prototype = &TestAllTypes::default_instance();
 
   TestAllTypes initial_message;
   FillArenaAwareFields(&initial_message);
@@ -941,6 +1022,7 @@
 
   arena.Reset();
 }
+#endif  // !GOOGLE_PROTOBUF_NO_RTTI
 
 
 // RepeatedField should support non-POD types, and invoke constructors and
@@ -962,16 +1044,23 @@
   }
 }
 
-TEST(ArenaTest, SpaceUsed) {
+// Align n to next multiple of 8
+namespace {
+uint64 Align8(uint64 n) { return (n + 7) & -8; }
+}  // namespace
+
+TEST(ArenaTest, SpaceAllocated_and_Used) {
   ArenaOptions options;
   options.start_block_size = 256;
   options.max_block_size = 8192;
   Arena arena_1(options);
+  EXPECT_EQ(0, arena_1.SpaceAllocated());
   EXPECT_EQ(0, arena_1.SpaceUsed());
   EXPECT_EQ(0, arena_1.Reset());
   ::google::protobuf::Arena::CreateArray<char>(&arena_1, 320);
   // Arena will allocate slightly more than 320 for the block headers.
-  EXPECT_LE(320, arena_1.SpaceUsed());
+  EXPECT_LE(320, arena_1.SpaceAllocated());
+  EXPECT_EQ(Align8(320), arena_1.SpaceUsed());
   EXPECT_LE(320, arena_1.Reset());
 
   // Test with initial block.
@@ -979,20 +1068,25 @@
   options.initial_block = &arena_block[0];
   options.initial_block_size = arena_block.size();
   Arena arena_2(options);
-  EXPECT_EQ(1024, arena_2.SpaceUsed());
+  EXPECT_EQ(1024, arena_2.SpaceAllocated());
+  EXPECT_EQ(0, arena_2.SpaceUsed());
   EXPECT_EQ(1024, arena_2.Reset());
   ::google::protobuf::Arena::CreateArray<char>(&arena_2, 55);
-  EXPECT_EQ(1024, arena_2.SpaceUsed());
+  EXPECT_EQ(1024, arena_2.SpaceAllocated());
+  EXPECT_EQ(Align8(55), arena_2.SpaceUsed());
   EXPECT_EQ(1024, arena_2.Reset());
 
   // Reset options to test doubling policy explicitly.
   options.initial_block = NULL;
   options.initial_block_size = 0;
   Arena arena_3(options);
+  EXPECT_EQ(0, arena_3.SpaceUsed());
   ::google::protobuf::Arena::CreateArray<char>(&arena_3, 190);
-  EXPECT_EQ(256, arena_3.SpaceUsed());
+  EXPECT_EQ(256, arena_3.SpaceAllocated());
+  EXPECT_EQ(Align8(190), arena_3.SpaceUsed());
   ::google::protobuf::Arena::CreateArray<char>(&arena_3, 70);
-  EXPECT_EQ(256 + 512, arena_3.SpaceUsed());
+  EXPECT_EQ(256 + 512, arena_3.SpaceAllocated());
+  EXPECT_EQ(Align8(190) + Align8(70), arena_3.SpaceUsed());
   EXPECT_EQ(256 + 512, arena_3.Reset());
 }
 
@@ -1004,5 +1098,76 @@
   }
 }
 
+TEST(ArenaTest, GetArenaShouldReturnTheArenaForArenaAllocatedMessages) {
+  ::google::protobuf::Arena arena;
+  ArenaMessage* message = Arena::CreateMessage<ArenaMessage>(&arena);
+  const ArenaMessage* const_pointer_to_message = message;
+  EXPECT_EQ(&arena, Arena::GetArena(message));
+  EXPECT_EQ(&arena, Arena::GetArena(const_pointer_to_message));
+}
+
+TEST(ArenaTest, GetArenaShouldReturnNullForNonArenaAllocatedMessages) {
+  ArenaMessage message;
+  const ArenaMessage* const_pointer_to_message = &message;
+  EXPECT_EQ(NULL, Arena::GetArena(&message));
+  EXPECT_EQ(NULL, Arena::GetArena(const_pointer_to_message));
+}
+
+// A helper utility class to only contain static hook functions, some
+// counters to be used to verify the counters have been called and a cookie
+// value to be verified.
+class ArenaHooksTestUtil {
+ public:
+  static void* on_init(::google::protobuf::Arena* arena) {
+    ++num_init;
+    int* cookie = new int(kCookieValue);
+    return static_cast<void*>(cookie);
+  }
+
+  static void on_reset(::google::protobuf::Arena* arena, void* cookie,
+                       uint64 space_used) {
+    ++num_reset;
+    int cookie_value = *static_cast<int*>(cookie);
+    EXPECT_EQ(kCookieValue, cookie_value);
+  }
+
+  static void on_destruction(::google::protobuf::Arena* arena, void* cookie,
+                             uint64 space_used) {
+    ++num_destruct;
+    int cookie_value = *static_cast<int*>(cookie);
+    EXPECT_EQ(kCookieValue, cookie_value);
+    delete static_cast<int*>(cookie);
+  }
+
+  static const int kCookieValue = 999;
+  static uint32 num_init;
+  static uint32 num_reset;
+  static uint32 num_destruct;
+};
+uint32 ArenaHooksTestUtil::num_init = 0;
+uint32 ArenaHooksTestUtil::num_reset = 0;
+uint32 ArenaHooksTestUtil::num_destruct = 0;
+const int ArenaHooksTestUtil::kCookieValue;
+
+// Test the hooks are correctly called and that the cookie is passed.
+TEST(ArenaTest, ArenaHooksSanity) {
+  ::google::protobuf::ArenaOptions options;
+  options.on_arena_init = ArenaHooksTestUtil::on_init;
+  options.on_arena_reset = ArenaHooksTestUtil::on_reset;
+  options.on_arena_destruction = ArenaHooksTestUtil::on_destruction;
+
+  // Scope for defining the arena
+  {
+    ::google::protobuf::Arena arena(options);
+    EXPECT_EQ(1, ArenaHooksTestUtil::num_init);
+
+    arena.Reset();
+    arena.Reset();
+    EXPECT_EQ(2, ArenaHooksTestUtil::num_reset);
+  }
+  EXPECT_EQ(3, ArenaHooksTestUtil::num_reset);
+  EXPECT_EQ(1, ArenaHooksTestUtil::num_destruct);
+}
+
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index 1325070..0910631 100644
--- a/src/google/protobuf/compiler/command_line_interface.cc
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -152,7 +152,7 @@
   if (path.empty()) return true;
 
   if (access(path.c_str(), F_OK) == -1) {
-    cerr << path << ": " << strerror(errno) << endl;
+    std::cerr << path << ": " << strerror(errno) << std::endl;
     return false;
   } else {
     return true;
@@ -171,8 +171,8 @@
     path_so_far += parts[i];
     if (mkdir(path_so_far.c_str(), 0777) != 0) {
       if (errno != EEXIST) {
-        cerr << filename << ": while trying to create directory "
-             << path_so_far << ": " << strerror(errno) << endl;
+        std::cerr << filename << ": while trying to create directory "
+                  << path_so_far << ": " << strerror(errno) << std::endl;
         return false;
       }
     }
@@ -201,9 +201,9 @@
     if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS &&
         tree_ != NULL &&
         tree_->VirtualFileToDiskFile(filename, &dfile)) {
-      cerr << dfile;
+      std::cerr << dfile;
     } else {
-      cerr << filename;
+      std::cerr << filename;
     }
 
     // Users typically expect 1-based line/column numbers, so we add 1
@@ -212,15 +212,16 @@
       // Allow for both GCC- and Visual-Studio-compatible output.
       switch (format_) {
         case CommandLineInterface::ERROR_FORMAT_GCC:
-          cerr << ":" << (line + 1) << ":" << (column + 1);
+          std::cerr << ":" << (line + 1) << ":" << (column + 1);
           break;
         case CommandLineInterface::ERROR_FORMAT_MSVS:
-          cerr << "(" << (line + 1) << ") : error in column=" << (column + 1);
+          std::cerr << "(" << (line + 1)
+                    << ") : error in column=" << (column + 1);
           break;
       }
     }
 
-    cerr << ": " << message << endl;
+    std::cerr << ": " << message << std::endl;
   }
 
   // implements io::ErrorCollector -----------------------------------
@@ -345,7 +346,7 @@
 
     if (file_descriptor < 0) {
       int error = errno;
-      cerr << filename << ": " << strerror(error);
+      std::cerr << filename << ": " << strerror(error);
       return false;
     }
 
@@ -369,9 +370,9 @@
 
         if (write_result < 0) {
           int error = errno;
-          cerr << filename << ": write: " << strerror(error);
+          std::cerr << filename << ": write: " << strerror(error);
         } else {
-          cerr << filename << ": write() returned zero?" << endl;
+          std::cerr << filename << ": write() returned zero?" << std::endl;
         }
         return false;
       }
@@ -382,7 +383,7 @@
 
     if (close(file_descriptor) != 0) {
       int error = errno;
-      cerr << filename << ": close: " << strerror(error);
+      std::cerr << filename << ": close: " << strerror(error);
       return false;
     }
   }
@@ -405,7 +406,7 @@
 
   if (file_descriptor < 0) {
     int error = errno;
-    cerr << filename << ": " << strerror(error);
+    std::cerr << filename << ": " << strerror(error);
     return false;
   }
 
@@ -421,11 +422,11 @@
   zip_writer.WriteDirectory();
 
   if (stream.GetErrno() != 0) {
-    cerr << filename << ": " << strerror(stream.GetErrno()) << endl;
+    std::cerr << filename << ": " << strerror(stream.GetErrno()) << std::endl;
   }
 
   if (!stream.Close()) {
-    cerr << filename << ": " << strerror(stream.GetErrno()) << endl;
+    std::cerr << filename << ": " << strerror(stream.GetErrno()) << std::endl;
   }
 
   return true;
@@ -490,7 +491,8 @@
       if (append_mode_) {
         (*map_slot)->append(data_);
       } else {
-        cerr << filename_ << ": Tried to write the same file twice." << endl;
+        std::cerr << filename_ << ": Tried to write the same file twice."
+                  << std::endl;
         directory_->had_error_ = true;
       }
       return;
@@ -508,8 +510,9 @@
 
     // Find the file we are going to insert into.
     if (*map_slot == NULL) {
-      cerr << filename_ << ": Tried to insert into file that doesn't exist."
-           << endl;
+      std::cerr << filename_
+                << ": Tried to insert into file that doesn't exist."
+                << std::endl;
       directory_->had_error_ = true;
       return;
     }
@@ -521,8 +524,8 @@
     string::size_type pos = target->find(magic_string);
 
     if (pos == string::npos) {
-      cerr << filename_ << ": insertion point \"" << insertion_point_
-           << "\" not found." << endl;
+      std::cerr << filename_ << ": insertion point \"" << insertion_point_
+                << "\" not found." << std::endl;
       directory_->had_error_ = true;
       return;
     }
@@ -793,27 +796,31 @@
         input_files_[i] = virtual_file;
         break;
       case DiskSourceTree::SHADOWED:
-        cerr << input_files_[i] << ": Input is shadowed in the --proto_path "
-                "by \"" << shadowing_disk_file << "\".  Either use the latter "
-                "file as your input or reorder the --proto_path so that the "
-                "former file's location comes first." << endl;
+        std::cerr << input_files_[i]
+                  << ": Input is shadowed in the --proto_path by \""
+                  << shadowing_disk_file
+                  << "\".  Either use the latter file as your input or reorder "
+                     "the --proto_path so that the former file's location "
+                     "comes first." << std::endl;
         return false;
       case DiskSourceTree::CANNOT_OPEN:
-        cerr << input_files_[i] << ": " << strerror(errno) << endl;
+        std::cerr << input_files_[i] << ": " << strerror(errno) << std::endl;
         return false;
       case DiskSourceTree::NO_MAPPING:
         // First check if the file exists at all.
         if (access(input_files_[i].c_str(), F_OK) < 0) {
           // File does not even exist.
-          cerr << input_files_[i] << ": " << strerror(ENOENT) << endl;
+          std::cerr << input_files_[i] << ": " << strerror(ENOENT) << std::endl;
         } else {
-          cerr << input_files_[i] << ": File does not reside within any path "
-                  "specified using --proto_path (or -I).  You must specify a "
-                  "--proto_path which encompasses this file.  Note that the "
-                  "proto_path must be an exact prefix of the .proto file "
-                  "names -- protoc is too dumb to figure out when two paths "
-                  "(e.g. absolute and relative) are equivalent (it's harder "
-                  "than you think)." << endl;
+          std::cerr
+              << input_files_[i]
+              << ": File does not reside within any path "
+                 "specified using --proto_path (or -I).  You must specify a "
+                 "--proto_path which encompasses this file.  Note that the "
+                 "proto_path must be an exact prefix of the .proto file "
+                 "names -- protoc is too dumb to figure out when two paths "
+                 "(e.g. absolute and relative) are equivalent (it's harder "
+                 "than you think)." << std::endl;
         }
         return false;
     }
@@ -833,9 +840,10 @@
     if (ParseArgument(argv[i], &name, &value)) {
       // Returned true => Use the next argument as the flag value.
       if (i + 1 == argc || argv[i+1][0] == '-') {
-        cerr << "Missing value for flag: " << name << endl;
+        std::cerr << "Missing value for flag: " << name << std::endl;
         if (name == "--decode") {
-          cerr << "To decode an unknown message, use --decode_raw." << endl;
+          std::cerr << "To decode an unknown message, use --decode_raw."
+                    << std::endl;
         }
         return PARSE_ARGUMENT_FAIL;
       } else {
@@ -860,24 +868,25 @@
   // Check some errror cases.
   bool decoding_raw = (mode_ == MODE_DECODE) && codec_type_.empty();
   if (decoding_raw && !input_files_.empty()) {
-    cerr << "When using --decode_raw, no input files should be given." << endl;
+    std::cerr << "When using --decode_raw, no input files should be given."
+              << std::endl;
     return PARSE_ARGUMENT_FAIL;
   } else if (!decoding_raw && input_files_.empty()) {
-    cerr << "Missing input file." << endl;
+    std::cerr << "Missing input file." << std::endl;
     return PARSE_ARGUMENT_FAIL;
   }
   if (mode_ == MODE_COMPILE && output_directives_.empty() &&
       descriptor_set_name_.empty()) {
-    cerr << "Missing output directives." << endl;
+    std::cerr << "Missing output directives." << std::endl;
     return PARSE_ARGUMENT_FAIL;
   }
   if (imports_in_descriptor_set_ && descriptor_set_name_.empty()) {
-    cerr << "--include_imports only makes sense when combined with "
-            "--descriptor_set_out." << endl;
+    std::cerr << "--include_imports only makes sense when combined with "
+                 "--descriptor_set_out." << std::endl;
   }
   if (source_info_in_descriptor_set_ && descriptor_set_name_.empty()) {
-    cerr << "--include_source_info only makes sense when combined with "
-            "--descriptor_set_out." << endl;
+    std::cerr << "--include_source_info only makes sense when combined with "
+                 "--descriptor_set_out." << std::endl;
   }
 
   return PARSE_ARGUMENT_DONE_AND_CONTINUE;
@@ -950,10 +959,12 @@
   if (name.empty()) {
     // Not a flag.  Just a filename.
     if (value.empty()) {
-      cerr << "You seem to have passed an empty string as one of the "
-              "arguments to " << executable_name_ << ".  This is actually "
-              "sort of hard to do.  Congrats.  Unfortunately it is not valid "
-              "input so the program is going to die now." << endl;
+      std::cerr
+          << "You seem to have passed an empty string as one of the "
+             "arguments to " << executable_name_
+          << ".  This is actually "
+             "sort of hard to do.  Congrats.  Unfortunately it is not valid "
+             "input so the program is going to die now." << std::endl;
       return PARSE_ARGUMENT_FAIL;
     }
 
@@ -980,14 +991,16 @@
       }
 
       if (disk_path.empty()) {
-        cerr << "--proto_path passed empty directory name.  (Use \".\" for "
-                "current directory.)" << endl;
+        std::cerr
+            << "--proto_path passed empty directory name.  (Use \".\" for "
+               "current directory.)" << std::endl;
         return PARSE_ARGUMENT_FAIL;
       }
 
       // Make sure disk path exists, warn otherwise.
       if (access(disk_path.c_str(), F_OK) < 0) {
-        cerr << disk_path << ": warning: directory does not exist." << endl;
+        std::cerr << disk_path << ": warning: directory does not exist."
+                  << std::endl;
       }
 
       // Don't use make_pair as the old/default standard library on Solaris
@@ -998,30 +1011,31 @@
 
   } else if (name == "-o" || name == "--descriptor_set_out") {
     if (!descriptor_set_name_.empty()) {
-      cerr << name << " may only be passed once." << endl;
+      std::cerr << name << " may only be passed once." << std::endl;
       return PARSE_ARGUMENT_FAIL;
     }
     if (value.empty()) {
-      cerr << name << " requires a non-empty value." << endl;
+      std::cerr << name << " requires a non-empty value." << std::endl;
       return PARSE_ARGUMENT_FAIL;
     }
     if (mode_ != MODE_COMPILE) {
-      cerr << "Cannot use --encode or --decode and generate descriptors at the "
-              "same time." << endl;
+      std::cerr
+          << "Cannot use --encode or --decode and generate descriptors at the "
+             "same time." << std::endl;
       return PARSE_ARGUMENT_FAIL;
     }
     descriptor_set_name_ = value;
 
   } else if (name == "--include_imports") {
     if (imports_in_descriptor_set_) {
-      cerr << name << " may only be passed once." << endl;
+      std::cerr << name << " may only be passed once." << std::endl;
       return PARSE_ARGUMENT_FAIL;
     }
     imports_in_descriptor_set_ = true;
 
   } else if (name == "--include_source_info") {
     if (source_info_in_descriptor_set_) {
-      cerr << name << " may only be passed once." << endl;
+      std::cerr << name << " may only be passed once." << std::endl;
       return PARSE_ARGUMENT_FAIL;
     }
     source_info_in_descriptor_set_ = true;
@@ -1032,7 +1046,7 @@
 
   } else if (name == "--version") {
     if (!version_info_.empty()) {
-      cout << version_info_ << endl;
+      std::cout << version_info_ << std::endl;
     }
     cout << "libprotoc "
          << protobuf::internal::VersionString(GOOGLE_PROTOBUF_VERSION)
@@ -1045,25 +1059,28 @@
   } else if (name == "--encode" || name == "--decode" ||
              name == "--decode_raw") {
     if (mode_ != MODE_COMPILE) {
-      cerr << "Only one of --encode and --decode can be specified." << endl;
+      std::cerr << "Only one of --encode and --decode can be specified."
+                << std::endl;
       return PARSE_ARGUMENT_FAIL;
     }
     if (!output_directives_.empty() || !descriptor_set_name_.empty()) {
-      cerr << "Cannot use " << name
-           << " and generate code or descriptors at the same time." << endl;
+      std::cerr << "Cannot use " << name
+                << " and generate code or descriptors at the same time."
+                << std::endl;
       return PARSE_ARGUMENT_FAIL;
     }
 
     mode_ = (name == "--encode") ? MODE_ENCODE : MODE_DECODE;
 
     if (value.empty() && name != "--decode_raw") {
-      cerr << "Type name for " << name << " cannot be blank." << endl;
+      std::cerr << "Type name for " << name << " cannot be blank." << std::endl;
       if (name == "--decode") {
-        cerr << "To decode an unknown message, use --decode_raw." << endl;
+        std::cerr << "To decode an unknown message, use --decode_raw."
+                  << std::endl;
       }
       return PARSE_ARGUMENT_FAIL;
     } else if (!value.empty() && name == "--decode_raw") {
-      cerr << "--decode_raw does not take a parameter." << endl;
+      std::cerr << "--decode_raw does not take a parameter." << std::endl;
       return PARSE_ARGUMENT_FAIL;
     }
 
@@ -1075,13 +1092,13 @@
     } else if (value == "msvs") {
       error_format_ = ERROR_FORMAT_MSVS;
     } else {
-      cerr << "Unknown error format: " << value << endl;
+      std::cerr << "Unknown error format: " << value << std::endl;
       return PARSE_ARGUMENT_FAIL;
     }
 
   } else if (name == "--plugin") {
     if (plugin_prefix_.empty()) {
-      cerr << "This compiler does not support plugins." << endl;
+      std::cerr << "This compiler does not support plugins." << std::endl;
       return PARSE_ARGUMENT_FAIL;
     }
 
@@ -1107,13 +1124,15 @@
 
   } else if (name == "--print_free_field_numbers") {
     if (mode_ != MODE_COMPILE) {
-      cerr << "Cannot use " << name << " and use --encode, --decode or print "
-           << "other info at the same time." << endl;
+      std::cerr << "Cannot use " << name
+                << " and use --encode, --decode or print "
+                << "other info at the same time." << std::endl;
       return PARSE_ARGUMENT_FAIL;
     }
     if (!output_directives_.empty() || !descriptor_set_name_.empty()) {
-      cerr << "Cannot use " << name
-           << " and generate code or descriptors at the same time." << endl;
+      std::cerr << "Cannot use " << name
+                << " and generate code or descriptors at the same time."
+                << std::endl;
       return PARSE_ARGUMENT_FAIL;
     }
     mode_ = MODE_PRINT;
@@ -1127,7 +1146,7 @@
       // Check if it's a generator option flag.
       generator_info = FindOrNull(generators_by_option_name_, name);
       if (generator_info == NULL) {
-        cerr << "Unknown flag: " << name << endl;
+        std::cerr << "Unknown flag: " << name << std::endl;
         return PARSE_ARGUMENT_FAIL;
       } else {
         string* parameters = &generator_parameters_[generator_info->flag_name];
@@ -1139,8 +1158,8 @@
     } else {
       // It's an output flag.  Add it to the output directives.
       if (mode_ != MODE_COMPILE) {
-        cerr << "Cannot use --encode, --decode or print .proto info and "
-                "generate code at the same time." << endl;
+        std::cerr << "Cannot use --encode, --decode or print .proto info and "
+                     "generate code at the same time." << std::endl;
         return PARSE_ARGUMENT_FAIL;
       }
 
@@ -1172,7 +1191,7 @@
 
 void CommandLineInterface::PrintHelpText() {
   // Sorry for indentation here; line wrapping would be uglier.
-  cerr <<
+  std::cerr <<
 "Usage: " << executable_name_ << " [OPTION] PROTO_FILES\n"
 "Parse PROTO_FILES and generate output based on the options given:\n"
 "  -IPATH, --proto_path=PATH   Specify the directory in which to search for\n"
@@ -1213,9 +1232,9 @@
 "                              defined in the given proto files. Groups share\n"
 "                              the same field number space with the parent \n"
 "                              message. Extension ranges are counted as \n"
-"                              occupied fields numbers."  << endl;
+"                              occupied fields numbers."  << std::endl;
   if (!plugin_prefix_.empty()) {
-    cerr <<
+    std::cerr <<
 "  --plugin=EXECUTABLE         Specifies a plugin executable to use.\n"
 "                              Normally, protoc searches the PATH for\n"
 "                              plugins, but you may specify additional\n"
@@ -1223,7 +1242,7 @@
 "                              Additionally, EXECUTABLE may be of the form\n"
 "                              NAME=PATH, in which case the given plugin name\n"
 "                              is mapped to the given executable even if\n"
-"                              the executable's own name differs." << endl;
+"                              the executable's own name differs." << std::endl;
   }
 
   for (GeneratorMap::iterator iter = generators_by_flag_name_.begin();
@@ -1231,9 +1250,9 @@
     // FIXME(kenton):  If the text is long enough it will wrap, which is ugly,
     //   but fixing this nicely (e.g. splitting on spaces) is probably more
     //   trouble than it's worth.
-    cerr << "  " << iter->first << "=OUT_DIR "
-         << string(19 - iter->first.size(), ' ')  // Spaces for alignment.
-         << iter->second.help_text << endl;
+    std::cerr << "  " << iter->first << "=OUT_DIR "
+              << string(19 - iter->first.size(), ' ')  // Spaces for alignment.
+              << iter->second.help_text << std::endl;
   }
 }
 
@@ -1256,7 +1275,7 @@
     if (!GeneratePluginOutput(parsed_files, plugin_name,
                               output_directive.parameter,
                               generator_context, &error)) {
-      cerr << output_directive.name << ": " << error << endl;
+      std::cerr << output_directive.name << ": " << error << std::endl;
       return false;
     }
   } else {
@@ -1272,8 +1291,8 @@
       if (!output_directive.generator->Generate(parsed_files[i], parameters,
                                                 generator_context, &error)) {
         // Generator returned an error.
-        cerr << output_directive.name << ": " << parsed_files[i]->name() << ": "
-             << error << endl;
+        std::cerr << output_directive.name << ": " << parsed_files[i]->name()
+                  << ": " << error << std::endl;
         return false;
       }
     }
@@ -1365,7 +1384,7 @@
   // Look up the type.
   const Descriptor* type = pool->FindMessageTypeByName(codec_type_);
   if (type == NULL) {
-    cerr << "Type not defined: " << codec_type_ << endl;
+    std::cerr << "Type not defined: " << codec_type_ << std::endl;
     return false;
   }
 
@@ -1391,32 +1410,32 @@
     parser.AllowPartialMessage(true);
 
     if (!parser.Parse(&in, message.get())) {
-      cerr << "Failed to parse input." << endl;
+      std::cerr << "Failed to parse input." << std::endl;
       return false;
     }
   } else {
     // Input is binary.
     if (!message->ParsePartialFromZeroCopyStream(&in)) {
-      cerr << "Failed to parse input." << endl;
+      std::cerr << "Failed to parse input." << std::endl;
       return false;
     }
   }
 
   if (!message->IsInitialized()) {
-    cerr << "warning:  Input message is missing required fields:  "
-         << message->InitializationErrorString() << endl;
+    std::cerr << "warning:  Input message is missing required fields:  "
+              << message->InitializationErrorString() << std::endl;
   }
 
   if (mode_ == MODE_ENCODE) {
     // Output is binary.
     if (!message->SerializePartialToZeroCopyStream(&out)) {
-      cerr << "output: I/O error." << endl;
+      std::cerr << "output: I/O error." << std::endl;
       return false;
     }
   } else {
     // Output is text.
     if (!TextFormat::Print(*message, &out)) {
-      cerr << "output: I/O error." << endl;
+      std::cerr << "output: I/O error." << std::endl;
       return false;
     }
   }
@@ -1458,12 +1477,14 @@
 
   io::FileOutputStream out(fd);
   if (!file_set.SerializeToZeroCopyStream(&out)) {
-    cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) << endl;
+    std::cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno())
+              << std::endl;
     out.Close();
     return false;
   }
   if (!out.Close()) {
-    cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) << endl;
+    std::cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno())
+              << std::endl;
     return false;
   }
 
@@ -1582,7 +1603,7 @@
   if (next_free_number <= FieldDescriptor::kMaxNumber) {
     StringAppendF(&output, " %d-INF", next_free_number);
   }
-  cout << output << endl;
+  std::cout << output << std::endl;
 }
 
 }  // namespace
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index 64e877a..3d27829 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -67,7 +67,6 @@
 // Disable the whole test when we use tcmalloc for "draconian" heap checks, in
 // which case tcmalloc will print warnings that fail the plugin tests.
 #if !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
-
 namespace google {
 namespace protobuf {
 namespace compiler {
@@ -1666,6 +1665,6 @@
 
 }  // namespace compiler
 }  // namespace protobuf
-}  // namespace google
 
-#endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
+#endif  // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
+}  // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
index 4878819..13ed0b6 100644
--- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
@@ -98,7 +98,8 @@
                           &actual_contents, true));
     EXPECT_TRUE(actual_contents == *expected_contents)
       << physical_filename << " needs to be regenerated.  Please run "
-         "generate_descriptor_proto.sh and add this file "
+         "google/protobuf/compiler/release_compiler.sh and "
+         "generate_descriptor_proto.sh. Then add this file "
          "to your CL.";
   }
 
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc
index 3ce1f12..0404b73 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc
@@ -47,7 +47,7 @@
 
 namespace {
 // The GOOGLE_ARRAYSIZE constant is the max enum value plus 1. If the max enum value
-// is kint32max, GOOGLE_ARRAYSIZE will overflow. In such cases we should omit the
+// is ::google::protobuf::kint32max, GOOGLE_ARRAYSIZE will overflow. In such cases we should omit the
 // generation of the GOOGLE_ARRAYSIZE constant.
 bool ShouldGenerateArraySize(const EnumDescriptor* descriptor) {
   int32 max_value = descriptor->value(0)->number();
@@ -56,7 +56,7 @@
       max_value = descriptor->value(i)->number();
     }
   }
-  return max_value != kint32max;
+  return max_value != ::google::protobuf::kint32max;
 }
 }  // namespace
 
@@ -153,9 +153,12 @@
 
 void EnumGenerator::
 GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
+  printer->Print(
+      "template <> struct is_proto_enum< $classname$> : ::google::protobuf::internal::true_type "
+      "{};\n",
+      "classname", ClassName(descriptor_, true));
   if (HasDescriptorMethods(descriptor_->file())) {
     printer->Print(
-      "template <> struct is_proto_enum< $classname$> : ::google::protobuf::internal::true_type {};\n"
       "template <>\n"
       "inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n"
       "  return $classname$_descriptor();\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
index 1792613..7498970 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -76,23 +76,26 @@
 void EnumFieldGenerator::
 GenerateAccessorDeclarations(io::Printer* printer) const {
   printer->Print(variables_,
-    "inline $type$ $name$() const$deprecation$;\n"
-    "inline void set_$name$($type$ value)$deprecation$;\n");
+    "$type$ $name$() const$deprecation$;\n"
+    "void set_$name$($type$ value)$deprecation$;\n");
 }
 
 void EnumFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline $type$ $classname$::$name$() const {\n"
+GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                  bool is_inline) const {
+  map<string, string> variables(variables_);
+  variables["inline"] = is_inline ? "inline" : "";
+  printer->Print(variables,
+    "$inline$ $type$ $classname$::$name$() const {\n"
     "  // @@protoc_insertion_point(field_get:$full_name$)\n"
     "  return static_cast< $type$ >($name$_);\n"
     "}\n"
-    "inline void $classname$::set_$name$($type$ value) {\n");
+    "$inline$ void $classname$::set_$name$($type$ value) {\n");
   if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
-    printer->Print(variables_,
+    printer->Print(variables,
     "  assert($type$_IsValid(value));\n");
   }
-  printer->Print(variables_,
+  printer->Print(variables,
     "  $set_hasbit$\n"
     "  $name$_ = value;\n"
     "  // @@protoc_insertion_point(field_set:$full_name$)\n"
@@ -181,21 +184,24 @@
 EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {}
 
 void EnumOneofFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline $type$ $classname$::$name$() const {\n"
+GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                  bool is_inline) const {
+  map<string, string> variables(variables_);
+  variables["inline"] = is_inline ? "inline" : "";
+  printer->Print(variables,
+    "$inline$ $type$ $classname$::$name$() const {\n"
     "  // @@protoc_insertion_point(field_get:$full_name$)\n"
     "  if (has_$name$()) {\n"
     "    return static_cast< $type$ >($oneof_prefix$$name$_);\n"
     "  }\n"
     "  return static_cast< $type$ >($default$);\n"
     "}\n"
-    "inline void $classname$::set_$name$($type$ value) {\n");
+    "$inline$ void $classname$::set_$name$($type$ value) {\n");
   if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
-    printer->Print(variables_,
+    printer->Print(variables,
     "  assert($type$_IsValid(value));\n");
   }
-  printer->Print(variables_,
+  printer->Print(variables,
     "  if (!has_$name$()) {\n"
     "    clear_$oneof_name$();\n"
     "    set_has_$name$();\n"
@@ -246,46 +252,49 @@
 void RepeatedEnumFieldGenerator::
 GenerateAccessorDeclarations(io::Printer* printer) const {
   printer->Print(variables_,
-    "inline $type$ $name$(int index) const$deprecation$;\n"
-    "inline void set_$name$(int index, $type$ value)$deprecation$;\n"
-    "inline void add_$name$($type$ value)$deprecation$;\n");
+    "$type$ $name$(int index) const$deprecation$;\n"
+    "void set_$name$(int index, $type$ value)$deprecation$;\n"
+    "void add_$name$($type$ value)$deprecation$;\n");
   printer->Print(variables_,
-    "inline const ::google::protobuf::RepeatedField<int>& $name$() const$deprecation$;\n"
-    "inline ::google::protobuf::RepeatedField<int>* mutable_$name$()$deprecation$;\n");
+    "const ::google::protobuf::RepeatedField<int>& $name$() const$deprecation$;\n"
+    "::google::protobuf::RepeatedField<int>* mutable_$name$()$deprecation$;\n");
 }
 
 void RepeatedEnumFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline $type$ $classname$::$name$(int index) const {\n"
+GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                  bool is_inline) const {
+  map<string, string> variables(variables_);
+  variables["inline"] = is_inline ? "inline" : "";
+  printer->Print(variables,
+    "$inline$ $type$ $classname$::$name$(int index) const {\n"
     "  // @@protoc_insertion_point(field_get:$full_name$)\n"
     "  return static_cast< $type$ >($name$_.Get(index));\n"
     "}\n"
-    "inline void $classname$::set_$name$(int index, $type$ value) {\n");
+    "$inline$ void $classname$::set_$name$(int index, $type$ value) {\n");
   if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
-    printer->Print(variables_,
+    printer->Print(variables,
     "  assert($type$_IsValid(value));\n");
   }
-  printer->Print(variables_,
+  printer->Print(variables,
     "  $name$_.Set(index, value);\n"
     "  // @@protoc_insertion_point(field_set:$full_name$)\n"
     "}\n"
-    "inline void $classname$::add_$name$($type$ value) {\n");
+    "$inline$ void $classname$::add_$name$($type$ value) {\n");
   if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
-    printer->Print(variables_,
+    printer->Print(variables,
     "  assert($type$_IsValid(value));\n");
   }
-  printer->Print(variables_,
+  printer->Print(variables,
     "  $name$_.Add(value);\n"
     "  // @@protoc_insertion_point(field_add:$full_name$)\n"
     "}\n");
-  printer->Print(variables_,
-    "inline const ::google::protobuf::RepeatedField<int>&\n"
+  printer->Print(variables,
+    "$inline$ const ::google::protobuf::RepeatedField<int>&\n"
     "$classname$::$name$() const {\n"
     "  // @@protoc_insertion_point(field_list:$full_name$)\n"
     "  return $name$_;\n"
     "}\n"
-    "inline ::google::protobuf::RepeatedField<int>*\n"
+    "$inline$ ::google::protobuf::RepeatedField<int>*\n"
     "$classname$::mutable_$name$() {\n"
     "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
     "  return &$name$_;\n"
@@ -344,20 +353,34 @@
 void RepeatedEnumFieldGenerator::
 GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
   if (!descriptor_->options().packed()) {
-    // We use a non-inlined implementation in this case, since this path will
-    // rarely be executed.
-    printer->Print(variables_,
-      "DO_((::google::protobuf::internal::WireFormatLite::ReadPackedEnumNoInline(\n"
-      "       input,\n");
+      // This path is rarely executed, so we use a non-inlined implementation.
     if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
       printer->Print(variables_,
-      "       NULL,\n");
+        "DO_((::google::protobuf::internal::"
+                    "WireFormatLite::ReadPackedEnumPreserveUnknowns(\n"
+        "       input,\n"
+        "       $number$,\n"
+        "       NULL,\n"
+        "       NULL,\n"
+        "       this->mutable_$name$())));\n");
+    } else if (UseUnknownFieldSet(descriptor_->file())) {
+      printer->Print(variables_,
+        "DO_((::google::protobuf::internal::WireFormat::ReadPackedEnumPreserveUnknowns(\n"
+        "       input,\n"
+        "       $number$,\n"
+        "       $type$_IsValid,\n"
+        "       mutable_unknown_fields(),\n"
+        "       this->mutable_$name$())));\n");
     } else {
       printer->Print(variables_,
-      "       &$type$_IsValid,\n");
+        "DO_((::google::protobuf::internal::"
+                     "WireFormatLite::ReadPackedEnumPreserveUnknowns(\n"
+        "       input,\n"
+        "       $number$,\n"
+        "       $type$_IsValid,\n"
+        "       &unknown_fields_stream,\n"
+        "       this->mutable_$name$())));\n");
     }
-    printer->Print(variables_,
-      "       this->mutable_$name$())));\n");
   } else {
     printer->Print(variables_,
       "::google::protobuf::uint32 length;\n"
@@ -376,6 +399,16 @@
       printer->Print(variables_,
       "  if ($type$_IsValid(value)) {\n"
       "    add_$name$(static_cast< $type$ >(value));\n"
+      "  } else {\n");
+      if (UseUnknownFieldSet(descriptor_->file())) {
+        printer->Print(variables_,
+        "    mutable_unknown_fields()->AddVarint($number$, value);\n");
+      } else {
+        printer->Print(variables_,
+        "    unknown_fields_stream.WriteVarint32(tag);\n"
+        "    unknown_fields_stream.WriteVarint32(value);\n");
+      }
+      printer->Print(
       "  }\n");
     }
     printer->Print(variables_,
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/src/google/protobuf/compiler/cpp/cpp_enum_field.h
index def2b23..5b1d01e 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.h
@@ -53,7 +53,8 @@
   // implements FieldGenerator ---------------------------------------
   void GeneratePrivateMembers(io::Printer* printer) const;
   void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                         bool is_inline) const;
   void GenerateClearingCode(io::Printer* printer) const;
   void GenerateMergingCode(io::Printer* printer) const;
   void GenerateSwappingCode(io::Printer* printer) const;
@@ -78,7 +79,8 @@
   ~EnumOneofFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                         bool is_inline) const;
   void GenerateClearingCode(io::Printer* printer) const;
   void GenerateSwappingCode(io::Printer* printer) const;
   void GenerateConstructorCode(io::Printer* printer) const;
@@ -96,7 +98,8 @@
   // implements FieldGenerator ---------------------------------------
   void GeneratePrivateMembers(io::Printer* printer) const;
   void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                         bool is_inline) const;
   void GenerateClearingCode(io::Printer* printer) const;
   void GenerateMergingCode(io::Printer* printer) const;
   void GenerateSwappingCode(io::Printer* printer) const;
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h
index c37fe0b..cd2b6b7 100644
--- a/src/google/protobuf/compiler/cpp/cpp_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_field.h
@@ -89,7 +89,7 @@
   // Generate inline definitions of accessor functions for this field.
   // These are placed inside the header after all class definitions.
   virtual void GenerateInlineAccessorDefinitions(
-    io::Printer* printer) const = 0;
+    io::Printer* printer, bool is_inline) const = 0;
 
   // Generate definitions of accessors that aren't inlined.  These are
   // placed somewhere in the .cc file.
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index fae4df4..a98c7d9 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -136,8 +136,11 @@
   printer->Print(
     "#include <google/protobuf/arena.h>\n"
     "#include <google/protobuf/arenastring.h>\n"
-    "#include <google/protobuf/generated_message_util.h>\n"
-    "#include <google/protobuf/metadata.h>\n");
+    "#include <google/protobuf/generated_message_util.h>\n");
+  if (UseUnknownFieldSet(file_)) {
+    printer->Print(
+      "#include <google/protobuf/metadata.h>\n");
+  }
   if (file_->message_type_count() > 0) {
     if (HasDescriptorMethods(file_)) {
       printer->Print(
@@ -152,13 +155,24 @@
     "#include <google/protobuf/extension_set.h>\n");
   if (HasMapFields(file_)) {
     printer->Print(
-      "#include <google/protobuf/map.h>\n"
-      "#include <google/protobuf/map_field_inl.h>\n");
+        "#include <google/protobuf/map.h>\n");
+    if (HasDescriptorMethods(file_)) {
+      printer->Print(
+          "#include <google/protobuf/map_field_inl.h>\n");
+    } else {
+      printer->Print(
+          "#include <google/protobuf/map_field_lite.h>\n");
+    }
   }
 
-  if (HasDescriptorMethods(file_) && HasEnumDefinitions(file_)) {
-    printer->Print(
-      "#include <google/protobuf/generated_enum_reflection.h>\n");
+  if (HasEnumDefinitions(file_)) {
+    if (HasDescriptorMethods(file_)) {
+      printer->Print(
+          "#include <google/protobuf/generated_enum_reflection.h>\n");
+    } else {
+      printer->Print(
+          "#include <google/protobuf/generated_enum_util.h>\n");
+    }
   }
 
   if (HasGenericServices(file_)) {
@@ -272,15 +286,17 @@
   printer->Print(kThickSeparator);
   printer->Print("\n");
 
-
+  printer->Print("#if !PROTOBUF_INLINE_NOT_IN_HEADERS\n");
   // Generate class inline methods.
   for (int i = 0; i < file_->message_type_count(); i++) {
     if (i > 0) {
       printer->Print(kThinSeparator);
       printer->Print("\n");
     }
-    message_generators_[i]->GenerateInlineMethods(printer);
+    message_generators_[i]->GenerateInlineMethods(printer,
+                                                  /* is_inline = */ true);
   }
+  printer->Print("#endif  // !PROTOBUF_INLINE_NOT_IN_HEADERS\n");
 
   printer->Print(
     "\n"
@@ -290,7 +306,7 @@
   GenerateNamespaceClosers(printer);
 
   // Emit GetEnumDescriptor specializations into google::protobuf namespace:
-  if (HasDescriptorMethods(file_)) {
+  if (HasEnumDefinitions(file_)) {
     // The SWIG conditional is to avoid a null-pointer dereference
     // (bug 1984964) in swig-1.3.21 resulting from the following syntax:
     //   namespace X { void Y<Z::W>(); }
@@ -417,6 +433,12 @@
     printer->Print(kThickSeparator);
     printer->Print("\n");
     message_generators_[i]->GenerateClassMethods(printer);
+
+    printer->Print("#if PROTOBUF_INLINE_NOT_IN_HEADERS\n");
+    // Generate class inline methods.
+    message_generators_[i]->GenerateInlineMethods(printer,
+                                                  /* is_inline = */ false);
+    printer->Print("#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS\n");
   }
 
   if (HasGenericServices(file_)) {
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index 28c4dd5..237278d 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -352,9 +352,7 @@
     } else {
       // Not alphanumeric.  To avoid any possibility of name conflicts we
       // use the hex code for the character.
-      result.push_back('_');
-      char buffer[kFastToBufferSize];
-      result.append(FastHexToBuffer(static_cast<uint8>(filename[i]), buffer));
+      StrAppend(&result, "_", ToHex(static_cast<uint8>(filename[i])));
     }
   }
   return result;
@@ -508,6 +506,13 @@
   return false;
 }
 
+FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field) {
+  GOOGLE_DCHECK(field->cpp_type() == FieldDescriptor::CPPTYPE_STRING);
+  // Open-source protobuf release only supports STRING ctype.
+  return FieldOptions::STRING;
+
+}
+
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h
index e60fa7c..c7bb8f9 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.h
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -211,6 +211,10 @@
 // Returns true if the field's CPPTYPE is string or message.
 bool IsStringOrMessage(const FieldDescriptor* field);
 
+// For a string field, returns the effective ctype.  If the actual ctype is
+// not supported, returns the default of STRING.
+FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field);
+
 string UnderscoresToCamelCase(const string& input, bool cap_next_letter);
 
 inline bool HasFieldPresence(const FileDescriptor* file) {
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
index 0154eeb..8c38db2 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
@@ -31,6 +31,7 @@
 #include <google/protobuf/compiler/cpp/cpp_map_field.h>
 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
 #include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format.h>
 #include <google/protobuf/stubs/strutil.h>
 
 namespace google {
@@ -72,14 +73,21 @@
       (*variables)["val_cpp"] = PrimitiveTypeName(val->cpp_type());
       (*variables)["wrapper"] = "EntryWrapper";
   }
-  (*variables)["key_type"] =
-      "::google::protobuf::FieldDescriptor::TYPE_" +
+  (*variables)["key_wire_type"] =
+      "::google::protobuf::internal::WireFormatLite::TYPE_" +
       ToUpper(DeclaredTypeMethodName(key->type()));
-  (*variables)["val_type"] =
-      "::google::protobuf::FieldDescriptor::TYPE_" +
+  (*variables)["val_wire_type"] =
+      "::google::protobuf::internal::WireFormatLite::TYPE_" +
       ToUpper(DeclaredTypeMethodName(val->type()));
   (*variables)["map_classname"] = ClassName(descriptor->message_type(), false);
-  (*variables)["number"] = Int32ToString(descriptor->number());
+  (*variables)["number"] = SimpleItoa(descriptor->number());
+  (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
+
+  if (HasDescriptorMethods(descriptor->file())) {
+    (*variables)["lite"] = "";
+  } else {
+    (*variables)["lite"] = "Lite";
+  }
 
   if (!IsProto3Field(descriptor) &&
       val->type() == FieldDescriptor::TYPE_ENUM) {
@@ -102,33 +110,40 @@
 void MapFieldGenerator::
 GeneratePrivateMembers(io::Printer* printer) const {
   printer->Print(variables_,
-      "typedef ::google::protobuf::internal::MapEntry<\n"
+      "typedef ::google::protobuf::internal::MapEntryLite<\n"
       "    $key_cpp$, $val_cpp$,\n"
-      "    $key_type$,\n"
-      "    $val_type$, $default_enum_value$>\n"
+      "    $key_wire_type$,\n"
+      "    $val_wire_type$,\n"
+      "    $default_enum_value$ >\n"
       "    $map_classname$;\n"
-      "::google::protobuf::internal::MapField< $key_cpp$, $val_cpp$,"
-      "$key_type$, $val_type$, $default_enum_value$ > $name$_;\n");
+      "::google::protobuf::internal::MapField$lite$<\n"
+      "    $key_cpp$, $val_cpp$,\n"
+      "    $key_wire_type$,\n"
+      "    $val_wire_type$,\n"
+      "    $default_enum_value$ > $name$_;\n");
 }
 
 void MapFieldGenerator::
 GenerateAccessorDeclarations(io::Printer* printer) const {
   printer->Print(variables_,
-      "inline const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n"
+      "const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n"
       "    $name$() const$deprecation$;\n"
-      "inline ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n"
+      "::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n"
       "    mutable_$name$()$deprecation$;\n");
 }
 
 void MapFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-      "inline const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n"
+GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                  bool is_inline) const {
+  map<string, string> variables(variables_);
+  variables["inline"] = is_inline ? "inline" : "";
+  printer->Print(variables,
+      "$inline$ const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n"
       "$classname$::$name$() const {\n"
       "  // @@protoc_insertion_point(field_map:$full_name$)\n"
       "  return $name$_.GetMap();\n"
       "}\n"
-      "inline ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n"
+      "$inline$ ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n"
       "$classname$::mutable_$name$() {\n"
       "  // @@protoc_insertion_point(field_mutable_map:$full_name$)\n"
       "  return $name$_.MutableMap();\n"
@@ -198,11 +213,29 @@
         "  if ($val_cpp$_IsValid(*entry->mutable_value())) {\n"
         "    (*mutable_$name$())[entry->key()] =\n"
         "        static_cast<$val_cpp$>(*entry->mutable_value());\n"
-        "  } else {\n"
-        "    mutable_unknown_fields()->AddLengthDelimited($number$, data);\n"
+        "  } else {\n");
+    if (HasDescriptorMethods(descriptor_->file())) {
+      printer->Print(variables_,
+          "    mutable_unknown_fields()"
+          "->AddLengthDelimited($number$, data);\n");
+    } else {
+      printer->Print(variables_,
+          "    unknown_fields_stream.WriteVarint32($tag$);\n"
+          "    unknown_fields_stream.WriteVarint32(data.size());\n"
+          "    unknown_fields_stream.WriteString(data);\n");
+    }
+
+
+    printer->Print(variables_,
         "  }\n"
         "}\n");
   }
+
+  // If entry is allocated by arena, its desctructor should be avoided.
+  if (SupportsArenas(descriptor_)) {
+    printer->Print(variables_,
+        "if (entry->GetArena() != NULL) entry.release();\n");
+  }
 }
 
 void MapFieldGenerator::
@@ -211,12 +244,31 @@
       "{\n"
       "  ::google::protobuf::scoped_ptr<$map_classname$> entry;\n"
       "  for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
-      "      it = $name$().begin(); it != $name$().end(); ++it) {\n"
+      "      it = $name$().begin(); it != $name$().end(); ++it) {\n");
+
+  // If entry is allocated by arena, its desctructor should be avoided.
+  if (SupportsArenas(descriptor_)) {
+    printer->Print(variables_,
+        "    if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
+        "      entry.release();\n"
+        "    }\n");
+  }
+
+  printer->Print(variables_,
       "    entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
       "    ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
       "        $number$, *entry, output);\n"
-      "  }\n"
-      "}\n");
+      "  }\n");
+
+  // If entry is allocated by arena, its desctructor should be avoided.
+  if (SupportsArenas(descriptor_)) {
+    printer->Print(variables_,
+        "  if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
+        "    entry.release();\n"
+        "  }\n");
+  }
+
+  printer->Print("}\n");
 }
 
 void MapFieldGenerator::
@@ -225,13 +277,32 @@
       "{\n"
       "  ::google::protobuf::scoped_ptr<$map_classname$> entry;\n"
       "  for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
-      "      it = $name$().begin(); it != $name$().end(); ++it) {\n"
+      "      it = $name$().begin(); it != $name$().end(); ++it) {\n");
+
+  // If entry is allocated by arena, its desctructor should be avoided.
+  if (SupportsArenas(descriptor_)) {
+    printer->Print(variables_,
+        "    if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
+        "      entry.release();\n"
+        "    }\n");
+  }
+
+  printer->Print(variables_,
       "    entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
       "    target = ::google::protobuf::internal::WireFormatLite::\n"
       "        Write$declared_type$NoVirtualToArray(\n"
       "            $number$, *entry, target);\n"
-      "  }\n"
-      "}\n");
+      "  }\n");
+
+  // If entry is allocated by arena, its desctructor should be avoided.
+  if (SupportsArenas(descriptor_)) {
+    printer->Print(variables_,
+        "  if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
+        "    entry.release();\n"
+        "  }\n");
+  }
+
+  printer->Print("}\n");
 }
 
 void MapFieldGenerator::
@@ -241,12 +312,31 @@
       "{\n"
       "  ::google::protobuf::scoped_ptr<$map_classname$> entry;\n"
       "  for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
-      "      it = $name$().begin(); it != $name$().end(); ++it) {\n"
+      "      it = $name$().begin(); it != $name$().end(); ++it) {\n");
+
+  // If entry is allocated by arena, its desctructor should be avoided.
+  if (SupportsArenas(descriptor_)) {
+    printer->Print(variables_,
+        "    if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
+        "      entry.release();\n"
+        "    }\n");
+  }
+
+  printer->Print(variables_,
       "    entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
       "    total_size += ::google::protobuf::internal::WireFormatLite::\n"
       "        $declared_type$SizeNoVirtual(*entry);\n"
-      "  }\n"
-      "}\n");
+      "  }\n");
+
+  // If entry is allocated by arena, its desctructor should be avoided.
+  if (SupportsArenas(descriptor_)) {
+    printer->Print(variables_,
+        "  if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
+        "    entry.release();\n"
+        "  }\n");
+  }
+
+  printer->Print("}\n");
 }
 
 }  // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.h b/src/google/protobuf/compiler/cpp/cpp_map_field.h
index 0ff032f..d27d485 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.h
@@ -50,7 +50,8 @@
   // implements FieldGenerator ---------------------------------------
   void GeneratePrivateMembers(io::Printer* printer) const;
   void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                         bool is_inline) const;
   void GenerateClearingCode(io::Printer* printer) const;
   void GenerateMergingCode(io::Printer* printer) const;
   void GenerateSwappingCode(io::Printer* printer) const;
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index e71d35f..bafa36f 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -87,8 +87,8 @@
   for (int i = 0; i < descriptor->field_count(); i++) {
     fields[i] = descriptor->field(i);
   }
-  sort(fields, fields + descriptor->field_count(),
-       FieldOrderingByNumber());
+  std::sort(fields, fields + descriptor->field_count(),
+            FieldOrderingByNumber());
   return fields;
 }
 
@@ -253,7 +253,7 @@
   // Sort by preferred location to keep fields as close to their original
   // location as possible.  Using stable_sort ensures that the output is
   // consistent across runs.
-  stable_sort(aligned_to_4.begin(), aligned_to_4.end());
+  std::stable_sort(aligned_to_4.begin(), aligned_to_4.end());
 
   // Now group fields aligned to 4 bytes (or the 4-field groups created above)
   // into pairs, and treat those like a single field aligned to 8 bytes.
@@ -269,7 +269,7 @@
     aligned_to_8.push_back(field_group);
   }
   // Sort by preferred location.
-  stable_sort(aligned_to_8.begin(), aligned_to_8.end());
+  std::stable_sort(aligned_to_8.begin(), aligned_to_8.end());
 
   // Now pull out all the FieldDescriptors in order.
   fields->clear();
@@ -280,10 +280,6 @@
   }
 }
 
-string MessageTypeProtoName(const FieldDescriptor* field) {
-  return field->message_type()->full_name();
-}
-
 // Emits an if-statement with a condition that evaluates to true if |field| is
 // considered non-default (will be sent over the wire), for message types
 // without true field presence. Should only be called if
@@ -351,11 +347,11 @@
     default:
       (*variables)["val"] = PrimitiveTypeName(val->cpp_type());
   }
-  (*variables)["key_type"] =
-      "::google::protobuf::FieldDescriptor::TYPE_" +
+  (*variables)["key_wire_type"] =
+      "::google::protobuf::internal::WireFormatLite::TYPE_" +
       ToUpper(DeclaredTypeMethodName(key->type()));
-  (*variables)["val_type"] =
-      "::google::protobuf::FieldDescriptor::TYPE_" +
+  (*variables)["val_wire_type"] =
+      "::google::protobuf::internal::WireFormatLite::TYPE_" +
       ToUpper(DeclaredTypeMethodName(val->type()));
 }
 
@@ -457,17 +453,17 @@
     vars["constant_name"] = FieldConstantName(field);
 
     if (field->is_repeated()) {
-      printer->Print(vars, "inline int $name$_size() const$deprecation$;\n");
+      printer->Print(vars, "int $name$_size() const$deprecation$;\n");
     } else if (HasHasMethod(field)) {
-      printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n");
+      printer->Print(vars, "bool has_$name$() const$deprecation$;\n");
     } else if (HasPrivateHasMethod(field)) {
       printer->Print(vars,
           "private:\n"
-          "inline bool has_$name$() const$deprecation$;\n"
+          "bool has_$name$() const$deprecation$;\n"
           "public:\n");
     }
 
-    printer->Print(vars, "inline void clear_$name$()$deprecation$;\n");
+    printer->Print(vars, "void clear_$name$()$deprecation$;\n");
     printer->Print(vars, "static const int $constant_name$ = $number$;\n");
 
     // Generate type-specific accessor declarations.
@@ -486,7 +482,7 @@
 
   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
     printer->Print(
-        "inline $camel_oneof_name$Case $oneof_name$_case() const;\n",
+        "$camel_oneof_name$Case $oneof_name$_case() const;\n",
         "camel_oneof_name",
         UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true),
         "oneof_name", descriptor_->oneof_decl(i)->name());
@@ -494,7 +490,7 @@
 }
 
 void MessageGenerator::
-GenerateFieldAccessorDefinitions(io::Printer* printer) {
+GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) {
   printer->Print("// $classname$\n\n", "classname", classname_);
 
   for (int i = 0; i < descriptor_->field_count(); i++) {
@@ -504,11 +500,12 @@
 
     map<string, string> vars;
     SetCommonFieldVariables(field, &vars, options_);
+    vars["inline"] = is_inline ? "inline" : "";
 
     // Generate has_$name$() or $name$_size().
     if (field->is_repeated()) {
       printer->Print(vars,
-        "inline int $classname$::$name$_size() const {\n"
+        "$inline$ int $classname$::$name$_size() const {\n"
         "  return $name$_.size();\n"
         "}\n");
     } else if (field->containing_oneof()) {
@@ -522,11 +519,11 @@
       vars["oneof_name"] = field->containing_oneof()->name();
       vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index());
       printer->Print(vars,
-        "inline bool $classname$::has_$name$() const {\n"
+        "$inline$ bool $classname$::has_$name$() const {\n"
         "  return $oneof_name$_case() == k$field_name$;\n"
         "}\n");
       printer->Print(vars,
-        "inline void $classname$::set_has_$name$() {\n"
+        "$inline$ void $classname$::set_has_$name$() {\n"
         "  _oneof_case_[$oneof_index$] = k$field_name$;\n"
         "}\n");
     } else {
@@ -539,13 +536,13 @@
         vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32),
                                              buffer);
         printer->Print(vars,
-          "inline bool $classname$::has_$name$() const {\n"
+          "$inline$ bool $classname$::has_$name$() const {\n"
           "  return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"
           "}\n"
-          "inline void $classname$::set_has_$name$() {\n"
+          "$inline$ void $classname$::set_has_$name$() {\n"
           "  _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n"
           "}\n"
-          "inline void $classname$::clear_has_$name$() {\n"
+          "$inline$ void $classname$::clear_has_$name$() {\n"
           "  _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"
           "}\n"
           );
@@ -555,12 +552,12 @@
           bool is_lazy = false;
           if (is_lazy) {
             printer->Print(vars,
-              "inline bool $classname$::has_$name$() const {\n"
+              "$inline$ bool $classname$::has_$name$() const {\n"
               "  return !$name$_.IsCleared();\n"
               "}\n");
           } else {
             printer->Print(vars,
-              "inline bool $classname$::has_$name$() const {\n"
+              "$inline$ bool $classname$::has_$name$() const {\n"
               "  return !_is_default_instance_ && $name$_ != NULL;\n"
               "}\n");
           }
@@ -570,7 +567,7 @@
 
     // Generate clear_$name$()
     printer->Print(vars,
-      "inline void $classname$::clear_$name$() {\n");
+      "$inline$ void $classname$::clear_$name$() {\n");
 
     printer->Indent();
 
@@ -599,7 +596,8 @@
     printer->Print("}\n");
 
     // Generate type-specific accessors.
-    field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
+    field_generators_.get(field).GenerateInlineAccessorDefinitions(printer,
+                                                                   is_inline);
 
     printer->Print("\n");
   }
@@ -612,12 +610,13 @@
     vars["cap_oneof_name"] =
         ToUpper(descriptor_->oneof_decl(i)->name());
     vars["classname"] = classname_;
+    vars["inline"] = is_inline ? "inline" : "";
     printer->Print(
       vars,
-      "inline bool $classname$::has_$oneof_name$() const {\n"
+      "$inline$ bool $classname$::has_$oneof_name$() const {\n"
       "  return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n"
       "}\n"
-      "inline void $classname$::clear_has_$oneof_name$() {\n"
+      "$inline$ void $classname$::clear_has_$oneof_name$() {\n"
       "  _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n"
       "}\n");
   }
@@ -1173,18 +1172,18 @@
 }
 
 void MessageGenerator::
-GenerateInlineMethods(io::Printer* printer) {
+GenerateInlineMethods(io::Printer* printer, bool is_inline) {
   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
     // map entry message doesn't need inline methods. Since map entry message
     // cannot be a top level class, we just need to avoid calling
     // GenerateInlineMethods here.
     if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
-    nested_generators_[i]->GenerateInlineMethods(printer);
+    nested_generators_[i]->GenerateInlineMethods(printer, is_inline);
     printer->Print(kThinSeparator);
     printer->Print("\n");
   }
 
-  GenerateFieldAccessorDefinitions(printer);
+  GenerateFieldAccessorDefinitions(printer, is_inline);
 
   // Generate oneof_case() functions.
   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
@@ -1194,9 +1193,10 @@
         descriptor_->oneof_decl(i)->name(), true);
     vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
     vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
+    vars["inline"] = is_inline ? "inline " : "";
     printer->Print(
         vars,
-        "inline $class_name$::$camel_oneof_name$Case $class_name$::"
+        "$inline$$class_name$::$camel_oneof_name$Case $class_name$::"
         "$oneof_name$_case() const {\n"
         "  return $class_name$::$camel_oneof_name$Case("
         "_oneof_case_[$oneof_index$]);\n"
@@ -1226,7 +1226,9 @@
       for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
         const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
         printer->Print("  ");
-        if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+        if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
+            (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
+             EffectiveStringCType(field) != FieldOptions::STRING)) {
           printer->Print("const ");
         }
         field_generators_.get(field).GeneratePrivateMembers(printer);
@@ -1395,8 +1397,8 @@
       "      ::google::protobuf::internal::MapEntry<\n"
       "          $key$,\n"
       "          $val$,\n"
-      "          $key_type$,\n"
-      "          $val_type$,\n"
+      "          $key_wire_type$,\n"
+      "          $val_wire_type$,\n"
       "          $default_enum_value$>::CreateDefaultInstance(\n"
       "              $classname$_descriptor_));\n");
   }
@@ -2038,17 +2040,16 @@
 
   // Step 2a: Greedily seek runs of fields that can be cleared by memset-to-0.
   // The generated code uses two macros to help it clear runs of fields:
-  // OFFSET_OF_FIELD_ computes the offset (in bytes) of a field in the Message.
+  // ZR_HELPER_(f1) - ZR_HELPER_(f0) computes the difference, in bytes, of the
+  // positions of two fields in the Message.
   // ZR_ zeroes a non-empty range of fields via memset.
   const char* macros =
-      "#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \\\n"
-      "  &reinterpret_cast<$classname$*>(16)->f) - \\\n"
-      "   reinterpret_cast<char*>(16))\n\n"
-      "#define ZR_(first, last) do {                              \\\n"
-      "    size_t f = OFFSET_OF_FIELD_(first);                    \\\n"
-      "    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \\\n"
-      "    ::memset(&first, 0, n);                                \\\n"
-      "  } while (0)\n\n";
+      "#define ZR_HELPER_(f) reinterpret_cast<char*>(\\\n"
+      "  &reinterpret_cast<$classname$*>(16)->f)\n\n"
+      "#define ZR_(first, last) do {\\\n"
+      "  ::memset(&first, 0,\\\n"
+      "           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\\\n"
+      "} while (0)\n\n";
   for (int i = 0; i < runs_of_fields_.size(); i++) {
     const vector<string>& run = runs_of_fields_[i];
     if (run.size() < 2) continue;
@@ -2137,7 +2138,7 @@
   }
   if (macros_are_needed) {
     printer->Outdent();
-    printer->Print("\n#undef OFFSET_OF_FIELD_\n#undef ZR_\n\n");
+    printer->Print("\n#undef ZR_HELPER_\n#undef ZR_\n\n");
     printer->Indent();
   }
 
@@ -2923,8 +2924,8 @@
   for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
     sorted_extensions.push_back(descriptor_->extension_range(i));
   }
-  sort(sorted_extensions.begin(), sorted_extensions.end(),
-       ExtensionRangeSorter());
+  std::sort(sorted_extensions.begin(), sorted_extensions.end(),
+            ExtensionRangeSorter());
 
   // Merge the fields and the extension ranges, both sorted by field number.
   int i, j;
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h
index dfbc9af..ea96581 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message.h
@@ -82,7 +82,7 @@
 
   // Generate definitions of inline methods (placed at the end of the header
   // file).
-  void GenerateInlineMethods(io::Printer* printer);
+  void GenerateInlineMethods(io::Printer* printer, bool is_inline);
 
   // Source file stuff.
 
@@ -116,7 +116,7 @@
  private:
   // Generate declarations and definitions of accessors for fields.
   void GenerateFieldAccessorDeclarations(io::Printer* printer);
-  void GenerateFieldAccessorDefinitions(io::Printer* printer);
+  void GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline);
 
   // Generate the field offsets array.
   void GenerateOffsets(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
index b3cd0ba..467b6bf 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -85,115 +85,83 @@
 
 void MessageFieldGenerator::
 GenerateAccessorDeclarations(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline const $type$& $name$() const$deprecation$;\n"
-    "inline $type$* mutable_$name$()$deprecation$;\n"
-    "inline $type$* $release_name$()$deprecation$;\n"
-    "inline void set_allocated_$name$($type$* $name$)$deprecation$;\n");
   if (SupportsArenas(descriptor_)) {
     printer->Print(variables_,
-      "inline $type$* unsafe_arena_release_$name$()$deprecation$;\n"
-      "inline void unsafe_arena_set_allocated_$name$(\n"
+       "private:\n"
+       "void _slow_mutable_$name$()$deprecation$;\n");
+    if (SupportsArenas(descriptor_->message_type())) {
+      printer->Print(variables_,
+       "void _slow_set_allocated_$name$(\n"
+       "    ::google::protobuf::Arena* message_arena, $type$** $name$)$deprecation$;\n");
+    }
+    printer->Print(variables_,
+       "$type$* _slow_$release_name$()$deprecation$;\n"
+       "public:\n");
+  }
+  printer->Print(variables_,
+    "const $type$& $name$() const$deprecation$;\n"
+    "$type$* mutable_$name$()$deprecation$;\n"
+    "$type$* $release_name$()$deprecation$;\n"
+    "void set_allocated_$name$($type$* $name$)$deprecation$;\n");
+  if (SupportsArenas(descriptor_)) {
+    printer->Print(variables_,
+      "$type$* unsafe_arena_release_$name$()$deprecation$;\n"
+      "void unsafe_arena_set_allocated_$name$(\n"
       "    $type$* $name$)$deprecation$;\n");
   }
 }
 
-void MessageFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline const $type$& $classname$::$name$() const {\n"
-    "  // @@protoc_insertion_point(field_get:$full_name$)\n");
-
-  PrintHandlingOptionalStaticInitializers(
-    variables_, descriptor_->file(), printer,
-    // With static initializers.
-    "  return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n",
-    // Without.
-    "  return $name$_ != NULL ? *$name$_ : *default_instance().$name$_;\n");
-
+void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
+    io::Printer* printer) const {
   if (SupportsArenas(descriptor_)) {
     printer->Print(variables_,
-      "}\n"
-      "inline $type$* $classname$::mutable_$name$() {\n"
-      "  $set_hasbit$\n"
-      "  if ($name$_ == NULL) {\n");
-    if (SupportsArenas(descriptor_->message_type())) {
-      printer->Print(variables_,
-      "    $name$_ = ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
+      "void $classname$::_slow_mutable_$name$() {\n");
+      if (SupportsArenas(descriptor_->message_type())) {
+        printer->Print(variables_,
+        "  $name$_ = ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
       "        GetArenaNoVirtual());\n");
-    } else {
-      printer->Print(variables_,
-       "    $name$_ = ::google::protobuf::Arena::Create< $type$ >(\n"
-       "        GetArenaNoVirtual());\n");
-    }
-    printer->Print(variables_, "  }\n"
-      "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
-      "  return $name$_;\n"
+      } else {
+        printer->Print(variables_,
+         "  $name$_ = ::google::protobuf::Arena::Create< $type$ >(\n"
+         "     GetArenaNoVirtual());\n");
+      }
+    printer->Print(variables_,
       "}\n"
-      "inline $type$* $classname$::$release_name$() {\n"
-      "  $clear_hasbit$\n"
-      "  if (GetArenaNoVirtual() != NULL) {\n"
-      "    if ($name$_ == NULL) {\n"
-      "      return NULL;\n"
-      "    } else {\n"
-      "      $type$* temp = new $type$;\n"
-      "      temp->MergeFrom(*$name$_);\n"
-      "      $name$_ = NULL;\n"
-      "      return temp;\n"
-      "    }\n"
+      "$type$* $classname$::_slow_$release_name$() {\n"
+      "  if ($name$_ == NULL) {\n"
+      "    return NULL;\n"
       "  } else {\n"
-      "    $type$* temp = $name$_;\n"
+      "    $type$* temp = new $type$;\n"
+      "    temp->MergeFrom(*$name$_);\n"
       "    $name$_ = NULL;\n"
       "    return temp;\n"
       "  }\n"
       "}\n"
-      "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
+      "$type$* $classname$::unsafe_arena_release_$name$() {\n"
       "  $clear_hasbit$\n"
       "  $type$* temp = $name$_;\n"
       "  $name$_ = NULL;\n"
       "  return temp;\n"
-      "}\n"
-      "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
-      "  if (GetArenaNoVirtual() == NULL) {\n"
-      "    delete $name$_;\n"
-      "  }\n"
-      "  if ($name$ != NULL) {\n");
+      "}\n");
     if (SupportsArenas(descriptor_->message_type())) {
-      // If we're on an arena and the incoming message is not, simply Own() it
-      // rather than copy to the arena -- either way we need a heap dealloc,
-      // so we might as well defer it. Otherwise, if incoming message is on a
-      // different ownership domain (specific arena, or the heap) than we are,
-      // copy to our arena (or heap, as the case may be).
-      printer->Print(variables_,
-        "    if (GetArenaNoVirtual() != NULL && \n"
-        "        ::google::protobuf::Arena::GetArena($name$) == NULL) {\n"
-        "      GetArenaNoVirtual()->Own($name$);\n"
-        "    } else if (GetArenaNoVirtual() !=\n"
-        "               ::google::protobuf::Arena::GetArena($name$)) {\n"
-        "      $type$* new_$name$ = \n"
-        "            ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
-        "            GetArenaNoVirtual());\n"
-        "      new_$name$->CopyFrom(*$name$);\n"
-        "      $name$ = new_$name$;\n"
-        "    }\n");
-    } else {
-      printer->Print(variables_,
-        "    if (GetArenaNoVirtual() != NULL) {\n"
-        "      GetArenaNoVirtual()->Own($name$);\n"
-        "    }\n");
+        printer->Print(variables_,
+          "void $classname$::_slow_set_allocated_$name$(\n"
+          "    ::google::protobuf::Arena* message_arena, $type$** $name$) {\n"
+          "    if (message_arena != NULL && \n"
+          "        ::google::protobuf::Arena::GetArena(*$name$) == NULL) {\n"
+          "      message_arena->Own(*$name$);\n"
+          "    } else if (message_arena !=\n"
+          "               ::google::protobuf::Arena::GetArena(*$name$)) {\n"
+          "      $type$* new_$name$ = \n"
+          "            ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
+          "            message_arena);\n"
+          "      new_$name$->CopyFrom(**$name$);\n"
+          "      *$name$ = new_$name$;\n"
+          "    }\n"
+          "}\n");
     }
-
     printer->Print(variables_,
-      "  }\n"
-      "  $name$_ = $name$;\n"
-      "  if ($name$) {\n"
-      "    $set_hasbit$\n"
-      "  } else {\n"
-      "    $clear_hasbit$\n"
-      "  }\n"
-      "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
-      "}\n"
-      "inline void $classname$::unsafe_arena_set_allocated_$name$(\n"
+      "void $classname$::unsafe_arena_set_allocated_$name$(\n"
       "    $type$* $name$) {\n"
       // If we're not on an arena, free whatever we were holding before.
       // (If we are on arena, we can just forget the earlier pointer.)
@@ -209,10 +177,80 @@
       "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated"
       ":$full_name$)\n"
       "}\n");
-  } else {
-    printer->Print(variables_,
+  }
+}
+
+void MessageFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                  bool is_inline) const {
+  map<string, string> variables(variables_);
+  variables["inline"] = is_inline ? "inline" : "";
+  printer->Print(variables,
+    "$inline$ const $type$& $classname$::$name$() const {\n"
+    "  // @@protoc_insertion_point(field_get:$full_name$)\n");
+
+  PrintHandlingOptionalStaticInitializers(
+    variables, descriptor_->file(), printer,
+    // With static initializers.
+    "  return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n",
+    // Without.
+    "  return $name$_ != NULL ? *$name$_ : *default_instance().$name$_;\n");
+
+  if (SupportsArenas(descriptor_)) {
+    printer->Print(variables,
       "}\n"
-      "inline $type$* $classname$::mutable_$name$() {\n"
+      "$inline$ $type$* $classname$::mutable_$name$() {\n"
+      "  $set_hasbit$\n"
+      "  if ($name$_ == NULL) {\n"
+      "    _slow_mutable_$name$();"
+      "  }\n"
+      "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+      "  return $name$_;\n"
+      "}\n"
+      "$inline$ $type$* $classname$::$release_name$() {\n"
+      "  $clear_hasbit$\n"
+      "  if (GetArenaNoVirtual() != NULL) {\n"
+      "    return _slow_$release_name$();\n"
+      "  } else {\n"
+      "    $type$* temp = $name$_;\n"
+      "    $name$_ = NULL;\n"
+      "    return temp;\n"
+      "  }\n"
+      "}\n"
+      "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n"
+      "  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();\n"
+      "  if (message_arena == NULL) {\n"
+      "    delete $name$_;\n"
+      "  }\n"
+      "  if ($name$ != NULL) {\n");
+    if (SupportsArenas(descriptor_->message_type())) {
+      // If we're on an arena and the incoming message is not, simply Own() it
+      // rather than copy to the arena -- either way we need a heap dealloc,
+      // so we might as well defer it. Otherwise, if incoming message is on a
+      // different ownership domain (specific arena, or the heap) than we are,
+      // copy to our arena (or heap, as the case may be).
+      printer->Print(variables,
+        "    _slow_set_allocated_$name$(message_arena, &$name$);\n");
+    } else {
+      printer->Print(variables,
+        "    if (message_arena != NULL) {\n"
+        "      message_arena->Own($name$);\n"
+        "    }\n");
+    }
+    printer->Print(variables,
+      "  }\n"
+      "  $name$_ = $name$;\n"
+      "  if ($name$) {\n"
+      "    $set_hasbit$\n"
+      "  } else {\n"
+      "    $clear_hasbit$\n"
+      "  }\n"
+      "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+      "}\n");
+  } else {
+    printer->Print(variables,
+      "}\n"
+      "$inline$ $type$* $classname$::mutable_$name$() {\n"
       "  $set_hasbit$\n"
       "  if ($name$_ == NULL) {\n"
       "    $name$_ = new $type$;\n"
@@ -220,17 +258,17 @@
       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
       "  return $name$_;\n"
       "}\n"
-      "inline $type$* $classname$::$release_name$() {\n"
+      "$inline$ $type$* $classname$::$release_name$() {\n"
       "  $clear_hasbit$\n"
       "  $type$* temp = $name$_;\n"
       "  $name$_ = NULL;\n"
       "  return temp;\n"
       "}\n"
-      "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
+      "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n"
       "  delete $name$_;\n");
 
     if (SupportsArenas(descriptor_->message_type())) {
-      printer->Print(variables_,
+      printer->Print(variables,
       "  if ($name$ != NULL && $name$->GetArena() != NULL) {\n"
       "    $type$* new_$name$ = new $type$;\n"
       "    new_$name$->CopyFrom(*$name$);\n"
@@ -238,7 +276,7 @@
       "  }\n");
     }
 
-    printer->Print(variables_,
+    printer->Print(variables,
       "  $name$_ = $name$;\n"
       "  if ($name$) {\n"
       "    $set_hasbit$\n"
@@ -328,35 +366,38 @@
 MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}
 
 void MessageOneofFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                  bool is_inline) const {
+  map<string, string> variables(variables_);
+  variables["inline"] = is_inline ? "inline" : "";
   if (SupportsArenas(descriptor_)) {
-    printer->Print(variables_,
-      "inline const $type$& $classname$::$name$() const {\n"
+    printer->Print(variables,
+      "$inline$ const $type$& $classname$::$name$() const {\n"
       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
       "  return has_$name$() ? *$oneof_prefix$$name$_\n"
       "                      : $type$::default_instance();\n"
       "}\n"
-      "inline $type$* $classname$::mutable_$name$() {\n"
+      "$inline$ $type$* $classname$::mutable_$name$() {\n"
       "  if (!has_$name$()) {\n"
       "    clear_$oneof_name$();\n"
       "    set_has_$name$();\n");
     if (SupportsArenas(descriptor_->message_type())) {
-      printer->Print(variables_,
+      printer->Print(variables,
          "    $oneof_prefix$$name$_ = \n"
          "      ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
          "      GetArenaNoVirtual());\n");
     } else {
-      printer->Print(variables_,
+      printer->Print(variables,
          "    $oneof_prefix$$name$_ = \n"
          "      ::google::protobuf::Arena::Create< $type$ >(\n"
          "      GetArenaNoVirtual());\n");
     }
-    printer->Print(variables_,
+    printer->Print(variables,
       "  }\n"
       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
       "  return $oneof_prefix$$name$_;\n"
       "}\n"
-      "inline $type$* $classname$::$release_name$() {\n"
+      "$inline$ $type$* $classname$::$release_name$() {\n"
       "  if (has_$name$()) {\n"
       "    clear_has_$oneof_name$();\n"
       "    if (GetArenaNoVirtual() != NULL) {\n"
@@ -375,7 +416,7 @@
       "    return NULL;\n"
       "  }\n"
       "}\n"
-      "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
+      "$inline$ $type$* $classname$::unsafe_arena_release_$name$() {\n"
       "  if (has_$name$()) {\n"
       "    clear_has_$oneof_name$();\n"
       "    $type$* temp = $oneof_prefix$$name$_;\n"
@@ -385,12 +426,12 @@
       "    return NULL;\n"
       "  }\n"
       "}\n"
-      "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
+      "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n"
       "  clear_$oneof_name$();\n"
       "  if ($name$) {\n");
 
     if (SupportsArenas(descriptor_->message_type())) {
-      printer->Print(variables_,
+      printer->Print(variables,
         // If incoming message is on the heap and we are on an arena, just Own()
         // it (see above). If it's on a different arena than we are or one of us
         // is on the heap, we make a copy to our arena/heap.
@@ -406,19 +447,19 @@
         "      $name$ = new_$name$;\n"
         "    }\n");
     } else {
-      printer->Print(variables_,
+      printer->Print(variables,
         "    if (GetArenaNoVirtual() != NULL) {\n"
         "      GetArenaNoVirtual()->Own($name$);\n"
         "    }\n");
     }
 
-    printer->Print(variables_,
+    printer->Print(variables,
       "    set_has_$name$();\n"
       "    $oneof_prefix$$name$_ = $name$;\n"
       "  }\n"
       "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
       "}\n"
-      "inline void $classname$::unsafe_arena_set_allocated_$name$("
+      "$inline$ void $classname$::unsafe_arena_set_allocated_$name$("
       "$type$* $name$) {\n"
       // We rely on the oneof clear method to free the earlier contents of this
       // oneof. We can directly use the pointer we're given to set the new
@@ -432,13 +473,13 @@
       "$full_name$)\n"
       "}\n");
   } else {
-    printer->Print(variables_,
-      "inline const $type$& $classname$::$name$() const {\n"
+    printer->Print(variables,
+      "$inline$ const $type$& $classname$::$name$() const {\n"
       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
       "  return has_$name$() ? *$oneof_prefix$$name$_\n"
       "                      : $type$::default_instance();\n"
       "}\n"
-      "inline $type$* $classname$::mutable_$name$() {\n"
+      "$inline$ $type$* $classname$::mutable_$name$() {\n"
       "  if (!has_$name$()) {\n"
       "    clear_$oneof_name$();\n"
       "    set_has_$name$();\n"
@@ -447,7 +488,7 @@
       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
       "  return $oneof_prefix$$name$_;\n"
       "}\n"
-      "inline $type$* $classname$::$release_name$() {\n"
+      "$inline$ $type$* $classname$::$release_name$() {\n"
       "  if (has_$name$()) {\n"
       "    clear_has_$oneof_name$();\n"
       "    $type$* temp = $oneof_prefix$$name$_;\n"
@@ -457,18 +498,18 @@
       "    return NULL;\n"
       "  }\n"
       "}\n"
-      "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
+      "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n"
       "  clear_$oneof_name$();\n"
       "  if ($name$) {\n");
     if (SupportsArenas(descriptor_->message_type())) {
-      printer->Print(variables_,
+      printer->Print(variables,
         "    if ($name$->GetArena() != NULL) {\n"
         "      $type$* new_$name$ = new $type$;\n"
         "      new_$name$->CopyFrom(*$name$);\n"
         "      $name$ = new_$name$;\n"
         "    }\n");
     }
-    printer->Print(variables_,
+    printer->Print(variables,
       "    set_has_$name$();\n"
       "    $oneof_prefix$$name$_ = $name$;\n"
       "  }\n"
@@ -521,38 +562,41 @@
 void RepeatedMessageFieldGenerator::
 GenerateAccessorDeclarations(io::Printer* printer) const {
   printer->Print(variables_,
-    "inline const $type$& $name$(int index) const$deprecation$;\n"
-    "inline $type$* mutable_$name$(int index)$deprecation$;\n"
-    "inline $type$* add_$name$()$deprecation$;\n");
+    "const $type$& $name$(int index) const$deprecation$;\n"
+    "$type$* mutable_$name$(int index)$deprecation$;\n"
+    "$type$* add_$name$()$deprecation$;\n");
   printer->Print(variables_,
-    "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+    "const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
     "    $name$() const$deprecation$;\n"
-    "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
+    "::google::protobuf::RepeatedPtrField< $type$ >*\n"
     "    mutable_$name$()$deprecation$;\n");
 }
 
 void RepeatedMessageFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline const $type$& $classname$::$name$(int index) const {\n"
+GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                  bool is_inline) const {
+  map<string, string> variables(variables_);
+  variables["inline"] = is_inline ? "inline" : "";
+  printer->Print(variables,
+    "$inline$ const $type$& $classname$::$name$(int index) const {\n"
     "  // @@protoc_insertion_point(field_get:$full_name$)\n"
     "  return $name$_.$cppget$(index);\n"
     "}\n"
-    "inline $type$* $classname$::mutable_$name$(int index) {\n"
+    "$inline$ $type$* $classname$::mutable_$name$(int index) {\n"
     "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
     "  return $name$_.Mutable(index);\n"
     "}\n"
-    "inline $type$* $classname$::add_$name$() {\n"
+    "$inline$ $type$* $classname$::add_$name$() {\n"
     "  // @@protoc_insertion_point(field_add:$full_name$)\n"
     "  return $name$_.Add();\n"
     "}\n");
-  printer->Print(variables_,
-    "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+  printer->Print(variables,
+    "$inline$ const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
     "$classname$::$name$() const {\n"
     "  // @@protoc_insertion_point(field_list:$full_name$)\n"
     "  return $name$_;\n"
     "}\n"
-    "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
+    "$inline$ ::google::protobuf::RepeatedPtrField< $type$ >*\n"
     "$classname$::mutable_$name$() {\n"
     "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
     "  return &$name$_;\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/google/protobuf/compiler/cpp/cpp_message_field.h
index 2dff314..c1704fc 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.h
@@ -53,7 +53,9 @@
   // implements FieldGenerator ---------------------------------------
   void GeneratePrivateMembers(io::Printer* printer) const;
   void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                         bool is_inline) const;
+  void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const;
   void GenerateClearingCode(io::Printer* printer) const;
   void GenerateMergingCode(io::Printer* printer) const;
   void GenerateSwappingCode(io::Printer* printer) const;
@@ -78,7 +80,9 @@
   ~MessageOneofFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                         bool is_inline) const;
+  void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {}
   void GenerateClearingCode(io::Printer* printer) const;
   void GenerateSwappingCode(io::Printer* printer) const;
   void GenerateConstructorCode(io::Printer* printer) const;
@@ -96,7 +100,8 @@
   // implements FieldGenerator ---------------------------------------
   void GeneratePrivateMembers(io::Printer* printer) const;
   void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                         bool is_inline) const;
   void GenerateClearingCode(io::Printer* printer) const;
   void GenerateMergingCode(io::Printer* printer) const;
   void GenerateSwappingCode(io::Printer* printer) const;
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
index 9a2c930..329eae3 100644
--- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -117,18 +117,20 @@
 void PrimitiveFieldGenerator::
 GenerateAccessorDeclarations(io::Printer* printer) const {
   printer->Print(variables_,
-    "inline $type$ $name$() const$deprecation$;\n"
-    "inline void set_$name$($type$ value)$deprecation$;\n");
+    "$type$ $name$() const$deprecation$;\n"
+    "void set_$name$($type$ value)$deprecation$;\n");
 }
 
 void PrimitiveFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline $type$ $classname$::$name$() const {\n"
+GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const {
+  map<string, string> variables(variables_);
+  variables["inline"] = is_inline ? "inline" : "";
+  printer->Print(variables,
+    "$inline$ $type$ $classname$::$name$() const {\n"
     "  // @@protoc_insertion_point(field_get:$full_name$)\n"
     "  return $name$_;\n"
     "}\n"
-    "inline void $classname$::set_$name$($type$ value) {\n"
+    "$inline$ void $classname$::set_$name$($type$ value) {\n"
     "  $set_hasbit$\n"
     "  $name$_ = value;\n"
     "  // @@protoc_insertion_point(field_set:$full_name$)\n"
@@ -204,16 +206,18 @@
 PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {}
 
 void PrimitiveOneofFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline $type$ $classname$::$name$() const {\n"
+GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const {
+  map<string, string> variables(variables_);
+  variables["inline"] = is_inline ? "inline" : "";
+  printer->Print(variables,
+    "$inline$ $type$ $classname$::$name$() const {\n"
     "  // @@protoc_insertion_point(field_get:$full_name$)\n"
     "  if (has_$name$()) {\n"
     "    return $oneof_prefix$$name$_;\n"
     "  }\n"
     "  return $default$;\n"
     "}\n"
-    "inline void $classname$::set_$name$($type$ value) {\n"
+    "$inline$ void $classname$::set_$name$($type$ value) {\n"
     "  if (!has_$name$()) {\n"
     "    clear_$oneof_name$();\n"
     "    set_has_$name$();\n"
@@ -282,38 +286,40 @@
 void RepeatedPrimitiveFieldGenerator::
 GenerateAccessorDeclarations(io::Printer* printer) const {
   printer->Print(variables_,
-    "inline $type$ $name$(int index) const$deprecation$;\n"
-    "inline void set_$name$(int index, $type$ value)$deprecation$;\n"
-    "inline void add_$name$($type$ value)$deprecation$;\n");
+    "$type$ $name$(int index) const$deprecation$;\n"
+    "void set_$name$(int index, $type$ value)$deprecation$;\n"
+    "void add_$name$($type$ value)$deprecation$;\n");
   printer->Print(variables_,
-    "inline const ::google::protobuf::RepeatedField< $type$ >&\n"
+    "const ::google::protobuf::RepeatedField< $type$ >&\n"
     "    $name$() const$deprecation$;\n"
-    "inline ::google::protobuf::RepeatedField< $type$ >*\n"
+    "::google::protobuf::RepeatedField< $type$ >*\n"
     "    mutable_$name$()$deprecation$;\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline $type$ $classname$::$name$(int index) const {\n"
+GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const {
+  map<string, string> variables(variables_);
+  variables["inline"] = is_inline ? "inline" : "";
+  printer->Print(variables,
+    "$inline$ $type$ $classname$::$name$(int index) const {\n"
     "  // @@protoc_insertion_point(field_get:$full_name$)\n"
     "  return $name$_.Get(index);\n"
     "}\n"
-    "inline void $classname$::set_$name$(int index, $type$ value) {\n"
+    "$inline$ void $classname$::set_$name$(int index, $type$ value) {\n"
     "  $name$_.Set(index, value);\n"
     "  // @@protoc_insertion_point(field_set:$full_name$)\n"
     "}\n"
-    "inline void $classname$::add_$name$($type$ value) {\n"
+    "$inline$ void $classname$::add_$name$($type$ value) {\n"
     "  $name$_.Add(value);\n"
     "  // @@protoc_insertion_point(field_add:$full_name$)\n"
     "}\n");
-  printer->Print(variables_,
-    "inline const ::google::protobuf::RepeatedField< $type$ >&\n"
+  printer->Print(variables,
+    "$inline$ const ::google::protobuf::RepeatedField< $type$ >&\n"
     "$classname$::$name$() const {\n"
     "  // @@protoc_insertion_point(field_list:$full_name$)\n"
     "  return $name$_;\n"
     "}\n"
-    "inline ::google::protobuf::RepeatedField< $type$ >*\n"
+    "$inline$ ::google::protobuf::RepeatedField< $type$ >*\n"
     "$classname$::mutable_$name$() {\n"
     "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
     "  return &$name$_;\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
index 97b5e86..fcd7d68 100644
--- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
@@ -53,7 +53,8 @@
   // implements FieldGenerator ---------------------------------------
   void GeneratePrivateMembers(io::Printer* printer) const;
   void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                         bool is_inline) const;
   void GenerateClearingCode(io::Printer* printer) const;
   void GenerateMergingCode(io::Printer* printer) const;
   void GenerateSwappingCode(io::Printer* printer) const;
@@ -78,7 +79,8 @@
   ~PrimitiveOneofFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                         bool is_inline) const;
   void GenerateClearingCode(io::Printer* printer) const;
   void GenerateSwappingCode(io::Printer* printer) const;
   void GenerateConstructorCode(io::Printer* printer) const;
@@ -97,7 +99,8 @@
   // implements FieldGenerator ---------------------------------------
   void GeneratePrivateMembers(io::Printer* printer) const;
   void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                         bool is_inline) const;
   void GenerateClearingCode(io::Printer* printer) const;
   void GenerateMergingCode(io::Printer* printer) const;
   void GenerateSwappingCode(io::Printer* printer) const;
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index 04ed08c..1a1bcd3 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -127,7 +127,11 @@
   // files that applied the ctype.  The field can still be accessed via the
   // reflection interface since the reflection interface is independent of
   // the string's underlying representation.
-  if (descriptor_->options().ctype() != FieldOptions::STRING) {
+
+  bool unknown_ctype =
+      descriptor_->options().ctype() != EffectiveStringCType(descriptor_);
+
+  if (unknown_ctype) {
     printer->Outdent();
     printer->Print(
       " private:\n"
@@ -136,23 +140,23 @@
   }
 
   printer->Print(variables_,
-    "inline const ::std::string& $name$() const$deprecation$;\n"
-    "inline void set_$name$(const ::std::string& value)$deprecation$;\n"
-    "inline void set_$name$(const char* value)$deprecation$;\n"
-    "inline void set_$name$(const $pointer_type$* value, size_t size)"
+    "const ::std::string& $name$() const$deprecation$;\n"
+    "void set_$name$(const ::std::string& value)$deprecation$;\n"
+    "void set_$name$(const char* value)$deprecation$;\n"
+    "void set_$name$(const $pointer_type$* value, size_t size)"
                  "$deprecation$;\n"
-    "inline ::std::string* mutable_$name$()$deprecation$;\n"
-    "inline ::std::string* $release_name$()$deprecation$;\n"
-    "inline void set_allocated_$name$(::std::string* $name$)$deprecation$;\n");
+    "::std::string* mutable_$name$()$deprecation$;\n"
+    "::std::string* $release_name$()$deprecation$;\n"
+    "void set_allocated_$name$(::std::string* $name$)$deprecation$;\n");
   if (SupportsArenas(descriptor_)) {
     printer->Print(variables_,
-      "inline ::std::string* unsafe_arena_release_$name$()$deprecation$;\n"
-      "inline void unsafe_arena_set_allocated_$name$(\n"
+      "::std::string* unsafe_arena_release_$name$()$deprecation$;\n"
+      "void unsafe_arena_set_allocated_$name$(\n"
       "    ::std::string* $name$)$deprecation$;\n");
   }
 
 
-  if (descriptor_->options().ctype() != FieldOptions::STRING) {
+  if (unknown_ctype) {
     printer->Outdent();
     printer->Print(" public:\n");
     printer->Indent();
@@ -160,25 +164,28 @@
 }
 
 void StringFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                  bool is_inline) const {
+  map<string, string> variables(variables_);
+  variables["inline"] = is_inline ? "inline" : "";
   if (SupportsArenas(descriptor_)) {
-    printer->Print(variables_,
-      "inline const ::std::string& $classname$::$name$() const {\n"
+    printer->Print(variables,
+      "$inline$ const ::std::string& $classname$::$name$() const {\n"
       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
       "  return $name$_.Get($default_variable$);\n"
       "}\n"
-      "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+      "$inline$ void $classname$::set_$name$(const ::std::string& value) {\n"
       "  $set_hasbit$\n"
       "  $name$_.Set($default_variable$, value, GetArenaNoVirtual());\n"
       "  // @@protoc_insertion_point(field_set:$full_name$)\n"
       "}\n"
-      "inline void $classname$::set_$name$(const char* value) {\n"
+      "$inline$ void $classname$::set_$name$(const char* value) {\n"
       "  $set_hasbit$\n"
       "  $name$_.Set($default_variable$, $string_piece$(value),\n"
       "              GetArenaNoVirtual());\n"
       "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
       "}\n"
-      "inline "
+      "$inline$ "
       "void $classname$::set_$name$(const $pointer_type$* value,\n"
       "    size_t size) {\n"
       "  $set_hasbit$\n"
@@ -186,22 +193,22 @@
       "      reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());\n"
       "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
       "}\n"
-      "inline ::std::string* $classname$::mutable_$name$() {\n"
+      "$inline$ ::std::string* $classname$::mutable_$name$() {\n"
       "  $set_hasbit$\n"
       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
       "  return $name$_.Mutable($default_variable$, GetArenaNoVirtual());\n"
       "}\n"
-      "inline ::std::string* $classname$::$release_name$() {\n"
+      "$inline$ ::std::string* $classname$::$release_name$() {\n"
       "  $clear_hasbit$\n"
       "  return $name$_.Release($default_variable$, GetArenaNoVirtual());\n"
       "}\n"
-      "inline ::std::string* $classname$::unsafe_arena_release_$name$() {\n"
+      "$inline$ ::std::string* $classname$::unsafe_arena_release_$name$() {\n"
       "  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n"
       "  $clear_hasbit$\n"
       "  return $name$_.UnsafeArenaRelease($default_variable$,\n"
       "      GetArenaNoVirtual());\n"
       "}\n"
-      "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
+      "$inline$ void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
       "  if ($name$ != NULL) {\n"
       "    $set_hasbit$\n"
       "  } else {\n"
@@ -211,7 +218,7 @@
       "      GetArenaNoVirtual());\n"
       "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
       "}\n"
-      "inline void $classname$::unsafe_arena_set_allocated_$name$(\n"
+      "$inline$ void $classname$::unsafe_arena_set_allocated_$name$(\n"
       "    ::std::string* $name$) {\n"
       "  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n"
       "  if ($name$ != NULL) {\n"
@@ -226,22 +233,22 @@
       "}\n");
   } else {
     // No-arena case.
-    printer->Print(variables_,
-      "inline const ::std::string& $classname$::$name$() const {\n"
+    printer->Print(variables,
+      "$inline$ const ::std::string& $classname$::$name$() const {\n"
       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
       "  return $name$_.GetNoArena($default_variable$);\n"
       "}\n"
-      "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+      "$inline$ void $classname$::set_$name$(const ::std::string& value) {\n"
       "  $set_hasbit$\n"
       "  $name$_.SetNoArena($default_variable$, value);\n"
       "  // @@protoc_insertion_point(field_set:$full_name$)\n"
       "}\n"
-      "inline void $classname$::set_$name$(const char* value) {\n"
+      "$inline$ void $classname$::set_$name$(const char* value) {\n"
       "  $set_hasbit$\n"
       "  $name$_.SetNoArena($default_variable$, $string_piece$(value));\n"
       "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
       "}\n"
-      "inline "
+      "$inline$ "
       "void $classname$::set_$name$(const $pointer_type$* value, "
       "size_t size) {\n"
       "  $set_hasbit$\n"
@@ -249,16 +256,16 @@
       "      $string_piece$(reinterpret_cast<const char*>(value), size));\n"
       "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
       "}\n"
-      "inline ::std::string* $classname$::mutable_$name$() {\n"
+      "$inline$ ::std::string* $classname$::mutable_$name$() {\n"
       "  $set_hasbit$\n"
       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
       "  return $name$_.MutableNoArena($default_variable$);\n"
       "}\n"
-      "inline ::std::string* $classname$::$release_name$() {\n"
+      "$inline$ ::std::string* $classname$::$release_name$() {\n"
       "  $clear_hasbit$\n"
       "  return $name$_.ReleaseNoArena($default_variable$);\n"
       "}\n"
-      "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
+      "$inline$ void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
       "  if ($name$ != NULL) {\n"
       "    $set_hasbit$\n"
       "  } else {\n"
@@ -422,17 +429,20 @@
 StringOneofFieldGenerator::~StringOneofFieldGenerator() {}
 
 void StringOneofFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                  bool is_inline) const {
+  map<string, string> variables(variables_);
+  variables["inline"] = is_inline ? "inline" : "";
   if (SupportsArenas(descriptor_)) {
-    printer->Print(variables_,
-      "inline const ::std::string& $classname$::$name$() const {\n"
+    printer->Print(variables,
+      "$inline$ const ::std::string& $classname$::$name$() const {\n"
       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
       "  if (has_$name$()) {\n"
       "    return $oneof_prefix$$name$_.Get($default_variable$);\n"
       "  }\n"
       "  return *$default_variable$;\n"
       "}\n"
-      "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+      "$inline$ void $classname$::set_$name$(const ::std::string& value) {\n"
       "  if (!has_$name$()) {\n"
       "    clear_$oneof_name$();\n"
       "    set_has_$name$();\n"
@@ -442,7 +452,7 @@
       "      GetArenaNoVirtual());\n"
       "  // @@protoc_insertion_point(field_set:$full_name$)\n"
       "}\n"
-      "inline void $classname$::set_$name$(const char* value) {\n"
+      "$inline$ void $classname$::set_$name$(const char* value) {\n"
       "  if (!has_$name$()) {\n"
       "    clear_$oneof_name$();\n"
       "    set_has_$name$();\n"
@@ -452,7 +462,7 @@
       "      $string_piece$(value), GetArenaNoVirtual());\n"
       "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
       "}\n"
-      "inline "
+      "$inline$ "
       "void $classname$::set_$name$(const $pointer_type$* value,\n"
       "                             size_t size) {\n"
       "  if (!has_$name$()) {\n"
@@ -465,7 +475,7 @@
       "      GetArenaNoVirtual());\n"
       "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
       "}\n"
-      "inline ::std::string* $classname$::mutable_$name$() {\n"
+      "$inline$ ::std::string* $classname$::mutable_$name$() {\n"
       "  if (!has_$name$()) {\n"
       "    clear_$oneof_name$();\n"
       "    set_has_$name$();\n"
@@ -475,7 +485,7 @@
       "      GetArenaNoVirtual());\n"
       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
       "}\n"
-      "inline ::std::string* $classname$::$release_name$() {\n"
+      "$inline$ ::std::string* $classname$::$release_name$() {\n"
       "  if (has_$name$()) {\n"
       "    clear_has_$oneof_name$();\n"
       "    return $oneof_prefix$$name$_.Release($default_variable$,\n"
@@ -484,7 +494,7 @@
       "    return NULL;\n"
       "  }\n"
       "}\n"
-      "inline ::std::string* $classname$::unsafe_arena_release_$name$() {\n"
+      "$inline$ ::std::string* $classname$::unsafe_arena_release_$name$() {\n"
       "  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n"
       "  if (has_$name$()) {\n"
       "    clear_has_$oneof_name$();\n"
@@ -494,7 +504,7 @@
       "    return NULL;\n"
       "  }\n"
       "}\n"
-      "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
+      "$inline$ void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
       "  if (!has_$name$()) {\n"
       "    $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n"
       "  }\n"
@@ -506,7 +516,7 @@
       "  }\n"
       "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
       "}\n"
-      "inline void $classname$::unsafe_arena_set_allocated_$name$("
+      "$inline$ void $classname$::unsafe_arena_set_allocated_$name$("
       "::std::string* $name$) {\n"
       "  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n"
       "  if (!has_$name$()) {\n"
@@ -522,15 +532,15 @@
       "}\n");
   } else {
     // No-arena case.
-    printer->Print(variables_,
-      "inline const ::std::string& $classname$::$name$() const {\n"
+    printer->Print(variables,
+      "$inline$ const ::std::string& $classname$::$name$() const {\n"
       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
       "  if (has_$name$()) {\n"
       "    return $oneof_prefix$$name$_.GetNoArena($default_variable$);\n"
       "  }\n"
       "  return *$default_variable$;\n"
       "}\n"
-      "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+      "$inline$ void $classname$::set_$name$(const ::std::string& value) {\n"
       "  // @@protoc_insertion_point(field_set:$full_name$)\n"
       "  if (!has_$name$()) {\n"
       "    clear_$oneof_name$();\n"
@@ -540,7 +550,7 @@
       "  $oneof_prefix$$name$_.SetNoArena($default_variable$, value);\n"
       "  // @@protoc_insertion_point(field_set:$full_name$)\n"
       "}\n"
-      "inline void $classname$::set_$name$(const char* value) {\n"
+      "$inline$ void $classname$::set_$name$(const char* value) {\n"
       "  if (!has_$name$()) {\n"
       "    clear_$oneof_name$();\n"
       "    set_has_$name$();\n"
@@ -550,7 +560,7 @@
       "      $string_piece$(value));\n"
       "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
       "}\n"
-      "inline "
+      "$inline$ "
       "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n"
       "  if (!has_$name$()) {\n"
       "    clear_$oneof_name$();\n"
@@ -561,7 +571,7 @@
       "      reinterpret_cast<const char*>(value), size));\n"
       "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
       "}\n"
-      "inline ::std::string* $classname$::mutable_$name$() {\n"
+      "$inline$ ::std::string* $classname$::mutable_$name$() {\n"
       "  if (!has_$name$()) {\n"
       "    clear_$oneof_name$();\n"
       "    set_has_$name$();\n"
@@ -570,7 +580,7 @@
       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
       "  return $oneof_prefix$$name$_.MutableNoArena($default_variable$);\n"
       "}\n"
-      "inline ::std::string* $classname$::$release_name$() {\n"
+      "$inline$ ::std::string* $classname$::$release_name$() {\n"
       "  if (has_$name$()) {\n"
       "    clear_has_$oneof_name$();\n"
       "    return $oneof_prefix$$name$_.ReleaseNoArena($default_variable$);\n"
@@ -578,7 +588,7 @@
       "    return NULL;\n"
       "  }\n"
       "}\n"
-      "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
+      "$inline$ void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
       "  if (!has_$name$()) {\n"
       "    $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n"
       "  }\n"
@@ -670,7 +680,10 @@
 void RepeatedStringFieldGenerator::
 GenerateAccessorDeclarations(io::Printer* printer) const {
   // See comment above about unknown ctypes.
-  if (descriptor_->options().ctype() != FieldOptions::STRING) {
+  bool unknown_ctype =
+      descriptor_->options().ctype() != EffectiveStringCType(descriptor_);
+
+  if (unknown_ctype) {
     printer->Outdent();
     printer->Print(
       " private:\n"
@@ -679,26 +692,26 @@
   }
 
   printer->Print(variables_,
-    "inline const ::std::string& $name$(int index) const$deprecation$;\n"
-    "inline ::std::string* mutable_$name$(int index)$deprecation$;\n"
-    "inline void set_$name$(int index, const ::std::string& value)$deprecation$;\n"
-    "inline void set_$name$(int index, const char* value)$deprecation$;\n"
-    "inline "
+    "const ::std::string& $name$(int index) const$deprecation$;\n"
+    "::std::string* mutable_$name$(int index)$deprecation$;\n"
+    "void set_$name$(int index, const ::std::string& value)$deprecation$;\n"
+    "void set_$name$(int index, const char* value)$deprecation$;\n"
+    ""
     "void set_$name$(int index, const $pointer_type$* value, size_t size)"
                  "$deprecation$;\n"
-    "inline ::std::string* add_$name$()$deprecation$;\n"
-    "inline void add_$name$(const ::std::string& value)$deprecation$;\n"
-    "inline void add_$name$(const char* value)$deprecation$;\n"
-    "inline void add_$name$(const $pointer_type$* value, size_t size)"
+    "::std::string* add_$name$()$deprecation$;\n"
+    "void add_$name$(const ::std::string& value)$deprecation$;\n"
+    "void add_$name$(const char* value)$deprecation$;\n"
+    "void add_$name$(const $pointer_type$* value, size_t size)"
                  "$deprecation$;\n");
 
   printer->Print(variables_,
-    "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const"
+    "const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const"
                  "$deprecation$;\n"
-    "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()"
+    "::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()"
                  "$deprecation$;\n");
 
-  if (descriptor_->options().ctype() != FieldOptions::STRING) {
+  if (unknown_ctype) {
     printer->Outdent();
     printer->Print(" public:\n");
     printer->Indent();
@@ -706,54 +719,57 @@
 }
 
 void RepeatedStringFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline const ::std::string& $classname$::$name$(int index) const {\n"
+GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                  bool is_inline) const {
+  map<string, string> variables(variables_);
+  variables["inline"] = is_inline ? "inline" : "";
+  printer->Print(variables,
+    "$inline$ const ::std::string& $classname$::$name$(int index) const {\n"
     "  // @@protoc_insertion_point(field_get:$full_name$)\n"
     "  return $name$_.$cppget$(index);\n"
     "}\n"
-    "inline ::std::string* $classname$::mutable_$name$(int index) {\n"
+    "$inline$ ::std::string* $classname$::mutable_$name$(int index) {\n"
     "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
     "  return $name$_.Mutable(index);\n"
     "}\n"
-    "inline void $classname$::set_$name$(int index, const ::std::string& value) {\n"
+    "$inline$ void $classname$::set_$name$(int index, const ::std::string& value) {\n"
     "  // @@protoc_insertion_point(field_set:$full_name$)\n"
     "  $name$_.Mutable(index)->assign(value);\n"
     "}\n"
-    "inline void $classname$::set_$name$(int index, const char* value) {\n"
+    "$inline$ void $classname$::set_$name$(int index, const char* value) {\n"
     "  $name$_.Mutable(index)->assign(value);\n"
     "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
     "}\n"
-    "inline void "
+    "$inline$ void "
     "$classname$::set_$name$"
     "(int index, const $pointer_type$* value, size_t size) {\n"
     "  $name$_.Mutable(index)->assign(\n"
     "    reinterpret_cast<const char*>(value), size);\n"
     "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
     "}\n"
-    "inline ::std::string* $classname$::add_$name$() {\n"
+    "$inline$ ::std::string* $classname$::add_$name$() {\n"
     "  return $name$_.Add();\n"
     "}\n"
-    "inline void $classname$::add_$name$(const ::std::string& value) {\n"
+    "$inline$ void $classname$::add_$name$(const ::std::string& value) {\n"
     "  $name$_.Add()->assign(value);\n"
     "  // @@protoc_insertion_point(field_add:$full_name$)\n"
     "}\n"
-    "inline void $classname$::add_$name$(const char* value) {\n"
+    "$inline$ void $classname$::add_$name$(const char* value) {\n"
     "  $name$_.Add()->assign(value);\n"
     "  // @@protoc_insertion_point(field_add_char:$full_name$)\n"
     "}\n"
-    "inline void "
+    "$inline$ void "
     "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
     "  $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
     "  // @@protoc_insertion_point(field_add_pointer:$full_name$)\n"
     "}\n");
-  printer->Print(variables_,
-    "inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n"
+  printer->Print(variables,
+    "$inline$ const ::google::protobuf::RepeatedPtrField< ::std::string>&\n"
     "$classname$::$name$() const {\n"
     "  // @@protoc_insertion_point(field_list:$full_name$)\n"
     "  return $name$_;\n"
     "}\n"
-    "inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n"
+    "$inline$ ::google::protobuf::RepeatedPtrField< ::std::string>*\n"
     "$classname$::mutable_$name$() {\n"
     "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
     "  return &$name$_;\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h
index 0a5ca44..d1f19cd 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h
@@ -54,7 +54,8 @@
   void GeneratePrivateMembers(io::Printer* printer) const;
   void GenerateStaticMembers(io::Printer* printer) const;
   void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                         bool is_inline) const;
   void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const;
   void GenerateClearingCode(io::Printer* printer) const;
   void GenerateMergingCode(io::Printer* printer) const;
@@ -83,7 +84,8 @@
   ~StringOneofFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                         bool is_inline) const;
   void GenerateClearingCode(io::Printer* printer) const;
   void GenerateSwappingCode(io::Printer* printer) const;
   void GenerateConstructorCode(io::Printer* printer) const;
@@ -103,7 +105,8 @@
   // implements FieldGenerator ---------------------------------------
   void GeneratePrivateMembers(io::Printer* printer) const;
   void GenerateAccessorDeclarations(io::Printer* printer) const;
-  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer,
+                                         bool is_inline) const;
   void GenerateClearingCode(io::Printer* printer) const;
   void GenerateMergingCode(io::Printer* printer) const;
   void GenerateSwappingCode(io::Printer* printer) const;
diff --git a/src/google/protobuf/compiler/java/java_field.h b/src/google/protobuf/compiler/java/java_field.h
index e8d6f3a..1cf360c 100644
--- a/src/google/protobuf/compiler/java/java_field.h
+++ b/src/google/protobuf/compiler/java/java_field.h
@@ -83,6 +83,7 @@
   virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0;
   virtual void GenerateFieldBuilderInitializationCode(io::Printer* printer)
       const = 0;
+  virtual void GenerateStaticInitializationCode(io::Printer* printer) const {}
 
   virtual void GenerateEqualsCode(io::Printer* printer) const = 0;
   virtual void GenerateHashCode(io::Printer* printer) const = 0;
diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc
index 2368538..e24894b 100644
--- a/src/google/protobuf/compiler/java/java_helpers.cc
+++ b/src/google/protobuf/compiler/java/java_helpers.cc
@@ -690,8 +690,8 @@
   for (int i = 0; i < descriptor->field_count(); i++) {
     fields[i] = descriptor->field(i);
   }
-  sort(fields, fields + descriptor->field_count(),
-       FieldOrderingByNumber());
+  std::sort(fields, fields + descriptor->field_count(),
+            FieldOrderingByNumber());
   return fields;
 }
 
diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h
index d957fdc..62efbef 100644
--- a/src/google/protobuf/compiler/java/java_helpers.h
+++ b/src/google/protobuf/compiler/java/java_helpers.h
@@ -297,6 +297,16 @@
 // and return it. The caller should delete the returned array.
 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor);
 
+// Does this message class have any packed fields?
+inline bool HasPackedFields(const Descriptor* descriptor) {
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    if (descriptor->field(i)->is_packed()) {
+      return true;
+    }
+  }
+  return false;
+}
+
 // Check a message type and its sub-message types recursively to see if any of
 // them has a required field. Return true if a required field is found.
 bool HasRequiredFields(const Descriptor* descriptor);
diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field.cc b/src/google/protobuf/compiler/java/java_lazy_message_field.cc
index 21cab7d..6e29a40 100644
--- a/src/google/protobuf/compiler/java/java_lazy_message_field.cc
+++ b/src/google/protobuf/compiler/java/java_lazy_message_field.cc
@@ -243,9 +243,8 @@
       "}\n");
 
   printer->Print(variables_,
-      "result.$name$_.setByteString(\n"
-      "    $name$_.toByteString(),\n"
-      "    $name$_.getExtensionRegistry());\n");
+      "result.$name$_.set(\n"
+      "    $name$_);\n");
 }
 
 void ImmutableLazyMessageFieldGenerator::
@@ -425,9 +424,8 @@
 
   printer->Print(variables_,
       "result.$oneof_name$_ = new $lazy_type$();\n"
-      "(($lazy_type$) result.$oneof_name$_).setByteString(\n"
-      "    (($lazy_type$) $oneof_name$_).toByteString(),\n"
-      "    (($lazy_type$) $oneof_name$_).getExtensionRegistry());\n");
+      "(($lazy_type$) result.$oneof_name$_).set(\n"
+      "    (($lazy_type$) $oneof_name$_));\n");
   printer->Outdent();
   printer->Print("}\n");
 }
diff --git a/src/google/protobuf/compiler/java/java_map_field.cc b/src/google/protobuf/compiler/java/java_map_field.cc
index 2986f51..cf1ef58 100644
--- a/src/google/protobuf/compiler/java/java_map_field.cc
+++ b/src/google/protobuf/compiler/java/java_map_field.cc
@@ -198,25 +198,38 @@
 }
 
 void ImmutableMapFieldGenerator::
+GenerateStaticInitializationCode(io::Printer* printer) const {
+  printer->Print(
+      variables_,
+      "$name$DefaultEntry =\n"
+      "    com.google.protobuf.MapEntry$lite$\n"
+      "    .<$type_parameters$>newDefaultInstance(\n"
+      "        $descriptor$\n"
+      "        $key_wire_type$,\n"
+      "        $key_default_value$,\n"
+      "        $value_wire_type$,\n"
+      "        $value_default_value$);\n"
+      "\n");
+}
+
+void ImmutableMapFieldGenerator::
 GenerateMembers(io::Printer* printer) const {
   printer->Print(
       variables_,
       "private static final com.google.protobuf.MapEntry$lite$<\n"
-      "    $type_parameters$> $name$DefaultEntry =\n"
-      "        com.google.protobuf.MapEntry$lite$\n"
-      "        .<$type_parameters$>newDefaultInstance(\n"
-      "            $descriptor$\n"
-      "            $key_wire_type$,\n"
-      "            $key_default_value$,\n"
-      "            $value_wire_type$,\n"
-      "            $value_default_value$);\n");
+      "    $type_parameters$> $name$DefaultEntry;\n");
   printer->Print(
       variables_,
       "private com.google.protobuf.MapField$lite$<\n"
-      "    $type_parameters$> $name$_ =\n"
-      "        com.google.protobuf.MapField$lite$.emptyMapField(\n"
-      "            $map_field_parameter$);\n"
-      "\n");
+      "    $type_parameters$> $name$_;\n"
+      "private com.google.protobuf.MapField$lite$<$type_parameters$>\n"
+      "internalGet$capitalized_name$() {\n"
+      "  if ($name$_ == null) {\n"
+      "    return com.google.protobuf.MapField$lite$.emptyMapField(\n"
+      "        $map_field_parameter$);\n"
+      " }\n"
+      "  return $name$_;\n"
+      "}\n");
   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
     printer->Print(
         variables_,
@@ -233,7 +246,7 @@
           "$deprecation$\n"
           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
           "get$capitalized_name$Value() {\n"
-          "  return $name$_.getMap();\n"
+          "  return internalGet$capitalized_name$().getMap();\n"
           "}\n");
     }
     WriteFieldDocComment(printer, descriptor_);
@@ -244,7 +257,8 @@
         "get$capitalized_name$() {\n"
         "  return new com.google.protobuf.Internal.MapAdapter<\n"
         "      $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
-        "          $name$_.getMap(), $name$ValueConverter);\n"
+        "          internalGet$capitalized_name$().getMap(),\n"
+        "          $name$ValueConverter);\n"
         "}\n");
   } else {
     WriteFieldDocComment(printer, descriptor_);
@@ -252,7 +266,7 @@
         variables_,
         "$deprecation$\n"
         "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n"
-        "  return $name$_.getMap();\n"
+        "  return internalGet$capitalized_name$().getMap();\n"
         "}\n");
   }
 }
@@ -262,10 +276,24 @@
   printer->Print(
       variables_,
       "private com.google.protobuf.MapField$lite$<\n"
-      "    $type_parameters$> $name$_ =\n"
-      "        com.google.protobuf.MapField$lite$.newMapField(\n"
-      "            $map_field_parameter$);\n"
-      "\n");
+      "    $type_parameters$> $name$_;\n"
+      "private com.google.protobuf.MapField$lite$<$type_parameters$>\n"
+      "internalGet$capitalized_name$() {\n"
+      "  if ($name$_ == null) {\n"
+      "    return com.google.protobuf.MapField$lite$.emptyMapField(\n"
+      "        $map_field_parameter$);\n"
+      " }\n"
+      "  return $name$_;\n"
+      "}\n"
+      "private com.google.protobuf.MapField$lite$<$type_parameters$>\n"
+      "internalGetMutable$capitalized_name$() {\n"
+      "  $on_changed$;\n"
+      "  if ($name$_ == null) {\n"
+      "    $name$_ = com.google.protobuf.MapField$lite$.newMapField(\n"
+      "        $map_field_parameter$);\n"
+      " }\n"
+      "  return $name$_;\n"
+      "}\n");
   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
     WriteFieldDocComment(printer, descriptor_);
     printer->Print(
@@ -275,7 +303,8 @@
         "get$capitalized_name$() {\n"
         "  return new com.google.protobuf.Internal.MapAdapter<\n"
         "      $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
-        "          $name$_.getMap(), $name$ValueConverter);\n"
+        "          internalGet$capitalized_name$().getMap(),\n"
+        "          $name$ValueConverter);\n"
         "}\n");
     WriteFieldDocComment(printer, descriptor_);
     printer->Print(
@@ -283,10 +312,10 @@
         "$deprecation$\n"
         "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
         "getMutable$capitalized_name$() {\n"
-        "  $on_changed$\n"
         "  return new com.google.protobuf.Internal.MapAdapter<\n"
         "      $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
-        "          $name$_.getMutableMap(), $name$ValueConverter);\n"
+        "          internalGetMutable$capitalized_name$().getMutableMap(),\n"
+        "          $name$ValueConverter);\n"
         "}\n");
     if (SupportUnknownEnumValue(descriptor_->file())) {
       WriteFieldDocComment(printer, descriptor_);
@@ -295,7 +324,7 @@
           "$deprecation$\n"
           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
           "get$capitalized_name$Value() {\n"
-          "  return $name$_.getMap();\n"
+          "  return internalGet$capitalized_name$().getMap();\n"
           "}\n");
       WriteFieldDocComment(printer, descriptor_);
       printer->Print(
@@ -303,8 +332,7 @@
           "$deprecation$\n"
           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
           "getMutable$capitalized_name$Value() {\n"
-          "  $on_changed$\n"
-          "  return $name$_.getMutableMap();\n"
+          "  return internalGetMutable$capitalized_name$().getMutableMap();\n"
           "}\n");
     }
   } else {
@@ -312,15 +340,14 @@
     printer->Print(
         variables_,
         "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n"
-        "  return $name$_.getMap();\n"
+        "  return internalGet$capitalized_name$().getMap();\n"
         "}\n");
     WriteFieldDocComment(printer, descriptor_);
     printer->Print(
         variables_,
         "public java.util.Map<$type_parameters$>\n"
         "getMutable$capitalized_name$() {\n"
-        "  $on_changed$\n"
-        "  return $name$_.getMutableMap();\n"
+        "  return internalGetMutable$capitalized_name$().getMutableMap();\n"
         "}\n");
   }
 }
@@ -339,14 +366,15 @@
 GenerateBuilderClearCode(io::Printer* printer) const {
   printer->Print(
       variables_,
-      "$name$_.clear();\n");
+      "internalGetMutable$capitalized_name$().clear();\n");
 }
 
 void ImmutableMapFieldGenerator::
 GenerateMergingCode(io::Printer* printer) const {
   printer->Print(
       variables_,
-      "$name$_.mergeFrom(other.$name$_);\n");
+      "internalGetMutable$capitalized_name$().mergeFrom(\n"
+      "    other.internalGet$capitalized_name$());\n");
 }
 
 void ImmutableMapFieldGenerator::
@@ -356,7 +384,7 @@
       // We do a copy of the map field to ensure that the built result is
       // immutable. Implementation of this copy() method can do copy-on-write
       // to defer this copy until further modifications are made on the field.
-      "result.$name$_ = $name$_.copy();\n");
+      "result.$name$_ = internalGet$capitalized_name$().copy();\n");
 }
 
 void ImmutableMapFieldGenerator::
@@ -402,7 +430,7 @@
   printer->Print(
       variables_,
       "for (java.util.Map.Entry<$type_parameters$> entry\n"
-      "     : $name$_.getMap().entrySet()) {\n"
+      "     : internalGet$capitalized_name$().getMap().entrySet()) {\n"
       "  com.google.protobuf.MapEntry$lite$<$type_parameters$>\n"
       "  $name$ = $name$DefaultEntry.newBuilderForType()\n"
       "      .setKey(entry.getKey())\n"
@@ -417,7 +445,7 @@
   printer->Print(
       variables_,
       "for (java.util.Map.Entry<$type_parameters$> entry\n"
-      "     : $name$_.getMap().entrySet()) {\n"
+      "     : internalGet$capitalized_name$().getMap().entrySet()) {\n"
       "  com.google.protobuf.MapEntry$lite$<$type_parameters$>\n"
       "  $name$ = $name$DefaultEntry.newBuilderForType()\n"
       "      .setKey(entry.getKey())\n"
@@ -432,16 +460,17 @@
 GenerateEqualsCode(io::Printer* printer) const {
   printer->Print(
       variables_,
-      "result = result && $name$_.equals(other.$name$_);\n");
+      "result = result && internalGet$capitalized_name$().equals(\n"
+      "    other.internalGet$capitalized_name$());\n");
 }
 
 void ImmutableMapFieldGenerator::
 GenerateHashCode(io::Printer* printer) const {
   printer->Print(
       variables_,
-      "if (!$name$_.getMap().isEmpty()) {\n"
+      "if (!internalGet$capitalized_name$().getMap().isEmpty()) {\n"
       "  hash = (37 * hash) + $constant_name$;\n"
-      "  hash = (53 * hash) + $name$_.hashCode();\n"
+      "  hash = (53 * hash) + internalGet$capitalized_name$().hashCode();\n"
       "}\n");
 }
 
diff --git a/src/google/protobuf/compiler/java/java_map_field.h b/src/google/protobuf/compiler/java/java_map_field.h
index 80a94f4..3e6dd97 100644
--- a/src/google/protobuf/compiler/java/java_map_field.h
+++ b/src/google/protobuf/compiler/java/java_map_field.h
@@ -60,6 +60,7 @@
   void GenerateSerializationCode(io::Printer* printer) const;
   void GenerateSerializedSizeCode(io::Printer* printer) const;
   void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+  void GenerateStaticInitializationCode(io::Printer* printer) const;
   void GenerateEqualsCode(io::Printer* printer) const;
   void GenerateHashCode(io::Printer* printer) const;
 
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index 1171b71..e982a17 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -234,7 +234,8 @@
         "public interface $classname$OrBuilder extends \n"
         "    $extra_interfaces$\n"
         "     com.google.protobuf.GeneratedMessageLite.\n"
-        "          ExtendableMessageOrBuilder<$classname$> {\n",
+        "          ExtendableMessageOrBuilder<\n"
+        "              $classname$, $classname$.Builder> {\n",
         "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
         "classname", descriptor_->name());
     }
@@ -285,22 +286,41 @@
   // The builder_type stores the super type name of the nested Builder class.
   string builder_type;
   if (descriptor_->extension_range_count() > 0) {
-    printer->Print(variables,
-      "public $static$final class $classname$ extends\n"
-      "    com.google.protobuf.GeneratedMessage$lite$.ExtendableMessage<\n"
-      "      $classname$> implements\n"
-      "    $extra_interfaces$\n"
-      "    $classname$OrBuilder {\n");
+    if (HasDescriptorMethods(descriptor_)) {
+      printer->Print(variables,
+        "public $static$final class $classname$ extends\n"
+        "    com.google.protobuf.GeneratedMessage.ExtendableMessage<\n"
+        "      $classname$> implements\n"
+        "    $extra_interfaces$\n"
+        "    $classname$OrBuilder {\n");
+    } else {
+      printer->Print(variables,
+        "public $static$final class $classname$ extends\n"
+        "    com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n"
+        "      $classname$, $classname$.Builder> implements\n"
+        "    $extra_interfaces$\n"
+        "    $classname$OrBuilder {\n");
+    }
     builder_type = strings::Substitute(
-        "com.google.protobuf.GeneratedMessage$1.ExtendableBuilder<$0, ?>",
-        name_resolver_->GetImmutableClassName(descriptor_),
-        variables["lite"]);
+             "com.google.protobuf.GeneratedMessage$1.ExtendableBuilder<$0, ?>",
+             name_resolver_->GetImmutableClassName(descriptor_),
+             variables["lite"]);
   } else {
-    printer->Print(variables,
-      "public $static$final class $classname$ extends\n"
-      "    com.google.protobuf.GeneratedMessage$lite$ implements\n"
-      "    $extra_interfaces$\n"
-      "    $classname$OrBuilder {\n");
+    if (HasDescriptorMethods(descriptor_)) {
+      printer->Print(variables,
+        "public $static$final class $classname$ extends\n"
+        "    com.google.protobuf.GeneratedMessage implements\n"
+        "    $extra_interfaces$\n"
+        "    $classname$OrBuilder {\n");
+    } else {
+      printer->Print(variables,
+              "public $static$final class $classname$ extends\n"
+              "    com.google.protobuf.GeneratedMessageLite<\n"
+              "        $classname$, $classname$.Builder> implements\n"
+              "    $extra_interfaces$\n"
+              "    $classname$OrBuilder {\n");
+    }
+
     builder_type = strings::Substitute(
         "com.google.protobuf.GeneratedMessage$0.Builder",
         variables["lite"]);
@@ -349,7 +369,7 @@
     GenerateParsingConstructor(printer);
   }
 
-  GenerateDescriptorMethods(printer);
+  GenerateDescriptorMethods(printer, false);
   GenerateParser(printer);
 
   // Nested types
@@ -481,7 +501,7 @@
   // Carefully initialize the default instance in such a way that it doesn't
   // conflict with other initialization.
   printer->Print(
-    "private static final $classname$ defaultInstance;",
+    "private static final $classname$ defaultInstance;\n",
     "classname", name_resolver_->GetImmutableClassName(descriptor_));
   if (HasDescriptorMethods(descriptor_)) {
     printer->Print(
@@ -494,15 +514,11 @@
     // LITE_RUNTIME only has one constructor.
     printer->Print(
       "static {\n"
-      "  try {\n"
-      "    defaultInstance = new $classname$(\n"
-      "        com.google.protobuf.Internal\n"
-      "            .EMPTY_CODED_INPUT_STREAM,\n"
-      "        com.google.protobuf.ExtensionRegistryLite\n"
-      "            .getEmptyRegistry());\n"
-      "  } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
-      "    throw new ExceptionInInitializerError(e);\n"
-      "  }\n"
+      "  defaultInstance = new $classname$(\n"
+      "      com.google.protobuf.Internal\n"
+      "          .EMPTY_CODED_INPUT_STREAM,\n"
+      "      com.google.protobuf.ExtensionRegistryLite\n"
+      "          .getEmptyRegistry());\n"
       "}\n"
       "\n",
       "classname", descriptor_->name());
@@ -511,12 +527,30 @@
       "public static $classname$ getDefaultInstance() {\n"
       "  return defaultInstance;\n"
       "}\n"
-      "\n"
+      "\n",
+      "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+  if (HasDescriptorMethods(descriptor_)) {
+    // LITE_RUNTIME implements this at the GeneratedMessageLite level.
+    printer->Print(
       "public $classname$ getDefaultInstanceForType() {\n"
       "  return defaultInstance;\n"
       "}\n"
       "\n",
       "classname", name_resolver_->GetImmutableClassName(descriptor_));
+  } else {
+    // LITE_RUNTIME uses this to implement the *ForType methods at the
+    // GeneratedMessageLite level.
+    printer->Print(
+      "static {"
+      "  com.google.protobuf.GeneratedMessageLite.onLoad(\n"
+      "      $classname$.class, new com.google.protobuf.GeneratedMessageLite\n"
+      "          .PrototypeHolder<$classname$, Builder>(\n"
+      "              defaultInstance, PARSER));"
+      "}\n"
+      "\n",
+      "classname", name_resolver_->GetImmutableClassName(descriptor_));
+  }
 
   // Extensions must be declared after the defaultInstance is initialized
   // because the defaultInstance is used by the extension to lazily retrieve
@@ -526,6 +560,19 @@
         .Generate(printer);
   }
 
+  // Some fields also have static members that must be initialized after we
+  // have the default instance available.
+  printer->Print(
+      "static {\n");
+  printer->Indent();
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    field_generators_.get(descriptor_->field(i))
+        .GenerateStaticInitializationCode(printer);
+  }
+  printer->Outdent();
+  printer->Print(
+      "}\n");
+
   printer->Outdent();
   printer->Print("}\n\n");
 }
@@ -542,37 +589,55 @@
   for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
     sorted_extensions.push_back(descriptor_->extension_range(i));
   }
-  sort(sorted_extensions.begin(), sorted_extensions.end(),
-       ExtensionRangeOrdering());
+  std::sort(sorted_extensions.begin(), sorted_extensions.end(),
+            ExtensionRangeOrdering());
 
   printer->Print(
     "public void writeTo(com.google.protobuf.CodedOutputStream output)\n"
     "                    throws java.io.IOException {\n");
   printer->Indent();
-  // writeTo(CodedOutputStream output) might be invoked without
-  // getSerializedSize() ever being called, but we need the memoized
-  // sizes in case this message has packed fields. Rather than emit checks for
-  // each packed field, just call getSerializedSize() up front for all messages.
-  // In most cases, getSerializedSize() will have already been called anyway by
-  // one of the wrapper writeTo() methods, making this call cheap.
-  printer->Print(
-    "getSerializedSize();\n");
+  if (HasPackedFields(descriptor_)) {
+    // writeTo(CodedOutputStream output) might be invoked without
+    // getSerializedSize() ever being called, but we need the memoized
+    // sizes in case this message has packed fields. Rather than emit checks for
+    // each packed field, just call getSerializedSize() up front.
+    // In most cases, getSerializedSize() will have already been called anyway
+    // by one of the wrapper writeTo() methods, making this call cheap.
+    printer->Print(
+      "getSerializedSize();\n");
+  }
 
   if (descriptor_->extension_range_count() > 0) {
     if (descriptor_->options().message_set_wire_format()) {
-      printer->Print(
-        "com.google.protobuf.GeneratedMessage$lite$\n"
-        "  .ExtendableMessage<$classname$>.ExtensionWriter extensionWriter =\n"
-        "    newMessageSetExtensionWriter();\n",
-        "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite",
-        "classname", name_resolver_->GetImmutableClassName(descriptor_));
+      if (HasDescriptorMethods(descriptor_)) {
+        printer->Print(
+          "com.google.protobuf.GeneratedMessage\n"
+          "  .ExtendableMessage<$classname$>.ExtensionWriter\n"
+          "    extensionWriter = newMessageSetExtensionWriter();\n",
+          "classname", name_resolver_->GetImmutableClassName(descriptor_));
+      } else {
+        printer->Print(
+          "com.google.protobuf.GeneratedMessageLite\n"
+          "  .ExtendableMessage<$classname$, $classname$.Builder>\n"
+          "    .ExtensionWriter extensionWriter =\n"
+          "      newMessageSetExtensionWriter();\n",
+          "classname", name_resolver_->GetImmutableClassName(descriptor_));
+      }
     } else {
-      printer->Print(
-        "com.google.protobuf.GeneratedMessage$lite$\n"
-        "  .ExtendableMessage<$classname$>.ExtensionWriter extensionWriter =\n"
-        "    newExtensionWriter();\n",
-        "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite",
-        "classname", name_resolver_->GetImmutableClassName(descriptor_));
+      if (HasDescriptorMethods(descriptor_)) {
+        printer->Print(
+          "com.google.protobuf.GeneratedMessage\n"
+          "  .ExtendableMessage<$classname$>.ExtensionWriter\n"
+          "    extensionWriter = newExtensionWriter();\n",
+          "classname", name_resolver_->GetImmutableClassName(descriptor_));
+      } else {
+        printer->Print(
+          "com.google.protobuf.GeneratedMessageLite\n"
+          "  .ExtendableMessage<$classname$, $classname$.Builder>\n"
+          "    .ExtensionWriter extensionWriter =\n"
+          "      newExtensionWriter();\n",
+          "classname", name_resolver_->GetImmutableClassName(descriptor_));
+      }
     }
   }
 
@@ -727,13 +792,23 @@
 // ===================================================================
 
 void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) {
+  if (HasDescriptorMethods(descriptor_)) {
+    // LITE_RUNTIME implements this at the GeneratedMessageLite level.
+    printer->Print(
+      "public Builder newBuilderForType() { return newBuilder(); }\n");
+  }
+
   printer->Print(
-    "public static Builder newBuilder() { return new Builder(); }\n"
-    "public Builder newBuilderForType() { return newBuilder(); }\n"
-    "public static Builder newBuilder($classname$ prototype) {\n"
-    "  return newBuilder().mergeFrom(prototype);\n"
+    "public static Builder newBuilder() {\n"
+    "  return defaultInstance.toBuilder();\n"
     "}\n"
-    "public Builder toBuilder() { return newBuilder(this); }\n"
+    "public static Builder newBuilder($classname$ prototype) {\n"
+    "  return defaultInstance.toBuilder().mergeFrom(prototype);\n"
+    "}\n"
+    "public Builder toBuilder() {\n"
+    "  return this == defaultInstance\n"
+    "      ? new Builder() : new Builder().mergeFrom(this);\n"
+    "}\n"
     "\n",
     "classname", name_resolver_->GetImmutableClassName(descriptor_));
 
@@ -792,7 +867,7 @@
   }
   printer->Indent();
 
-  GenerateDescriptorMethods(printer);
+  GenerateDescriptorMethods(printer, true);
   GenerateCommonBuilderMethods(printer);
 
   if (HasGeneratedMethods(descriptor_)) {
@@ -876,7 +951,7 @@
 }
 
 void ImmutableMessageGenerator::
-GenerateDescriptorMethods(io::Printer* printer) {
+GenerateDescriptorMethods(io::Printer* printer, bool is_builder) {
   if (HasDescriptorMethods(descriptor_)) {
     if (!descriptor_->options().no_standard_descriptor_accessor()) {
       printer->Print(
@@ -909,9 +984,9 @@
         const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
         printer->Print(
           "case $number$:\n"
-          "  return $name$_;\n",
+          "  return internalGet$capitalized_name$();\n",
           "number", SimpleItoa(field->number()),
-          "name", info->name);
+          "capitalized_name", info->capitalized_name);
       }
       printer->Print(
           "default:\n"
@@ -922,6 +997,34 @@
       printer->Print(
           "  }\n"
           "}\n");
+      if (is_builder) {
+        printer->Print(
+          "@SuppressWarnings({\"rawtypes\"})\n"
+          "protected com.google.protobuf.MapField internalGetMutableMapField(\n"
+          "    int number) {\n"
+          "  switch (number) {\n");
+        printer->Indent();
+        printer->Indent();
+        for (int i = 0; i < map_fields.size(); ++i) {
+          const FieldDescriptor* field = map_fields[i];
+          const FieldGeneratorInfo* info =
+              context_->GetFieldGeneratorInfo(field);
+          printer->Print(
+            "case $number$:\n"
+            "  return internalGetMutable$capitalized_name$();\n",
+            "number", SimpleItoa(field->number()),
+            "capitalized_name", info->capitalized_name);
+        }
+        printer->Print(
+            "default:\n"
+            "  throw new RuntimeException(\n"
+            "      \"Invalid map field number: \" + number);\n");
+        printer->Outdent();
+        printer->Outdent();
+        printer->Print(
+            "  }\n"
+            "}\n");
+      }
     }
     printer->Print(
       "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
@@ -959,7 +1062,7 @@
       "classname", name_resolver_->GetImmutableClassName(descriptor_));
   } else {
     // LITE runtime passes along the default instance to implement
-    // getDefaultInstanceForType() at the GneratedMessageLite level.
+    // getDefaultInstanceForType() at the GeneratedMessageLite level.
     printer->Print(
         "// Construct using $classname$.newBuilder()\n"
         "private Builder() {\n"
@@ -1062,22 +1165,17 @@
   if (HasDescriptorMethods(descriptor_)) {
     printer->Print(
         "public $classname$ buildPartial() {\n"
-            "  $classname$ result = new $classname$(this);\n",
-         "classname", name_resolver_->GetImmutableClassName(descriptor_));
+        "  $classname$ result = new $classname$(this);\n",
+        "classname", name_resolver_->GetImmutableClassName(descriptor_));
   } else {
     // LITE_RUNTIME only provides a single message constructor.
     printer->Print(
         "public $classname$ buildPartial() {\n"
-        "  $classname$ result = null;\n"
-        "  try {\n"
-        "    result = new $classname$(\n"
-        "        com.google.protobuf.Internal\n"
-        "            .EMPTY_CODED_INPUT_STREAM,\n"
-        "        com.google.protobuf.ExtensionRegistryLite\n"
-        "            .getEmptyRegistry());\n"
-        "  } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
-        "    throw new RuntimeException(e);\n"
-        "  }\n"
+        "  $classname$ result = new $classname$(\n"
+        "      com.google.protobuf.Internal\n"
+        "          .EMPTY_CODED_INPUT_STREAM,\n"
+        "      com.google.protobuf.ExtensionRegistryLite\n"
+        "          .getEmptyRegistry());\n"
         "  result.unknownFields = this.unknownFields;\n",
         "classname", name_resolver_->GetImmutableClassName(descriptor_));
 
@@ -1271,6 +1369,12 @@
 
 void ImmutableMessageGenerator::GenerateIsInitialized(
     io::Printer* printer, UseMemoization useMemoization) {
+  // LITE_RUNTIME avoids generating isInitialized if it's not needed.
+  if (!HasDescriptorMethods(descriptor_)
+      && !HasRequiredFields(descriptor_)) {
+    return;
+  }
+
   bool memoization = useMemoization == MEMOIZE;
   if (memoization) {
     // Memoizes whether the protocol buffer is fully initialized (has all
@@ -1558,8 +1662,7 @@
   printer->Print(
       "private $classname$(\n"
       "    com.google.protobuf.CodedInputStream input,\n"
-      "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
-      "    throws com.google.protobuf.InvalidProtocolBufferException {\n",
+      "    com.google.protobuf.ExtensionRegistryLite extensionRegistry) {\n",
       "classname", descriptor_->name());
   printer->Indent();
 
@@ -1695,10 +1798,11 @@
   printer->Outdent();
   printer->Print(
       "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
-      "  throw e.setUnfinishedMessage(this);\n"
+      "  throw new RuntimeException(e.setUnfinishedMessage(this));\n"
       "} catch (java.io.IOException e) {\n"
-      "  throw new com.google.protobuf.InvalidProtocolBufferException(\n"
-      "      e.getMessage()).setUnfinishedMessage(this);\n"
+      "  throw new RuntimeException(\n"
+      "      new com.google.protobuf.InvalidProtocolBufferException(\n"
+      "          e.getMessage()).setUnfinishedMessage(this));\n"
       "} finally {\n");
   printer->Indent();
 
@@ -1747,8 +1851,19 @@
       "    throws com.google.protobuf.InvalidProtocolBufferException {\n",
       "classname", descriptor_->name());
   if (HasGeneratedMethods(descriptor_)) {
+    // The parsing constructor throws an InvalidProtocolBufferException via a
+    // RuntimeException to aid in method pruning. We unwrap it here.
     printer->Print(
-        "  return new $classname$(input, extensionRegistry);\n",
+        "  try {\n"
+        "    return new $classname$(input, extensionRegistry);\n"
+        "  } catch (RuntimeException e) {\n"
+        "    if (e.getCause() instanceof\n"
+        "        com.google.protobuf.InvalidProtocolBufferException) {\n"
+        "      throw (com.google.protobuf.InvalidProtocolBufferException)\n"
+        "          e.getCause();\n"
+        "    }\n"
+        "    throw e;\n"
+        "  }\n",
         "classname", descriptor_->name());
   } else {
     // When parsing constructor isn't generated, use builder to parse messages.
@@ -1775,13 +1890,16 @@
       "};\n"
       "\n");
 
-  printer->Print(
-      "@java.lang.Override\n"
-      "public com.google.protobuf.Parser<$classname$> getParserForType() {\n"
-      "  return PARSER;\n"
-      "}\n"
-      "\n",
-      "classname", descriptor_->name());
+  if (HasDescriptorMethods(descriptor_)) {
+    // LITE_RUNTIME implements this at the GeneratedMessageLite level.
+    printer->Print(
+        "@java.lang.Override\n"
+        "public com.google.protobuf.Parser<$classname$> getParserForType() {\n"
+        "  return PARSER;\n"
+        "}\n"
+        "\n",
+        "classname", descriptor_->name());
+  }
 }
 
 // ===================================================================
diff --git a/src/google/protobuf/compiler/java/java_message.h b/src/google/protobuf/compiler/java/java_message.h
index 91eb287..016fdd5 100644
--- a/src/google/protobuf/compiler/java/java_message.h
+++ b/src/google/protobuf/compiler/java/java_message.h
@@ -117,7 +117,7 @@
 
   void GenerateBuilder(io::Printer* printer);
   void GenerateCommonBuilderMethods(io::Printer* printer);
-  void GenerateDescriptorMethods(io::Printer* printer);
+  void GenerateDescriptorMethods(io::Printer* printer, bool is_builder);
   void GenerateBuilderParsingMethods(io::Printer* printer);
   void GenerateIsInitialized(io::Printer* printer,
       UseMemoization useMemoization);
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc
index e331d7a..48757c6 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field.cc
@@ -772,6 +772,9 @@
 void RepeatedImmutablePrimitiveFieldGenerator::
 GenerateSerializationCode(io::Printer* printer) const {
   if (descriptor_->options().packed()) {
+    // We invoke getSerializedSize in writeTo for messages that have packed
+    // fields in ImmutableMessageGenerator::GenerateMessageSerializationMethods.
+    // That makes it safe to rely on the memoized size here.
     printer->Print(variables_,
       "if (get$capitalized_name$List().size() > 0) {\n"
       "  output.writeRawVarint32($tag$);\n"
diff --git a/src/google/protobuf/compiler/java/java_shared_code_generator.cc b/src/google/protobuf/compiler/java/java_shared_code_generator.cc
index 2e61ea8..7017736 100644
--- a/src/google/protobuf/compiler/java/java_shared_code_generator.cc
+++ b/src/google/protobuf/compiler/java/java_shared_code_generator.cc
@@ -171,7 +171,7 @@
       string classname = FileJavaPackage(file_->dependency(i)) + "." +
                          name_resolver_->GetDescriptorClassName(
                              file_->dependency(i));
-      dependencies.push_back(make_pair(filename, classname));
+      dependencies.push_back(std::make_pair(filename, classname));
     }
   }
 
diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc
index 1c9302a..8aa5699 100644
--- a/src/google/protobuf/compiler/java/java_string_field.cc
+++ b/src/google/protobuf/compiler/java/java_string_field.cc
@@ -667,7 +667,7 @@
     printer->Print(variables_,
       "String s = input.readStringRequireUtf8();\n"
       "$set_oneof_case_message$;\n"
-      "$oneof_name$_ = s;\n}\n");
+      "$oneof_name$_ = s;\n");
   } else if (!HasDescriptorMethods(descriptor_->file())) {
     // Lite runtime should attempt to reduce allocations by attempting to
     // construct the string directly from the input stream buffer. This avoids
diff --git a/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc b/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
index 106a750..41bad0a 100644
--- a/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
@@ -155,28 +155,6 @@
   return -1;
 }
 
-// Return true if the type is a that has variable length
-// for instance String's.
-bool IsVariableLenType(JavaType type) {
-  switch (type) {
-    case JAVATYPE_INT    : return false;
-    case JAVATYPE_LONG   : return false;
-    case JAVATYPE_FLOAT  : return false;
-    case JAVATYPE_DOUBLE : return false;
-    case JAVATYPE_BOOLEAN: return false;
-    case JAVATYPE_STRING : return true;
-    case JAVATYPE_BYTES  : return true;
-    case JAVATYPE_ENUM   : return false;
-    case JAVATYPE_MESSAGE: return true;
-
-    // No default because we want the compiler to complain if any new
-    // JavaTypes are added.
-  }
-
-  GOOGLE_LOG(FATAL) << "Can't get here.";
-  return false;
-}
-
 bool AllAscii(const string& text) {
   for (int i = 0; i < text.size(); i++) {
     if ((text[i] & 0x80) != 0) {
@@ -186,6 +164,7 @@
   return true;
 }
 
+
 void SetPrimitiveVariables(const FieldDescriptor* descriptor, const Params params,
                            map<string, string>* variables) {
   (*variables)["name"] =
diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc
index e7d5117..9826143 100644
--- a/src/google/protobuf/compiler/mock_code_generator.cc
+++ b/src/google/protobuf/compiler/mock_code_generator.cc
@@ -133,10 +133,10 @@
         *error = "Saw message type MockCodeGenerator_Error.";
         return false;
       } else if (command == "Exit") {
-        cerr << "Saw message type MockCodeGenerator_Exit." << endl;
+        std::cerr << "Saw message type MockCodeGenerator_Exit." << std::endl;
         exit(123);
       } else if (command == "Abort") {
-        cerr << "Saw message type MockCodeGenerator_Abort." << endl;
+        std::cerr << "Saw message type MockCodeGenerator_Abort." << std::endl;
         abort();
       } else if (command == "HasSourceCodeInfo") {
         FileDescriptorProto file_descriptor_proto;
@@ -144,8 +144,8 @@
         bool has_source_code_info =
             file_descriptor_proto.has_source_code_info() &&
             file_descriptor_proto.source_code_info().location_size() > 0;
-        cerr << "Saw message type MockCodeGenerator_HasSourceCodeInfo: "
-             << has_source_code_info << "." << endl;
+        std::cerr << "Saw message type MockCodeGenerator_HasSourceCodeInfo: "
+                  << has_source_code_info << "." << std::endl;
         abort();
       } else {
         GOOGLE_LOG(FATAL) << "Unknown MockCodeGenerator command: " << command;
diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc
index fe697ac..c50cdf5 100644
--- a/src/google/protobuf/compiler/parser.cc
+++ b/src/google/protobuf/compiler/parser.cc
@@ -277,27 +277,39 @@
   }
 }
 
-bool Parser::TryConsumeEndOfDeclaration(const char* text,
-                                        const LocationRecorder* location) {
+bool Parser::TryConsumeEndOfDeclaration(
+    const char* text, const LocationRecorder* location) {
   if (LookingAt(text)) {
     string leading, trailing;
-    input_->NextWithComments(&trailing, NULL, &leading);
+    vector<string> detached;
+    input_->NextWithComments(&trailing, &detached, &leading);
 
     // Save the leading comments for next time, and recall the leading comments
     // from last time.
     leading.swap(upcoming_doc_comments_);
 
     if (location != NULL) {
-      location->AttachComments(&leading, &trailing);
+      upcoming_detached_comments_.swap(detached);
+      location->AttachComments(&leading, &trailing, &detached);
+    } else if (strcmp(text, "}") == 0) {
+      // If the current location is null and we are finishing the current scope,
+      // drop pending upcoming detached comments.
+      upcoming_detached_comments_.swap(detached);
+    } else {
+      // Otherwise, append the new detached comments to the existing upcoming
+      // detached comments.
+      upcoming_detached_comments_.insert(upcoming_detached_comments_.end(),
+                                         detached.begin(), detached.end());
     }
+
     return true;
   } else {
     return false;
   }
 }
 
-bool Parser::ConsumeEndOfDeclaration(const char* text,
-                                     const LocationRecorder* location) {
+bool Parser::ConsumeEndOfDeclaration(
+    const char* text, const LocationRecorder* location) {
   if (TryConsumeEndOfDeclaration(text, location)) {
     return true;
   } else {
@@ -390,7 +402,8 @@
 }
 
 void Parser::LocationRecorder::AttachComments(
-    string* leading, string* trailing) const {
+    string* leading, string* trailing,
+    vector<string>* detached_comments) const {
   GOOGLE_CHECK(!location_->has_leading_comments());
   GOOGLE_CHECK(!location_->has_trailing_comments());
 
@@ -400,6 +413,11 @@
   if (!trailing->empty()) {
     location_->mutable_trailing_comments()->swap(*trailing);
   }
+  for (int i = 0; i < detached_comments->size(); ++i) {
+    location_->add_leading_detached_comments()->swap(
+        (*detached_comments)[i]);
+  }
+  detached_comments->clear();
 }
 
 // -------------------------------------------------------------------
@@ -451,16 +469,18 @@
   SourceCodeInfo source_code_info;
   source_code_info_ = &source_code_info;
 
+  vector<string> top_doc_comments;
   if (LookingAtType(io::Tokenizer::TYPE_START)) {
     // Advance to first token.
-    input_->NextWithComments(NULL, NULL, &upcoming_doc_comments_);
+    input_->NextWithComments(NULL, &upcoming_detached_comments_,
+                             &upcoming_doc_comments_);
   }
 
   {
     LocationRecorder root_location(this);
 
     if (require_syntax_identifier_ || LookingAt("syntax")) {
-      if (!ParseSyntaxIdentifier()) {
+      if (!ParseSyntaxIdentifier(root_location)) {
         // Don't attempt to parse the file if we didn't recognize the syntax
         // identifier.
         return false;
@@ -469,9 +489,9 @@
       if (file != NULL) file->set_syntax(syntax_identifier_);
     } else if (!stop_after_syntax_identifier_) {
       GOOGLE_LOG(WARNING) << "No syntax specified for the proto file. "
-                          << "Please use 'syntax = \"proto2\";' or "
-                          << "'syntax = \"proto3\";' to specify a syntax "
-                          << "version. (Defaulted to proto2 syntax.)";
+                   << "Please use 'syntax = \"proto2\";' or "
+                   << "'syntax = \"proto3\";' to specify a syntax "
+                   << "version. (Defaulted to proto2 syntax.)";
       syntax_identifier_ = "proto2";
     }
 
@@ -486,7 +506,8 @@
 
         if (LookingAt("}")) {
           AddError("Unmatched \"}\".");
-          input_->NextWithComments(NULL, NULL, &upcoming_doc_comments_);
+          input_->NextWithComments(NULL, &upcoming_detached_comments_,
+                                   &upcoming_doc_comments_);
         }
       }
     }
@@ -498,7 +519,9 @@
   return !had_errors_;
 }
 
-bool Parser::ParseSyntaxIdentifier() {
+bool Parser::ParseSyntaxIdentifier(const LocationRecorder& parent) {
+  LocationRecorder syntax_location(parent,
+                                   FileDescriptorProto::kSyntaxFieldNumber);
   DO(Consume(
       "syntax",
       "File must begin with a syntax statement, e.g. 'syntax = \"proto2\";'."));
@@ -506,7 +529,7 @@
   io::Tokenizer::Token syntax_token = input_->current();
   string syntax;
   DO(ConsumeString(&syntax, "Expected syntax identifier."));
-  DO(ConsumeEndOfDeclaration(";", NULL));
+  DO(ConsumeEndOfDeclaration(";", &syntax_location));
 
   syntax_identifier_ = syntax;
 
@@ -1271,7 +1294,6 @@
     DO(ConsumeEndOfDeclaration(";", &location));
   }
 
-
   return true;
 }
 
@@ -1636,8 +1658,14 @@
   // Parse input type.
   DO(Consume("("));
   {
-    if (TryConsume("stream")) {
+    if (LookingAt("stream")) {
+      LocationRecorder location(
+          method_location, MethodDescriptorProto::kClientStreamingFieldNumber);
+      location.RecordLegacyLocation(
+          method, DescriptorPool::ErrorCollector::OTHER);
       method->set_client_streaming(true);
+      DO(Consume("stream"));
+
     }
     LocationRecorder location(method_location,
                               MethodDescriptorProto::kInputTypeFieldNumber);
@@ -1651,8 +1679,14 @@
   DO(Consume("returns"));
   DO(Consume("("));
   {
-    if (TryConsume("stream")) {
+    if (LookingAt("stream")) {
+      LocationRecorder location(
+          method_location, MethodDescriptorProto::kServerStreamingFieldNumber);
+      location.RecordLegacyLocation(
+          method, DescriptorPool::ErrorCollector::OTHER);
+      DO(Consume("stream"));
       method->set_server_streaming(true);
+
     }
     LocationRecorder location(method_location,
                               MethodDescriptorProto::kOutputTypeFieldNumber);
@@ -1664,10 +1698,9 @@
 
   if (LookingAt("{")) {
     // Options!
-    DO(ParseOptions(method_location,
-                    containing_file,
-                    MethodDescriptorProto::kOptionsFieldNumber,
-                    method->mutable_options()));
+    DO(ParseMethodOptions(method_location, containing_file,
+                          MethodDescriptorProto::kOptionsFieldNumber,
+                          method->mutable_options()));
   } else {
     DO(ConsumeEndOfDeclaration(";", &method_location));
   }
@@ -1676,10 +1709,10 @@
 }
 
 
-bool Parser::ParseOptions(const LocationRecorder& parent_location,
-                          const FileDescriptorProto* containing_file,
-                          const int optionsFieldNumber,
-                          Message* mutable_options) {
+bool Parser::ParseMethodOptions(const LocationRecorder& parent_location,
+                                const FileDescriptorProto* containing_file,
+                                const int optionsFieldNumber,
+                                Message* mutable_options) {
   // Options!
   ConsumeEndOfDeclaration("{", &parent_location);
   while (!TryConsumeEndOfDeclaration("}", NULL)) {
@@ -1693,8 +1726,8 @@
     } else {
       LocationRecorder location(parent_location,
                                 optionsFieldNumber);
-      if (!ParseOption(mutable_options, location, containing_file,
-                       OPTION_STATEMENT)) {
+      if (!ParseOption(mutable_options, location,
+                       containing_file, OPTION_STATEMENT)) {
         // This statement failed to parse.  Skip it, but keep looping to
         // parse other statements.
         SkipStatement();
@@ -1847,7 +1880,7 @@
     DescriptorPool::ErrorCollector::ErrorLocation location,
     int* line, int* column) const {
   const pair<int, int>* result =
-    FindOrNull(location_map_, make_pair(descriptor, location));
+      FindOrNull(location_map_, std::make_pair(descriptor, location));
   if (result == NULL) {
     *line   = -1;
     *column = 0;
@@ -1863,7 +1896,8 @@
     const Message* descriptor,
     DescriptorPool::ErrorCollector::ErrorLocation location,
     int line, int column) {
-  location_map_[make_pair(descriptor, location)] = make_pair(line, column);
+  location_map_[std::make_pair(descriptor, location)] =
+      std::make_pair(line, column);
 }
 
 void SourceLocationTable::Clear() {
diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h
index a15cc70..7cb1678 100644
--- a/src/google/protobuf/compiler/parser.h
+++ b/src/google/protobuf/compiler/parser.h
@@ -185,10 +185,13 @@
   //   have been passed around by const reference, for no particularly good
   //   reason.  We should probably go through and change them all to mutable
   //   pointer to make this more intuitive.
-  bool TryConsumeEndOfDeclaration(const char* text,
-                                  const LocationRecorder* location);
-  bool ConsumeEndOfDeclaration(const char* text,
-                               const LocationRecorder* location);
+  bool TryConsumeEndOfDeclaration(
+      const char* text, const LocationRecorder* location);
+  bool TryConsumeEndOfDeclarationFinishScope(
+      const char* text, const LocationRecorder* location);
+
+  bool ConsumeEndOfDeclaration(
+      const char* text, const LocationRecorder* location);
 
   // -----------------------------------------------------------------
   // Error logging helpers
@@ -253,9 +256,13 @@
     //
     // TODO(kenton):  See comment on TryConsumeEndOfDeclaration(), above, for
     //   why this is const.
-    void AttachComments(string* leading, string* trailing) const;
+    void AttachComments(string* leading, string* trailing,
+                        vector<string>* detached_comments) const;
 
    private:
+    // Indexes of parent and current location in the parent
+    // SourceCodeInfo.location repeated field. For top-level elements,
+    // parent_index_ is -1.
     Parser* parser_;
     SourceCodeInfo::Location* location_;
 
@@ -268,7 +275,7 @@
   // Parses the "syntax = \"proto2\";" line at the top of the file.  Returns
   // false if it failed to parse or if the syntax identifier was not
   // recognized.
-  bool ParseSyntaxIdentifier();
+  bool ParseSyntaxIdentifier(const LocationRecorder& parent);
 
   // These methods parse various individual bits of code.  They return
   // false if they completely fail to parse the construct.  In this case,
@@ -302,9 +309,6 @@
                    RepeatedField<int32>* weak_dependency,
                    const LocationRecorder& root_location,
                    const FileDescriptorProto* containing_file);
-  bool ParseOption(Message* options,
-                   const LocationRecorder& options_location,
-                   const FileDescriptorProto* containing_file);
 
   // These methods parse the contents of a message, enum, or service type and
   // add them to the given object.  They consume the entire block including
@@ -397,10 +401,10 @@
 
 
   // Parse options of a single method or stream.
-  bool ParseOptions(const LocationRecorder& parent_location,
-                    const FileDescriptorProto* containing_file,
-                    const int optionsFieldNumber,
-                    Message* mutable_options);
+  bool ParseMethodOptions(const LocationRecorder& parent_location,
+                          const FileDescriptorProto* containing_file,
+                          const int optionsFieldNumber,
+                          Message* mutable_options);
 
   // Parse "required", "optional", or "repeated" and fill in "label"
   // with the value. Returns true if shuch a label is consumed.
@@ -497,6 +501,13 @@
   // yet; use ConsumeEndOfDeclaration() to get the complete comments.
   string upcoming_doc_comments_;
 
+  // Detached comments are not connected to any syntax entities. Elements in
+  // this vector are paragraphs of comments separated by empty lines. The
+  // detached comments will be put into the leading_detached_comments field for
+  // the next element (See SourceCodeInfo.Location in descriptor.proto), when
+  // ConsumeEndOfDeclaration() is called.
+  vector<string> upcoming_detached_comments_;
+
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Parser);
 };
 
diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc
index fe0719f..1684beb 100644
--- a/src/google/protobuf/compiler/parser_unittest.cc
+++ b/src/google/protobuf/compiler/parser_unittest.cc
@@ -1571,7 +1571,7 @@
   }
   DescriptorProto **data =
     descriptor_proto->mutable_nested_type()->mutable_data();
-  sort(data, data + size, CompareDescriptorNames());
+  std::sort(data, data + size, CompareDescriptorNames());
 }
 
 // Sorts DescriptorProtos belonging to a FileDescriptorProto, by name.
@@ -1583,7 +1583,7 @@
   }
   DescriptorProto **data =
     file_descriptor_proto->mutable_message_type()->mutable_data();
-  sort(data, data + size, CompareDescriptorNames());
+  std::sort(data, data + size, CompareDescriptorNames());
 }
 
 // Strips the message and enum field type names for comparison purpose only.
@@ -1703,25 +1703,52 @@
 // places.
 TEST_F(ParseDescriptorDebugTest, TestCommentsInDebugString) {
   SetupParser(
+      "// Detached comment before syntax.\n"
+      "\n"
+      "// Syntax comment.\n"
+      "syntax = \"proto2\";\n"
+      "\n"
+      "// Detached comment before package.\n"
+      "\n"
+      "// Package comment.\n"
+      "package comment_test;\n"
+      "\n"
+      "// Detached comment before TestMessage1.\n"
+      "\n"
       "// Message comment.\n"
       "message TestMessage1 {\n"
+      "\n"
+      "  // Detached comment before foo.\n"
+      "\n"
       "  // Field comment.\n"
       "  optional int32 foo = 1;\n"
       "\n"
+      "  // Detached comment before NestedMessage.\n"
+      "\n"
       "  // Nested-message comment.\n"
       "  message NestedMessage {\n"
       "    optional int32 bar = 1;\n"
       "  }\n"
       "}\n"
       "\n"
+      "// Detached comment before MyEnumType.\n"
+      "\n"
       "// Enum comment.\n"
       "enum MyEnumType {\n"
+      "\n"
+      "  // Detached comment before ASDF.\n"
+      "\n"
       "  // Enum-value comment.\n"
       "  ASDF = 1;\n"
       "}\n"
       "\n"
+      "// Detached comment before MyService.\n"
+      "\n"
       "// Service comment.\n"
       "service MyService {\n"
+      "\n"
+      "  // Detached comment before MyRPCCall.\n"
+      "\n"
       "  // RPC comment.\n"
       "  rpc MyRPCCall(TestMessage1) returns (TestMessage1) { }\n"
       "}\n");
@@ -1745,22 +1772,34 @@
   const string debug_string =
       descriptor->DebugStringWithOptions(debug_string_options);
 
-  // Ensure that each of the comments appears somewhere in the DebugString(),
-  // and that these comments appear in order. We don't test the exact comment
-  // placement or formatting, because we do not want to be too fragile here.
+  // Ensure that each of the comments appears somewhere in the DebugString().
+  // We don't test the exact comment placement or formatting, because we do not
+  // want to be too fragile here.
   const char* expected_comments[] = {
+    "Detached comment before syntax.",
+    "Syntax comment.",
+    "Detached comment before package.",
+    "Package comment.",
+    "Detached comment before TestMessage1.",
     "Message comment.",
+    "Detached comment before foo.",
     "Field comment",
+    "Detached comment before NestedMessage.",
     "Nested-message comment",
+    "Detached comment before MyEnumType.",
     "Enum comment",
+    "Detached comment before ASDF.",
     "Enum-value comment",
+    "Detached comment before MyService.",
     "Service comment",
+    "Detached comment before MyRPCCall.",
     "RPC comment",
   };
 
   for (int i = 0; i < GOOGLE_ARRAYSIZE(expected_comments); ++i) {
     string::size_type found_pos = debug_string.find(expected_comments[i]);
-    ASSERT_TRUE(found_pos != string::npos);
+    EXPECT_TRUE(found_pos != string::npos)
+        << "\"" << expected_comments[i] << "\" not found.";
   }
 }
 
@@ -1930,8 +1969,8 @@
         return false;
       }
 
-      spans_.insert(make_pair(SpanKey(*descriptor_proto, field, index),
-                              &location));
+      spans_.insert(
+          std::make_pair(SpanKey(*descriptor_proto, field, index), &location));
     }
 
     return true;
@@ -1952,16 +1991,18 @@
   bool HasSpan(char start_marker, char end_marker,
                const Message& descriptor_proto) {
     return HasSpanWithComment(
-        start_marker, end_marker, descriptor_proto, NULL, -1, NULL, NULL);
+        start_marker, end_marker, descriptor_proto, NULL, -1, NULL, NULL, NULL);
   }
 
   bool HasSpanWithComment(char start_marker, char end_marker,
                           const Message& descriptor_proto,
                           const char* expected_leading_comments,
-                          const char* expected_trailing_comments) {
+                          const char* expected_trailing_comments,
+                          const char* expected_leading_detached_comments) {
     return HasSpanWithComment(
         start_marker, end_marker, descriptor_proto, NULL, -1,
-        expected_leading_comments, expected_trailing_comments);
+        expected_leading_comments, expected_trailing_comments,
+        expected_leading_detached_comments);
   }
 
   bool HasSpan(char start_marker, char end_marker,
@@ -1973,14 +2014,15 @@
                const Message& descriptor_proto, const string& field_name,
                int index) {
     return HasSpan(start_marker, end_marker, descriptor_proto,
-                   field_name, index, NULL, NULL);
+                   field_name, index, NULL, NULL, NULL);
   }
 
   bool HasSpan(char start_marker, char end_marker,
                const Message& descriptor_proto,
                const string& field_name, int index,
                const char* expected_leading_comments,
-               const char* expected_trailing_comments) {
+               const char* expected_trailing_comments,
+               const char* expected_leading_detached_comments) {
     const FieldDescriptor* field =
         descriptor_proto.GetDescriptor()->FindFieldByName(field_name);
     if (field == NULL) {
@@ -1991,12 +2033,13 @@
 
     return HasSpanWithComment(
         start_marker, end_marker, descriptor_proto, field, index,
-        expected_leading_comments, expected_trailing_comments);
+        expected_leading_comments, expected_trailing_comments,
+        expected_leading_detached_comments);
   }
 
   bool HasSpan(const Message& descriptor_proto) {
     return HasSpanWithComment(
-        '\0', '\0', descriptor_proto, NULL, -1, NULL, NULL);
+        '\0', '\0', descriptor_proto, NULL, -1, NULL, NULL, NULL);
   }
 
   bool HasSpan(const Message& descriptor_proto, const string& field_name) {
@@ -2008,11 +2051,12 @@
     return HasSpan('\0', '\0', descriptor_proto, field_name, index);
   }
 
-  bool HasSpanWithComment(char start_marker, char end_marker,
-                          const Message& descriptor_proto,
-                          const FieldDescriptor* field, int index,
-                          const char* expected_leading_comments,
-                          const char* expected_trailing_comments) {
+  bool HasSpanWithComment(
+      char start_marker, char end_marker, const Message& descriptor_proto,
+      const FieldDescriptor* field, int index,
+      const char* expected_leading_comments,
+      const char* expected_trailing_comments,
+      const char* expected_leading_detached_comments) {
     pair<SpanMap::iterator, SpanMap::iterator> range =
         spans_.equal_range(SpanKey(descriptor_proto, field, index));
 
@@ -2051,6 +2095,13 @@
             EXPECT_EQ(expected_trailing_comments,
                       iter->second->trailing_comments());
           }
+          if (expected_leading_detached_comments == NULL) {
+            EXPECT_EQ(0, iter->second->leading_detached_comments_size());
+          } else {
+            EXPECT_EQ(
+                expected_leading_detached_comments,
+                Join(iter->second->leading_detached_comments(), "\n"));
+          }
 
           spans_.erase(iter);
           return true;
@@ -2101,7 +2152,7 @@
           text_without_markers_ += '$';
           ++column;
         } else {
-          markers_[*text] = make_pair(line, column);
+          markers_[*text] = std::make_pair(line, column);
           ++text;
           GOOGLE_CHECK_EQ('$', *text);
         }
@@ -2120,7 +2171,7 @@
 
 TEST_F(SourceInfoTest, BasicFileDecls) {
   EXPECT_TRUE(Parse(
-      "$a$syntax = \"proto2\";\n"
+      "$a$syntax = \"proto2\";$i$\n"
       "package $b$foo.bar$c$;\n"
       "import $d$\"baz.proto\"$e$;\n"
       "import $f$\"qux.proto\"$g$;$h$\n"
@@ -2131,6 +2182,7 @@
   EXPECT_TRUE(HasSpan('b', 'c', file_, "package"));
   EXPECT_TRUE(HasSpan('d', 'e', file_, "dependency", 0));
   EXPECT_TRUE(HasSpan('f', 'g', file_, "dependency", 1));
+  EXPECT_TRUE(HasSpan('a', 'i', file_, "syntax"));
 }
 
 TEST_F(SourceInfoTest, Messages) {
@@ -2561,6 +2613,9 @@
     "  rpc M(X) returns(Y) {\n"
     "    $g$option mopt = 1;$h$\n"
     "  }\n"
+    "  rpc MS4($1$stream$2$ X) returns($3$stream$4$ Y) {\n"
+    "    $k$option mopt = 1;$l$\n"
+    "  }\n"
     "}\n"));
 
   EXPECT_TRUE(HasSpan('a', 'b', file_.message_type(0).options()));
@@ -2620,6 +2675,26 @@
                       .uninterpreted_option(0).name(0), "name_part"));
   EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
                       .uninterpreted_option(0), "positive_int_value"));
+
+  EXPECT_TRUE(HasSpan('k', 'l', file_.service(0).method(1).options()));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(1)));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(1), "name"));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(1), "input_type"));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(1), "output_type"));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(1).options()
+                      .uninterpreted_option(0)));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(1).options()
+                      .uninterpreted_option(0), "name"));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(1).options()
+                      .uninterpreted_option(0).name(0)));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(1).options()
+                      .uninterpreted_option(0).name(0), "name_part"));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(1).options()
+                      .uninterpreted_option(0), "positive_int_value"));
+  EXPECT_TRUE(HasSpan('1', '2', file_.service(0).method(1),
+                      "client_streaming"));
+  EXPECT_TRUE(HasSpan('3', '4', file_.service(0).method(1),
+                      "server_streaming"));
 }
 
 TEST_F(SourceInfoTest, FieldOptions) {
@@ -2705,7 +2780,7 @@
       "  // Foo trailing\n"
       "  // line 2\n"
       "\n"
-      "  // ignored\n"
+      "  // detached\n"
       "\n"
       "  // bar leading\n"
       "  $b$optional int32 bar = 1;$c$\n"
@@ -2719,10 +2794,12 @@
 
   EXPECT_TRUE(HasSpanWithComment('a', 'd', foo,
       " Foo leading\n line 2\n",
-      " Foo trailing\n line 2\n"));
+      " Foo trailing\n line 2\n",
+      NULL));
   EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
       " bar leading\n",
-      " bar trailing\n"));
+      " bar trailing\n",
+      " detached\n"));
 
   // Ignore these.
   EXPECT_TRUE(HasSpan(file_));
@@ -2735,21 +2812,23 @@
 
 TEST_F(SourceInfoTest, DocComments2) {
   EXPECT_TRUE(Parse(
-      "// ignored\n"
-      "syntax = \"proto2\";\n"
+      "// detached before message.\n"
+      "\n"
       "// Foo leading\n"
       "// line 2\n"
       "$a$message Foo {\n"
       "  /* Foo trailing\n"
       "   * line 2 */\n"
-      "  // ignored\n"
+      "  // detached\n"
       "  /* bar leading\n"
       "   */"
       "  $b$optional int32 bar = 1;$c$  // bar trailing\n"
-      "  // ignored\n"
+      "  // ignored detached\n"
       "}$d$\n"
       "// ignored\n"
       "\n"
+      "// detached before option\n"
+      "\n"
       "// option leading\n"
       "$e$option baz = 123;$f$\n"
       "// option trailing\n"
@@ -2761,13 +2840,16 @@
 
   EXPECT_TRUE(HasSpanWithComment('a', 'd', foo,
       " Foo leading\n line 2\n",
-      " Foo trailing\n line 2 "));
+      " Foo trailing\n line 2 ",
+      " detached before message.\n"));
   EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
       " bar leading\n",
-      " bar trailing\n"));
+      " bar trailing\n",
+      " detached\n"));
   EXPECT_TRUE(HasSpanWithComment('e', 'f', baz,
       " option leading\n",
-      " option trailing\n"));
+      " option trailing\n",
+      " detached before option\n"));
 
   // Ignore these.
   EXPECT_TRUE(HasSpan(file_));
@@ -2798,7 +2880,8 @@
 
   EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
       " bar leading\n",
-      " bar trailing\n"));
+      " bar trailing\n",
+      NULL));
 
   // Ignore these.
   EXPECT_TRUE(HasSpan(file_));
@@ -2818,25 +2901,63 @@
       bar.options().uninterpreted_option(0), "aggregate_value"));
 }
 
+TEST_F(SourceInfoTest, DocCommentsTopLevel) {
+  EXPECT_TRUE(Parse(
+      "// detached before syntax paragraph 1\n"
+      "\n"
+      "// detached before syntax paragraph 2\n"
+      "\n"
+      "// syntax leading\n"
+      "$a$syntax = \"proto2\";$b$\n"
+      "// syntax trailing\n"
+      "\n"
+      "// syntax-package detached comments\n"
+      "\n"
+      ";\n"
+      "\n"
+      "// detached after empty before package\n"
+      "\n"
+      "// package leading\n"
+      "package $c$foo$d$;\n"
+      "// package trailing\n"
+      "\n"
+      "// ignored detach\n"
+      "\n"));
+
+  EXPECT_TRUE(HasSpan('a', 'b', file_, "syntax", -1,
+      " syntax leading\n",
+      " syntax trailing\n",
+      " detached before syntax paragraph 1\n"
+      "\n"
+      " detached before syntax paragraph 2\n"));
+  EXPECT_TRUE(HasSpan('c', 'd', file_, "package", -1,
+      " package leading\n",
+      " package trailing\n",
+      " syntax-package detached comments\n"
+      "\n"
+      " detached after empty before package\n"));
+
+  // ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+}
+
 TEST_F(SourceInfoTest, DocCommentsOneof) {
   EXPECT_TRUE(Parse(
-      "// ignored\n"
-      "syntax = \"proto2\";\n"
       "// Foo leading\n"
       "$a$message Foo {\n"
       "  /* Foo trailing\n"
       "   */\n"
-      "  // ignored\n"
+      "  // detached before oneof\n"
       "  /* bar leading\n"
       "   * line 2 */\n"
       "  $b$oneof bar {\n"
       "  /* bar trailing\n"
       "   * line 2 */\n"
-      "  // ignored\n"
+      "  // detached before bar_int\n"
       "  /* bar_int leading\n"
       "   */\n"
       "  $c$int32 bar_int = 1;$d$  // bar_int trailing\n"
-      "  // ignored\n"
+      "  // detach comment ignored\n"
       "  }$e$\n"
       "}$f$\n"));
 
@@ -2846,13 +2967,16 @@
 
   EXPECT_TRUE(HasSpanWithComment('a', 'f', foo,
       " Foo leading\n",
-      " Foo trailing\n"));
+      " Foo trailing\n",
+      NULL));
   EXPECT_TRUE(HasSpanWithComment('b', 'e', bar,
       " bar leading\n line 2 ",
-      " bar trailing\n line 2 "));
+      " bar trailing\n line 2 ",
+      " detached before oneof\n"));
   EXPECT_TRUE(HasSpanWithComment('c', 'd', bar_int,
       " bar_int leading\n",
-      " bar_int trailing\n"));
+      " bar_int trailing\n",
+      " detached before bar_int\n"));
 
   // Ignore these.
   EXPECT_TRUE(HasSpan(file_));
diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc
index 9011a6b..ad501ac 100644
--- a/src/google/protobuf/compiler/plugin.cc
+++ b/src/google/protobuf/compiler/plugin.cc
@@ -95,7 +95,7 @@
 int PluginMain(int argc, char* argv[], const CodeGenerator* generator) {
 
   if (argc > 1) {
-    cerr << argv[0] << ": Unknown option: " << argv[1] << endl;
+    std::cerr << argv[0] << ": Unknown option: " << argv[1] << std::endl;
     return 1;
   }
 
@@ -106,7 +106,8 @@
 
   CodeGeneratorRequest request;
   if (!request.ParseFromFileDescriptor(STDIN_FILENO)) {
-    cerr << argv[0] << ": protoc sent unparseable request to plugin." << endl;
+    std::cerr << argv[0] << ": protoc sent unparseable request to plugin."
+              << std::endl;
     return 1;
   }
 
@@ -123,9 +124,9 @@
   for (int i = 0; i < request.file_to_generate_size(); i++) {
     parsed_files.push_back(pool.FindFileByName(request.file_to_generate(i)));
     if (parsed_files.back() == NULL) {
-      cerr << argv[0] << ": protoc asked plugin to generate a file but "
-              "did not provide a descriptor for the file: "
-           << request.file_to_generate(i) << endl;
+      std::cerr << argv[0] << ": protoc asked plugin to generate a file but "
+                              "did not provide a descriptor for the file: "
+                << request.file_to_generate(i) << std::endl;
       return 1;
     }
   }
@@ -151,7 +152,7 @@
   }
 
   if (!response.SerializeToFileDescriptor(STDOUT_FILENO)) {
-    cerr << argv[0] << ": Error writing to stdout." << endl;
+    std::cerr << argv[0] << ": Error writing to stdout." << std::endl;
     return 1;
   }
 
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index 5118de1..fed1726 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -140,8 +140,8 @@
     "\01324.google.protobuf.compiler.CodeGenerat"
     "orResponse.File\032>\n\004File\022\014\n\004name\030\001 \001(\t\022\027\n"
     "\017insertion_point\030\002 \001(\t\022\017\n\007content\030\017 \001(\tB"
-    ",\n\034com.google.protobuf.compilerB\014PluginP"
-    "rotos", 445);
+    "7\n\034com.google.protobuf.compilerB\014PluginP"
+    "rotosZ\tplugin_go", 456);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "google/protobuf/compiler/plugin.proto", &protobuf_RegisterTypes);
   CodeGeneratorRequest::default_instance_ = new CodeGeneratorRequest();
@@ -509,6 +509,147 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// CodeGeneratorRequest
+
+// repeated string file_to_generate = 1;
+ int CodeGeneratorRequest::file_to_generate_size() const {
+  return file_to_generate_.size();
+}
+ void CodeGeneratorRequest::clear_file_to_generate() {
+  file_to_generate_.Clear();
+}
+ const ::std::string& CodeGeneratorRequest::file_to_generate(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+  return file_to_generate_.Get(index);
+}
+ ::std::string* CodeGeneratorRequest::mutable_file_to_generate(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+  return file_to_generate_.Mutable(index);
+}
+ void CodeGeneratorRequest::set_file_to_generate(int index, const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+  file_to_generate_.Mutable(index)->assign(value);
+}
+ void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) {
+  file_to_generate_.Mutable(index)->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+ void CodeGeneratorRequest::set_file_to_generate(int index, const char* value, size_t size) {
+  file_to_generate_.Mutable(index)->assign(
+    reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+ ::std::string* CodeGeneratorRequest::add_file_to_generate() {
+  return file_to_generate_.Add();
+}
+ void CodeGeneratorRequest::add_file_to_generate(const ::std::string& value) {
+  file_to_generate_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+ void CodeGeneratorRequest::add_file_to_generate(const char* value) {
+  file_to_generate_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+ void CodeGeneratorRequest::add_file_to_generate(const char* value, size_t size) {
+  file_to_generate_.Add()->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_add_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+ const ::google::protobuf::RepeatedPtrField< ::std::string>&
+CodeGeneratorRequest::file_to_generate() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+  return file_to_generate_;
+}
+ ::google::protobuf::RepeatedPtrField< ::std::string>*
+CodeGeneratorRequest::mutable_file_to_generate() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+  return &file_to_generate_;
+}
+
+// optional string parameter = 2;
+ bool CodeGeneratorRequest::has_parameter() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+ void CodeGeneratorRequest::set_has_parameter() {
+  _has_bits_[0] |= 0x00000002u;
+}
+ void CodeGeneratorRequest::clear_has_parameter() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+ void CodeGeneratorRequest::clear_parameter() {
+  parameter_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_parameter();
+}
+ const ::std::string& CodeGeneratorRequest::parameter() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+  return parameter_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void CodeGeneratorRequest::set_parameter(const ::std::string& value) {
+  set_has_parameter();
+  parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+}
+ void CodeGeneratorRequest::set_parameter(const char* value) {
+  set_has_parameter();
+  parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+}
+ void CodeGeneratorRequest::set_parameter(const char* value, size_t size) {
+  set_has_parameter();
+  parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+}
+ ::std::string* CodeGeneratorRequest::mutable_parameter() {
+  set_has_parameter();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+  return parameter_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* CodeGeneratorRequest::release_parameter() {
+  clear_has_parameter();
+  return parameter_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void CodeGeneratorRequest::set_allocated_parameter(::std::string* parameter) {
+  if (parameter != NULL) {
+    set_has_parameter();
+  } else {
+    clear_has_parameter();
+  }
+  parameter_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), parameter);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+}
+
+// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+ int CodeGeneratorRequest::proto_file_size() const {
+  return proto_file_.size();
+}
+ void CodeGeneratorRequest::clear_proto_file() {
+  proto_file_.Clear();
+}
+ const ::google::protobuf::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+  return proto_file_.Get(index);
+}
+ ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::mutable_proto_file(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+  return proto_file_.Mutable(index);
+}
+ ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() {
+  // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+  return proto_file_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+CodeGeneratorRequest::proto_file() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+  return proto_file_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
+CodeGeneratorRequest::mutable_proto_file() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+  return &proto_file_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -1162,6 +1303,256 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// CodeGeneratorResponse_File
+
+// optional string name = 1;
+ bool CodeGeneratorResponse_File::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void CodeGeneratorResponse_File::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void CodeGeneratorResponse_File::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void CodeGeneratorResponse_File::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_name();
+}
+ const ::std::string& CodeGeneratorResponse_File::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void CodeGeneratorResponse_File::set_name(const ::std::string& value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+}
+ void CodeGeneratorResponse_File::set_name(const char* value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+}
+ void CodeGeneratorResponse_File::set_name(const char* value, size_t size) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+}
+ ::std::string* CodeGeneratorResponse_File::mutable_name() {
+  set_has_name();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* CodeGeneratorResponse_File::release_name() {
+  clear_has_name();
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void CodeGeneratorResponse_File::set_allocated_name(::std::string* name) {
+  if (name != NULL) {
+    set_has_name();
+  } else {
+    clear_has_name();
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+}
+
+// optional string insertion_point = 2;
+ bool CodeGeneratorResponse_File::has_insertion_point() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+ void CodeGeneratorResponse_File::set_has_insertion_point() {
+  _has_bits_[0] |= 0x00000002u;
+}
+ void CodeGeneratorResponse_File::clear_has_insertion_point() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+ void CodeGeneratorResponse_File::clear_insertion_point() {
+  insertion_point_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_insertion_point();
+}
+ const ::std::string& CodeGeneratorResponse_File::insertion_point() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+  return insertion_point_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void CodeGeneratorResponse_File::set_insertion_point(const ::std::string& value) {
+  set_has_insertion_point();
+  insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+}
+ void CodeGeneratorResponse_File::set_insertion_point(const char* value) {
+  set_has_insertion_point();
+  insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+}
+ void CodeGeneratorResponse_File::set_insertion_point(const char* value, size_t size) {
+  set_has_insertion_point();
+  insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+}
+ ::std::string* CodeGeneratorResponse_File::mutable_insertion_point() {
+  set_has_insertion_point();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+  return insertion_point_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* CodeGeneratorResponse_File::release_insertion_point() {
+  clear_has_insertion_point();
+  return insertion_point_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void CodeGeneratorResponse_File::set_allocated_insertion_point(::std::string* insertion_point) {
+  if (insertion_point != NULL) {
+    set_has_insertion_point();
+  } else {
+    clear_has_insertion_point();
+  }
+  insertion_point_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), insertion_point);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+}
+
+// optional string content = 15;
+ bool CodeGeneratorResponse_File::has_content() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+ void CodeGeneratorResponse_File::set_has_content() {
+  _has_bits_[0] |= 0x00000004u;
+}
+ void CodeGeneratorResponse_File::clear_has_content() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+ void CodeGeneratorResponse_File::clear_content() {
+  content_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_content();
+}
+ const ::std::string& CodeGeneratorResponse_File::content() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+  return content_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void CodeGeneratorResponse_File::set_content(const ::std::string& value) {
+  set_has_content();
+  content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+}
+ void CodeGeneratorResponse_File::set_content(const char* value) {
+  set_has_content();
+  content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+}
+ void CodeGeneratorResponse_File::set_content(const char* value, size_t size) {
+  set_has_content();
+  content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+}
+ ::std::string* CodeGeneratorResponse_File::mutable_content() {
+  set_has_content();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+  return content_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* CodeGeneratorResponse_File::release_content() {
+  clear_has_content();
+  return content_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void CodeGeneratorResponse_File::set_allocated_content(::std::string* content) {
+  if (content != NULL) {
+    set_has_content();
+  } else {
+    clear_has_content();
+  }
+  content_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), content);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+}
+
+// -------------------------------------------------------------------
+
+// CodeGeneratorResponse
+
+// optional string error = 1;
+ bool CodeGeneratorResponse::has_error() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void CodeGeneratorResponse::set_has_error() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void CodeGeneratorResponse::clear_has_error() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void CodeGeneratorResponse::clear_error() {
+  error_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_error();
+}
+ const ::std::string& CodeGeneratorResponse::error() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.error)
+  return error_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void CodeGeneratorResponse::set_error(const ::std::string& value) {
+  set_has_error();
+  error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.error)
+}
+ void CodeGeneratorResponse::set_error(const char* value) {
+  set_has_error();
+  error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.error)
+}
+ void CodeGeneratorResponse::set_error(const char* value, size_t size) {
+  set_has_error();
+  error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.error)
+}
+ ::std::string* CodeGeneratorResponse::mutable_error() {
+  set_has_error();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.error)
+  return error_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* CodeGeneratorResponse::release_error() {
+  clear_has_error();
+  return error_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void CodeGeneratorResponse::set_allocated_error(::std::string* error) {
+  if (error != NULL) {
+    set_has_error();
+  } else {
+    clear_has_error();
+  }
+  error_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), error);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.error)
+}
+
+// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+ int CodeGeneratorResponse::file_size() const {
+  return file_.size();
+}
+ void CodeGeneratorResponse::clear_file() {
+  file_.Clear();
+}
+ const ::google::protobuf::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::file(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.file)
+  return file_.Get(index);
+}
+ ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::mutable_file(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.file)
+  return file_.Mutable(index);
+}
+ ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() {
+  // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorResponse.file)
+  return file_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
+CodeGeneratorResponse::file() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file)
+  return file_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
+CodeGeneratorResponse::mutable_file() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorResponse.file)
+  return &file_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // @@protoc_insertion_point(namespace_scope)
 
diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h
index ad01700..ea48b8b 100644
--- a/src/google/protobuf/compiler/plugin.pb.h
+++ b/src/google/protobuf/compiler/plugin.pb.h
@@ -110,43 +110,43 @@
   // accessors -------------------------------------------------------
 
   // repeated string file_to_generate = 1;
-  inline int file_to_generate_size() const;
-  inline void clear_file_to_generate();
+  int file_to_generate_size() const;
+  void clear_file_to_generate();
   static const int kFileToGenerateFieldNumber = 1;
-  inline const ::std::string& file_to_generate(int index) const;
-  inline ::std::string* mutable_file_to_generate(int index);
-  inline void set_file_to_generate(int index, const ::std::string& value);
-  inline void set_file_to_generate(int index, const char* value);
-  inline void set_file_to_generate(int index, const char* value, size_t size);
-  inline ::std::string* add_file_to_generate();
-  inline void add_file_to_generate(const ::std::string& value);
-  inline void add_file_to_generate(const char* value);
-  inline void add_file_to_generate(const char* value, size_t size);
-  inline const ::google::protobuf::RepeatedPtrField< ::std::string>& file_to_generate() const;
-  inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_file_to_generate();
+  const ::std::string& file_to_generate(int index) const;
+  ::std::string* mutable_file_to_generate(int index);
+  void set_file_to_generate(int index, const ::std::string& value);
+  void set_file_to_generate(int index, const char* value);
+  void set_file_to_generate(int index, const char* value, size_t size);
+  ::std::string* add_file_to_generate();
+  void add_file_to_generate(const ::std::string& value);
+  void add_file_to_generate(const char* value);
+  void add_file_to_generate(const char* value, size_t size);
+  const ::google::protobuf::RepeatedPtrField< ::std::string>& file_to_generate() const;
+  ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_file_to_generate();
 
   // optional string parameter = 2;
-  inline bool has_parameter() const;
-  inline void clear_parameter();
+  bool has_parameter() const;
+  void clear_parameter();
   static const int kParameterFieldNumber = 2;
-  inline const ::std::string& parameter() const;
-  inline void set_parameter(const ::std::string& value);
-  inline void set_parameter(const char* value);
-  inline void set_parameter(const char* value, size_t size);
-  inline ::std::string* mutable_parameter();
-  inline ::std::string* release_parameter();
-  inline void set_allocated_parameter(::std::string* parameter);
+  const ::std::string& parameter() const;
+  void set_parameter(const ::std::string& value);
+  void set_parameter(const char* value);
+  void set_parameter(const char* value, size_t size);
+  ::std::string* mutable_parameter();
+  ::std::string* release_parameter();
+  void set_allocated_parameter(::std::string* parameter);
 
   // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
-  inline int proto_file_size() const;
-  inline void clear_proto_file();
+  int proto_file_size() const;
+  void clear_proto_file();
   static const int kProtoFileFieldNumber = 15;
-  inline const ::google::protobuf::FileDescriptorProto& proto_file(int index) const;
-  inline ::google::protobuf::FileDescriptorProto* mutable_proto_file(int index);
-  inline ::google::protobuf::FileDescriptorProto* add_proto_file();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+  const ::google::protobuf::FileDescriptorProto& proto_file(int index) const;
+  ::google::protobuf::FileDescriptorProto* mutable_proto_file(int index);
+  ::google::protobuf::FileDescriptorProto* add_proto_file();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
       proto_file() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
       mutable_proto_file();
 
   // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest)
@@ -234,40 +234,40 @@
   // accessors -------------------------------------------------------
 
   // optional string name = 1;
-  inline bool has_name() const;
-  inline void clear_name();
+  bool has_name() const;
+  void clear_name();
   static const int kNameFieldNumber = 1;
-  inline const ::std::string& name() const;
-  inline void set_name(const ::std::string& value);
-  inline void set_name(const char* value);
-  inline void set_name(const char* value, size_t size);
-  inline ::std::string* mutable_name();
-  inline ::std::string* release_name();
-  inline void set_allocated_name(::std::string* name);
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  void set_name(const char* value);
+  void set_name(const char* value, size_t size);
+  ::std::string* mutable_name();
+  ::std::string* release_name();
+  void set_allocated_name(::std::string* name);
 
   // optional string insertion_point = 2;
-  inline bool has_insertion_point() const;
-  inline void clear_insertion_point();
+  bool has_insertion_point() const;
+  void clear_insertion_point();
   static const int kInsertionPointFieldNumber = 2;
-  inline const ::std::string& insertion_point() const;
-  inline void set_insertion_point(const ::std::string& value);
-  inline void set_insertion_point(const char* value);
-  inline void set_insertion_point(const char* value, size_t size);
-  inline ::std::string* mutable_insertion_point();
-  inline ::std::string* release_insertion_point();
-  inline void set_allocated_insertion_point(::std::string* insertion_point);
+  const ::std::string& insertion_point() const;
+  void set_insertion_point(const ::std::string& value);
+  void set_insertion_point(const char* value);
+  void set_insertion_point(const char* value, size_t size);
+  ::std::string* mutable_insertion_point();
+  ::std::string* release_insertion_point();
+  void set_allocated_insertion_point(::std::string* insertion_point);
 
   // optional string content = 15;
-  inline bool has_content() const;
-  inline void clear_content();
+  bool has_content() const;
+  void clear_content();
   static const int kContentFieldNumber = 15;
-  inline const ::std::string& content() const;
-  inline void set_content(const ::std::string& value);
-  inline void set_content(const char* value);
-  inline void set_content(const char* value, size_t size);
-  inline ::std::string* mutable_content();
-  inline ::std::string* release_content();
-  inline void set_allocated_content(::std::string* content);
+  const ::std::string& content() const;
+  void set_content(const ::std::string& value);
+  void set_content(const char* value);
+  void set_content(const char* value, size_t size);
+  ::std::string* mutable_content();
+  ::std::string* release_content();
+  void set_allocated_content(::std::string* content);
 
   // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File)
  private:
@@ -360,27 +360,27 @@
   // accessors -------------------------------------------------------
 
   // optional string error = 1;
-  inline bool has_error() const;
-  inline void clear_error();
+  bool has_error() const;
+  void clear_error();
   static const int kErrorFieldNumber = 1;
-  inline const ::std::string& error() const;
-  inline void set_error(const ::std::string& value);
-  inline void set_error(const char* value);
-  inline void set_error(const char* value, size_t size);
-  inline ::std::string* mutable_error();
-  inline ::std::string* release_error();
-  inline void set_allocated_error(::std::string* error);
+  const ::std::string& error() const;
+  void set_error(const ::std::string& value);
+  void set_error(const char* value);
+  void set_error(const char* value, size_t size);
+  ::std::string* mutable_error();
+  ::std::string* release_error();
+  void set_allocated_error(::std::string* error);
 
   // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
-  inline int file_size() const;
-  inline void clear_file();
+  int file_size() const;
+  void clear_file();
   static const int kFileFieldNumber = 15;
-  inline const ::google::protobuf::compiler::CodeGeneratorResponse_File& file(int index) const;
-  inline ::google::protobuf::compiler::CodeGeneratorResponse_File* mutable_file(int index);
-  inline ::google::protobuf::compiler::CodeGeneratorResponse_File* add_file();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
+  const ::google::protobuf::compiler::CodeGeneratorResponse_File& file(int index) const;
+  ::google::protobuf::compiler::CodeGeneratorResponse_File* mutable_file(int index);
+  ::google::protobuf::compiler::CodeGeneratorResponse_File* add_file();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
       file() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
       mutable_file();
 
   // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse)
@@ -405,6 +405,7 @@
 
 // ===================================================================
 
+#if !PROTOBUF_INLINE_NOT_IN_HEADERS
 // CodeGeneratorRequest
 
 // repeated string file_to_generate = 1;
@@ -794,6 +795,7 @@
   return &file_;
 }
 
+#endif  // !PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // @@protoc_insertion_point(namespace_scope)
 
@@ -801,15 +803,6 @@
 }  // namespace protobuf
 }  // namespace google
 
-#ifndef SWIG
-namespace google {
-namespace protobuf {
-
-
-}  // namespace protobuf
-}  // namespace google
-#endif  // SWIG
-
 // @@protoc_insertion_point(global_scope)
 
 #endif  // PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED
diff --git a/src/google/protobuf/compiler/plugin.proto b/src/google/protobuf/compiler/plugin.proto
index e627289..acaee1f 100644
--- a/src/google/protobuf/compiler/plugin.proto
+++ b/src/google/protobuf/compiler/plugin.proto
@@ -49,6 +49,8 @@
 option java_package = "com.google.protobuf.compiler";
 option java_outer_classname = "PluginProtos";
 
+option go_package = "plugin_go";
+
 import "google/protobuf/descriptor.proto";
 
 // An encoded CodeGeneratorRequest is written to the plugin's stdin.
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index b8dd198..bfdacd9 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -783,7 +783,7 @@
 
 inline const FieldDescriptor* FileDescriptorTables::FindFieldByNumber(
     const Descriptor* parent, int number) const {
-  return FindPtrOrNull(fields_by_number_, make_pair(parent, number));
+  return FindPtrOrNull(fields_by_number_, std::make_pair(parent, number));
 }
 
 inline const FieldDescriptor* FileDescriptorTables::FindFieldByLowercaseName(
@@ -800,7 +800,7 @@
 
 inline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber(
     const EnumDescriptor* parent, int number) const {
-  return FindPtrOrNull(enum_values_by_number_, make_pair(parent, number));
+  return FindPtrOrNull(enum_values_by_number_, std::make_pair(parent, number));
 }
 
 inline const EnumValueDescriptor*
@@ -808,8 +808,8 @@
     const EnumDescriptor* parent, int number) const {
   // First try, with map of compiled-in values.
   {
-    const EnumValueDescriptor* desc = FindPtrOrNull(
-        enum_values_by_number_, make_pair(parent, number));
+    const EnumValueDescriptor* desc =
+        FindPtrOrNull(enum_values_by_number_, std::make_pair(parent, number));
     if (desc != NULL) {
       return desc;
     }
@@ -818,7 +818,7 @@
   {
     ReaderMutexLock l(&unknown_enum_values_mu_);
     const EnumValueDescriptor* desc = FindPtrOrNull(
-        unknown_enum_values_by_number_, make_pair(parent, number));
+        unknown_enum_values_by_number_, std::make_pair(parent, number));
     if (desc != NULL) {
       return desc;
     }
@@ -828,7 +828,7 @@
   {
     WriterMutexLock l(&unknown_enum_values_mu_);
     const EnumValueDescriptor* desc = FindPtrOrNull(
-        unknown_enum_values_by_number_, make_pair(parent, number));
+        unknown_enum_values_by_number_, std::make_pair(parent, number));
     if (desc != NULL) {
       return desc;
     }
@@ -850,8 +850,7 @@
     result->type_ = parent;
     result->options_ = &EnumValueOptions::default_instance();
     InsertIfNotPresent(&unknown_enum_values_by_number_,
-                       make_pair(parent, number),
-                       result);
+                       std::make_pair(parent, number), result);
     return result;
   }
 }
@@ -859,13 +858,13 @@
 
 inline const FieldDescriptor* DescriptorPool::Tables::FindExtension(
     const Descriptor* extendee, int number) {
-  return FindPtrOrNull(extensions_, make_pair(extendee, number));
+  return FindPtrOrNull(extensions_, std::make_pair(extendee, number));
 }
 
 inline void DescriptorPool::Tables::FindAllExtensions(
     const Descriptor* extendee, vector<const FieldDescriptor*>* out) const {
   ExtensionsGroupedByDescriptorMap::const_iterator it =
-      extensions_.lower_bound(make_pair(extendee, 0));
+      extensions_.lower_bound(std::make_pair(extendee, 0));
   for (; it != extensions_.end() && it->first.first == extendee; ++it) {
     out->push_back(it->second);
   }
@@ -993,7 +992,7 @@
 const SourceCodeInfo_Location* FileDescriptorTables::GetSourceLocation(
     const vector<int>& path, const SourceCodeInfo* info) const {
   pair<const FileDescriptorTables*, const SourceCodeInfo*> p(
-      make_pair(this, info));
+      std::make_pair(this, info));
   locations_by_path_once_.Init(&FileDescriptorTables::BuildLocationsByPath, &p);
   return FindPtrOrNull(locations_by_path_, Join(path, ","));
 }
@@ -1929,9 +1928,9 @@
   return !all_options.empty();
 }
 
-template<typename DescType>
 class SourceLocationCommentPrinter {
  public:
+  template<typename DescType>
   SourceLocationCommentPrinter(const DescType* desc,
                                const string& prefix,
                                const DebugStringOptions& options)
@@ -1941,9 +1940,27 @@
     have_source_loc_ = options.include_comments &&
         desc->GetSourceLocation(&source_loc_);
   }
+  SourceLocationCommentPrinter(const FileDescriptor* file,
+                               const vector<int>& path,
+                               const string& prefix,
+                               const DebugStringOptions& options)
+      : options_(options), prefix_(prefix) {
+    // Perform the SourceLocation lookup only if we're including user comments,
+    // because the lookup is fairly expensive.
+    have_source_loc_ = options.include_comments &&
+        file->GetSourceLocation(path, &source_loc_);
+  }
   void AddPreComment(string* output) {
-    if (have_source_loc_ && source_loc_.leading_comments.size() > 0) {
-      *output += FormatComment(source_loc_.leading_comments);
+    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]);
+        *output += "\n";
+      }
+      // Attached leading comments.
+      if (!source_loc_.leading_comments.empty()) {
+        *output += FormatComment(source_loc_.leading_comments);
+      }
     }
   }
   void AddPostComment(string* output) {
@@ -1967,7 +1984,6 @@
   }
 
  private:
-  const DescType* desc_;
   bool have_source_loc_;
   SourceLocation source_loc_;
   DebugStringOptions options_;
@@ -1984,10 +2000,18 @@
 string FileDescriptor::DebugStringWithOptions(
     const DebugStringOptions& debug_string_options) const {
   string contents;
-  strings::SubstituteAndAppend(&contents, "syntax = \"$0\";\n\n",
-                               SyntaxName(syntax()));
+  {
+    vector<int> path;
+    path.push_back(FileDescriptorProto::kSyntaxFieldNumber);
+    SourceLocationCommentPrinter syntax_comment(
+        this, path, "", debug_string_options);
+    syntax_comment.AddPreComment(&contents);
+    strings::SubstituteAndAppend(&contents, "syntax = \"$0\";\n\n",
+                                 SyntaxName(syntax()));
+    syntax_comment.AddPostComment(&contents);
+  }
 
-  SourceLocationCommentPrinter<FileDescriptor>
+  SourceLocationCommentPrinter
       comment_printer(this, "", debug_string_options);
   comment_printer.AddPreComment(&contents);
 
@@ -2012,7 +2036,13 @@
   }
 
   if (!package().empty()) {
+    vector<int> path;
+    path.push_back(FileDescriptorProto::kPackageFieldNumber);
+    SourceLocationCommentPrinter package_comment(
+        this, path, "", debug_string_options);
+    package_comment.AddPreComment(&contents);
     strings::SubstituteAndAppend(&contents, "package $0;\n\n", package());
+    package_comment.AddPostComment(&contents);
   }
 
   if (FormatLineOptions(0, options(), &contents)) {
@@ -2087,7 +2117,7 @@
   string prefix(depth * 2, ' ');
   ++depth;
 
-  SourceLocationCommentPrinter<Descriptor>
+  SourceLocationCommentPrinter
       comment_printer(this, prefix, debug_string_options);
   comment_printer.AddPreComment(contents);
 
@@ -2217,7 +2247,7 @@
     label.push_back(' ');
   }
 
-  SourceLocationCommentPrinter<FieldDescriptor>
+  SourceLocationCommentPrinter
       comment_printer(this, prefix, debug_string_options);
   comment_printer.AddPreComment(contents);
 
@@ -2274,7 +2304,7 @@
                                   debug_string_options) const {
   string prefix(depth * 2, ' ');
   ++depth;
-  SourceLocationCommentPrinter<OneofDescriptor>
+  SourceLocationCommentPrinter
       comment_printer(this, prefix, debug_string_options);
   comment_printer.AddPreComment(contents);
   strings::SubstituteAndAppend(
@@ -2305,7 +2335,7 @@
   string prefix(depth * 2, ' ');
   ++depth;
 
-  SourceLocationCommentPrinter<EnumDescriptor>
+  SourceLocationCommentPrinter
       comment_printer(this, prefix, debug_string_options);
   comment_printer.AddPreComment(contents);
 
@@ -2339,7 +2369,7 @@
                                       debug_string_options) const {
   string prefix(depth * 2, ' ');
 
-  SourceLocationCommentPrinter<EnumValueDescriptor>
+  SourceLocationCommentPrinter
       comment_printer(this, prefix, debug_string_options);
   comment_printer.AddPreComment(contents);
 
@@ -2370,7 +2400,7 @@
 void ServiceDescriptor::DebugString(string *contents,
                                     const DebugStringOptions&
                                     debug_string_options) const {
-  SourceLocationCommentPrinter<ServiceDescriptor>
+  SourceLocationCommentPrinter
       comment_printer(this, /* prefix */ "", debug_string_options);
   comment_printer.AddPreComment(contents);
 
@@ -2405,7 +2435,7 @@
   string prefix(depth * 2, ' ');
   ++depth;
 
-  SourceLocationCommentPrinter<MethodDescriptor>
+  SourceLocationCommentPrinter
       comment_printer(this, prefix, debug_string_options);
   comment_printer.AddPreComment(contents);
 
@@ -2445,6 +2475,9 @@
 
         out_location->leading_comments = loc->leading_comments();
         out_location->trailing_comments = loc->trailing_comments();
+        out_location->leading_detached_comments.assign(
+            loc->leading_detached_comments().begin(),
+            loc->leading_detached_comments().end());
         return true;
       }
     }
@@ -3697,7 +3730,6 @@
              "Unrecognized syntax: " + proto.syntax());
   }
 
-
   result->name_ = tables_->AllocateString(proto.name());
   if (proto.has_package()) {
     result->package_ = tables_->AllocateString(proto.package());
@@ -5110,7 +5142,7 @@
     case FieldDescriptor::TYPE_SFIXED64:
       // Legal cases
       break;
-    // Do not add a default, so that the compiler will complian when new types
+    // Do not add a default, so that the compiler will complain when new types
     // are added.
   }
 
@@ -5123,7 +5155,7 @@
   for (int i = 0; i < message->nested_type_count(); ++i) {
     const Descriptor* nested = message->nested_type(i);
     pair<map<string, const Descriptor*>::iterator, bool> result =
-        seen_types.insert(make_pair(nested->name(), nested));
+        seen_types.insert(std::make_pair(nested->name(), nested));
     if (!result.second) {
       if (result.first->second->options().map_entry() ||
           nested->options().map_entry()) {
diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h
index 52df47f..0e264f5 100644
--- a/src/google/protobuf/descriptor.h
+++ b/src/google/protobuf/descriptor.h
@@ -117,8 +117,10 @@
   int end_column;
 
   // Doc comments found at the source location.
+  // See the comments in SourceCodeInfo.Location (descriptor.proto) for details.
   string leading_comments;
   string trailing_comments;
+  vector<string> leading_detached_comments;
 };
 
 // Options when generating machine-parsable output from a descriptor with
@@ -312,7 +314,7 @@
 
   // Walks up the descriptor tree to generate the source location path
   // to this descriptor from the file root.
-  void GetLocationPath(vector<int>* output) const;
+  void GetLocationPath(std::vector<int>* output) const;
 
   const string* name_;
   const string* full_name_;
@@ -594,7 +596,7 @@
 
   // Walks up the descriptor tree to generate the source location path
   // to this descriptor from the file root.
-  void GetLocationPath(vector<int>* output) const;
+  void GetLocationPath(std::vector<int>* output) const;
 
   const string* name_;
   const string* full_name_;
@@ -688,7 +690,7 @@
 
   // Walks up the descriptor tree to generate the source location path
   // to this descriptor from the file root.
-  void GetLocationPath(vector<int>* output) const;
+  void GetLocationPath(std::vector<int>* output) const;
 
   const string* name_;
   const string* full_name_;
@@ -790,7 +792,7 @@
 
   // Walks up the descriptor tree to generate the source location path
   // to this descriptor from the file root.
-  void GetLocationPath(vector<int>* output) const;
+  void GetLocationPath(std::vector<int>* output) const;
 
   const string* name_;
   const string* full_name_;
@@ -874,7 +876,7 @@
 
   // Walks up the descriptor tree to generate the source location path
   // to this descriptor from the file root.
-  void GetLocationPath(vector<int>* output) const;
+  void GetLocationPath(std::vector<int>* output) const;
 
   const string* name_;
   const string* full_name_;
@@ -949,7 +951,7 @@
 
   // Walks up the descriptor tree to generate the source location path
   // to this descriptor from the file root.
-  void GetLocationPath(vector<int>* output) const;
+  void GetLocationPath(std::vector<int>* output) const;
 
   const string* name_;
   const string* full_name_;
@@ -1028,7 +1030,7 @@
 
   // Walks up the descriptor tree to generate the source location path
   // to this descriptor from the file root.
-  void GetLocationPath(vector<int>* output) const;
+  void GetLocationPath(std::vector<int>* output) const;
 
   const string* name_;
   const string* full_name_;
@@ -1173,17 +1175,15 @@
   // this file declaration (namely, the empty path).
   bool GetSourceLocation(SourceLocation* out_location) const;
 
- private:
-  // Source Location ---------------------------------------------------
-
   // Updates |*out_location| to the source location of the complete
   // extent of the declaration or declaration-part denoted by |path|.
   // Returns false and leaves |*out_location| unchanged iff location
   // information was not available.  (See SourceCodeInfo for
   // description of path encoding.)
-  bool GetSourceLocation(const vector<int>& path,
+  bool GetSourceLocation(const std::vector<int>& path,
                          SourceLocation* out_location) const;
 
+ private:
   typedef FileOptions OptionsType;
 
   const string* name_;
@@ -1326,7 +1326,7 @@
   // found: extensions defined in the fallback database might not be found
   // depending on the database implementation.
   void FindAllExtensions(const Descriptor* extendee,
-                         vector<const FieldDescriptor*>* out) const;
+                         std::vector<const FieldDescriptor*>* out) const;
 
   // Building descriptors --------------------------------------------
 
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index 97121fa..9556206 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -289,7 +289,7 @@
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _internal_metadata_),
       -1);
   FileOptions_descriptor_ = file->message_type(9);
-  static const int FileOptions_offsets_[13] = {
+  static const int FileOptions_offsets_[14] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_),
@@ -302,6 +302,7 @@
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, py_generic_services_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, deprecated_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_enable_arenas_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, objc_class_prefix_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, uninterpreted_option_),
   };
   FileOptions_reflection_ =
@@ -474,11 +475,12 @@
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _internal_metadata_),
       -1);
   SourceCodeInfo_Location_descriptor_ = SourceCodeInfo_descriptor_->nested_type(0);
-  static const int SourceCodeInfo_Location_offsets_[4] = {
+  static const int SourceCodeInfo_Location_offsets_[5] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, path_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, span_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, leading_comments_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, trailing_comments_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, leading_detached_comments_),
   };
   SourceCodeInfo_Location_reflection_ =
     ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
@@ -661,7 +663,7 @@
     "t_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google.p"
     "rotobuf.MethodOptions\022\037\n\020client_streamin"
     "g\030\005 \001(\010:\005false\022\037\n\020server_streaming\030\006 \001(\010"
-    ":\005false\"\314\004\n\013FileOptions\022\024\n\014java_package\030"
+    ":\005false\"\347\004\n\013FileOptions\022\024\n\014java_package\030"
     "\001 \001(\t\022\034\n\024java_outer_classname\030\010 \001(\t\022\"\n\023j"
     "ava_multiple_files\030\n \001(\010:\005false\022,\n\035java_"
     "generate_equals_and_hash\030\024 \001(\010:\005false\022%\n"
@@ -672,49 +674,51 @@
     "alse\022$\n\025java_generic_services\030\021 \001(\010:\005fal"
     "se\022\"\n\023py_generic_services\030\022 \001(\010:\005false\022\031"
     "\n\ndeprecated\030\027 \001(\010:\005false\022\037\n\020cc_enable_a"
-    "renas\030\037 \001(\010:\005false\022C\n\024uninterpreted_opti"
+    "renas\030\037 \001(\010:\005false\022\031\n\021objc_class_prefix\030"
+    "$ \001(\t\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.g"
+    "oogle.protobuf.UninterpretedOption\":\n\014Op"
+    "timizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014"
+    "LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\346\001\n\016MessageOpt"
+    "ions\022&\n\027message_set_wire_format\030\001 \001(\010:\005f"
+    "alse\022.\n\037no_standard_descriptor_accessor\030"
+    "\002 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022"
+    "\021\n\tmap_entry\030\007 \001(\010\022C\n\024uninterpreted_opti"
     "on\030\347\007 \003(\0132$.google.protobuf.Uninterprete"
-    "dOption\":\n\014OptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tCO"
-    "DE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\346"
-    "\001\n\016MessageOptions\022&\n\027message_set_wire_fo"
-    "rmat\030\001 \001(\010:\005false\022.\n\037no_standard_descrip"
-    "tor_accessor\030\002 \001(\010:\005false\022\031\n\ndeprecated\030"
-    "\003 \001(\010:\005false\022\021\n\tmap_entry\030\007 \001(\010\022C\n\024unint"
-    "erpreted_option\030\347\007 \003(\0132$.google.protobuf"
-    ".UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\240\002\n\014Fiel"
-    "dOptions\022:\n\005ctype\030\001 \001(\0162#.google.protobu"
-    "f.FieldOptions.CType:\006STRING\022\016\n\006packed\030\002"
-    " \001(\010\022\023\n\004lazy\030\005 \001(\010:\005false\022\031\n\ndeprecated\030"
-    "\003 \001(\010:\005false\022\023\n\004weak\030\n \001(\010:\005false\022C\n\024uni"
-    "nterpreted_option\030\347\007 \003(\0132$.google.protob"
-    "uf.UninterpretedOption\"/\n\005CType\022\n\n\006STRIN"
-    "G\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_PIECE\020\002*\t\010\350\007\020\200\200\200"
-    "\200\002\"\215\001\n\013EnumOptions\022\023\n\013allow_alias\030\002 \001(\010\022"
-    "\031\n\ndeprecated\030\003 \001(\010:\005false\022C\n\024uninterpre"
-    "ted_option\030\347\007 \003(\0132$.google.protobuf.Unin"
-    "terpretedOption*\t\010\350\007\020\200\200\200\200\002\"}\n\020EnumValueO"
-    "ptions\022\031\n\ndeprecated\030\001 \001(\010:\005false\022C\n\024uni"
-    "nterpreted_option\030\347\007 \003(\0132$.google.protob"
-    "uf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"{\n\016Ser"
-    "viceOptions\022\031\n\ndeprecated\030! \001(\010:\005false\022C"
-    "\n\024uninterpreted_option\030\347\007 \003(\0132$.google.p"
-    "rotobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"z"
-    "\n\rMethodOptions\022\031\n\ndeprecated\030! \001(\010:\005fal"
-    "se\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goog"
-    "le.protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200"
-    "\200\002\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003(\013"
-    "2-.google.protobuf.UninterpretedOption.N"
-    "amePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022pos"
-    "itive_int_value\030\004 \001(\004\022\032\n\022negative_int_va"
-    "lue\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014strin"
-    "g_value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323"
-    "\n\010NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_exte"
-    "nsion\030\002 \002(\010\"\261\001\n\016SourceCodeInfo\022:\n\010locati"
-    "on\030\001 \003(\0132(.google.protobuf.SourceCodeInf"
-    "o.Location\032c\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001"
-    "\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020leading_comments\030\003"
-    " \001(\t\022\031\n\021trailing_comments\030\004 \001(\tB)\n\023com.g"
-    "oogle.protobufB\020DescriptorProtosH\001", 4554);
+    "dOption*\t\010\350\007\020\200\200\200\200\002\"\240\002\n\014FieldOptions\022:\n\005c"
+    "type\030\001 \001(\0162#.google.protobuf.FieldOption"
+    "s.CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\023\n\004lazy\030"
+    "\005 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022"
+    "\023\n\004weak\030\n \001(\010:\005false\022C\n\024uninterpreted_op"
+    "tion\030\347\007 \003(\0132$.google.protobuf.Uninterpre"
+    "tedOption\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001"
+    "\022\020\n\014STRING_PIECE\020\002*\t\010\350\007\020\200\200\200\200\002\"\215\001\n\013EnumOp"
+    "tions\022\023\n\013allow_alias\030\002 \001(\010\022\031\n\ndeprecated"
+    "\030\003 \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007"
+    " \003(\0132$.google.protobuf.UninterpretedOpti"
+    "on*\t\010\350\007\020\200\200\200\200\002\"}\n\020EnumValueOptions\022\031\n\ndep"
+    "recated\030\001 \001(\010:\005false\022C\n\024uninterpreted_op"
+    "tion\030\347\007 \003(\0132$.google.protobuf.Uninterpre"
+    "tedOption*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031"
+    "\n\ndeprecated\030! \001(\010:\005false\022C\n\024uninterpret"
+    "ed_option\030\347\007 \003(\0132$.google.protobuf.Unint"
+    "erpretedOption*\t\010\350\007\020\200\200\200\200\002\"z\n\rMethodOptio"
+    "ns\022\031\n\ndeprecated\030! \001(\010:\005false\022C\n\024uninter"
+    "preted_option\030\347\007 \003(\0132$.google.protobuf.U"
+    "ninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023Uninte"
+    "rpretedOption\022;\n\004name\030\002 \003(\0132-.google.pro"
+    "tobuf.UninterpretedOption.NamePart\022\030\n\020id"
+    "entifier_value\030\003 \001(\t\022\032\n\022positive_int_val"
+    "ue\030\004 \001(\004\022\032\n\022negative_int_value\030\005 \001(\003\022\024\n\014"
+    "double_value\030\006 \001(\001\022\024\n\014string_value\030\007 \001(\014"
+    "\022\027\n\017aggregate_value\030\010 \001(\t\0323\n\010NamePart\022\021\n"
+    "\tname_part\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010\"\325"
+    "\001\n\016SourceCodeInfo\022:\n\010location\030\001 \003(\0132(.go"
+    "ogle.protobuf.SourceCodeInfo.Location\032\206\001"
+    "\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003"
+    "(\005B\002\020\001\022\030\n\020leading_comments\030\003 \001(\t\022\031\n\021trai"
+    "ling_comments\030\004 \001(\t\022!\n\031leading_detached_"
+    "comments\030\006 \003(\tB)\n\023com.google.protobufB\020D"
+    "escriptorProtosH\001", 4617);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
   FileDescriptorSet::default_instance_ = new FileDescriptorSet();
@@ -1009,6 +1013,40 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// FileDescriptorSet
+
+// repeated .google.protobuf.FileDescriptorProto file = 1;
+ int FileDescriptorSet::file_size() const {
+  return file_.size();
+}
+ void FileDescriptorSet::clear_file() {
+  file_.Clear();
+}
+ const ::google::protobuf::FileDescriptorProto& FileDescriptorSet::file(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorSet.file)
+  return file_.Get(index);
+}
+ ::google::protobuf::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorSet.file)
+  return file_.Mutable(index);
+}
+ ::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() {
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorSet.file)
+  return file_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+FileDescriptorSet::file() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorSet.file)
+  return file_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
+FileDescriptorSet::mutable_file() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorSet.file)
+  return &file_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -1771,6 +1809,489 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// FileDescriptorProto
+
+// optional string name = 1;
+ bool FileDescriptorProto::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void FileDescriptorProto::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void FileDescriptorProto::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void FileDescriptorProto::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_name();
+}
+ const ::std::string& FileDescriptorProto::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.name)
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FileDescriptorProto::set_name(const ::std::string& value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.name)
+}
+ void FileDescriptorProto::set_name(const char* value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.name)
+}
+ void FileDescriptorProto::set_name(const char* value, size_t size) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.name)
+}
+ ::std::string* FileDescriptorProto::mutable_name() {
+  set_has_name();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* FileDescriptorProto::release_name() {
+  clear_has_name();
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FileDescriptorProto::set_allocated_name(::std::string* name) {
+  if (name != NULL) {
+    set_has_name();
+  } else {
+    clear_has_name();
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.name)
+}
+
+// optional string package = 2;
+ bool FileDescriptorProto::has_package() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+ void FileDescriptorProto::set_has_package() {
+  _has_bits_[0] |= 0x00000002u;
+}
+ void FileDescriptorProto::clear_has_package() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+ void FileDescriptorProto::clear_package() {
+  package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_package();
+}
+ const ::std::string& FileDescriptorProto::package() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.package)
+  return package_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FileDescriptorProto::set_package(const ::std::string& value) {
+  set_has_package();
+  package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.package)
+}
+ void FileDescriptorProto::set_package(const char* value) {
+  set_has_package();
+  package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.package)
+}
+ void FileDescriptorProto::set_package(const char* value, size_t size) {
+  set_has_package();
+  package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.package)
+}
+ ::std::string* FileDescriptorProto::mutable_package() {
+  set_has_package();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.package)
+  return package_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* FileDescriptorProto::release_package() {
+  clear_has_package();
+  return package_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FileDescriptorProto::set_allocated_package(::std::string* package) {
+  if (package != NULL) {
+    set_has_package();
+  } else {
+    clear_has_package();
+  }
+  package_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), package);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.package)
+}
+
+// repeated string dependency = 3;
+ int FileDescriptorProto::dependency_size() const {
+  return dependency_.size();
+}
+ void FileDescriptorProto::clear_dependency() {
+  dependency_.Clear();
+}
+ const ::std::string& FileDescriptorProto::dependency(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.dependency)
+  return dependency_.Get(index);
+}
+ ::std::string* FileDescriptorProto::mutable_dependency(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.dependency)
+  return dependency_.Mutable(index);
+}
+ void FileDescriptorProto::set_dependency(int index, const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency)
+  dependency_.Mutable(index)->assign(value);
+}
+ void FileDescriptorProto::set_dependency(int index, const char* value) {
+  dependency_.Mutable(index)->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.dependency)
+}
+ void FileDescriptorProto::set_dependency(int index, const char* value, size_t size) {
+  dependency_.Mutable(index)->assign(
+    reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.dependency)
+}
+ ::std::string* FileDescriptorProto::add_dependency() {
+  return dependency_.Add();
+}
+ void FileDescriptorProto::add_dependency(const ::std::string& value) {
+  dependency_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
+}
+ void FileDescriptorProto::add_dependency(const char* value) {
+  dependency_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add_char:google.protobuf.FileDescriptorProto.dependency)
+}
+ void FileDescriptorProto::add_dependency(const char* value, size_t size) {
+  dependency_.Add()->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_add_pointer:google.protobuf.FileDescriptorProto.dependency)
+}
+ const ::google::protobuf::RepeatedPtrField< ::std::string>&
+FileDescriptorProto::dependency() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.dependency)
+  return dependency_;
+}
+ ::google::protobuf::RepeatedPtrField< ::std::string>*
+FileDescriptorProto::mutable_dependency() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.dependency)
+  return &dependency_;
+}
+
+// repeated int32 public_dependency = 10;
+ int FileDescriptorProto::public_dependency_size() const {
+  return public_dependency_.size();
+}
+ void FileDescriptorProto::clear_public_dependency() {
+  public_dependency_.Clear();
+}
+ ::google::protobuf::int32 FileDescriptorProto::public_dependency(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.public_dependency)
+  return public_dependency_.Get(index);
+}
+ void FileDescriptorProto::set_public_dependency(int index, ::google::protobuf::int32 value) {
+  public_dependency_.Set(index, value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.public_dependency)
+}
+ void FileDescriptorProto::add_public_dependency(::google::protobuf::int32 value) {
+  public_dependency_.Add(value);
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.public_dependency)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+FileDescriptorProto::public_dependency() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.public_dependency)
+  return public_dependency_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+FileDescriptorProto::mutable_public_dependency() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.public_dependency)
+  return &public_dependency_;
+}
+
+// repeated int32 weak_dependency = 11;
+ int FileDescriptorProto::weak_dependency_size() const {
+  return weak_dependency_.size();
+}
+ void FileDescriptorProto::clear_weak_dependency() {
+  weak_dependency_.Clear();
+}
+ ::google::protobuf::int32 FileDescriptorProto::weak_dependency(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.weak_dependency)
+  return weak_dependency_.Get(index);
+}
+ void FileDescriptorProto::set_weak_dependency(int index, ::google::protobuf::int32 value) {
+  weak_dependency_.Set(index, value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.weak_dependency)
+}
+ void FileDescriptorProto::add_weak_dependency(::google::protobuf::int32 value) {
+  weak_dependency_.Add(value);
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.weak_dependency)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+FileDescriptorProto::weak_dependency() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.weak_dependency)
+  return weak_dependency_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+FileDescriptorProto::mutable_weak_dependency() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.weak_dependency)
+  return &weak_dependency_;
+}
+
+// repeated .google.protobuf.DescriptorProto message_type = 4;
+ int FileDescriptorProto::message_type_size() const {
+  return message_type_.size();
+}
+ void FileDescriptorProto::clear_message_type() {
+  message_type_.Clear();
+}
+ const ::google::protobuf::DescriptorProto& FileDescriptorProto::message_type(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.message_type)
+  return message_type_.Get(index);
+}
+ ::google::protobuf::DescriptorProto* FileDescriptorProto::mutable_message_type(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.message_type)
+  return message_type_.Mutable(index);
+}
+ ::google::protobuf::DescriptorProto* FileDescriptorProto::add_message_type() {
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.message_type)
+  return message_type_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+FileDescriptorProto::message_type() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.message_type)
+  return message_type_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
+FileDescriptorProto::mutable_message_type() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.message_type)
+  return &message_type_;
+}
+
+// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+ int FileDescriptorProto::enum_type_size() const {
+  return enum_type_.size();
+}
+ void FileDescriptorProto::clear_enum_type() {
+  enum_type_.Clear();
+}
+ const ::google::protobuf::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.enum_type)
+  return enum_type_.Get(index);
+}
+ ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::mutable_enum_type(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.enum_type)
+  return enum_type_.Mutable(index);
+}
+ ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::add_enum_type() {
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.enum_type)
+  return enum_type_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+FileDescriptorProto::enum_type() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.enum_type)
+  return enum_type_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
+FileDescriptorProto::mutable_enum_type() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.enum_type)
+  return &enum_type_;
+}
+
+// repeated .google.protobuf.ServiceDescriptorProto service = 6;
+ int FileDescriptorProto::service_size() const {
+  return service_.size();
+}
+ void FileDescriptorProto::clear_service() {
+  service_.Clear();
+}
+ const ::google::protobuf::ServiceDescriptorProto& FileDescriptorProto::service(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.service)
+  return service_.Get(index);
+}
+ ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.service)
+  return service_.Mutable(index);
+}
+ ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::add_service() {
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.service)
+  return service_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
+FileDescriptorProto::service() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.service)
+  return service_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
+FileDescriptorProto::mutable_service() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.service)
+  return &service_;
+}
+
+// repeated .google.protobuf.FieldDescriptorProto extension = 7;
+ int FileDescriptorProto::extension_size() const {
+  return extension_.size();
+}
+ void FileDescriptorProto::clear_extension() {
+  extension_.Clear();
+}
+ const ::google::protobuf::FieldDescriptorProto& FileDescriptorProto::extension(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.extension)
+  return extension_.Get(index);
+}
+ ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.extension)
+  return extension_.Mutable(index);
+}
+ ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::add_extension() {
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.extension)
+  return extension_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+FileDescriptorProto::extension() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.extension)
+  return extension_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+FileDescriptorProto::mutable_extension() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.extension)
+  return &extension_;
+}
+
+// optional .google.protobuf.FileOptions options = 8;
+ bool FileDescriptorProto::has_options() const {
+  return (_has_bits_[0] & 0x00000200u) != 0;
+}
+ void FileDescriptorProto::set_has_options() {
+  _has_bits_[0] |= 0x00000200u;
+}
+ void FileDescriptorProto::clear_has_options() {
+  _has_bits_[0] &= ~0x00000200u;
+}
+ void FileDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
+  clear_has_options();
+}
+ const ::google::protobuf::FileOptions& FileDescriptorProto::options() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.options)
+  return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+ ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() {
+  set_has_options();
+  if (options_ == NULL) {
+    options_ = new ::google::protobuf::FileOptions;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.options)
+  return options_;
+}
+ ::google::protobuf::FileOptions* FileDescriptorProto::release_options() {
+  clear_has_options();
+  ::google::protobuf::FileOptions* temp = options_;
+  options_ = NULL;
+  return temp;
+}
+ void FileDescriptorProto::set_allocated_options(::google::protobuf::FileOptions* options) {
+  delete options_;
+  options_ = options;
+  if (options) {
+    set_has_options();
+  } else {
+    clear_has_options();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.options)
+}
+
+// optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ bool FileDescriptorProto::has_source_code_info() const {
+  return (_has_bits_[0] & 0x00000400u) != 0;
+}
+ void FileDescriptorProto::set_has_source_code_info() {
+  _has_bits_[0] |= 0x00000400u;
+}
+ void FileDescriptorProto::clear_has_source_code_info() {
+  _has_bits_[0] &= ~0x00000400u;
+}
+ void FileDescriptorProto::clear_source_code_info() {
+  if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear();
+  clear_has_source_code_info();
+}
+ const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.source_code_info)
+  return source_code_info_ != NULL ? *source_code_info_ : *default_instance_->source_code_info_;
+}
+ ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() {
+  set_has_source_code_info();
+  if (source_code_info_ == NULL) {
+    source_code_info_ = new ::google::protobuf::SourceCodeInfo;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.source_code_info)
+  return source_code_info_;
+}
+ ::google::protobuf::SourceCodeInfo* FileDescriptorProto::release_source_code_info() {
+  clear_has_source_code_info();
+  ::google::protobuf::SourceCodeInfo* temp = source_code_info_;
+  source_code_info_ = NULL;
+  return temp;
+}
+ void FileDescriptorProto::set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info) {
+  delete source_code_info_;
+  source_code_info_ = source_code_info;
+  if (source_code_info) {
+    set_has_source_code_info();
+  } else {
+    clear_has_source_code_info();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.source_code_info)
+}
+
+// optional string syntax = 12;
+ bool FileDescriptorProto::has_syntax() const {
+  return (_has_bits_[0] & 0x00000800u) != 0;
+}
+ void FileDescriptorProto::set_has_syntax() {
+  _has_bits_[0] |= 0x00000800u;
+}
+ void FileDescriptorProto::clear_has_syntax() {
+  _has_bits_[0] &= ~0x00000800u;
+}
+ void FileDescriptorProto::clear_syntax() {
+  syntax_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_syntax();
+}
+ const ::std::string& FileDescriptorProto::syntax() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.syntax)
+  return syntax_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FileDescriptorProto::set_syntax(const ::std::string& value) {
+  set_has_syntax();
+  syntax_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.syntax)
+}
+ void FileDescriptorProto::set_syntax(const char* value) {
+  set_has_syntax();
+  syntax_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.syntax)
+}
+ void FileDescriptorProto::set_syntax(const char* value, size_t size) {
+  set_has_syntax();
+  syntax_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.syntax)
+}
+ ::std::string* FileDescriptorProto::mutable_syntax() {
+  set_has_syntax();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.syntax)
+  return syntax_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* FileDescriptorProto::release_syntax() {
+  clear_has_syntax();
+  return syntax_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FileDescriptorProto::set_allocated_syntax(::std::string* syntax) {
+  if (syntax != NULL) {
+    set_has_syntax();
+  } else {
+    clear_has_syntax();
+  }
+  syntax_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), syntax);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.syntax)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -1839,19 +2360,17 @@
 }
 
 void DescriptorProto_ExtensionRange::Clear() {
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
-  &reinterpret_cast<DescriptorProto_ExtensionRange*>(16)->f) - \
-   reinterpret_cast<char*>(16))
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+  &reinterpret_cast<DescriptorProto_ExtensionRange*>(16)->f)
 
-#define ZR_(first, last) do {                              \
-    size_t f = OFFSET_OF_FIELD_(first);                    \
-    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
-    ::memset(&first, 0, n);                                \
-  } while (0)
+#define ZR_(first, last) do {\
+  ::memset(&first, 0,\
+           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
 
   ZR_(start_, end_);
 
-#undef OFFSET_OF_FIELD_
+#undef ZR_HELPER_
 #undef ZR_
 
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -2594,6 +3113,338 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// DescriptorProto_ExtensionRange
+
+// optional int32 start = 1;
+ bool DescriptorProto_ExtensionRange::has_start() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void DescriptorProto_ExtensionRange::set_has_start() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void DescriptorProto_ExtensionRange::clear_has_start() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void DescriptorProto_ExtensionRange::clear_start() {
+  start_ = 0;
+  clear_has_start();
+}
+ ::google::protobuf::int32 DescriptorProto_ExtensionRange::start() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.start)
+  return start_;
+}
+ void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 value) {
+  set_has_start();
+  start_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.start)
+}
+
+// optional int32 end = 2;
+ bool DescriptorProto_ExtensionRange::has_end() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+ void DescriptorProto_ExtensionRange::set_has_end() {
+  _has_bits_[0] |= 0x00000002u;
+}
+ void DescriptorProto_ExtensionRange::clear_has_end() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+ void DescriptorProto_ExtensionRange::clear_end() {
+  end_ = 0;
+  clear_has_end();
+}
+ ::google::protobuf::int32 DescriptorProto_ExtensionRange::end() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.end)
+  return end_;
+}
+ void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 value) {
+  set_has_end();
+  end_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.end)
+}
+
+// -------------------------------------------------------------------
+
+// DescriptorProto
+
+// optional string name = 1;
+ bool DescriptorProto::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void DescriptorProto::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void DescriptorProto::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void DescriptorProto::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_name();
+}
+ const ::std::string& DescriptorProto::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.name)
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void DescriptorProto::set_name(const ::std::string& value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.name)
+}
+ void DescriptorProto::set_name(const char* value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.name)
+}
+ void DescriptorProto::set_name(const char* value, size_t size) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.DescriptorProto.name)
+}
+ ::std::string* DescriptorProto::mutable_name() {
+  set_has_name();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* DescriptorProto::release_name() {
+  clear_has_name();
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void DescriptorProto::set_allocated_name(::std::string* name) {
+  if (name != NULL) {
+    set_has_name();
+  } else {
+    clear_has_name();
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.name)
+}
+
+// repeated .google.protobuf.FieldDescriptorProto field = 2;
+ int DescriptorProto::field_size() const {
+  return field_.size();
+}
+ void DescriptorProto::clear_field() {
+  field_.Clear();
+}
+ const ::google::protobuf::FieldDescriptorProto& DescriptorProto::field(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.field)
+  return field_.Get(index);
+}
+ ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_field(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.field)
+  return field_.Mutable(index);
+}
+ ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() {
+  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.field)
+  return field_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+DescriptorProto::field() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.field)
+  return field_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+DescriptorProto::mutable_field() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.field)
+  return &field_;
+}
+
+// repeated .google.protobuf.FieldDescriptorProto extension = 6;
+ int DescriptorProto::extension_size() const {
+  return extension_.size();
+}
+ void DescriptorProto::clear_extension() {
+  extension_.Clear();
+}
+ const ::google::protobuf::FieldDescriptorProto& DescriptorProto::extension(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension)
+  return extension_.Get(index);
+}
+ ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension)
+  return extension_.Mutable(index);
+}
+ ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_extension() {
+  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension)
+  return extension_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+DescriptorProto::extension() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension)
+  return extension_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+DescriptorProto::mutable_extension() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension)
+  return &extension_;
+}
+
+// repeated .google.protobuf.DescriptorProto nested_type = 3;
+ int DescriptorProto::nested_type_size() const {
+  return nested_type_.size();
+}
+ void DescriptorProto::clear_nested_type() {
+  nested_type_.Clear();
+}
+ const ::google::protobuf::DescriptorProto& DescriptorProto::nested_type(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.nested_type)
+  return nested_type_.Get(index);
+}
+ ::google::protobuf::DescriptorProto* DescriptorProto::mutable_nested_type(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.nested_type)
+  return nested_type_.Mutable(index);
+}
+ ::google::protobuf::DescriptorProto* DescriptorProto::add_nested_type() {
+  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.nested_type)
+  return nested_type_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+DescriptorProto::nested_type() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.nested_type)
+  return nested_type_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
+DescriptorProto::mutable_nested_type() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.nested_type)
+  return &nested_type_;
+}
+
+// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+ int DescriptorProto::enum_type_size() const {
+  return enum_type_.size();
+}
+ void DescriptorProto::clear_enum_type() {
+  enum_type_.Clear();
+}
+ const ::google::protobuf::EnumDescriptorProto& DescriptorProto::enum_type(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.enum_type)
+  return enum_type_.Get(index);
+}
+ ::google::protobuf::EnumDescriptorProto* DescriptorProto::mutable_enum_type(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.enum_type)
+  return enum_type_.Mutable(index);
+}
+ ::google::protobuf::EnumDescriptorProto* DescriptorProto::add_enum_type() {
+  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.enum_type)
+  return enum_type_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+DescriptorProto::enum_type() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.enum_type)
+  return enum_type_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
+DescriptorProto::mutable_enum_type() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.enum_type)
+  return &enum_type_;
+}
+
+// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+ int DescriptorProto::extension_range_size() const {
+  return extension_range_.size();
+}
+ void DescriptorProto::clear_extension_range() {
+  extension_range_.Clear();
+}
+ const ::google::protobuf::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension_range)
+  return extension_range_.Get(index);
+}
+ ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::mutable_extension_range(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension_range)
+  return extension_range_.Mutable(index);
+}
+ ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() {
+  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension_range)
+  return extension_range_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
+DescriptorProto::extension_range() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension_range)
+  return extension_range_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
+DescriptorProto::mutable_extension_range() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension_range)
+  return &extension_range_;
+}
+
+// repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+ int DescriptorProto::oneof_decl_size() const {
+  return oneof_decl_.size();
+}
+ void DescriptorProto::clear_oneof_decl() {
+  oneof_decl_.Clear();
+}
+ const ::google::protobuf::OneofDescriptorProto& DescriptorProto::oneof_decl(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.oneof_decl)
+  return oneof_decl_.Get(index);
+}
+ ::google::protobuf::OneofDescriptorProto* DescriptorProto::mutable_oneof_decl(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.oneof_decl)
+  return oneof_decl_.Mutable(index);
+}
+ ::google::protobuf::OneofDescriptorProto* DescriptorProto::add_oneof_decl() {
+  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.oneof_decl)
+  return oneof_decl_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
+DescriptorProto::oneof_decl() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.oneof_decl)
+  return oneof_decl_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >*
+DescriptorProto::mutable_oneof_decl() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.oneof_decl)
+  return &oneof_decl_;
+}
+
+// optional .google.protobuf.MessageOptions options = 7;
+ bool DescriptorProto::has_options() const {
+  return (_has_bits_[0] & 0x00000080u) != 0;
+}
+ void DescriptorProto::set_has_options() {
+  _has_bits_[0] |= 0x00000080u;
+}
+ void DescriptorProto::clear_has_options() {
+  _has_bits_[0] &= ~0x00000080u;
+}
+ void DescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
+  clear_has_options();
+}
+ const ::google::protobuf::MessageOptions& DescriptorProto::options() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.options)
+  return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+ ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() {
+  set_has_options();
+  if (options_ == NULL) {
+    options_ = new ::google::protobuf::MessageOptions;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.options)
+  return options_;
+}
+ ::google::protobuf::MessageOptions* DescriptorProto::release_options() {
+  clear_has_options();
+  ::google::protobuf::MessageOptions* temp = options_;
+  options_ = NULL;
+  return temp;
+}
+ void DescriptorProto::set_allocated_options(::google::protobuf::MessageOptions* options) {
+  delete options_;
+  options_ = options;
+  if (options) {
+    set_has_options();
+  } else {
+    clear_has_options();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.options)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -3308,6 +4159,363 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// FieldDescriptorProto
+
+// optional string name = 1;
+ bool FieldDescriptorProto::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void FieldDescriptorProto::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void FieldDescriptorProto::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void FieldDescriptorProto::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_name();
+}
+ const ::std::string& FieldDescriptorProto::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.name)
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FieldDescriptorProto::set_name(const ::std::string& value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.name)
+}
+ void FieldDescriptorProto::set_name(const char* value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.name)
+}
+ void FieldDescriptorProto::set_name(const char* value, size_t size) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.name)
+}
+ ::std::string* FieldDescriptorProto::mutable_name() {
+  set_has_name();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* FieldDescriptorProto::release_name() {
+  clear_has_name();
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FieldDescriptorProto::set_allocated_name(::std::string* name) {
+  if (name != NULL) {
+    set_has_name();
+  } else {
+    clear_has_name();
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.name)
+}
+
+// optional int32 number = 3;
+ bool FieldDescriptorProto::has_number() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+ void FieldDescriptorProto::set_has_number() {
+  _has_bits_[0] |= 0x00000002u;
+}
+ void FieldDescriptorProto::clear_has_number() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+ void FieldDescriptorProto::clear_number() {
+  number_ = 0;
+  clear_has_number();
+}
+ ::google::protobuf::int32 FieldDescriptorProto::number() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.number)
+  return number_;
+}
+ void FieldDescriptorProto::set_number(::google::protobuf::int32 value) {
+  set_has_number();
+  number_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.number)
+}
+
+// optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+ bool FieldDescriptorProto::has_label() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+ void FieldDescriptorProto::set_has_label() {
+  _has_bits_[0] |= 0x00000004u;
+}
+ void FieldDescriptorProto::clear_has_label() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+ void FieldDescriptorProto::clear_label() {
+  label_ = 1;
+  clear_has_label();
+}
+ ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::label() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.label)
+  return static_cast< ::google::protobuf::FieldDescriptorProto_Label >(label_);
+}
+ void FieldDescriptorProto::set_label(::google::protobuf::FieldDescriptorProto_Label value) {
+  assert(::google::protobuf::FieldDescriptorProto_Label_IsValid(value));
+  set_has_label();
+  label_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.label)
+}
+
+// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+ bool FieldDescriptorProto::has_type() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+ void FieldDescriptorProto::set_has_type() {
+  _has_bits_[0] |= 0x00000008u;
+}
+ void FieldDescriptorProto::clear_has_type() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+ void FieldDescriptorProto::clear_type() {
+  type_ = 1;
+  clear_has_type();
+}
+ ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::type() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type)
+  return static_cast< ::google::protobuf::FieldDescriptorProto_Type >(type_);
+}
+ void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Type value) {
+  assert(::google::protobuf::FieldDescriptorProto_Type_IsValid(value));
+  set_has_type();
+  type_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type)
+}
+
+// optional string type_name = 6;
+ bool FieldDescriptorProto::has_type_name() const {
+  return (_has_bits_[0] & 0x00000010u) != 0;
+}
+ void FieldDescriptorProto::set_has_type_name() {
+  _has_bits_[0] |= 0x00000010u;
+}
+ void FieldDescriptorProto::clear_has_type_name() {
+  _has_bits_[0] &= ~0x00000010u;
+}
+ void FieldDescriptorProto::clear_type_name() {
+  type_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_type_name();
+}
+ const ::std::string& FieldDescriptorProto::type_name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type_name)
+  return type_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FieldDescriptorProto::set_type_name(const ::std::string& value) {
+  set_has_type_name();
+  type_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type_name)
+}
+ void FieldDescriptorProto::set_type_name(const char* value) {
+  set_has_type_name();
+  type_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.type_name)
+}
+ void FieldDescriptorProto::set_type_name(const char* value, size_t size) {
+  set_has_type_name();
+  type_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.type_name)
+}
+ ::std::string* FieldDescriptorProto::mutable_type_name() {
+  set_has_type_name();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.type_name)
+  return type_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* FieldDescriptorProto::release_type_name() {
+  clear_has_type_name();
+  return type_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FieldDescriptorProto::set_allocated_type_name(::std::string* type_name) {
+  if (type_name != NULL) {
+    set_has_type_name();
+  } else {
+    clear_has_type_name();
+  }
+  type_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), type_name);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.type_name)
+}
+
+// optional string extendee = 2;
+ bool FieldDescriptorProto::has_extendee() const {
+  return (_has_bits_[0] & 0x00000020u) != 0;
+}
+ void FieldDescriptorProto::set_has_extendee() {
+  _has_bits_[0] |= 0x00000020u;
+}
+ void FieldDescriptorProto::clear_has_extendee() {
+  _has_bits_[0] &= ~0x00000020u;
+}
+ void FieldDescriptorProto::clear_extendee() {
+  extendee_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_extendee();
+}
+ const ::std::string& FieldDescriptorProto::extendee() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.extendee)
+  return extendee_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FieldDescriptorProto::set_extendee(const ::std::string& value) {
+  set_has_extendee();
+  extendee_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.extendee)
+}
+ void FieldDescriptorProto::set_extendee(const char* value) {
+  set_has_extendee();
+  extendee_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.extendee)
+}
+ void FieldDescriptorProto::set_extendee(const char* value, size_t size) {
+  set_has_extendee();
+  extendee_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.extendee)
+}
+ ::std::string* FieldDescriptorProto::mutable_extendee() {
+  set_has_extendee();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.extendee)
+  return extendee_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* FieldDescriptorProto::release_extendee() {
+  clear_has_extendee();
+  return extendee_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FieldDescriptorProto::set_allocated_extendee(::std::string* extendee) {
+  if (extendee != NULL) {
+    set_has_extendee();
+  } else {
+    clear_has_extendee();
+  }
+  extendee_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), extendee);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.extendee)
+}
+
+// optional string default_value = 7;
+ bool FieldDescriptorProto::has_default_value() const {
+  return (_has_bits_[0] & 0x00000040u) != 0;
+}
+ void FieldDescriptorProto::set_has_default_value() {
+  _has_bits_[0] |= 0x00000040u;
+}
+ void FieldDescriptorProto::clear_has_default_value() {
+  _has_bits_[0] &= ~0x00000040u;
+}
+ void FieldDescriptorProto::clear_default_value() {
+  default_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_default_value();
+}
+ const ::std::string& FieldDescriptorProto::default_value() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.default_value)
+  return default_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FieldDescriptorProto::set_default_value(const ::std::string& value) {
+  set_has_default_value();
+  default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.default_value)
+}
+ void FieldDescriptorProto::set_default_value(const char* value) {
+  set_has_default_value();
+  default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.default_value)
+}
+ void FieldDescriptorProto::set_default_value(const char* value, size_t size) {
+  set_has_default_value();
+  default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.default_value)
+}
+ ::std::string* FieldDescriptorProto::mutable_default_value() {
+  set_has_default_value();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.default_value)
+  return default_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* FieldDescriptorProto::release_default_value() {
+  clear_has_default_value();
+  return default_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FieldDescriptorProto::set_allocated_default_value(::std::string* default_value) {
+  if (default_value != NULL) {
+    set_has_default_value();
+  } else {
+    clear_has_default_value();
+  }
+  default_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), default_value);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.default_value)
+}
+
+// optional int32 oneof_index = 9;
+ bool FieldDescriptorProto::has_oneof_index() const {
+  return (_has_bits_[0] & 0x00000080u) != 0;
+}
+ void FieldDescriptorProto::set_has_oneof_index() {
+  _has_bits_[0] |= 0x00000080u;
+}
+ void FieldDescriptorProto::clear_has_oneof_index() {
+  _has_bits_[0] &= ~0x00000080u;
+}
+ void FieldDescriptorProto::clear_oneof_index() {
+  oneof_index_ = 0;
+  clear_has_oneof_index();
+}
+ ::google::protobuf::int32 FieldDescriptorProto::oneof_index() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.oneof_index)
+  return oneof_index_;
+}
+ void FieldDescriptorProto::set_oneof_index(::google::protobuf::int32 value) {
+  set_has_oneof_index();
+  oneof_index_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.oneof_index)
+}
+
+// optional .google.protobuf.FieldOptions options = 8;
+ bool FieldDescriptorProto::has_options() const {
+  return (_has_bits_[0] & 0x00000100u) != 0;
+}
+ void FieldDescriptorProto::set_has_options() {
+  _has_bits_[0] |= 0x00000100u;
+}
+ void FieldDescriptorProto::clear_has_options() {
+  _has_bits_[0] &= ~0x00000100u;
+}
+ void FieldDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
+  clear_has_options();
+}
+ const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.options)
+  return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+ ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() {
+  set_has_options();
+  if (options_ == NULL) {
+    options_ = new ::google::protobuf::FieldOptions;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.options)
+  return options_;
+}
+ ::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() {
+  clear_has_options();
+  ::google::protobuf::FieldOptions* temp = options_;
+  options_ = NULL;
+  return temp;
+}
+ void FieldDescriptorProto::set_allocated_options(::google::protobuf::FieldOptions* options) {
+  delete options_;
+  options_ = options;
+  if (options) {
+    set_has_options();
+  } else {
+    clear_has_options();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.options)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -3557,6 +4765,63 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// OneofDescriptorProto
+
+// optional string name = 1;
+ bool OneofDescriptorProto::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void OneofDescriptorProto::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void OneofDescriptorProto::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void OneofDescriptorProto::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_name();
+}
+ const ::std::string& OneofDescriptorProto::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.name)
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void OneofDescriptorProto::set_name(const ::std::string& value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.OneofDescriptorProto.name)
+}
+ void OneofDescriptorProto::set_name(const char* value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.OneofDescriptorProto.name)
+}
+ void OneofDescriptorProto::set_name(const char* value, size_t size) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.OneofDescriptorProto.name)
+}
+ ::std::string* OneofDescriptorProto::mutable_name() {
+  set_has_name();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* OneofDescriptorProto::release_name() {
+  clear_has_name();
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void OneofDescriptorProto::set_allocated_name(::std::string* name) {
+  if (name != NULL) {
+    set_has_name();
+  } else {
+    clear_has_name();
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.name)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -3897,6 +5162,136 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// EnumDescriptorProto
+
+// optional string name = 1;
+ bool EnumDescriptorProto::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void EnumDescriptorProto::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void EnumDescriptorProto::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void EnumDescriptorProto::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_name();
+}
+ const ::std::string& EnumDescriptorProto::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.name)
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void EnumDescriptorProto::set_name(const ::std::string& value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.name)
+}
+ void EnumDescriptorProto::set_name(const char* value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.EnumDescriptorProto.name)
+}
+ void EnumDescriptorProto::set_name(const char* value, size_t size) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumDescriptorProto.name)
+}
+ ::std::string* EnumDescriptorProto::mutable_name() {
+  set_has_name();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* EnumDescriptorProto::release_name() {
+  clear_has_name();
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void EnumDescriptorProto::set_allocated_name(::std::string* name) {
+  if (name != NULL) {
+    set_has_name();
+  } else {
+    clear_has_name();
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.name)
+}
+
+// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+ int EnumDescriptorProto::value_size() const {
+  return value_.size();
+}
+ void EnumDescriptorProto::clear_value() {
+  value_.Clear();
+}
+ const ::google::protobuf::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.value)
+  return value_.Get(index);
+}
+ ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.value)
+  return value_.Mutable(index);
+}
+ ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_value() {
+  // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.value)
+  return value_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
+EnumDescriptorProto::value() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.value)
+  return value_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
+EnumDescriptorProto::mutable_value() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.value)
+  return &value_;
+}
+
+// optional .google.protobuf.EnumOptions options = 3;
+ bool EnumDescriptorProto::has_options() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+ void EnumDescriptorProto::set_has_options() {
+  _has_bits_[0] |= 0x00000004u;
+}
+ void EnumDescriptorProto::clear_has_options() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+ void EnumDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear();
+  clear_has_options();
+}
+ const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.options)
+  return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+ ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() {
+  set_has_options();
+  if (options_ == NULL) {
+    options_ = new ::google::protobuf::EnumOptions;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.options)
+  return options_;
+}
+ ::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() {
+  clear_has_options();
+  ::google::protobuf::EnumOptions* temp = options_;
+  options_ = NULL;
+  return temp;
+}
+ void EnumDescriptorProto::set_allocated_options(::google::protobuf::EnumOptions* options) {
+  delete options_;
+  options_ = options;
+  if (options) {
+    set_has_options();
+  } else {
+    clear_has_options();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.options)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -4236,6 +5631,130 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// EnumValueDescriptorProto
+
+// optional string name = 1;
+ bool EnumValueDescriptorProto::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void EnumValueDescriptorProto::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void EnumValueDescriptorProto::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void EnumValueDescriptorProto::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_name();
+}
+ const ::std::string& EnumValueDescriptorProto::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.name)
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void EnumValueDescriptorProto::set_name(const ::std::string& value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.name)
+}
+ void EnumValueDescriptorProto::set_name(const char* value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValueDescriptorProto.name)
+}
+ void EnumValueDescriptorProto::set_name(const char* value, size_t size) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumValueDescriptorProto.name)
+}
+ ::std::string* EnumValueDescriptorProto::mutable_name() {
+  set_has_name();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* EnumValueDescriptorProto::release_name() {
+  clear_has_name();
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void EnumValueDescriptorProto::set_allocated_name(::std::string* name) {
+  if (name != NULL) {
+    set_has_name();
+  } else {
+    clear_has_name();
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.name)
+}
+
+// optional int32 number = 2;
+ bool EnumValueDescriptorProto::has_number() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+ void EnumValueDescriptorProto::set_has_number() {
+  _has_bits_[0] |= 0x00000002u;
+}
+ void EnumValueDescriptorProto::clear_has_number() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+ void EnumValueDescriptorProto::clear_number() {
+  number_ = 0;
+  clear_has_number();
+}
+ ::google::protobuf::int32 EnumValueDescriptorProto::number() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.number)
+  return number_;
+}
+ void EnumValueDescriptorProto::set_number(::google::protobuf::int32 value) {
+  set_has_number();
+  number_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.number)
+}
+
+// optional .google.protobuf.EnumValueOptions options = 3;
+ bool EnumValueDescriptorProto::has_options() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+ void EnumValueDescriptorProto::set_has_options() {
+  _has_bits_[0] |= 0x00000004u;
+}
+ void EnumValueDescriptorProto::clear_has_options() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+ void EnumValueDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear();
+  clear_has_options();
+}
+ const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.options)
+  return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+ ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() {
+  set_has_options();
+  if (options_ == NULL) {
+    options_ = new ::google::protobuf::EnumValueOptions;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.options)
+  return options_;
+}
+ ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() {
+  clear_has_options();
+  ::google::protobuf::EnumValueOptions* temp = options_;
+  options_ = NULL;
+  return temp;
+}
+ void EnumValueDescriptorProto::set_allocated_options(::google::protobuf::EnumValueOptions* options) {
+  delete options_;
+  options_ = options;
+  if (options) {
+    set_has_options();
+  } else {
+    clear_has_options();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.options)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -4576,6 +6095,136 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// ServiceDescriptorProto
+
+// optional string name = 1;
+ bool ServiceDescriptorProto::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void ServiceDescriptorProto::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void ServiceDescriptorProto::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void ServiceDescriptorProto::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_name();
+}
+ const ::std::string& ServiceDescriptorProto::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.name)
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void ServiceDescriptorProto::set_name(const ::std::string& value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.ServiceDescriptorProto.name)
+}
+ void ServiceDescriptorProto::set_name(const char* value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.ServiceDescriptorProto.name)
+}
+ void ServiceDescriptorProto::set_name(const char* value, size_t size) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.ServiceDescriptorProto.name)
+}
+ ::std::string* ServiceDescriptorProto::mutable_name() {
+  set_has_name();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* ServiceDescriptorProto::release_name() {
+  clear_has_name();
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void ServiceDescriptorProto::set_allocated_name(::std::string* name) {
+  if (name != NULL) {
+    set_has_name();
+  } else {
+    clear_has_name();
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.name)
+}
+
+// repeated .google.protobuf.MethodDescriptorProto method = 2;
+ int ServiceDescriptorProto::method_size() const {
+  return method_.size();
+}
+ void ServiceDescriptorProto::clear_method() {
+  method_.Clear();
+}
+ const ::google::protobuf::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.method)
+  return method_.Get(index);
+}
+ ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.method)
+  return method_.Mutable(index);
+}
+ ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_method() {
+  // @@protoc_insertion_point(field_add:google.protobuf.ServiceDescriptorProto.method)
+  return method_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
+ServiceDescriptorProto::method() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.ServiceDescriptorProto.method)
+  return method_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
+ServiceDescriptorProto::mutable_method() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceDescriptorProto.method)
+  return &method_;
+}
+
+// optional .google.protobuf.ServiceOptions options = 3;
+ bool ServiceDescriptorProto::has_options() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+ void ServiceDescriptorProto::set_has_options() {
+  _has_bits_[0] |= 0x00000004u;
+}
+ void ServiceDescriptorProto::clear_has_options() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+ void ServiceDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear();
+  clear_has_options();
+}
+ const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.options)
+  return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+ ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() {
+  set_has_options();
+  if (options_ == NULL) {
+    options_ = new ::google::protobuf::ServiceOptions;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.options)
+  return options_;
+}
+ ::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() {
+  clear_has_options();
+  ::google::protobuf::ServiceOptions* temp = options_;
+  options_ = NULL;
+  return temp;
+}
+ void ServiceDescriptorProto::set_allocated_options(::google::protobuf::ServiceOptions* options) {
+  delete options_;
+  options_ = options;
+  if (options) {
+    set_has_options();
+  } else {
+    clear_has_options();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.options)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -4658,15 +6307,13 @@
 }
 
 void MethodDescriptorProto::Clear() {
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
-  &reinterpret_cast<MethodDescriptorProto*>(16)->f) - \
-   reinterpret_cast<char*>(16))
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+  &reinterpret_cast<MethodDescriptorProto*>(16)->f)
 
-#define ZR_(first, last) do {                              \
-    size_t f = OFFSET_OF_FIELD_(first);                    \
-    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
-    ::memset(&first, 0, n);                                \
-  } while (0)
+#define ZR_(first, last) do {\
+  ::memset(&first, 0,\
+           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
 
   if (_has_bits_[0 / 32] & 63) {
     ZR_(client_streaming_, server_streaming_);
@@ -4684,7 +6331,7 @@
     }
   }
 
-#undef OFFSET_OF_FIELD_
+#undef ZR_HELPER_
 #undef ZR_
 
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -5075,6 +6722,260 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// MethodDescriptorProto
+
+// optional string name = 1;
+ bool MethodDescriptorProto::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void MethodDescriptorProto::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void MethodDescriptorProto::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void MethodDescriptorProto::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_name();
+}
+ const ::std::string& MethodDescriptorProto::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.name)
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void MethodDescriptorProto::set_name(const ::std::string& value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.name)
+}
+ void MethodDescriptorProto::set_name(const char* value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.name)
+}
+ void MethodDescriptorProto::set_name(const char* value, size_t size) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.name)
+}
+ ::std::string* MethodDescriptorProto::mutable_name() {
+  set_has_name();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* MethodDescriptorProto::release_name() {
+  clear_has_name();
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void MethodDescriptorProto::set_allocated_name(::std::string* name) {
+  if (name != NULL) {
+    set_has_name();
+  } else {
+    clear_has_name();
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.name)
+}
+
+// optional string input_type = 2;
+ bool MethodDescriptorProto::has_input_type() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+ void MethodDescriptorProto::set_has_input_type() {
+  _has_bits_[0] |= 0x00000002u;
+}
+ void MethodDescriptorProto::clear_has_input_type() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+ void MethodDescriptorProto::clear_input_type() {
+  input_type_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_input_type();
+}
+ const ::std::string& MethodDescriptorProto::input_type() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.input_type)
+  return input_type_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void MethodDescriptorProto::set_input_type(const ::std::string& value) {
+  set_has_input_type();
+  input_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.input_type)
+}
+ void MethodDescriptorProto::set_input_type(const char* value) {
+  set_has_input_type();
+  input_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.input_type)
+}
+ void MethodDescriptorProto::set_input_type(const char* value, size_t size) {
+  set_has_input_type();
+  input_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.input_type)
+}
+ ::std::string* MethodDescriptorProto::mutable_input_type() {
+  set_has_input_type();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.input_type)
+  return input_type_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* MethodDescriptorProto::release_input_type() {
+  clear_has_input_type();
+  return input_type_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void MethodDescriptorProto::set_allocated_input_type(::std::string* input_type) {
+  if (input_type != NULL) {
+    set_has_input_type();
+  } else {
+    clear_has_input_type();
+  }
+  input_type_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), input_type);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.input_type)
+}
+
+// optional string output_type = 3;
+ bool MethodDescriptorProto::has_output_type() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+ void MethodDescriptorProto::set_has_output_type() {
+  _has_bits_[0] |= 0x00000004u;
+}
+ void MethodDescriptorProto::clear_has_output_type() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+ void MethodDescriptorProto::clear_output_type() {
+  output_type_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_output_type();
+}
+ const ::std::string& MethodDescriptorProto::output_type() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.output_type)
+  return output_type_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void MethodDescriptorProto::set_output_type(const ::std::string& value) {
+  set_has_output_type();
+  output_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.output_type)
+}
+ void MethodDescriptorProto::set_output_type(const char* value) {
+  set_has_output_type();
+  output_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.output_type)
+}
+ void MethodDescriptorProto::set_output_type(const char* value, size_t size) {
+  set_has_output_type();
+  output_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.output_type)
+}
+ ::std::string* MethodDescriptorProto::mutable_output_type() {
+  set_has_output_type();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.output_type)
+  return output_type_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* MethodDescriptorProto::release_output_type() {
+  clear_has_output_type();
+  return output_type_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void MethodDescriptorProto::set_allocated_output_type(::std::string* output_type) {
+  if (output_type != NULL) {
+    set_has_output_type();
+  } else {
+    clear_has_output_type();
+  }
+  output_type_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), output_type);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.output_type)
+}
+
+// optional .google.protobuf.MethodOptions options = 4;
+ bool MethodDescriptorProto::has_options() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+ void MethodDescriptorProto::set_has_options() {
+  _has_bits_[0] |= 0x00000008u;
+}
+ void MethodDescriptorProto::clear_has_options() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+ void MethodDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear();
+  clear_has_options();
+}
+ const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.options)
+  return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+ ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() {
+  set_has_options();
+  if (options_ == NULL) {
+    options_ = new ::google::protobuf::MethodOptions;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.options)
+  return options_;
+}
+ ::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() {
+  clear_has_options();
+  ::google::protobuf::MethodOptions* temp = options_;
+  options_ = NULL;
+  return temp;
+}
+ void MethodDescriptorProto::set_allocated_options(::google::protobuf::MethodOptions* options) {
+  delete options_;
+  options_ = options;
+  if (options) {
+    set_has_options();
+  } else {
+    clear_has_options();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.options)
+}
+
+// optional bool client_streaming = 5 [default = false];
+ bool MethodDescriptorProto::has_client_streaming() const {
+  return (_has_bits_[0] & 0x00000010u) != 0;
+}
+ void MethodDescriptorProto::set_has_client_streaming() {
+  _has_bits_[0] |= 0x00000010u;
+}
+ void MethodDescriptorProto::clear_has_client_streaming() {
+  _has_bits_[0] &= ~0x00000010u;
+}
+ void MethodDescriptorProto::clear_client_streaming() {
+  client_streaming_ = false;
+  clear_has_client_streaming();
+}
+ bool MethodDescriptorProto::client_streaming() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.client_streaming)
+  return client_streaming_;
+}
+ void MethodDescriptorProto::set_client_streaming(bool value) {
+  set_has_client_streaming();
+  client_streaming_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.client_streaming)
+}
+
+// optional bool server_streaming = 6 [default = false];
+ bool MethodDescriptorProto::has_server_streaming() const {
+  return (_has_bits_[0] & 0x00000020u) != 0;
+}
+ void MethodDescriptorProto::set_has_server_streaming() {
+  _has_bits_[0] |= 0x00000020u;
+}
+ void MethodDescriptorProto::clear_has_server_streaming() {
+  _has_bits_[0] &= ~0x00000020u;
+}
+ void MethodDescriptorProto::clear_server_streaming() {
+  server_streaming_ = false;
+  clear_has_server_streaming();
+}
+ bool MethodDescriptorProto::server_streaming() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.server_streaming)
+  return server_streaming_;
+}
+ void MethodDescriptorProto::set_server_streaming(bool value) {
+  set_has_server_streaming();
+  server_streaming_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.server_streaming)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -5114,6 +7015,7 @@
 const int FileOptions::kPyGenericServicesFieldNumber;
 const int FileOptions::kDeprecatedFieldNumber;
 const int FileOptions::kCcEnableArenasFieldNumber;
+const int FileOptions::kObjcClassPrefixFieldNumber;
 const int FileOptions::kUninterpretedOptionFieldNumber;
 #endif  // !_MSC_VER
 
@@ -5149,6 +7051,7 @@
   py_generic_services_ = false;
   deprecated_ = false;
   cc_enable_arenas_ = false;
+  objc_class_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
 }
 
@@ -5161,6 +7064,7 @@
   java_package_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   java_outer_classname_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   go_package_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  objc_class_prefix_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   if (this != default_instance_) {
   }
 }
@@ -5192,15 +7096,13 @@
 
 void FileOptions::Clear() {
   _extensions_.Clear();
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
-  &reinterpret_cast<FileOptions*>(16)->f) - \
-   reinterpret_cast<char*>(16))
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+  &reinterpret_cast<FileOptions*>(16)->f)
 
-#define ZR_(first, last) do {                              \
-    size_t f = OFFSET_OF_FIELD_(first);                    \
-    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
-    ::memset(&first, 0, n);                                \
-  } while (0)
+#define ZR_(first, last) do {\
+  ::memset(&first, 0,\
+           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
 
   if (_has_bits_[0 / 32] & 255) {
     ZR_(java_multiple_files_, cc_generic_services_);
@@ -5215,9 +7117,14 @@
       go_package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
     }
   }
-  ZR_(java_generic_services_, cc_enable_arenas_);
+  if (_has_bits_[8 / 32] & 7936) {
+    ZR_(java_generic_services_, cc_enable_arenas_);
+    if (has_objc_class_prefix()) {
+      objc_class_prefix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    }
+  }
 
-#undef OFFSET_OF_FIELD_
+#undef ZR_HELPER_
 #undef ZR_
 
   uninterpreted_option_.Clear();
@@ -5423,6 +7330,23 @@
         } else {
           goto handle_unusual;
         }
+        if (input->ExpectTag(290)) goto parse_objc_class_prefix;
+        break;
+      }
+
+      // optional string objc_class_prefix = 36;
+      case 36: {
+        if (tag == 290) {
+         parse_objc_class_prefix:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_objc_class_prefix()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->objc_class_prefix().data(), this->objc_class_prefix().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "google.protobuf.FileOptions.objc_class_prefix");
+        } else {
+          goto handle_unusual;
+        }
         if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
         break;
       }
@@ -5547,6 +7471,16 @@
     ::google::protobuf::internal::WireFormatLite::WriteBool(31, this->cc_enable_arenas(), output);
   }
 
+  // optional string objc_class_prefix = 36;
+  if (has_objc_class_prefix()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->objc_class_prefix().data(), this->objc_class_prefix().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.FileOptions.objc_class_prefix");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      36, this->objc_class_prefix(), output);
+  }
+
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
@@ -5646,6 +7580,17 @@
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(31, this->cc_enable_arenas(), target);
   }
 
+  // optional string objc_class_prefix = 36;
+  if (has_objc_class_prefix()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->objc_class_prefix().data(), this->objc_class_prefix().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.FileOptions.objc_class_prefix");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        36, this->objc_class_prefix(), target);
+  }
+
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
@@ -5717,7 +7662,7 @@
     }
 
   }
-  if (_has_bits_[8 / 32] & 3840) {
+  if (_has_bits_[8 / 32] & 7936) {
     // optional bool java_generic_services = 17 [default = false];
     if (has_java_generic_services()) {
       total_size += 2 + 1;
@@ -5738,6 +7683,13 @@
       total_size += 2 + 1;
     }
 
+    // optional string objc_class_prefix = 36;
+    if (has_objc_class_prefix()) {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->objc_class_prefix());
+    }
+
   }
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   total_size += 2 * this->uninterpreted_option_size();
@@ -5817,6 +7769,10 @@
     if (from.has_cc_enable_arenas()) {
       set_cc_enable_arenas(from.cc_enable_arenas());
     }
+    if (from.has_objc_class_prefix()) {
+      set_has_objc_class_prefix();
+      objc_class_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.objc_class_prefix_);
+    }
   }
   _extensions_.MergeFrom(from._extensions_);
   if (from._internal_metadata_.have_unknown_fields()) {
@@ -5860,6 +7816,7 @@
   std::swap(py_generic_services_, other->py_generic_services_);
   std::swap(deprecated_, other->deprecated_);
   std::swap(cc_enable_arenas_, other->cc_enable_arenas_);
+  objc_class_prefix_.Swap(&other->objc_class_prefix_);
   uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
@@ -5875,6 +7832,469 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// FileOptions
+
+// optional string java_package = 1;
+ bool FileOptions::has_java_package() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void FileOptions::set_has_java_package() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void FileOptions::clear_has_java_package() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void FileOptions::clear_java_package() {
+  java_package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_java_package();
+}
+ const ::std::string& FileOptions::java_package() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_package)
+  return java_package_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FileOptions::set_java_package(const ::std::string& value) {
+  set_has_java_package();
+  java_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_package)
+}
+ void FileOptions::set_java_package(const char* value) {
+  set_has_java_package();
+  java_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_package)
+}
+ void FileOptions::set_java_package(const char* value, size_t size) {
+  set_has_java_package();
+  java_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_package)
+}
+ ::std::string* FileOptions::mutable_java_package() {
+  set_has_java_package();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_package)
+  return java_package_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* FileOptions::release_java_package() {
+  clear_has_java_package();
+  return java_package_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FileOptions::set_allocated_java_package(::std::string* java_package) {
+  if (java_package != NULL) {
+    set_has_java_package();
+  } else {
+    clear_has_java_package();
+  }
+  java_package_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), java_package);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_package)
+}
+
+// optional string java_outer_classname = 8;
+ bool FileOptions::has_java_outer_classname() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+ void FileOptions::set_has_java_outer_classname() {
+  _has_bits_[0] |= 0x00000002u;
+}
+ void FileOptions::clear_has_java_outer_classname() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+ void FileOptions::clear_java_outer_classname() {
+  java_outer_classname_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_java_outer_classname();
+}
+ const ::std::string& FileOptions::java_outer_classname() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_outer_classname)
+  return java_outer_classname_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FileOptions::set_java_outer_classname(const ::std::string& value) {
+  set_has_java_outer_classname();
+  java_outer_classname_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_outer_classname)
+}
+ void FileOptions::set_java_outer_classname(const char* value) {
+  set_has_java_outer_classname();
+  java_outer_classname_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_outer_classname)
+}
+ void FileOptions::set_java_outer_classname(const char* value, size_t size) {
+  set_has_java_outer_classname();
+  java_outer_classname_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_outer_classname)
+}
+ ::std::string* FileOptions::mutable_java_outer_classname() {
+  set_has_java_outer_classname();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_outer_classname)
+  return java_outer_classname_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* FileOptions::release_java_outer_classname() {
+  clear_has_java_outer_classname();
+  return java_outer_classname_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FileOptions::set_allocated_java_outer_classname(::std::string* java_outer_classname) {
+  if (java_outer_classname != NULL) {
+    set_has_java_outer_classname();
+  } else {
+    clear_has_java_outer_classname();
+  }
+  java_outer_classname_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), java_outer_classname);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_outer_classname)
+}
+
+// optional bool java_multiple_files = 10 [default = false];
+ bool FileOptions::has_java_multiple_files() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+ void FileOptions::set_has_java_multiple_files() {
+  _has_bits_[0] |= 0x00000004u;
+}
+ void FileOptions::clear_has_java_multiple_files() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+ void FileOptions::clear_java_multiple_files() {
+  java_multiple_files_ = false;
+  clear_has_java_multiple_files();
+}
+ bool FileOptions::java_multiple_files() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_multiple_files)
+  return java_multiple_files_;
+}
+ void FileOptions::set_java_multiple_files(bool value) {
+  set_has_java_multiple_files();
+  java_multiple_files_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_multiple_files)
+}
+
+// optional bool java_generate_equals_and_hash = 20 [default = false];
+ bool FileOptions::has_java_generate_equals_and_hash() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+ void FileOptions::set_has_java_generate_equals_and_hash() {
+  _has_bits_[0] |= 0x00000008u;
+}
+ void FileOptions::clear_has_java_generate_equals_and_hash() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+ void FileOptions::clear_java_generate_equals_and_hash() {
+  java_generate_equals_and_hash_ = false;
+  clear_has_java_generate_equals_and_hash();
+}
+ bool FileOptions::java_generate_equals_and_hash() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generate_equals_and_hash)
+  return java_generate_equals_and_hash_;
+}
+ void FileOptions::set_java_generate_equals_and_hash(bool value) {
+  set_has_java_generate_equals_and_hash();
+  java_generate_equals_and_hash_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generate_equals_and_hash)
+}
+
+// optional bool java_string_check_utf8 = 27 [default = false];
+ bool FileOptions::has_java_string_check_utf8() const {
+  return (_has_bits_[0] & 0x00000010u) != 0;
+}
+ void FileOptions::set_has_java_string_check_utf8() {
+  _has_bits_[0] |= 0x00000010u;
+}
+ void FileOptions::clear_has_java_string_check_utf8() {
+  _has_bits_[0] &= ~0x00000010u;
+}
+ void FileOptions::clear_java_string_check_utf8() {
+  java_string_check_utf8_ = false;
+  clear_has_java_string_check_utf8();
+}
+ bool FileOptions::java_string_check_utf8() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_string_check_utf8)
+  return java_string_check_utf8_;
+}
+ void FileOptions::set_java_string_check_utf8(bool value) {
+  set_has_java_string_check_utf8();
+  java_string_check_utf8_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_string_check_utf8)
+}
+
+// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+ bool FileOptions::has_optimize_for() const {
+  return (_has_bits_[0] & 0x00000020u) != 0;
+}
+ void FileOptions::set_has_optimize_for() {
+  _has_bits_[0] |= 0x00000020u;
+}
+ void FileOptions::clear_has_optimize_for() {
+  _has_bits_[0] &= ~0x00000020u;
+}
+ void FileOptions::clear_optimize_for() {
+  optimize_for_ = 1;
+  clear_has_optimize_for();
+}
+ ::google::protobuf::FileOptions_OptimizeMode FileOptions::optimize_for() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.optimize_for)
+  return static_cast< ::google::protobuf::FileOptions_OptimizeMode >(optimize_for_);
+}
+ void FileOptions::set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value) {
+  assert(::google::protobuf::FileOptions_OptimizeMode_IsValid(value));
+  set_has_optimize_for();
+  optimize_for_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.optimize_for)
+}
+
+// optional string go_package = 11;
+ bool FileOptions::has_go_package() const {
+  return (_has_bits_[0] & 0x00000040u) != 0;
+}
+ void FileOptions::set_has_go_package() {
+  _has_bits_[0] |= 0x00000040u;
+}
+ void FileOptions::clear_has_go_package() {
+  _has_bits_[0] &= ~0x00000040u;
+}
+ void FileOptions::clear_go_package() {
+  go_package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_go_package();
+}
+ const ::std::string& FileOptions::go_package() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.go_package)
+  return go_package_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FileOptions::set_go_package(const ::std::string& value) {
+  set_has_go_package();
+  go_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.go_package)
+}
+ void FileOptions::set_go_package(const char* value) {
+  set_has_go_package();
+  go_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.go_package)
+}
+ void FileOptions::set_go_package(const char* value, size_t size) {
+  set_has_go_package();
+  go_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.go_package)
+}
+ ::std::string* FileOptions::mutable_go_package() {
+  set_has_go_package();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.go_package)
+  return go_package_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* FileOptions::release_go_package() {
+  clear_has_go_package();
+  return go_package_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FileOptions::set_allocated_go_package(::std::string* go_package) {
+  if (go_package != NULL) {
+    set_has_go_package();
+  } else {
+    clear_has_go_package();
+  }
+  go_package_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), go_package);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.go_package)
+}
+
+// optional bool cc_generic_services = 16 [default = false];
+ bool FileOptions::has_cc_generic_services() const {
+  return (_has_bits_[0] & 0x00000080u) != 0;
+}
+ void FileOptions::set_has_cc_generic_services() {
+  _has_bits_[0] |= 0x00000080u;
+}
+ void FileOptions::clear_has_cc_generic_services() {
+  _has_bits_[0] &= ~0x00000080u;
+}
+ void FileOptions::clear_cc_generic_services() {
+  cc_generic_services_ = false;
+  clear_has_cc_generic_services();
+}
+ bool FileOptions::cc_generic_services() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_generic_services)
+  return cc_generic_services_;
+}
+ void FileOptions::set_cc_generic_services(bool value) {
+  set_has_cc_generic_services();
+  cc_generic_services_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_generic_services)
+}
+
+// optional bool java_generic_services = 17 [default = false];
+ bool FileOptions::has_java_generic_services() const {
+  return (_has_bits_[0] & 0x00000100u) != 0;
+}
+ void FileOptions::set_has_java_generic_services() {
+  _has_bits_[0] |= 0x00000100u;
+}
+ void FileOptions::clear_has_java_generic_services() {
+  _has_bits_[0] &= ~0x00000100u;
+}
+ void FileOptions::clear_java_generic_services() {
+  java_generic_services_ = false;
+  clear_has_java_generic_services();
+}
+ bool FileOptions::java_generic_services() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generic_services)
+  return java_generic_services_;
+}
+ void FileOptions::set_java_generic_services(bool value) {
+  set_has_java_generic_services();
+  java_generic_services_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generic_services)
+}
+
+// optional bool py_generic_services = 18 [default = false];
+ bool FileOptions::has_py_generic_services() const {
+  return (_has_bits_[0] & 0x00000200u) != 0;
+}
+ void FileOptions::set_has_py_generic_services() {
+  _has_bits_[0] |= 0x00000200u;
+}
+ void FileOptions::clear_has_py_generic_services() {
+  _has_bits_[0] &= ~0x00000200u;
+}
+ void FileOptions::clear_py_generic_services() {
+  py_generic_services_ = false;
+  clear_has_py_generic_services();
+}
+ bool FileOptions::py_generic_services() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.py_generic_services)
+  return py_generic_services_;
+}
+ void FileOptions::set_py_generic_services(bool value) {
+  set_has_py_generic_services();
+  py_generic_services_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.py_generic_services)
+}
+
+// optional bool deprecated = 23 [default = false];
+ bool FileOptions::has_deprecated() const {
+  return (_has_bits_[0] & 0x00000400u) != 0;
+}
+ void FileOptions::set_has_deprecated() {
+  _has_bits_[0] |= 0x00000400u;
+}
+ void FileOptions::clear_has_deprecated() {
+  _has_bits_[0] &= ~0x00000400u;
+}
+ void FileOptions::clear_deprecated() {
+  deprecated_ = false;
+  clear_has_deprecated();
+}
+ bool FileOptions::deprecated() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.deprecated)
+  return deprecated_;
+}
+ void FileOptions::set_deprecated(bool value) {
+  set_has_deprecated();
+  deprecated_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.deprecated)
+}
+
+// optional bool cc_enable_arenas = 31 [default = false];
+ bool FileOptions::has_cc_enable_arenas() const {
+  return (_has_bits_[0] & 0x00000800u) != 0;
+}
+ void FileOptions::set_has_cc_enable_arenas() {
+  _has_bits_[0] |= 0x00000800u;
+}
+ void FileOptions::clear_has_cc_enable_arenas() {
+  _has_bits_[0] &= ~0x00000800u;
+}
+ void FileOptions::clear_cc_enable_arenas() {
+  cc_enable_arenas_ = false;
+  clear_has_cc_enable_arenas();
+}
+ bool FileOptions::cc_enable_arenas() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_enable_arenas)
+  return cc_enable_arenas_;
+}
+ void FileOptions::set_cc_enable_arenas(bool value) {
+  set_has_cc_enable_arenas();
+  cc_enable_arenas_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_enable_arenas)
+}
+
+// optional string objc_class_prefix = 36;
+ bool FileOptions::has_objc_class_prefix() const {
+  return (_has_bits_[0] & 0x00001000u) != 0;
+}
+ void FileOptions::set_has_objc_class_prefix() {
+  _has_bits_[0] |= 0x00001000u;
+}
+ void FileOptions::clear_has_objc_class_prefix() {
+  _has_bits_[0] &= ~0x00001000u;
+}
+ void FileOptions::clear_objc_class_prefix() {
+  objc_class_prefix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_objc_class_prefix();
+}
+ const ::std::string& FileOptions::objc_class_prefix() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.objc_class_prefix)
+  return objc_class_prefix_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FileOptions::set_objc_class_prefix(const ::std::string& value) {
+  set_has_objc_class_prefix();
+  objc_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.objc_class_prefix)
+}
+ void FileOptions::set_objc_class_prefix(const char* value) {
+  set_has_objc_class_prefix();
+  objc_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.objc_class_prefix)
+}
+ void FileOptions::set_objc_class_prefix(const char* value, size_t size) {
+  set_has_objc_class_prefix();
+  objc_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.objc_class_prefix)
+}
+ ::std::string* FileOptions::mutable_objc_class_prefix() {
+  set_has_objc_class_prefix();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.objc_class_prefix)
+  return objc_class_prefix_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* FileOptions::release_objc_class_prefix() {
+  clear_has_objc_class_prefix();
+  return objc_class_prefix_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FileOptions::set_allocated_objc_class_prefix(::std::string* objc_class_prefix) {
+  if (objc_class_prefix != NULL) {
+    set_has_objc_class_prefix();
+  } else {
+    clear_has_objc_class_prefix();
+  }
+  objc_class_prefix_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), objc_class_prefix);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.objc_class_prefix)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ int FileOptions::uninterpreted_option_size() const {
+  return uninterpreted_option_.size();
+}
+ void FileOptions::clear_uninterpreted_option() {
+  uninterpreted_option_.Clear();
+}
+ const ::google::protobuf::UninterpretedOption& FileOptions::uninterpreted_option(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.uninterpreted_option)
+  return uninterpreted_option_.Get(index);
+}
+ ::google::protobuf::UninterpretedOption* FileOptions::mutable_uninterpreted_option(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.uninterpreted_option)
+  return uninterpreted_option_.Mutable(index);
+}
+ ::google::protobuf::UninterpretedOption* FileOptions::add_uninterpreted_option() {
+  // @@protoc_insertion_point(field_add:google.protobuf.FileOptions.uninterpreted_option)
+  return uninterpreted_option_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+FileOptions::uninterpreted_option() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileOptions.uninterpreted_option)
+  return uninterpreted_option_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+FileOptions::mutable_uninterpreted_option() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileOptions.uninterpreted_option)
+  return &uninterpreted_option_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -5949,19 +8369,17 @@
 
 void MessageOptions::Clear() {
   _extensions_.Clear();
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
-  &reinterpret_cast<MessageOptions*>(16)->f) - \
-   reinterpret_cast<char*>(16))
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+  &reinterpret_cast<MessageOptions*>(16)->f)
 
-#define ZR_(first, last) do {                              \
-    size_t f = OFFSET_OF_FIELD_(first);                    \
-    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
-    ::memset(&first, 0, n);                                \
-  } while (0)
+#define ZR_(first, last) do {\
+  ::memset(&first, 0,\
+           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
 
   ZR_(message_set_wire_format_, map_entry_);
 
-#undef OFFSET_OF_FIELD_
+#undef ZR_HELPER_
 #undef ZR_
 
   uninterpreted_option_.Clear();
@@ -6287,6 +8705,136 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// MessageOptions
+
+// optional bool message_set_wire_format = 1 [default = false];
+ bool MessageOptions::has_message_set_wire_format() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void MessageOptions::set_has_message_set_wire_format() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void MessageOptions::clear_has_message_set_wire_format() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void MessageOptions::clear_message_set_wire_format() {
+  message_set_wire_format_ = false;
+  clear_has_message_set_wire_format();
+}
+ bool MessageOptions::message_set_wire_format() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.message_set_wire_format)
+  return message_set_wire_format_;
+}
+ void MessageOptions::set_message_set_wire_format(bool value) {
+  set_has_message_set_wire_format();
+  message_set_wire_format_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.message_set_wire_format)
+}
+
+// optional bool no_standard_descriptor_accessor = 2 [default = false];
+ bool MessageOptions::has_no_standard_descriptor_accessor() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+ void MessageOptions::set_has_no_standard_descriptor_accessor() {
+  _has_bits_[0] |= 0x00000002u;
+}
+ void MessageOptions::clear_has_no_standard_descriptor_accessor() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+ void MessageOptions::clear_no_standard_descriptor_accessor() {
+  no_standard_descriptor_accessor_ = false;
+  clear_has_no_standard_descriptor_accessor();
+}
+ bool MessageOptions::no_standard_descriptor_accessor() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.no_standard_descriptor_accessor)
+  return no_standard_descriptor_accessor_;
+}
+ void MessageOptions::set_no_standard_descriptor_accessor(bool value) {
+  set_has_no_standard_descriptor_accessor();
+  no_standard_descriptor_accessor_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.no_standard_descriptor_accessor)
+}
+
+// optional bool deprecated = 3 [default = false];
+ bool MessageOptions::has_deprecated() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+ void MessageOptions::set_has_deprecated() {
+  _has_bits_[0] |= 0x00000004u;
+}
+ void MessageOptions::clear_has_deprecated() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+ void MessageOptions::clear_deprecated() {
+  deprecated_ = false;
+  clear_has_deprecated();
+}
+ bool MessageOptions::deprecated() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.deprecated)
+  return deprecated_;
+}
+ void MessageOptions::set_deprecated(bool value) {
+  set_has_deprecated();
+  deprecated_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.deprecated)
+}
+
+// optional bool map_entry = 7;
+ bool MessageOptions::has_map_entry() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+ void MessageOptions::set_has_map_entry() {
+  _has_bits_[0] |= 0x00000008u;
+}
+ void MessageOptions::clear_has_map_entry() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+ void MessageOptions::clear_map_entry() {
+  map_entry_ = false;
+  clear_has_map_entry();
+}
+ bool MessageOptions::map_entry() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.map_entry)
+  return map_entry_;
+}
+ void MessageOptions::set_map_entry(bool value) {
+  set_has_map_entry();
+  map_entry_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.map_entry)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ int MessageOptions::uninterpreted_option_size() const {
+  return uninterpreted_option_.size();
+}
+ void MessageOptions::clear_uninterpreted_option() {
+  uninterpreted_option_.Clear();
+}
+ const ::google::protobuf::UninterpretedOption& MessageOptions::uninterpreted_option(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.uninterpreted_option)
+  return uninterpreted_option_.Get(index);
+}
+ ::google::protobuf::UninterpretedOption* MessageOptions::mutable_uninterpreted_option(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.MessageOptions.uninterpreted_option)
+  return uninterpreted_option_.Mutable(index);
+}
+ ::google::protobuf::UninterpretedOption* MessageOptions::add_uninterpreted_option() {
+  // @@protoc_insertion_point(field_add:google.protobuf.MessageOptions.uninterpreted_option)
+  return uninterpreted_option_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+MessageOptions::uninterpreted_option() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.MessageOptions.uninterpreted_option)
+  return uninterpreted_option_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+MessageOptions::mutable_uninterpreted_option() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.MessageOptions.uninterpreted_option)
+  return &uninterpreted_option_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -6386,21 +8934,19 @@
 
 void FieldOptions::Clear() {
   _extensions_.Clear();
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
-  &reinterpret_cast<FieldOptions*>(16)->f) - \
-   reinterpret_cast<char*>(16))
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+  &reinterpret_cast<FieldOptions*>(16)->f)
 
-#define ZR_(first, last) do {                              \
-    size_t f = OFFSET_OF_FIELD_(first);                    \
-    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
-    ::memset(&first, 0, n);                                \
-  } while (0)
+#define ZR_(first, last) do {\
+  ::memset(&first, 0,\
+           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
 
   if (_has_bits_[0 / 32] & 31) {
     ZR_(ctype_, weak_);
   }
 
-#undef OFFSET_OF_FIELD_
+#undef ZR_HELPER_
 #undef ZR_
 
   uninterpreted_option_.Clear();
@@ -6768,6 +9314,161 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// FieldOptions
+
+// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+ bool FieldOptions::has_ctype() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void FieldOptions::set_has_ctype() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void FieldOptions::clear_has_ctype() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void FieldOptions::clear_ctype() {
+  ctype_ = 0;
+  clear_has_ctype();
+}
+ ::google::protobuf::FieldOptions_CType FieldOptions::ctype() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.ctype)
+  return static_cast< ::google::protobuf::FieldOptions_CType >(ctype_);
+}
+ void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value) {
+  assert(::google::protobuf::FieldOptions_CType_IsValid(value));
+  set_has_ctype();
+  ctype_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.ctype)
+}
+
+// optional bool packed = 2;
+ bool FieldOptions::has_packed() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+ void FieldOptions::set_has_packed() {
+  _has_bits_[0] |= 0x00000002u;
+}
+ void FieldOptions::clear_has_packed() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+ void FieldOptions::clear_packed() {
+  packed_ = false;
+  clear_has_packed();
+}
+ bool FieldOptions::packed() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.packed)
+  return packed_;
+}
+ void FieldOptions::set_packed(bool value) {
+  set_has_packed();
+  packed_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.packed)
+}
+
+// optional bool lazy = 5 [default = false];
+ bool FieldOptions::has_lazy() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+ void FieldOptions::set_has_lazy() {
+  _has_bits_[0] |= 0x00000004u;
+}
+ void FieldOptions::clear_has_lazy() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+ void FieldOptions::clear_lazy() {
+  lazy_ = false;
+  clear_has_lazy();
+}
+ bool FieldOptions::lazy() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.lazy)
+  return lazy_;
+}
+ void FieldOptions::set_lazy(bool value) {
+  set_has_lazy();
+  lazy_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.lazy)
+}
+
+// optional bool deprecated = 3 [default = false];
+ bool FieldOptions::has_deprecated() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+ void FieldOptions::set_has_deprecated() {
+  _has_bits_[0] |= 0x00000008u;
+}
+ void FieldOptions::clear_has_deprecated() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+ void FieldOptions::clear_deprecated() {
+  deprecated_ = false;
+  clear_has_deprecated();
+}
+ bool FieldOptions::deprecated() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.deprecated)
+  return deprecated_;
+}
+ void FieldOptions::set_deprecated(bool value) {
+  set_has_deprecated();
+  deprecated_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.deprecated)
+}
+
+// optional bool weak = 10 [default = false];
+ bool FieldOptions::has_weak() const {
+  return (_has_bits_[0] & 0x00000010u) != 0;
+}
+ void FieldOptions::set_has_weak() {
+  _has_bits_[0] |= 0x00000010u;
+}
+ void FieldOptions::clear_has_weak() {
+  _has_bits_[0] &= ~0x00000010u;
+}
+ void FieldOptions::clear_weak() {
+  weak_ = false;
+  clear_has_weak();
+}
+ bool FieldOptions::weak() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.weak)
+  return weak_;
+}
+ void FieldOptions::set_weak(bool value) {
+  set_has_weak();
+  weak_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.weak)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ int FieldOptions::uninterpreted_option_size() const {
+  return uninterpreted_option_.size();
+}
+ void FieldOptions::clear_uninterpreted_option() {
+  uninterpreted_option_.Clear();
+}
+ const ::google::protobuf::UninterpretedOption& FieldOptions::uninterpreted_option(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.uninterpreted_option)
+  return uninterpreted_option_.Get(index);
+}
+ ::google::protobuf::UninterpretedOption* FieldOptions::mutable_uninterpreted_option(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.uninterpreted_option)
+  return uninterpreted_option_.Mutable(index);
+}
+ ::google::protobuf::UninterpretedOption* FieldOptions::add_uninterpreted_option() {
+  // @@protoc_insertion_point(field_add:google.protobuf.FieldOptions.uninterpreted_option)
+  return uninterpreted_option_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+FieldOptions::uninterpreted_option() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FieldOptions.uninterpreted_option)
+  return uninterpreted_option_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+FieldOptions::mutable_uninterpreted_option() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldOptions.uninterpreted_option)
+  return &uninterpreted_option_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -6838,19 +9539,17 @@
 
 void EnumOptions::Clear() {
   _extensions_.Clear();
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
-  &reinterpret_cast<EnumOptions*>(16)->f) - \
-   reinterpret_cast<char*>(16))
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+  &reinterpret_cast<EnumOptions*>(16)->f)
 
-#define ZR_(first, last) do {                              \
-    size_t f = OFFSET_OF_FIELD_(first);                    \
-    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
-    ::memset(&first, 0, n);                                \
-  } while (0)
+#define ZR_(first, last) do {\
+  ::memset(&first, 0,\
+           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
 
   ZR_(allow_alias_, deprecated_);
 
-#undef OFFSET_OF_FIELD_
+#undef ZR_HELPER_
 #undef ZR_
 
   uninterpreted_option_.Clear();
@@ -7108,6 +9807,88 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// EnumOptions
+
+// optional bool allow_alias = 2;
+ bool EnumOptions::has_allow_alias() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void EnumOptions::set_has_allow_alias() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void EnumOptions::clear_has_allow_alias() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void EnumOptions::clear_allow_alias() {
+  allow_alias_ = false;
+  clear_has_allow_alias();
+}
+ bool EnumOptions::allow_alias() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.allow_alias)
+  return allow_alias_;
+}
+ void EnumOptions::set_allow_alias(bool value) {
+  set_has_allow_alias();
+  allow_alias_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.allow_alias)
+}
+
+// optional bool deprecated = 3 [default = false];
+ bool EnumOptions::has_deprecated() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+ void EnumOptions::set_has_deprecated() {
+  _has_bits_[0] |= 0x00000002u;
+}
+ void EnumOptions::clear_has_deprecated() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+ void EnumOptions::clear_deprecated() {
+  deprecated_ = false;
+  clear_has_deprecated();
+}
+ bool EnumOptions::deprecated() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.deprecated)
+  return deprecated_;
+}
+ void EnumOptions::set_deprecated(bool value) {
+  set_has_deprecated();
+  deprecated_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.deprecated)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ int EnumOptions::uninterpreted_option_size() const {
+  return uninterpreted_option_.size();
+}
+ void EnumOptions::clear_uninterpreted_option() {
+  uninterpreted_option_.Clear();
+}
+ const ::google::protobuf::UninterpretedOption& EnumOptions::uninterpreted_option(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.uninterpreted_option)
+  return uninterpreted_option_.Get(index);
+}
+ ::google::protobuf::UninterpretedOption* EnumOptions::mutable_uninterpreted_option(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumOptions.uninterpreted_option)
+  return uninterpreted_option_.Mutable(index);
+}
+ ::google::protobuf::UninterpretedOption* EnumOptions::add_uninterpreted_option() {
+  // @@protoc_insertion_point(field_add:google.protobuf.EnumOptions.uninterpreted_option)
+  return uninterpreted_option_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+EnumOptions::uninterpreted_option() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.EnumOptions.uninterpreted_option)
+  return uninterpreted_option_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+EnumOptions::mutable_uninterpreted_option() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumOptions.uninterpreted_option)
+  return &uninterpreted_option_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -7396,6 +10177,64 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// EnumValueOptions
+
+// optional bool deprecated = 1 [default = false];
+ bool EnumValueOptions::has_deprecated() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void EnumValueOptions::set_has_deprecated() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void EnumValueOptions::clear_has_deprecated() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void EnumValueOptions::clear_deprecated() {
+  deprecated_ = false;
+  clear_has_deprecated();
+}
+ bool EnumValueOptions::deprecated() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.deprecated)
+  return deprecated_;
+}
+ void EnumValueOptions::set_deprecated(bool value) {
+  set_has_deprecated();
+  deprecated_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueOptions.deprecated)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ int EnumValueOptions::uninterpreted_option_size() const {
+  return uninterpreted_option_.size();
+}
+ void EnumValueOptions::clear_uninterpreted_option() {
+  uninterpreted_option_.Clear();
+}
+ const ::google::protobuf::UninterpretedOption& EnumValueOptions::uninterpreted_option(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.uninterpreted_option)
+  return uninterpreted_option_.Get(index);
+}
+ ::google::protobuf::UninterpretedOption* EnumValueOptions::mutable_uninterpreted_option(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueOptions.uninterpreted_option)
+  return uninterpreted_option_.Mutable(index);
+}
+ ::google::protobuf::UninterpretedOption* EnumValueOptions::add_uninterpreted_option() {
+  // @@protoc_insertion_point(field_add:google.protobuf.EnumValueOptions.uninterpreted_option)
+  return uninterpreted_option_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+EnumValueOptions::uninterpreted_option() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.EnumValueOptions.uninterpreted_option)
+  return uninterpreted_option_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+EnumValueOptions::mutable_uninterpreted_option() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValueOptions.uninterpreted_option)
+  return &uninterpreted_option_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -7684,6 +10523,64 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// ServiceOptions
+
+// optional bool deprecated = 33 [default = false];
+ bool ServiceOptions::has_deprecated() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void ServiceOptions::set_has_deprecated() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void ServiceOptions::clear_has_deprecated() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void ServiceOptions::clear_deprecated() {
+  deprecated_ = false;
+  clear_has_deprecated();
+}
+ bool ServiceOptions::deprecated() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.deprecated)
+  return deprecated_;
+}
+ void ServiceOptions::set_deprecated(bool value) {
+  set_has_deprecated();
+  deprecated_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.ServiceOptions.deprecated)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ int ServiceOptions::uninterpreted_option_size() const {
+  return uninterpreted_option_.size();
+}
+ void ServiceOptions::clear_uninterpreted_option() {
+  uninterpreted_option_.Clear();
+}
+ const ::google::protobuf::UninterpretedOption& ServiceOptions::uninterpreted_option(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.uninterpreted_option)
+  return uninterpreted_option_.Get(index);
+}
+ ::google::protobuf::UninterpretedOption* ServiceOptions::mutable_uninterpreted_option(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceOptions.uninterpreted_option)
+  return uninterpreted_option_.Mutable(index);
+}
+ ::google::protobuf::UninterpretedOption* ServiceOptions::add_uninterpreted_option() {
+  // @@protoc_insertion_point(field_add:google.protobuf.ServiceOptions.uninterpreted_option)
+  return uninterpreted_option_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ServiceOptions::uninterpreted_option() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.ServiceOptions.uninterpreted_option)
+  return uninterpreted_option_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+ServiceOptions::mutable_uninterpreted_option() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceOptions.uninterpreted_option)
+  return &uninterpreted_option_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -7972,6 +10869,64 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// MethodOptions
+
+// optional bool deprecated = 33 [default = false];
+ bool MethodOptions::has_deprecated() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void MethodOptions::set_has_deprecated() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void MethodOptions::clear_has_deprecated() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void MethodOptions::clear_deprecated() {
+  deprecated_ = false;
+  clear_has_deprecated();
+}
+ bool MethodOptions::deprecated() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.deprecated)
+  return deprecated_;
+}
+ void MethodOptions::set_deprecated(bool value) {
+  set_has_deprecated();
+  deprecated_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.deprecated)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ int MethodOptions::uninterpreted_option_size() const {
+  return uninterpreted_option_.size();
+}
+ void MethodOptions::clear_uninterpreted_option() {
+  uninterpreted_option_.Clear();
+}
+ const ::google::protobuf::UninterpretedOption& MethodOptions::uninterpreted_option(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.uninterpreted_option)
+  return uninterpreted_option_.Get(index);
+}
+ ::google::protobuf::UninterpretedOption* MethodOptions::mutable_uninterpreted_option(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodOptions.uninterpreted_option)
+  return uninterpreted_option_.Mutable(index);
+}
+ ::google::protobuf::UninterpretedOption* MethodOptions::add_uninterpreted_option() {
+  // @@protoc_insertion_point(field_add:google.protobuf.MethodOptions.uninterpreted_option)
+  return uninterpreted_option_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+MethodOptions::uninterpreted_option() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.MethodOptions.uninterpreted_option)
+  return uninterpreted_option_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+MethodOptions::mutable_uninterpreted_option() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.MethodOptions.uninterpreted_option)
+  return &uninterpreted_option_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -8359,15 +11314,13 @@
 }
 
 void UninterpretedOption::Clear() {
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
-  &reinterpret_cast<UninterpretedOption*>(16)->f) - \
-   reinterpret_cast<char*>(16))
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+  &reinterpret_cast<UninterpretedOption*>(16)->f)
 
-#define ZR_(first, last) do {                              \
-    size_t f = OFFSET_OF_FIELD_(first);                    \
-    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
-    ::memset(&first, 0, n);                                \
-  } while (0)
+#define ZR_(first, last) do {\
+  ::memset(&first, 0,\
+           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
 
   if (_has_bits_[0 / 32] & 126) {
     ZR_(positive_int_value_, double_value_);
@@ -8382,7 +11335,7 @@
     }
   }
 
-#undef OFFSET_OF_FIELD_
+#undef ZR_HELPER_
 #undef ZR_
 
   name_.Clear();
@@ -8799,6 +11752,352 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// UninterpretedOption_NamePart
+
+// required string name_part = 1;
+ bool UninterpretedOption_NamePart::has_name_part() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+ void UninterpretedOption_NamePart::set_has_name_part() {
+  _has_bits_[0] |= 0x00000001u;
+}
+ void UninterpretedOption_NamePart::clear_has_name_part() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+ void UninterpretedOption_NamePart::clear_name_part() {
+  name_part_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_name_part();
+}
+ const ::std::string& UninterpretedOption_NamePart::name_part() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.name_part)
+  return name_part_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void UninterpretedOption_NamePart::set_name_part(const ::std::string& value) {
+  set_has_name_part();
+  name_part_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.name_part)
+}
+ void UninterpretedOption_NamePart::set_name_part(const char* value) {
+  set_has_name_part();
+  name_part_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.NamePart.name_part)
+}
+ void UninterpretedOption_NamePart::set_name_part(const char* value, size_t size) {
+  set_has_name_part();
+  name_part_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.NamePart.name_part)
+}
+ ::std::string* UninterpretedOption_NamePart::mutable_name_part() {
+  set_has_name_part();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.NamePart.name_part)
+  return name_part_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* UninterpretedOption_NamePart::release_name_part() {
+  clear_has_name_part();
+  return name_part_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void UninterpretedOption_NamePart::set_allocated_name_part(::std::string* name_part) {
+  if (name_part != NULL) {
+    set_has_name_part();
+  } else {
+    clear_has_name_part();
+  }
+  name_part_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name_part);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.NamePart.name_part)
+}
+
+// required bool is_extension = 2;
+ bool UninterpretedOption_NamePart::has_is_extension() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+ void UninterpretedOption_NamePart::set_has_is_extension() {
+  _has_bits_[0] |= 0x00000002u;
+}
+ void UninterpretedOption_NamePart::clear_has_is_extension() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+ void UninterpretedOption_NamePart::clear_is_extension() {
+  is_extension_ = false;
+  clear_has_is_extension();
+}
+ bool UninterpretedOption_NamePart::is_extension() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.is_extension)
+  return is_extension_;
+}
+ void UninterpretedOption_NamePart::set_is_extension(bool value) {
+  set_has_is_extension();
+  is_extension_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.is_extension)
+}
+
+// -------------------------------------------------------------------
+
+// UninterpretedOption
+
+// repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+ int UninterpretedOption::name_size() const {
+  return name_.size();
+}
+ void UninterpretedOption::clear_name() {
+  name_.Clear();
+}
+ const ::google::protobuf::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.name)
+  return name_.Get(index);
+}
+ ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.name)
+  return name_.Mutable(index);
+}
+ ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::add_name() {
+  // @@protoc_insertion_point(field_add:google.protobuf.UninterpretedOption.name)
+  return name_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
+UninterpretedOption::name() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.UninterpretedOption.name)
+  return name_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
+UninterpretedOption::mutable_name() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.UninterpretedOption.name)
+  return &name_;
+}
+
+// optional string identifier_value = 3;
+ bool UninterpretedOption::has_identifier_value() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+ void UninterpretedOption::set_has_identifier_value() {
+  _has_bits_[0] |= 0x00000002u;
+}
+ void UninterpretedOption::clear_has_identifier_value() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+ void UninterpretedOption::clear_identifier_value() {
+  identifier_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_identifier_value();
+}
+ const ::std::string& UninterpretedOption::identifier_value() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.identifier_value)
+  return identifier_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void UninterpretedOption::set_identifier_value(const ::std::string& value) {
+  set_has_identifier_value();
+  identifier_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.identifier_value)
+}
+ void UninterpretedOption::set_identifier_value(const char* value) {
+  set_has_identifier_value();
+  identifier_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.identifier_value)
+}
+ void UninterpretedOption::set_identifier_value(const char* value, size_t size) {
+  set_has_identifier_value();
+  identifier_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.identifier_value)
+}
+ ::std::string* UninterpretedOption::mutable_identifier_value() {
+  set_has_identifier_value();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.identifier_value)
+  return identifier_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* UninterpretedOption::release_identifier_value() {
+  clear_has_identifier_value();
+  return identifier_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void UninterpretedOption::set_allocated_identifier_value(::std::string* identifier_value) {
+  if (identifier_value != NULL) {
+    set_has_identifier_value();
+  } else {
+    clear_has_identifier_value();
+  }
+  identifier_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), identifier_value);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.identifier_value)
+}
+
+// optional uint64 positive_int_value = 4;
+ bool UninterpretedOption::has_positive_int_value() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+ void UninterpretedOption::set_has_positive_int_value() {
+  _has_bits_[0] |= 0x00000004u;
+}
+ void UninterpretedOption::clear_has_positive_int_value() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+ void UninterpretedOption::clear_positive_int_value() {
+  positive_int_value_ = GOOGLE_ULONGLONG(0);
+  clear_has_positive_int_value();
+}
+ ::google::protobuf::uint64 UninterpretedOption::positive_int_value() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.positive_int_value)
+  return positive_int_value_;
+}
+ void UninterpretedOption::set_positive_int_value(::google::protobuf::uint64 value) {
+  set_has_positive_int_value();
+  positive_int_value_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.positive_int_value)
+}
+
+// optional int64 negative_int_value = 5;
+ bool UninterpretedOption::has_negative_int_value() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+ void UninterpretedOption::set_has_negative_int_value() {
+  _has_bits_[0] |= 0x00000008u;
+}
+ void UninterpretedOption::clear_has_negative_int_value() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+ void UninterpretedOption::clear_negative_int_value() {
+  negative_int_value_ = GOOGLE_LONGLONG(0);
+  clear_has_negative_int_value();
+}
+ ::google::protobuf::int64 UninterpretedOption::negative_int_value() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.negative_int_value)
+  return negative_int_value_;
+}
+ void UninterpretedOption::set_negative_int_value(::google::protobuf::int64 value) {
+  set_has_negative_int_value();
+  negative_int_value_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.negative_int_value)
+}
+
+// optional double double_value = 6;
+ bool UninterpretedOption::has_double_value() const {
+  return (_has_bits_[0] & 0x00000010u) != 0;
+}
+ void UninterpretedOption::set_has_double_value() {
+  _has_bits_[0] |= 0x00000010u;
+}
+ void UninterpretedOption::clear_has_double_value() {
+  _has_bits_[0] &= ~0x00000010u;
+}
+ void UninterpretedOption::clear_double_value() {
+  double_value_ = 0;
+  clear_has_double_value();
+}
+ double UninterpretedOption::double_value() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.double_value)
+  return double_value_;
+}
+ void UninterpretedOption::set_double_value(double value) {
+  set_has_double_value();
+  double_value_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.double_value)
+}
+
+// optional bytes string_value = 7;
+ bool UninterpretedOption::has_string_value() const {
+  return (_has_bits_[0] & 0x00000020u) != 0;
+}
+ void UninterpretedOption::set_has_string_value() {
+  _has_bits_[0] |= 0x00000020u;
+}
+ void UninterpretedOption::clear_has_string_value() {
+  _has_bits_[0] &= ~0x00000020u;
+}
+ void UninterpretedOption::clear_string_value() {
+  string_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_string_value();
+}
+ const ::std::string& UninterpretedOption::string_value() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.string_value)
+  return string_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void UninterpretedOption::set_string_value(const ::std::string& value) {
+  set_has_string_value();
+  string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.string_value)
+}
+ void UninterpretedOption::set_string_value(const char* value) {
+  set_has_string_value();
+  string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.string_value)
+}
+ void UninterpretedOption::set_string_value(const void* value, size_t size) {
+  set_has_string_value();
+  string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.string_value)
+}
+ ::std::string* UninterpretedOption::mutable_string_value() {
+  set_has_string_value();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.string_value)
+  return string_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* UninterpretedOption::release_string_value() {
+  clear_has_string_value();
+  return string_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void UninterpretedOption::set_allocated_string_value(::std::string* string_value) {
+  if (string_value != NULL) {
+    set_has_string_value();
+  } else {
+    clear_has_string_value();
+  }
+  string_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), string_value);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.string_value)
+}
+
+// optional string aggregate_value = 8;
+ bool UninterpretedOption::has_aggregate_value() const {
+  return (_has_bits_[0] & 0x00000040u) != 0;
+}
+ void UninterpretedOption::set_has_aggregate_value() {
+  _has_bits_[0] |= 0x00000040u;
+}
+ void UninterpretedOption::clear_has_aggregate_value() {
+  _has_bits_[0] &= ~0x00000040u;
+}
+ void UninterpretedOption::clear_aggregate_value() {
+  aggregate_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_aggregate_value();
+}
+ const ::std::string& UninterpretedOption::aggregate_value() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.aggregate_value)
+  return aggregate_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void UninterpretedOption::set_aggregate_value(const ::std::string& value) {
+  set_has_aggregate_value();
+  aggregate_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.aggregate_value)
+}
+ void UninterpretedOption::set_aggregate_value(const char* value) {
+  set_has_aggregate_value();
+  aggregate_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.aggregate_value)
+}
+ void UninterpretedOption::set_aggregate_value(const char* value, size_t size) {
+  set_has_aggregate_value();
+  aggregate_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.aggregate_value)
+}
+ ::std::string* UninterpretedOption::mutable_aggregate_value() {
+  set_has_aggregate_value();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.aggregate_value)
+  return aggregate_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* UninterpretedOption::release_aggregate_value() {
+  clear_has_aggregate_value();
+  return aggregate_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void UninterpretedOption::set_allocated_aggregate_value(::std::string* aggregate_value) {
+  if (aggregate_value != NULL) {
+    set_has_aggregate_value();
+  } else {
+    clear_has_aggregate_value();
+  }
+  aggregate_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), aggregate_value);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.aggregate_value)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
@@ -8807,6 +12106,7 @@
 const int SourceCodeInfo_Location::kSpanFieldNumber;
 const int SourceCodeInfo_Location::kLeadingCommentsFieldNumber;
 const int SourceCodeInfo_Location::kTrailingCommentsFieldNumber;
+const int SourceCodeInfo_Location::kLeadingDetachedCommentsFieldNumber;
 #endif  // !_MSC_VER
 
 SourceCodeInfo_Location::SourceCodeInfo_Location()
@@ -8882,6 +12182,7 @@
   }
   path_.Clear();
   span_.Clear();
+  leading_detached_comments_.Clear();
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   if (_internal_metadata_.have_unknown_fields()) {
     mutable_unknown_fields()->Clear();
@@ -8963,6 +12264,25 @@
         } else {
           goto handle_unusual;
         }
+        if (input->ExpectTag(50)) goto parse_leading_detached_comments;
+        break;
+      }
+
+      // repeated string leading_detached_comments = 6;
+      case 6: {
+        if (tag == 50) {
+         parse_leading_detached_comments:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->add_leading_detached_comments()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->leading_detached_comments(this->leading_detached_comments_size() - 1).data(),
+            this->leading_detached_comments(this->leading_detached_comments_size() - 1).length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(50)) goto parse_leading_detached_comments;
         if (input->ExpectAtEnd()) goto success;
         break;
       }
@@ -9032,6 +12352,16 @@
       4, this->trailing_comments(), output);
   }
 
+  // repeated string leading_detached_comments = 6;
+  for (int i = 0; i < this->leading_detached_comments_size(); i++) {
+  ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+    this->leading_detached_comments(i).data(), this->leading_detached_comments(i).length(),
+    ::google::protobuf::internal::WireFormat::SERIALIZE,
+    "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
+    ::google::protobuf::internal::WireFormatLite::WriteString(
+      6, this->leading_detached_comments(i), output);
+  }
+
   if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
         unknown_fields(), output);
@@ -9092,6 +12422,16 @@
         4, this->trailing_comments(), target);
   }
 
+  // repeated string leading_detached_comments = 6;
+  for (int i = 0; i < this->leading_detached_comments_size(); i++) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->leading_detached_comments(i).data(), this->leading_detached_comments(i).length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteStringToArray(6, this->leading_detached_comments(i), target);
+  }
+
   if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
         unknown_fields(), target);
@@ -9153,6 +12493,13 @@
     total_size += data_size;
   }
 
+  // repeated string leading_detached_comments = 6;
+  total_size += 1 * this->leading_detached_comments_size();
+  for (int i = 0; i < this->leading_detached_comments_size(); i++) {
+    total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
+      this->leading_detached_comments(i));
+  }
+
   if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -9180,6 +12527,7 @@
   if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
   path_.MergeFrom(from.path_);
   span_.MergeFrom(from.span_);
+  leading_detached_comments_.MergeFrom(from.leading_detached_comments_);
   if (from._has_bits_[2 / 32] & (0xffu << (2 % 32))) {
     if (from.has_leading_comments()) {
       set_has_leading_comments();
@@ -9221,6 +12569,7 @@
   span_.UnsafeArenaSwap(&other->span_);
   leading_comments_.Swap(&other->leading_comments_);
   trailing_comments_.Swap(&other->trailing_comments_);
+  leading_detached_comments_.UnsafeArenaSwap(&other->leading_detached_comments_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   std::swap(_cached_size_, other->_cached_size_);
@@ -9464,6 +12813,264 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// SourceCodeInfo_Location
+
+// repeated int32 path = 1 [packed = true];
+ int SourceCodeInfo_Location::path_size() const {
+  return path_.size();
+}
+ void SourceCodeInfo_Location::clear_path() {
+  path_.Clear();
+}
+ ::google::protobuf::int32 SourceCodeInfo_Location::path(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.path)
+  return path_.Get(index);
+}
+ void SourceCodeInfo_Location::set_path(int index, ::google::protobuf::int32 value) {
+  path_.Set(index, value);
+  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.path)
+}
+ void SourceCodeInfo_Location::add_path(::google::protobuf::int32 value) {
+  path_.Add(value);
+  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.path)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+SourceCodeInfo_Location::path() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.path)
+  return path_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+SourceCodeInfo_Location::mutable_path() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.path)
+  return &path_;
+}
+
+// repeated int32 span = 2 [packed = true];
+ int SourceCodeInfo_Location::span_size() const {
+  return span_.size();
+}
+ void SourceCodeInfo_Location::clear_span() {
+  span_.Clear();
+}
+ ::google::protobuf::int32 SourceCodeInfo_Location::span(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.span)
+  return span_.Get(index);
+}
+ void SourceCodeInfo_Location::set_span(int index, ::google::protobuf::int32 value) {
+  span_.Set(index, value);
+  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.span)
+}
+ void SourceCodeInfo_Location::add_span(::google::protobuf::int32 value) {
+  span_.Add(value);
+  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.span)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+SourceCodeInfo_Location::span() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.span)
+  return span_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+SourceCodeInfo_Location::mutable_span() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.span)
+  return &span_;
+}
+
+// optional string leading_comments = 3;
+ bool SourceCodeInfo_Location::has_leading_comments() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+ void SourceCodeInfo_Location::set_has_leading_comments() {
+  _has_bits_[0] |= 0x00000004u;
+}
+ void SourceCodeInfo_Location::clear_has_leading_comments() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+ void SourceCodeInfo_Location::clear_leading_comments() {
+  leading_comments_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_leading_comments();
+}
+ const ::std::string& SourceCodeInfo_Location::leading_comments() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.leading_comments)
+  return leading_comments_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void SourceCodeInfo_Location::set_leading_comments(const ::std::string& value) {
+  set_has_leading_comments();
+  leading_comments_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_comments)
+}
+ void SourceCodeInfo_Location::set_leading_comments(const char* value) {
+  set_has_leading_comments();
+  leading_comments_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_comments)
+}
+ void SourceCodeInfo_Location::set_leading_comments(const char* value, size_t size) {
+  set_has_leading_comments();
+  leading_comments_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_comments)
+}
+ ::std::string* SourceCodeInfo_Location::mutable_leading_comments() {
+  set_has_leading_comments();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_comments)
+  return leading_comments_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* SourceCodeInfo_Location::release_leading_comments() {
+  clear_has_leading_comments();
+  return leading_comments_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void SourceCodeInfo_Location::set_allocated_leading_comments(::std::string* leading_comments) {
+  if (leading_comments != NULL) {
+    set_has_leading_comments();
+  } else {
+    clear_has_leading_comments();
+  }
+  leading_comments_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), leading_comments);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.leading_comments)
+}
+
+// optional string trailing_comments = 4;
+ bool SourceCodeInfo_Location::has_trailing_comments() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+ void SourceCodeInfo_Location::set_has_trailing_comments() {
+  _has_bits_[0] |= 0x00000008u;
+}
+ void SourceCodeInfo_Location::clear_has_trailing_comments() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+ void SourceCodeInfo_Location::clear_trailing_comments() {
+  trailing_comments_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_trailing_comments();
+}
+ const ::std::string& SourceCodeInfo_Location::trailing_comments() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+  return trailing_comments_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void SourceCodeInfo_Location::set_trailing_comments(const ::std::string& value) {
+  set_has_trailing_comments();
+  trailing_comments_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+}
+ void SourceCodeInfo_Location::set_trailing_comments(const char* value) {
+  set_has_trailing_comments();
+  trailing_comments_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+}
+ void SourceCodeInfo_Location::set_trailing_comments(const char* value, size_t size) {
+  set_has_trailing_comments();
+  trailing_comments_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+}
+ ::std::string* SourceCodeInfo_Location::mutable_trailing_comments() {
+  set_has_trailing_comments();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+  return trailing_comments_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* SourceCodeInfo_Location::release_trailing_comments() {
+  clear_has_trailing_comments();
+  return trailing_comments_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void SourceCodeInfo_Location::set_allocated_trailing_comments(::std::string* trailing_comments) {
+  if (trailing_comments != NULL) {
+    set_has_trailing_comments();
+  } else {
+    clear_has_trailing_comments();
+  }
+  trailing_comments_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), trailing_comments);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+}
+
+// repeated string leading_detached_comments = 6;
+ int SourceCodeInfo_Location::leading_detached_comments_size() const {
+  return leading_detached_comments_.size();
+}
+ void SourceCodeInfo_Location::clear_leading_detached_comments() {
+  leading_detached_comments_.Clear();
+}
+ const ::std::string& SourceCodeInfo_Location::leading_detached_comments(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+  return leading_detached_comments_.Get(index);
+}
+ ::std::string* SourceCodeInfo_Location::mutable_leading_detached_comments(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+  return leading_detached_comments_.Mutable(index);
+}
+ void SourceCodeInfo_Location::set_leading_detached_comments(int index, const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+  leading_detached_comments_.Mutable(index)->assign(value);
+}
+ void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value) {
+  leading_detached_comments_.Mutable(index)->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+ void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value, size_t size) {
+  leading_detached_comments_.Mutable(index)->assign(
+    reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+ ::std::string* SourceCodeInfo_Location::add_leading_detached_comments() {
+  return leading_detached_comments_.Add();
+}
+ void SourceCodeInfo_Location::add_leading_detached_comments(const ::std::string& value) {
+  leading_detached_comments_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+ void SourceCodeInfo_Location::add_leading_detached_comments(const char* value) {
+  leading_detached_comments_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+ void SourceCodeInfo_Location::add_leading_detached_comments(const char* value, size_t size) {
+  leading_detached_comments_.Add()->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_add_pointer:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+ const ::google::protobuf::RepeatedPtrField< ::std::string>&
+SourceCodeInfo_Location::leading_detached_comments() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+  return leading_detached_comments_;
+}
+ ::google::protobuf::RepeatedPtrField< ::std::string>*
+SourceCodeInfo_Location::mutable_leading_detached_comments() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+  return &leading_detached_comments_;
+}
+
+// -------------------------------------------------------------------
+
+// SourceCodeInfo
+
+// repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ int SourceCodeInfo::location_size() const {
+  return location_.size();
+}
+ void SourceCodeInfo::clear_location() {
+  location_.Clear();
+}
+ const ::google::protobuf::SourceCodeInfo_Location& SourceCodeInfo::location(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.location)
+  return location_.Get(index);
+}
+ ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::mutable_location(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.location)
+  return location_.Mutable(index);
+}
+ ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::add_location() {
+  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.location)
+  return location_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
+SourceCodeInfo::location() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.location)
+  return location_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
+SourceCodeInfo::mutable_location() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.location)
+  return &location_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // @@protoc_insertion_point(namespace_scope)
 
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index cda2598..d8cba65 100644
--- a/src/google/protobuf/descriptor.pb.h
+++ b/src/google/protobuf/descriptor.pb.h
@@ -222,15 +222,15 @@
   // accessors -------------------------------------------------------
 
   // repeated .google.protobuf.FileDescriptorProto file = 1;
-  inline int file_size() const;
-  inline void clear_file();
+  int file_size() const;
+  void clear_file();
   static const int kFileFieldNumber = 1;
-  inline const ::google::protobuf::FileDescriptorProto& file(int index) const;
-  inline ::google::protobuf::FileDescriptorProto* mutable_file(int index);
-  inline ::google::protobuf::FileDescriptorProto* add_file();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+  const ::google::protobuf::FileDescriptorProto& file(int index) const;
+  ::google::protobuf::FileDescriptorProto* mutable_file(int index);
+  ::google::protobuf::FileDescriptorProto* add_file();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
       file() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
       mutable_file();
 
   // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet)
@@ -314,146 +314,146 @@
   // accessors -------------------------------------------------------
 
   // optional string name = 1;
-  inline bool has_name() const;
-  inline void clear_name();
+  bool has_name() const;
+  void clear_name();
   static const int kNameFieldNumber = 1;
-  inline const ::std::string& name() const;
-  inline void set_name(const ::std::string& value);
-  inline void set_name(const char* value);
-  inline void set_name(const char* value, size_t size);
-  inline ::std::string* mutable_name();
-  inline ::std::string* release_name();
-  inline void set_allocated_name(::std::string* name);
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  void set_name(const char* value);
+  void set_name(const char* value, size_t size);
+  ::std::string* mutable_name();
+  ::std::string* release_name();
+  void set_allocated_name(::std::string* name);
 
   // optional string package = 2;
-  inline bool has_package() const;
-  inline void clear_package();
+  bool has_package() const;
+  void clear_package();
   static const int kPackageFieldNumber = 2;
-  inline const ::std::string& package() const;
-  inline void set_package(const ::std::string& value);
-  inline void set_package(const char* value);
-  inline void set_package(const char* value, size_t size);
-  inline ::std::string* mutable_package();
-  inline ::std::string* release_package();
-  inline void set_allocated_package(::std::string* package);
+  const ::std::string& package() const;
+  void set_package(const ::std::string& value);
+  void set_package(const char* value);
+  void set_package(const char* value, size_t size);
+  ::std::string* mutable_package();
+  ::std::string* release_package();
+  void set_allocated_package(::std::string* package);
 
   // repeated string dependency = 3;
-  inline int dependency_size() const;
-  inline void clear_dependency();
+  int dependency_size() const;
+  void clear_dependency();
   static const int kDependencyFieldNumber = 3;
-  inline const ::std::string& dependency(int index) const;
-  inline ::std::string* mutable_dependency(int index);
-  inline void set_dependency(int index, const ::std::string& value);
-  inline void set_dependency(int index, const char* value);
-  inline void set_dependency(int index, const char* value, size_t size);
-  inline ::std::string* add_dependency();
-  inline void add_dependency(const ::std::string& value);
-  inline void add_dependency(const char* value);
-  inline void add_dependency(const char* value, size_t size);
-  inline const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const;
-  inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency();
+  const ::std::string& dependency(int index) const;
+  ::std::string* mutable_dependency(int index);
+  void set_dependency(int index, const ::std::string& value);
+  void set_dependency(int index, const char* value);
+  void set_dependency(int index, const char* value, size_t size);
+  ::std::string* add_dependency();
+  void add_dependency(const ::std::string& value);
+  void add_dependency(const char* value);
+  void add_dependency(const char* value, size_t size);
+  const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const;
+  ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency();
 
   // repeated int32 public_dependency = 10;
-  inline int public_dependency_size() const;
-  inline void clear_public_dependency();
+  int public_dependency_size() const;
+  void clear_public_dependency();
   static const int kPublicDependencyFieldNumber = 10;
-  inline ::google::protobuf::int32 public_dependency(int index) const;
-  inline void set_public_dependency(int index, ::google::protobuf::int32 value);
-  inline void add_public_dependency(::google::protobuf::int32 value);
-  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+  ::google::protobuf::int32 public_dependency(int index) const;
+  void set_public_dependency(int index, ::google::protobuf::int32 value);
+  void add_public_dependency(::google::protobuf::int32 value);
+  const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
       public_dependency() const;
-  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
       mutable_public_dependency();
 
   // repeated int32 weak_dependency = 11;
-  inline int weak_dependency_size() const;
-  inline void clear_weak_dependency();
+  int weak_dependency_size() const;
+  void clear_weak_dependency();
   static const int kWeakDependencyFieldNumber = 11;
-  inline ::google::protobuf::int32 weak_dependency(int index) const;
-  inline void set_weak_dependency(int index, ::google::protobuf::int32 value);
-  inline void add_weak_dependency(::google::protobuf::int32 value);
-  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+  ::google::protobuf::int32 weak_dependency(int index) const;
+  void set_weak_dependency(int index, ::google::protobuf::int32 value);
+  void add_weak_dependency(::google::protobuf::int32 value);
+  const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
       weak_dependency() const;
-  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
       mutable_weak_dependency();
 
   // repeated .google.protobuf.DescriptorProto message_type = 4;
-  inline int message_type_size() const;
-  inline void clear_message_type();
+  int message_type_size() const;
+  void clear_message_type();
   static const int kMessageTypeFieldNumber = 4;
-  inline const ::google::protobuf::DescriptorProto& message_type(int index) const;
-  inline ::google::protobuf::DescriptorProto* mutable_message_type(int index);
-  inline ::google::protobuf::DescriptorProto* add_message_type();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+  const ::google::protobuf::DescriptorProto& message_type(int index) const;
+  ::google::protobuf::DescriptorProto* mutable_message_type(int index);
+  ::google::protobuf::DescriptorProto* add_message_type();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
       message_type() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
       mutable_message_type();
 
   // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
-  inline int enum_type_size() const;
-  inline void clear_enum_type();
+  int enum_type_size() const;
+  void clear_enum_type();
   static const int kEnumTypeFieldNumber = 5;
-  inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const;
-  inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index);
-  inline ::google::protobuf::EnumDescriptorProto* add_enum_type();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+  const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const;
+  ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index);
+  ::google::protobuf::EnumDescriptorProto* add_enum_type();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
       enum_type() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
       mutable_enum_type();
 
   // repeated .google.protobuf.ServiceDescriptorProto service = 6;
-  inline int service_size() const;
-  inline void clear_service();
+  int service_size() const;
+  void clear_service();
   static const int kServiceFieldNumber = 6;
-  inline const ::google::protobuf::ServiceDescriptorProto& service(int index) const;
-  inline ::google::protobuf::ServiceDescriptorProto* mutable_service(int index);
-  inline ::google::protobuf::ServiceDescriptorProto* add_service();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
+  const ::google::protobuf::ServiceDescriptorProto& service(int index) const;
+  ::google::protobuf::ServiceDescriptorProto* mutable_service(int index);
+  ::google::protobuf::ServiceDescriptorProto* add_service();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
       service() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
       mutable_service();
 
   // repeated .google.protobuf.FieldDescriptorProto extension = 7;
-  inline int extension_size() const;
-  inline void clear_extension();
+  int extension_size() const;
+  void clear_extension();
   static const int kExtensionFieldNumber = 7;
-  inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
-  inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
-  inline ::google::protobuf::FieldDescriptorProto* add_extension();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+  const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
+  ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
+  ::google::protobuf::FieldDescriptorProto* add_extension();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
       extension() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
       mutable_extension();
 
   // optional .google.protobuf.FileOptions options = 8;
-  inline bool has_options() const;
-  inline void clear_options();
+  bool has_options() const;
+  void clear_options();
   static const int kOptionsFieldNumber = 8;
-  inline const ::google::protobuf::FileOptions& options() const;
-  inline ::google::protobuf::FileOptions* mutable_options();
-  inline ::google::protobuf::FileOptions* release_options();
-  inline void set_allocated_options(::google::protobuf::FileOptions* options);
+  const ::google::protobuf::FileOptions& options() const;
+  ::google::protobuf::FileOptions* mutable_options();
+  ::google::protobuf::FileOptions* release_options();
+  void set_allocated_options(::google::protobuf::FileOptions* options);
 
   // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
-  inline bool has_source_code_info() const;
-  inline void clear_source_code_info();
+  bool has_source_code_info() const;
+  void clear_source_code_info();
   static const int kSourceCodeInfoFieldNumber = 9;
-  inline const ::google::protobuf::SourceCodeInfo& source_code_info() const;
-  inline ::google::protobuf::SourceCodeInfo* mutable_source_code_info();
-  inline ::google::protobuf::SourceCodeInfo* release_source_code_info();
-  inline void set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info);
+  const ::google::protobuf::SourceCodeInfo& source_code_info() const;
+  ::google::protobuf::SourceCodeInfo* mutable_source_code_info();
+  ::google::protobuf::SourceCodeInfo* release_source_code_info();
+  void set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info);
 
   // optional string syntax = 12;
-  inline bool has_syntax() const;
-  inline void clear_syntax();
+  bool has_syntax() const;
+  void clear_syntax();
   static const int kSyntaxFieldNumber = 12;
-  inline const ::std::string& syntax() const;
-  inline void set_syntax(const ::std::string& value);
-  inline void set_syntax(const char* value);
-  inline void set_syntax(const char* value, size_t size);
-  inline ::std::string* mutable_syntax();
-  inline ::std::string* release_syntax();
-  inline void set_allocated_syntax(::std::string* syntax);
+  const ::std::string& syntax() const;
+  void set_syntax(const ::std::string& value);
+  void set_syntax(const char* value);
+  void set_syntax(const char* value, size_t size);
+  ::std::string* mutable_syntax();
+  ::std::string* release_syntax();
+  void set_allocated_syntax(::std::string* syntax);
 
   // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto)
  private:
@@ -557,18 +557,18 @@
   // accessors -------------------------------------------------------
 
   // optional int32 start = 1;
-  inline bool has_start() const;
-  inline void clear_start();
+  bool has_start() const;
+  void clear_start();
   static const int kStartFieldNumber = 1;
-  inline ::google::protobuf::int32 start() const;
-  inline void set_start(::google::protobuf::int32 value);
+  ::google::protobuf::int32 start() const;
+  void set_start(::google::protobuf::int32 value);
 
   // optional int32 end = 2;
-  inline bool has_end() const;
-  inline void clear_end();
+  bool has_end() const;
+  void clear_end();
   static const int kEndFieldNumber = 2;
-  inline ::google::protobuf::int32 end() const;
-  inline void set_end(::google::protobuf::int32 value);
+  ::google::protobuf::int32 end() const;
+  void set_end(::google::protobuf::int32 value);
 
   // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange)
  private:
@@ -658,97 +658,97 @@
   // accessors -------------------------------------------------------
 
   // optional string name = 1;
-  inline bool has_name() const;
-  inline void clear_name();
+  bool has_name() const;
+  void clear_name();
   static const int kNameFieldNumber = 1;
-  inline const ::std::string& name() const;
-  inline void set_name(const ::std::string& value);
-  inline void set_name(const char* value);
-  inline void set_name(const char* value, size_t size);
-  inline ::std::string* mutable_name();
-  inline ::std::string* release_name();
-  inline void set_allocated_name(::std::string* name);
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  void set_name(const char* value);
+  void set_name(const char* value, size_t size);
+  ::std::string* mutable_name();
+  ::std::string* release_name();
+  void set_allocated_name(::std::string* name);
 
   // repeated .google.protobuf.FieldDescriptorProto field = 2;
-  inline int field_size() const;
-  inline void clear_field();
+  int field_size() const;
+  void clear_field();
   static const int kFieldFieldNumber = 2;
-  inline const ::google::protobuf::FieldDescriptorProto& field(int index) const;
-  inline ::google::protobuf::FieldDescriptorProto* mutable_field(int index);
-  inline ::google::protobuf::FieldDescriptorProto* add_field();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+  const ::google::protobuf::FieldDescriptorProto& field(int index) const;
+  ::google::protobuf::FieldDescriptorProto* mutable_field(int index);
+  ::google::protobuf::FieldDescriptorProto* add_field();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
       field() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
       mutable_field();
 
   // repeated .google.protobuf.FieldDescriptorProto extension = 6;
-  inline int extension_size() const;
-  inline void clear_extension();
+  int extension_size() const;
+  void clear_extension();
   static const int kExtensionFieldNumber = 6;
-  inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
-  inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
-  inline ::google::protobuf::FieldDescriptorProto* add_extension();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+  const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
+  ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
+  ::google::protobuf::FieldDescriptorProto* add_extension();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
       extension() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
       mutable_extension();
 
   // repeated .google.protobuf.DescriptorProto nested_type = 3;
-  inline int nested_type_size() const;
-  inline void clear_nested_type();
+  int nested_type_size() const;
+  void clear_nested_type();
   static const int kNestedTypeFieldNumber = 3;
-  inline const ::google::protobuf::DescriptorProto& nested_type(int index) const;
-  inline ::google::protobuf::DescriptorProto* mutable_nested_type(int index);
-  inline ::google::protobuf::DescriptorProto* add_nested_type();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+  const ::google::protobuf::DescriptorProto& nested_type(int index) const;
+  ::google::protobuf::DescriptorProto* mutable_nested_type(int index);
+  ::google::protobuf::DescriptorProto* add_nested_type();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
       nested_type() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
       mutable_nested_type();
 
   // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
-  inline int enum_type_size() const;
-  inline void clear_enum_type();
+  int enum_type_size() const;
+  void clear_enum_type();
   static const int kEnumTypeFieldNumber = 4;
-  inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const;
-  inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index);
-  inline ::google::protobuf::EnumDescriptorProto* add_enum_type();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+  const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const;
+  ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index);
+  ::google::protobuf::EnumDescriptorProto* add_enum_type();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
       enum_type() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
       mutable_enum_type();
 
   // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
-  inline int extension_range_size() const;
-  inline void clear_extension_range();
+  int extension_range_size() const;
+  void clear_extension_range();
   static const int kExtensionRangeFieldNumber = 5;
-  inline const ::google::protobuf::DescriptorProto_ExtensionRange& extension_range(int index) const;
-  inline ::google::protobuf::DescriptorProto_ExtensionRange* mutable_extension_range(int index);
-  inline ::google::protobuf::DescriptorProto_ExtensionRange* add_extension_range();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
+  const ::google::protobuf::DescriptorProto_ExtensionRange& extension_range(int index) const;
+  ::google::protobuf::DescriptorProto_ExtensionRange* mutable_extension_range(int index);
+  ::google::protobuf::DescriptorProto_ExtensionRange* add_extension_range();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
       extension_range() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
       mutable_extension_range();
 
   // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
-  inline int oneof_decl_size() const;
-  inline void clear_oneof_decl();
+  int oneof_decl_size() const;
+  void clear_oneof_decl();
   static const int kOneofDeclFieldNumber = 8;
-  inline const ::google::protobuf::OneofDescriptorProto& oneof_decl(int index) const;
-  inline ::google::protobuf::OneofDescriptorProto* mutable_oneof_decl(int index);
-  inline ::google::protobuf::OneofDescriptorProto* add_oneof_decl();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
+  const ::google::protobuf::OneofDescriptorProto& oneof_decl(int index) const;
+  ::google::protobuf::OneofDescriptorProto* mutable_oneof_decl(int index);
+  ::google::protobuf::OneofDescriptorProto* add_oneof_decl();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
       oneof_decl() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >*
       mutable_oneof_decl();
 
   // optional .google.protobuf.MessageOptions options = 7;
-  inline bool has_options() const;
-  inline void clear_options();
+  bool has_options() const;
+  void clear_options();
   static const int kOptionsFieldNumber = 7;
-  inline const ::google::protobuf::MessageOptions& options() const;
-  inline ::google::protobuf::MessageOptions* mutable_options();
-  inline ::google::protobuf::MessageOptions* release_options();
-  inline void set_allocated_options(::google::protobuf::MessageOptions* options);
+  const ::google::protobuf::MessageOptions& options() const;
+  ::google::protobuf::MessageOptions* mutable_options();
+  ::google::protobuf::MessageOptions* release_options();
+  void set_allocated_options(::google::protobuf::MessageOptions* options);
 
   // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto)
  private:
@@ -907,89 +907,89 @@
   // accessors -------------------------------------------------------
 
   // optional string name = 1;
-  inline bool has_name() const;
-  inline void clear_name();
+  bool has_name() const;
+  void clear_name();
   static const int kNameFieldNumber = 1;
-  inline const ::std::string& name() const;
-  inline void set_name(const ::std::string& value);
-  inline void set_name(const char* value);
-  inline void set_name(const char* value, size_t size);
-  inline ::std::string* mutable_name();
-  inline ::std::string* release_name();
-  inline void set_allocated_name(::std::string* name);
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  void set_name(const char* value);
+  void set_name(const char* value, size_t size);
+  ::std::string* mutable_name();
+  ::std::string* release_name();
+  void set_allocated_name(::std::string* name);
 
   // optional int32 number = 3;
-  inline bool has_number() const;
-  inline void clear_number();
+  bool has_number() const;
+  void clear_number();
   static const int kNumberFieldNumber = 3;
-  inline ::google::protobuf::int32 number() const;
-  inline void set_number(::google::protobuf::int32 value);
+  ::google::protobuf::int32 number() const;
+  void set_number(::google::protobuf::int32 value);
 
   // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
-  inline bool has_label() const;
-  inline void clear_label();
+  bool has_label() const;
+  void clear_label();
   static const int kLabelFieldNumber = 4;
-  inline ::google::protobuf::FieldDescriptorProto_Label label() const;
-  inline void set_label(::google::protobuf::FieldDescriptorProto_Label value);
+  ::google::protobuf::FieldDescriptorProto_Label label() const;
+  void set_label(::google::protobuf::FieldDescriptorProto_Label value);
 
   // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
-  inline bool has_type() const;
-  inline void clear_type();
+  bool has_type() const;
+  void clear_type();
   static const int kTypeFieldNumber = 5;
-  inline ::google::protobuf::FieldDescriptorProto_Type type() const;
-  inline void set_type(::google::protobuf::FieldDescriptorProto_Type value);
+  ::google::protobuf::FieldDescriptorProto_Type type() const;
+  void set_type(::google::protobuf::FieldDescriptorProto_Type value);
 
   // optional string type_name = 6;
-  inline bool has_type_name() const;
-  inline void clear_type_name();
+  bool has_type_name() const;
+  void clear_type_name();
   static const int kTypeNameFieldNumber = 6;
-  inline const ::std::string& type_name() const;
-  inline void set_type_name(const ::std::string& value);
-  inline void set_type_name(const char* value);
-  inline void set_type_name(const char* value, size_t size);
-  inline ::std::string* mutable_type_name();
-  inline ::std::string* release_type_name();
-  inline void set_allocated_type_name(::std::string* type_name);
+  const ::std::string& type_name() const;
+  void set_type_name(const ::std::string& value);
+  void set_type_name(const char* value);
+  void set_type_name(const char* value, size_t size);
+  ::std::string* mutable_type_name();
+  ::std::string* release_type_name();
+  void set_allocated_type_name(::std::string* type_name);
 
   // optional string extendee = 2;
-  inline bool has_extendee() const;
-  inline void clear_extendee();
+  bool has_extendee() const;
+  void clear_extendee();
   static const int kExtendeeFieldNumber = 2;
-  inline const ::std::string& extendee() const;
-  inline void set_extendee(const ::std::string& value);
-  inline void set_extendee(const char* value);
-  inline void set_extendee(const char* value, size_t size);
-  inline ::std::string* mutable_extendee();
-  inline ::std::string* release_extendee();
-  inline void set_allocated_extendee(::std::string* extendee);
+  const ::std::string& extendee() const;
+  void set_extendee(const ::std::string& value);
+  void set_extendee(const char* value);
+  void set_extendee(const char* value, size_t size);
+  ::std::string* mutable_extendee();
+  ::std::string* release_extendee();
+  void set_allocated_extendee(::std::string* extendee);
 
   // optional string default_value = 7;
-  inline bool has_default_value() const;
-  inline void clear_default_value();
+  bool has_default_value() const;
+  void clear_default_value();
   static const int kDefaultValueFieldNumber = 7;
-  inline const ::std::string& default_value() const;
-  inline void set_default_value(const ::std::string& value);
-  inline void set_default_value(const char* value);
-  inline void set_default_value(const char* value, size_t size);
-  inline ::std::string* mutable_default_value();
-  inline ::std::string* release_default_value();
-  inline void set_allocated_default_value(::std::string* default_value);
+  const ::std::string& default_value() const;
+  void set_default_value(const ::std::string& value);
+  void set_default_value(const char* value);
+  void set_default_value(const char* value, size_t size);
+  ::std::string* mutable_default_value();
+  ::std::string* release_default_value();
+  void set_allocated_default_value(::std::string* default_value);
 
   // optional int32 oneof_index = 9;
-  inline bool has_oneof_index() const;
-  inline void clear_oneof_index();
+  bool has_oneof_index() const;
+  void clear_oneof_index();
   static const int kOneofIndexFieldNumber = 9;
-  inline ::google::protobuf::int32 oneof_index() const;
-  inline void set_oneof_index(::google::protobuf::int32 value);
+  ::google::protobuf::int32 oneof_index() const;
+  void set_oneof_index(::google::protobuf::int32 value);
 
   // optional .google.protobuf.FieldOptions options = 8;
-  inline bool has_options() const;
-  inline void clear_options();
+  bool has_options() const;
+  void clear_options();
   static const int kOptionsFieldNumber = 8;
-  inline const ::google::protobuf::FieldOptions& options() const;
-  inline ::google::protobuf::FieldOptions* mutable_options();
-  inline ::google::protobuf::FieldOptions* release_options();
-  inline void set_allocated_options(::google::protobuf::FieldOptions* options);
+  const ::google::protobuf::FieldOptions& options() const;
+  ::google::protobuf::FieldOptions* mutable_options();
+  ::google::protobuf::FieldOptions* release_options();
+  void set_allocated_options(::google::protobuf::FieldOptions* options);
 
   // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto)
  private:
@@ -1098,16 +1098,16 @@
   // accessors -------------------------------------------------------
 
   // optional string name = 1;
-  inline bool has_name() const;
-  inline void clear_name();
+  bool has_name() const;
+  void clear_name();
   static const int kNameFieldNumber = 1;
-  inline const ::std::string& name() const;
-  inline void set_name(const ::std::string& value);
-  inline void set_name(const char* value);
-  inline void set_name(const char* value, size_t size);
-  inline ::std::string* mutable_name();
-  inline ::std::string* release_name();
-  inline void set_allocated_name(::std::string* name);
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  void set_name(const char* value);
+  void set_name(const char* value, size_t size);
+  ::std::string* mutable_name();
+  ::std::string* release_name();
+  void set_allocated_name(::std::string* name);
 
   // @@protoc_insertion_point(class_scope:google.protobuf.OneofDescriptorProto)
  private:
@@ -1192,37 +1192,37 @@
   // accessors -------------------------------------------------------
 
   // optional string name = 1;
-  inline bool has_name() const;
-  inline void clear_name();
+  bool has_name() const;
+  void clear_name();
   static const int kNameFieldNumber = 1;
-  inline const ::std::string& name() const;
-  inline void set_name(const ::std::string& value);
-  inline void set_name(const char* value);
-  inline void set_name(const char* value, size_t size);
-  inline ::std::string* mutable_name();
-  inline ::std::string* release_name();
-  inline void set_allocated_name(::std::string* name);
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  void set_name(const char* value);
+  void set_name(const char* value, size_t size);
+  ::std::string* mutable_name();
+  ::std::string* release_name();
+  void set_allocated_name(::std::string* name);
 
   // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
-  inline int value_size() const;
-  inline void clear_value();
+  int value_size() const;
+  void clear_value();
   static const int kValueFieldNumber = 2;
-  inline const ::google::protobuf::EnumValueDescriptorProto& value(int index) const;
-  inline ::google::protobuf::EnumValueDescriptorProto* mutable_value(int index);
-  inline ::google::protobuf::EnumValueDescriptorProto* add_value();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
+  const ::google::protobuf::EnumValueDescriptorProto& value(int index) const;
+  ::google::protobuf::EnumValueDescriptorProto* mutable_value(int index);
+  ::google::protobuf::EnumValueDescriptorProto* add_value();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
       value() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
       mutable_value();
 
   // optional .google.protobuf.EnumOptions options = 3;
-  inline bool has_options() const;
-  inline void clear_options();
+  bool has_options() const;
+  void clear_options();
   static const int kOptionsFieldNumber = 3;
-  inline const ::google::protobuf::EnumOptions& options() const;
-  inline ::google::protobuf::EnumOptions* mutable_options();
-  inline ::google::protobuf::EnumOptions* release_options();
-  inline void set_allocated_options(::google::protobuf::EnumOptions* options);
+  const ::google::protobuf::EnumOptions& options() const;
+  ::google::protobuf::EnumOptions* mutable_options();
+  ::google::protobuf::EnumOptions* release_options();
+  void set_allocated_options(::google::protobuf::EnumOptions* options);
 
   // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto)
  private:
@@ -1311,32 +1311,32 @@
   // accessors -------------------------------------------------------
 
   // optional string name = 1;
-  inline bool has_name() const;
-  inline void clear_name();
+  bool has_name() const;
+  void clear_name();
   static const int kNameFieldNumber = 1;
-  inline const ::std::string& name() const;
-  inline void set_name(const ::std::string& value);
-  inline void set_name(const char* value);
-  inline void set_name(const char* value, size_t size);
-  inline ::std::string* mutable_name();
-  inline ::std::string* release_name();
-  inline void set_allocated_name(::std::string* name);
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  void set_name(const char* value);
+  void set_name(const char* value, size_t size);
+  ::std::string* mutable_name();
+  ::std::string* release_name();
+  void set_allocated_name(::std::string* name);
 
   // optional int32 number = 2;
-  inline bool has_number() const;
-  inline void clear_number();
+  bool has_number() const;
+  void clear_number();
   static const int kNumberFieldNumber = 2;
-  inline ::google::protobuf::int32 number() const;
-  inline void set_number(::google::protobuf::int32 value);
+  ::google::protobuf::int32 number() const;
+  void set_number(::google::protobuf::int32 value);
 
   // optional .google.protobuf.EnumValueOptions options = 3;
-  inline bool has_options() const;
-  inline void clear_options();
+  bool has_options() const;
+  void clear_options();
   static const int kOptionsFieldNumber = 3;
-  inline const ::google::protobuf::EnumValueOptions& options() const;
-  inline ::google::protobuf::EnumValueOptions* mutable_options();
-  inline ::google::protobuf::EnumValueOptions* release_options();
-  inline void set_allocated_options(::google::protobuf::EnumValueOptions* options);
+  const ::google::protobuf::EnumValueOptions& options() const;
+  ::google::protobuf::EnumValueOptions* mutable_options();
+  ::google::protobuf::EnumValueOptions* release_options();
+  void set_allocated_options(::google::protobuf::EnumValueOptions* options);
 
   // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto)
  private:
@@ -1427,37 +1427,37 @@
   // accessors -------------------------------------------------------
 
   // optional string name = 1;
-  inline bool has_name() const;
-  inline void clear_name();
+  bool has_name() const;
+  void clear_name();
   static const int kNameFieldNumber = 1;
-  inline const ::std::string& name() const;
-  inline void set_name(const ::std::string& value);
-  inline void set_name(const char* value);
-  inline void set_name(const char* value, size_t size);
-  inline ::std::string* mutable_name();
-  inline ::std::string* release_name();
-  inline void set_allocated_name(::std::string* name);
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  void set_name(const char* value);
+  void set_name(const char* value, size_t size);
+  ::std::string* mutable_name();
+  ::std::string* release_name();
+  void set_allocated_name(::std::string* name);
 
   // repeated .google.protobuf.MethodDescriptorProto method = 2;
-  inline int method_size() const;
-  inline void clear_method();
+  int method_size() const;
+  void clear_method();
   static const int kMethodFieldNumber = 2;
-  inline const ::google::protobuf::MethodDescriptorProto& method(int index) const;
-  inline ::google::protobuf::MethodDescriptorProto* mutable_method(int index);
-  inline ::google::protobuf::MethodDescriptorProto* add_method();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
+  const ::google::protobuf::MethodDescriptorProto& method(int index) const;
+  ::google::protobuf::MethodDescriptorProto* mutable_method(int index);
+  ::google::protobuf::MethodDescriptorProto* add_method();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
       method() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
       mutable_method();
 
   // optional .google.protobuf.ServiceOptions options = 3;
-  inline bool has_options() const;
-  inline void clear_options();
+  bool has_options() const;
+  void clear_options();
   static const int kOptionsFieldNumber = 3;
-  inline const ::google::protobuf::ServiceOptions& options() const;
-  inline ::google::protobuf::ServiceOptions* mutable_options();
-  inline ::google::protobuf::ServiceOptions* release_options();
-  inline void set_allocated_options(::google::protobuf::ServiceOptions* options);
+  const ::google::protobuf::ServiceOptions& options() const;
+  ::google::protobuf::ServiceOptions* mutable_options();
+  ::google::protobuf::ServiceOptions* release_options();
+  void set_allocated_options(::google::protobuf::ServiceOptions* options);
 
   // @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto)
  private:
@@ -1546,63 +1546,63 @@
   // accessors -------------------------------------------------------
 
   // optional string name = 1;
-  inline bool has_name() const;
-  inline void clear_name();
+  bool has_name() const;
+  void clear_name();
   static const int kNameFieldNumber = 1;
-  inline const ::std::string& name() const;
-  inline void set_name(const ::std::string& value);
-  inline void set_name(const char* value);
-  inline void set_name(const char* value, size_t size);
-  inline ::std::string* mutable_name();
-  inline ::std::string* release_name();
-  inline void set_allocated_name(::std::string* name);
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  void set_name(const char* value);
+  void set_name(const char* value, size_t size);
+  ::std::string* mutable_name();
+  ::std::string* release_name();
+  void set_allocated_name(::std::string* name);
 
   // optional string input_type = 2;
-  inline bool has_input_type() const;
-  inline void clear_input_type();
+  bool has_input_type() const;
+  void clear_input_type();
   static const int kInputTypeFieldNumber = 2;
-  inline const ::std::string& input_type() const;
-  inline void set_input_type(const ::std::string& value);
-  inline void set_input_type(const char* value);
-  inline void set_input_type(const char* value, size_t size);
-  inline ::std::string* mutable_input_type();
-  inline ::std::string* release_input_type();
-  inline void set_allocated_input_type(::std::string* input_type);
+  const ::std::string& input_type() const;
+  void set_input_type(const ::std::string& value);
+  void set_input_type(const char* value);
+  void set_input_type(const char* value, size_t size);
+  ::std::string* mutable_input_type();
+  ::std::string* release_input_type();
+  void set_allocated_input_type(::std::string* input_type);
 
   // optional string output_type = 3;
-  inline bool has_output_type() const;
-  inline void clear_output_type();
+  bool has_output_type() const;
+  void clear_output_type();
   static const int kOutputTypeFieldNumber = 3;
-  inline const ::std::string& output_type() const;
-  inline void set_output_type(const ::std::string& value);
-  inline void set_output_type(const char* value);
-  inline void set_output_type(const char* value, size_t size);
-  inline ::std::string* mutable_output_type();
-  inline ::std::string* release_output_type();
-  inline void set_allocated_output_type(::std::string* output_type);
+  const ::std::string& output_type() const;
+  void set_output_type(const ::std::string& value);
+  void set_output_type(const char* value);
+  void set_output_type(const char* value, size_t size);
+  ::std::string* mutable_output_type();
+  ::std::string* release_output_type();
+  void set_allocated_output_type(::std::string* output_type);
 
   // optional .google.protobuf.MethodOptions options = 4;
-  inline bool has_options() const;
-  inline void clear_options();
+  bool has_options() const;
+  void clear_options();
   static const int kOptionsFieldNumber = 4;
-  inline const ::google::protobuf::MethodOptions& options() const;
-  inline ::google::protobuf::MethodOptions* mutable_options();
-  inline ::google::protobuf::MethodOptions* release_options();
-  inline void set_allocated_options(::google::protobuf::MethodOptions* options);
+  const ::google::protobuf::MethodOptions& options() const;
+  ::google::protobuf::MethodOptions* mutable_options();
+  ::google::protobuf::MethodOptions* release_options();
+  void set_allocated_options(::google::protobuf::MethodOptions* options);
 
   // optional bool client_streaming = 5 [default = false];
-  inline bool has_client_streaming() const;
-  inline void clear_client_streaming();
+  bool has_client_streaming() const;
+  void clear_client_streaming();
   static const int kClientStreamingFieldNumber = 5;
-  inline bool client_streaming() const;
-  inline void set_client_streaming(bool value);
+  bool client_streaming() const;
+  void set_client_streaming(bool value);
 
   // optional bool server_streaming = 6 [default = false];
-  inline bool has_server_streaming() const;
-  inline void clear_server_streaming();
+  bool has_server_streaming() const;
+  void clear_server_streaming();
   static const int kServerStreamingFieldNumber = 6;
-  inline bool server_streaming() const;
-  inline void set_server_streaming(bool value);
+  bool server_streaming() const;
+  void set_server_streaming(bool value);
 
   // @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto)
  private:
@@ -1727,114 +1727,126 @@
   // accessors -------------------------------------------------------
 
   // optional string java_package = 1;
-  inline bool has_java_package() const;
-  inline void clear_java_package();
+  bool has_java_package() const;
+  void clear_java_package();
   static const int kJavaPackageFieldNumber = 1;
-  inline const ::std::string& java_package() const;
-  inline void set_java_package(const ::std::string& value);
-  inline void set_java_package(const char* value);
-  inline void set_java_package(const char* value, size_t size);
-  inline ::std::string* mutable_java_package();
-  inline ::std::string* release_java_package();
-  inline void set_allocated_java_package(::std::string* java_package);
+  const ::std::string& java_package() const;
+  void set_java_package(const ::std::string& value);
+  void set_java_package(const char* value);
+  void set_java_package(const char* value, size_t size);
+  ::std::string* mutable_java_package();
+  ::std::string* release_java_package();
+  void set_allocated_java_package(::std::string* java_package);
 
   // optional string java_outer_classname = 8;
-  inline bool has_java_outer_classname() const;
-  inline void clear_java_outer_classname();
+  bool has_java_outer_classname() const;
+  void clear_java_outer_classname();
   static const int kJavaOuterClassnameFieldNumber = 8;
-  inline const ::std::string& java_outer_classname() const;
-  inline void set_java_outer_classname(const ::std::string& value);
-  inline void set_java_outer_classname(const char* value);
-  inline void set_java_outer_classname(const char* value, size_t size);
-  inline ::std::string* mutable_java_outer_classname();
-  inline ::std::string* release_java_outer_classname();
-  inline void set_allocated_java_outer_classname(::std::string* java_outer_classname);
+  const ::std::string& java_outer_classname() const;
+  void set_java_outer_classname(const ::std::string& value);
+  void set_java_outer_classname(const char* value);
+  void set_java_outer_classname(const char* value, size_t size);
+  ::std::string* mutable_java_outer_classname();
+  ::std::string* release_java_outer_classname();
+  void set_allocated_java_outer_classname(::std::string* java_outer_classname);
 
   // optional bool java_multiple_files = 10 [default = false];
-  inline bool has_java_multiple_files() const;
-  inline void clear_java_multiple_files();
+  bool has_java_multiple_files() const;
+  void clear_java_multiple_files();
   static const int kJavaMultipleFilesFieldNumber = 10;
-  inline bool java_multiple_files() const;
-  inline void set_java_multiple_files(bool value);
+  bool java_multiple_files() const;
+  void set_java_multiple_files(bool value);
 
   // optional bool java_generate_equals_and_hash = 20 [default = false];
-  inline bool has_java_generate_equals_and_hash() const;
-  inline void clear_java_generate_equals_and_hash();
+  bool has_java_generate_equals_and_hash() const;
+  void clear_java_generate_equals_and_hash();
   static const int kJavaGenerateEqualsAndHashFieldNumber = 20;
-  inline bool java_generate_equals_and_hash() const;
-  inline void set_java_generate_equals_and_hash(bool value);
+  bool java_generate_equals_and_hash() const;
+  void set_java_generate_equals_and_hash(bool value);
 
   // optional bool java_string_check_utf8 = 27 [default = false];
-  inline bool has_java_string_check_utf8() const;
-  inline void clear_java_string_check_utf8();
+  bool has_java_string_check_utf8() const;
+  void clear_java_string_check_utf8();
   static const int kJavaStringCheckUtf8FieldNumber = 27;
-  inline bool java_string_check_utf8() const;
-  inline void set_java_string_check_utf8(bool value);
+  bool java_string_check_utf8() const;
+  void set_java_string_check_utf8(bool value);
 
   // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
-  inline bool has_optimize_for() const;
-  inline void clear_optimize_for();
+  bool has_optimize_for() const;
+  void clear_optimize_for();
   static const int kOptimizeForFieldNumber = 9;
-  inline ::google::protobuf::FileOptions_OptimizeMode optimize_for() const;
-  inline void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value);
+  ::google::protobuf::FileOptions_OptimizeMode optimize_for() const;
+  void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value);
 
   // optional string go_package = 11;
-  inline bool has_go_package() const;
-  inline void clear_go_package();
+  bool has_go_package() const;
+  void clear_go_package();
   static const int kGoPackageFieldNumber = 11;
-  inline const ::std::string& go_package() const;
-  inline void set_go_package(const ::std::string& value);
-  inline void set_go_package(const char* value);
-  inline void set_go_package(const char* value, size_t size);
-  inline ::std::string* mutable_go_package();
-  inline ::std::string* release_go_package();
-  inline void set_allocated_go_package(::std::string* go_package);
+  const ::std::string& go_package() const;
+  void set_go_package(const ::std::string& value);
+  void set_go_package(const char* value);
+  void set_go_package(const char* value, size_t size);
+  ::std::string* mutable_go_package();
+  ::std::string* release_go_package();
+  void set_allocated_go_package(::std::string* go_package);
 
   // optional bool cc_generic_services = 16 [default = false];
-  inline bool has_cc_generic_services() const;
-  inline void clear_cc_generic_services();
+  bool has_cc_generic_services() const;
+  void clear_cc_generic_services();
   static const int kCcGenericServicesFieldNumber = 16;
-  inline bool cc_generic_services() const;
-  inline void set_cc_generic_services(bool value);
+  bool cc_generic_services() const;
+  void set_cc_generic_services(bool value);
 
   // optional bool java_generic_services = 17 [default = false];
-  inline bool has_java_generic_services() const;
-  inline void clear_java_generic_services();
+  bool has_java_generic_services() const;
+  void clear_java_generic_services();
   static const int kJavaGenericServicesFieldNumber = 17;
-  inline bool java_generic_services() const;
-  inline void set_java_generic_services(bool value);
+  bool java_generic_services() const;
+  void set_java_generic_services(bool value);
 
   // optional bool py_generic_services = 18 [default = false];
-  inline bool has_py_generic_services() const;
-  inline void clear_py_generic_services();
+  bool has_py_generic_services() const;
+  void clear_py_generic_services();
   static const int kPyGenericServicesFieldNumber = 18;
-  inline bool py_generic_services() const;
-  inline void set_py_generic_services(bool value);
+  bool py_generic_services() const;
+  void set_py_generic_services(bool value);
 
   // optional bool deprecated = 23 [default = false];
-  inline bool has_deprecated() const;
-  inline void clear_deprecated();
+  bool has_deprecated() const;
+  void clear_deprecated();
   static const int kDeprecatedFieldNumber = 23;
-  inline bool deprecated() const;
-  inline void set_deprecated(bool value);
+  bool deprecated() const;
+  void set_deprecated(bool value);
 
   // optional bool cc_enable_arenas = 31 [default = false];
-  inline bool has_cc_enable_arenas() const;
-  inline void clear_cc_enable_arenas();
+  bool has_cc_enable_arenas() const;
+  void clear_cc_enable_arenas();
   static const int kCcEnableArenasFieldNumber = 31;
-  inline bool cc_enable_arenas() const;
-  inline void set_cc_enable_arenas(bool value);
+  bool cc_enable_arenas() const;
+  void set_cc_enable_arenas(bool value);
+
+  // optional string objc_class_prefix = 36;
+  bool has_objc_class_prefix() const;
+  void clear_objc_class_prefix();
+  static const int kObjcClassPrefixFieldNumber = 36;
+  const ::std::string& objc_class_prefix() const;
+  void set_objc_class_prefix(const ::std::string& value);
+  void set_objc_class_prefix(const char* value);
+  void set_objc_class_prefix(const char* value, size_t size);
+  ::std::string* mutable_objc_class_prefix();
+  ::std::string* release_objc_class_prefix();
+  void set_allocated_objc_class_prefix(::std::string* objc_class_prefix);
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  inline int uninterpreted_option_size() const;
-  inline void clear_uninterpreted_option();
+  int uninterpreted_option_size() const;
+  void clear_uninterpreted_option();
   static const int kUninterpretedOptionFieldNumber = 999;
-  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
-  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
-  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+  const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+  ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+  ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
       uninterpreted_option() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
       mutable_uninterpreted_option();
 
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FileOptions)
@@ -1864,6 +1876,8 @@
   inline void clear_has_deprecated();
   inline void set_has_cc_enable_arenas();
   inline void clear_has_cc_enable_arenas();
+  inline void set_has_objc_class_prefix();
+  inline void clear_has_objc_class_prefix();
 
   ::google::protobuf::internal::ExtensionSet _extensions_;
 
@@ -1878,6 +1892,7 @@
   bool cc_generic_services_;
   int optimize_for_;
   ::google::protobuf::internal::ArenaStringPtr go_package_;
+  ::google::protobuf::internal::ArenaStringPtr objc_class_prefix_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
   bool java_generic_services_;
   bool py_generic_services_;
@@ -1957,43 +1972,43 @@
   // accessors -------------------------------------------------------
 
   // optional bool message_set_wire_format = 1 [default = false];
-  inline bool has_message_set_wire_format() const;
-  inline void clear_message_set_wire_format();
+  bool has_message_set_wire_format() const;
+  void clear_message_set_wire_format();
   static const int kMessageSetWireFormatFieldNumber = 1;
-  inline bool message_set_wire_format() const;
-  inline void set_message_set_wire_format(bool value);
+  bool message_set_wire_format() const;
+  void set_message_set_wire_format(bool value);
 
   // optional bool no_standard_descriptor_accessor = 2 [default = false];
-  inline bool has_no_standard_descriptor_accessor() const;
-  inline void clear_no_standard_descriptor_accessor();
+  bool has_no_standard_descriptor_accessor() const;
+  void clear_no_standard_descriptor_accessor();
   static const int kNoStandardDescriptorAccessorFieldNumber = 2;
-  inline bool no_standard_descriptor_accessor() const;
-  inline void set_no_standard_descriptor_accessor(bool value);
+  bool no_standard_descriptor_accessor() const;
+  void set_no_standard_descriptor_accessor(bool value);
 
   // optional bool deprecated = 3 [default = false];
-  inline bool has_deprecated() const;
-  inline void clear_deprecated();
+  bool has_deprecated() const;
+  void clear_deprecated();
   static const int kDeprecatedFieldNumber = 3;
-  inline bool deprecated() const;
-  inline void set_deprecated(bool value);
+  bool deprecated() const;
+  void set_deprecated(bool value);
 
   // optional bool map_entry = 7;
-  inline bool has_map_entry() const;
-  inline void clear_map_entry();
+  bool has_map_entry() const;
+  void clear_map_entry();
   static const int kMapEntryFieldNumber = 7;
-  inline bool map_entry() const;
-  inline void set_map_entry(bool value);
+  bool map_entry() const;
+  void set_map_entry(bool value);
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  inline int uninterpreted_option_size() const;
-  inline void clear_uninterpreted_option();
+  int uninterpreted_option_size() const;
+  void clear_uninterpreted_option();
   static const int kUninterpretedOptionFieldNumber = 999;
-  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
-  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
-  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+  const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+  ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+  ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
       uninterpreted_option() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
       mutable_uninterpreted_option();
 
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MessageOptions)
@@ -2117,50 +2132,50 @@
   // accessors -------------------------------------------------------
 
   // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
-  inline bool has_ctype() const;
-  inline void clear_ctype();
+  bool has_ctype() const;
+  void clear_ctype();
   static const int kCtypeFieldNumber = 1;
-  inline ::google::protobuf::FieldOptions_CType ctype() const;
-  inline void set_ctype(::google::protobuf::FieldOptions_CType value);
+  ::google::protobuf::FieldOptions_CType ctype() const;
+  void set_ctype(::google::protobuf::FieldOptions_CType value);
 
   // optional bool packed = 2;
-  inline bool has_packed() const;
-  inline void clear_packed();
+  bool has_packed() const;
+  void clear_packed();
   static const int kPackedFieldNumber = 2;
-  inline bool packed() const;
-  inline void set_packed(bool value);
+  bool packed() const;
+  void set_packed(bool value);
 
   // optional bool lazy = 5 [default = false];
-  inline bool has_lazy() const;
-  inline void clear_lazy();
+  bool has_lazy() const;
+  void clear_lazy();
   static const int kLazyFieldNumber = 5;
-  inline bool lazy() const;
-  inline void set_lazy(bool value);
+  bool lazy() const;
+  void set_lazy(bool value);
 
   // optional bool deprecated = 3 [default = false];
-  inline bool has_deprecated() const;
-  inline void clear_deprecated();
+  bool has_deprecated() const;
+  void clear_deprecated();
   static const int kDeprecatedFieldNumber = 3;
-  inline bool deprecated() const;
-  inline void set_deprecated(bool value);
+  bool deprecated() const;
+  void set_deprecated(bool value);
 
   // optional bool weak = 10 [default = false];
-  inline bool has_weak() const;
-  inline void clear_weak();
+  bool has_weak() const;
+  void clear_weak();
   static const int kWeakFieldNumber = 10;
-  inline bool weak() const;
-  inline void set_weak(bool value);
+  bool weak() const;
+  void set_weak(bool value);
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  inline int uninterpreted_option_size() const;
-  inline void clear_uninterpreted_option();
+  int uninterpreted_option_size() const;
+  void clear_uninterpreted_option();
   static const int kUninterpretedOptionFieldNumber = 999;
-  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
-  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
-  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+  const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+  ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+  ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
       uninterpreted_option() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
       mutable_uninterpreted_option();
 
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions)
@@ -2262,29 +2277,29 @@
   // accessors -------------------------------------------------------
 
   // optional bool allow_alias = 2;
-  inline bool has_allow_alias() const;
-  inline void clear_allow_alias();
+  bool has_allow_alias() const;
+  void clear_allow_alias();
   static const int kAllowAliasFieldNumber = 2;
-  inline bool allow_alias() const;
-  inline void set_allow_alias(bool value);
+  bool allow_alias() const;
+  void set_allow_alias(bool value);
 
   // optional bool deprecated = 3 [default = false];
-  inline bool has_deprecated() const;
-  inline void clear_deprecated();
+  bool has_deprecated() const;
+  void clear_deprecated();
   static const int kDeprecatedFieldNumber = 3;
-  inline bool deprecated() const;
-  inline void set_deprecated(bool value);
+  bool deprecated() const;
+  void set_deprecated(bool value);
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  inline int uninterpreted_option_size() const;
-  inline void clear_uninterpreted_option();
+  int uninterpreted_option_size() const;
+  void clear_uninterpreted_option();
   static const int kUninterpretedOptionFieldNumber = 999;
-  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
-  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
-  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+  const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+  ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+  ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
       uninterpreted_option() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
       mutable_uninterpreted_option();
 
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumOptions)
@@ -2377,22 +2392,22 @@
   // accessors -------------------------------------------------------
 
   // optional bool deprecated = 1 [default = false];
-  inline bool has_deprecated() const;
-  inline void clear_deprecated();
+  bool has_deprecated() const;
+  void clear_deprecated();
   static const int kDeprecatedFieldNumber = 1;
-  inline bool deprecated() const;
-  inline void set_deprecated(bool value);
+  bool deprecated() const;
+  void set_deprecated(bool value);
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  inline int uninterpreted_option_size() const;
-  inline void clear_uninterpreted_option();
+  int uninterpreted_option_size() const;
+  void clear_uninterpreted_option();
   static const int kUninterpretedOptionFieldNumber = 999;
-  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
-  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
-  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+  const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+  ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+  ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
       uninterpreted_option() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
       mutable_uninterpreted_option();
 
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumValueOptions)
@@ -2482,22 +2497,22 @@
   // accessors -------------------------------------------------------
 
   // optional bool deprecated = 33 [default = false];
-  inline bool has_deprecated() const;
-  inline void clear_deprecated();
+  bool has_deprecated() const;
+  void clear_deprecated();
   static const int kDeprecatedFieldNumber = 33;
-  inline bool deprecated() const;
-  inline void set_deprecated(bool value);
+  bool deprecated() const;
+  void set_deprecated(bool value);
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  inline int uninterpreted_option_size() const;
-  inline void clear_uninterpreted_option();
+  int uninterpreted_option_size() const;
+  void clear_uninterpreted_option();
   static const int kUninterpretedOptionFieldNumber = 999;
-  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
-  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
-  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+  const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+  ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+  ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
       uninterpreted_option() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
       mutable_uninterpreted_option();
 
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ServiceOptions)
@@ -2587,22 +2602,22 @@
   // accessors -------------------------------------------------------
 
   // optional bool deprecated = 33 [default = false];
-  inline bool has_deprecated() const;
-  inline void clear_deprecated();
+  bool has_deprecated() const;
+  void clear_deprecated();
   static const int kDeprecatedFieldNumber = 33;
-  inline bool deprecated() const;
-  inline void set_deprecated(bool value);
+  bool deprecated() const;
+  void set_deprecated(bool value);
 
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
-  inline int uninterpreted_option_size() const;
-  inline void clear_uninterpreted_option();
+  int uninterpreted_option_size() const;
+  void clear_uninterpreted_option();
   static const int kUninterpretedOptionFieldNumber = 999;
-  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
-  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
-  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+  const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+  ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+  ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
       uninterpreted_option() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
       mutable_uninterpreted_option();
 
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MethodOptions)
@@ -2692,23 +2707,23 @@
   // accessors -------------------------------------------------------
 
   // required string name_part = 1;
-  inline bool has_name_part() const;
-  inline void clear_name_part();
+  bool has_name_part() const;
+  void clear_name_part();
   static const int kNamePartFieldNumber = 1;
-  inline const ::std::string& name_part() const;
-  inline void set_name_part(const ::std::string& value);
-  inline void set_name_part(const char* value);
-  inline void set_name_part(const char* value, size_t size);
-  inline ::std::string* mutable_name_part();
-  inline ::std::string* release_name_part();
-  inline void set_allocated_name_part(::std::string* name_part);
+  const ::std::string& name_part() const;
+  void set_name_part(const ::std::string& value);
+  void set_name_part(const char* value);
+  void set_name_part(const char* value, size_t size);
+  ::std::string* mutable_name_part();
+  ::std::string* release_name_part();
+  void set_allocated_name_part(::std::string* name_part);
 
   // required bool is_extension = 2;
-  inline bool has_is_extension() const;
-  inline void clear_is_extension();
+  bool has_is_extension() const;
+  void clear_is_extension();
   static const int kIsExtensionFieldNumber = 2;
-  inline bool is_extension() const;
-  inline void set_is_extension(bool value);
+  bool is_extension() const;
+  void set_is_extension(bool value);
 
   // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart)
  private:
@@ -2801,73 +2816,73 @@
   // accessors -------------------------------------------------------
 
   // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
-  inline int name_size() const;
-  inline void clear_name();
+  int name_size() const;
+  void clear_name();
   static const int kNameFieldNumber = 2;
-  inline const ::google::protobuf::UninterpretedOption_NamePart& name(int index) const;
-  inline ::google::protobuf::UninterpretedOption_NamePart* mutable_name(int index);
-  inline ::google::protobuf::UninterpretedOption_NamePart* add_name();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
+  const ::google::protobuf::UninterpretedOption_NamePart& name(int index) const;
+  ::google::protobuf::UninterpretedOption_NamePart* mutable_name(int index);
+  ::google::protobuf::UninterpretedOption_NamePart* add_name();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
       name() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
       mutable_name();
 
   // optional string identifier_value = 3;
-  inline bool has_identifier_value() const;
-  inline void clear_identifier_value();
+  bool has_identifier_value() const;
+  void clear_identifier_value();
   static const int kIdentifierValueFieldNumber = 3;
-  inline const ::std::string& identifier_value() const;
-  inline void set_identifier_value(const ::std::string& value);
-  inline void set_identifier_value(const char* value);
-  inline void set_identifier_value(const char* value, size_t size);
-  inline ::std::string* mutable_identifier_value();
-  inline ::std::string* release_identifier_value();
-  inline void set_allocated_identifier_value(::std::string* identifier_value);
+  const ::std::string& identifier_value() const;
+  void set_identifier_value(const ::std::string& value);
+  void set_identifier_value(const char* value);
+  void set_identifier_value(const char* value, size_t size);
+  ::std::string* mutable_identifier_value();
+  ::std::string* release_identifier_value();
+  void set_allocated_identifier_value(::std::string* identifier_value);
 
   // optional uint64 positive_int_value = 4;
-  inline bool has_positive_int_value() const;
-  inline void clear_positive_int_value();
+  bool has_positive_int_value() const;
+  void clear_positive_int_value();
   static const int kPositiveIntValueFieldNumber = 4;
-  inline ::google::protobuf::uint64 positive_int_value() const;
-  inline void set_positive_int_value(::google::protobuf::uint64 value);
+  ::google::protobuf::uint64 positive_int_value() const;
+  void set_positive_int_value(::google::protobuf::uint64 value);
 
   // optional int64 negative_int_value = 5;
-  inline bool has_negative_int_value() const;
-  inline void clear_negative_int_value();
+  bool has_negative_int_value() const;
+  void clear_negative_int_value();
   static const int kNegativeIntValueFieldNumber = 5;
-  inline ::google::protobuf::int64 negative_int_value() const;
-  inline void set_negative_int_value(::google::protobuf::int64 value);
+  ::google::protobuf::int64 negative_int_value() const;
+  void set_negative_int_value(::google::protobuf::int64 value);
 
   // optional double double_value = 6;
-  inline bool has_double_value() const;
-  inline void clear_double_value();
+  bool has_double_value() const;
+  void clear_double_value();
   static const int kDoubleValueFieldNumber = 6;
-  inline double double_value() const;
-  inline void set_double_value(double value);
+  double double_value() const;
+  void set_double_value(double value);
 
   // optional bytes string_value = 7;
-  inline bool has_string_value() const;
-  inline void clear_string_value();
+  bool has_string_value() const;
+  void clear_string_value();
   static const int kStringValueFieldNumber = 7;
-  inline const ::std::string& string_value() const;
-  inline void set_string_value(const ::std::string& value);
-  inline void set_string_value(const char* value);
-  inline void set_string_value(const void* value, size_t size);
-  inline ::std::string* mutable_string_value();
-  inline ::std::string* release_string_value();
-  inline void set_allocated_string_value(::std::string* string_value);
+  const ::std::string& string_value() const;
+  void set_string_value(const ::std::string& value);
+  void set_string_value(const char* value);
+  void set_string_value(const void* value, size_t size);
+  ::std::string* mutable_string_value();
+  ::std::string* release_string_value();
+  void set_allocated_string_value(::std::string* string_value);
 
   // optional string aggregate_value = 8;
-  inline bool has_aggregate_value() const;
-  inline void clear_aggregate_value();
+  bool has_aggregate_value() const;
+  void clear_aggregate_value();
   static const int kAggregateValueFieldNumber = 8;
-  inline const ::std::string& aggregate_value() const;
-  inline void set_aggregate_value(const ::std::string& value);
-  inline void set_aggregate_value(const char* value);
-  inline void set_aggregate_value(const char* value, size_t size);
-  inline ::std::string* mutable_aggregate_value();
-  inline ::std::string* release_aggregate_value();
-  inline void set_allocated_aggregate_value(::std::string* aggregate_value);
+  const ::std::string& aggregate_value() const;
+  void set_aggregate_value(const ::std::string& value);
+  void set_aggregate_value(const char* value);
+  void set_aggregate_value(const char* value, size_t size);
+  ::std::string* mutable_aggregate_value();
+  ::std::string* release_aggregate_value();
+  void set_allocated_aggregate_value(::std::string* aggregate_value);
 
   // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption)
  private:
@@ -2968,52 +2983,68 @@
   // accessors -------------------------------------------------------
 
   // repeated int32 path = 1 [packed = true];
-  inline int path_size() const;
-  inline void clear_path();
+  int path_size() const;
+  void clear_path();
   static const int kPathFieldNumber = 1;
-  inline ::google::protobuf::int32 path(int index) const;
-  inline void set_path(int index, ::google::protobuf::int32 value);
-  inline void add_path(::google::protobuf::int32 value);
-  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+  ::google::protobuf::int32 path(int index) const;
+  void set_path(int index, ::google::protobuf::int32 value);
+  void add_path(::google::protobuf::int32 value);
+  const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
       path() const;
-  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
       mutable_path();
 
   // repeated int32 span = 2 [packed = true];
-  inline int span_size() const;
-  inline void clear_span();
+  int span_size() const;
+  void clear_span();
   static const int kSpanFieldNumber = 2;
-  inline ::google::protobuf::int32 span(int index) const;
-  inline void set_span(int index, ::google::protobuf::int32 value);
-  inline void add_span(::google::protobuf::int32 value);
-  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+  ::google::protobuf::int32 span(int index) const;
+  void set_span(int index, ::google::protobuf::int32 value);
+  void add_span(::google::protobuf::int32 value);
+  const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
       span() const;
-  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
       mutable_span();
 
   // optional string leading_comments = 3;
-  inline bool has_leading_comments() const;
-  inline void clear_leading_comments();
+  bool has_leading_comments() const;
+  void clear_leading_comments();
   static const int kLeadingCommentsFieldNumber = 3;
-  inline const ::std::string& leading_comments() const;
-  inline void set_leading_comments(const ::std::string& value);
-  inline void set_leading_comments(const char* value);
-  inline void set_leading_comments(const char* value, size_t size);
-  inline ::std::string* mutable_leading_comments();
-  inline ::std::string* release_leading_comments();
-  inline void set_allocated_leading_comments(::std::string* leading_comments);
+  const ::std::string& leading_comments() const;
+  void set_leading_comments(const ::std::string& value);
+  void set_leading_comments(const char* value);
+  void set_leading_comments(const char* value, size_t size);
+  ::std::string* mutable_leading_comments();
+  ::std::string* release_leading_comments();
+  void set_allocated_leading_comments(::std::string* leading_comments);
 
   // optional string trailing_comments = 4;
-  inline bool has_trailing_comments() const;
-  inline void clear_trailing_comments();
+  bool has_trailing_comments() const;
+  void clear_trailing_comments();
   static const int kTrailingCommentsFieldNumber = 4;
-  inline const ::std::string& trailing_comments() const;
-  inline void set_trailing_comments(const ::std::string& value);
-  inline void set_trailing_comments(const char* value);
-  inline void set_trailing_comments(const char* value, size_t size);
-  inline ::std::string* mutable_trailing_comments();
-  inline ::std::string* release_trailing_comments();
-  inline void set_allocated_trailing_comments(::std::string* trailing_comments);
+  const ::std::string& trailing_comments() const;
+  void set_trailing_comments(const ::std::string& value);
+  void set_trailing_comments(const char* value);
+  void set_trailing_comments(const char* value, size_t size);
+  ::std::string* mutable_trailing_comments();
+  ::std::string* release_trailing_comments();
+  void set_allocated_trailing_comments(::std::string* trailing_comments);
+
+  // repeated string leading_detached_comments = 6;
+  int leading_detached_comments_size() const;
+  void clear_leading_detached_comments();
+  static const int kLeadingDetachedCommentsFieldNumber = 6;
+  const ::std::string& leading_detached_comments(int index) const;
+  ::std::string* mutable_leading_detached_comments(int index);
+  void set_leading_detached_comments(int index, const ::std::string& value);
+  void set_leading_detached_comments(int index, const char* value);
+  void set_leading_detached_comments(int index, const char* value, size_t size);
+  ::std::string* add_leading_detached_comments();
+  void add_leading_detached_comments(const ::std::string& value);
+  void add_leading_detached_comments(const char* value);
+  void add_leading_detached_comments(const char* value, size_t size);
+  const ::google::protobuf::RepeatedPtrField< ::std::string>& leading_detached_comments() const;
+  ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_leading_detached_comments();
 
   // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location)
  private:
@@ -3031,6 +3062,7 @@
   mutable int _span_cached_byte_size_;
   ::google::protobuf::internal::ArenaStringPtr leading_comments_;
   ::google::protobuf::internal::ArenaStringPtr trailing_comments_;
+  ::google::protobuf::RepeatedPtrField< ::std::string> leading_detached_comments_;
   friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
   friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
   friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
@@ -3107,15 +3139,15 @@
   // accessors -------------------------------------------------------
 
   // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
-  inline int location_size() const;
-  inline void clear_location();
+  int location_size() const;
+  void clear_location();
   static const int kLocationFieldNumber = 1;
-  inline const ::google::protobuf::SourceCodeInfo_Location& location(int index) const;
-  inline ::google::protobuf::SourceCodeInfo_Location* mutable_location(int index);
-  inline ::google::protobuf::SourceCodeInfo_Location* add_location();
-  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
+  const ::google::protobuf::SourceCodeInfo_Location& location(int index) const;
+  ::google::protobuf::SourceCodeInfo_Location* mutable_location(int index);
+  ::google::protobuf::SourceCodeInfo_Location* add_location();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
       location() const;
-  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
       mutable_location();
 
   // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo)
@@ -3137,6 +3169,7 @@
 
 // ===================================================================
 
+#if !PROTOBUF_INLINE_NOT_IN_HEADERS
 // FileDescriptorSet
 
 // repeated .google.protobuf.FileDescriptorProto file = 1;
@@ -5416,6 +5449,59 @@
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_enable_arenas)
 }
 
+// optional string objc_class_prefix = 36;
+inline bool FileOptions::has_objc_class_prefix() const {
+  return (_has_bits_[0] & 0x00001000u) != 0;
+}
+inline void FileOptions::set_has_objc_class_prefix() {
+  _has_bits_[0] |= 0x00001000u;
+}
+inline void FileOptions::clear_has_objc_class_prefix() {
+  _has_bits_[0] &= ~0x00001000u;
+}
+inline void FileOptions::clear_objc_class_prefix() {
+  objc_class_prefix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_objc_class_prefix();
+}
+inline const ::std::string& FileOptions::objc_class_prefix() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.objc_class_prefix)
+  return objc_class_prefix_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void FileOptions::set_objc_class_prefix(const ::std::string& value) {
+  set_has_objc_class_prefix();
+  objc_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.objc_class_prefix)
+}
+inline void FileOptions::set_objc_class_prefix(const char* value) {
+  set_has_objc_class_prefix();
+  objc_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.objc_class_prefix)
+}
+inline void FileOptions::set_objc_class_prefix(const char* value, size_t size) {
+  set_has_objc_class_prefix();
+  objc_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.objc_class_prefix)
+}
+inline ::std::string* FileOptions::mutable_objc_class_prefix() {
+  set_has_objc_class_prefix();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.objc_class_prefix)
+  return objc_class_prefix_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* FileOptions::release_objc_class_prefix() {
+  clear_has_objc_class_prefix();
+  return objc_class_prefix_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void FileOptions::set_allocated_objc_class_prefix(::std::string* objc_class_prefix) {
+  if (objc_class_prefix != NULL) {
+    set_has_objc_class_prefix();
+  } else {
+    clear_has_objc_class_prefix();
+  }
+  objc_class_prefix_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), objc_class_prefix);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.objc_class_prefix)
+}
+
 // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
 inline int FileOptions::uninterpreted_option_size() const {
   return uninterpreted_option_.size();
@@ -6503,6 +6589,60 @@
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.trailing_comments)
 }
 
+// repeated string leading_detached_comments = 6;
+inline int SourceCodeInfo_Location::leading_detached_comments_size() const {
+  return leading_detached_comments_.size();
+}
+inline void SourceCodeInfo_Location::clear_leading_detached_comments() {
+  leading_detached_comments_.Clear();
+}
+inline const ::std::string& SourceCodeInfo_Location::leading_detached_comments(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+  return leading_detached_comments_.Get(index);
+}
+inline ::std::string* SourceCodeInfo_Location::mutable_leading_detached_comments(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+  return leading_detached_comments_.Mutable(index);
+}
+inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+  leading_detached_comments_.Mutable(index)->assign(value);
+}
+inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value) {
+  leading_detached_comments_.Mutable(index)->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value, size_t size) {
+  leading_detached_comments_.Mutable(index)->assign(
+    reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+inline ::std::string* SourceCodeInfo_Location::add_leading_detached_comments() {
+  return leading_detached_comments_.Add();
+}
+inline void SourceCodeInfo_Location::add_leading_detached_comments(const ::std::string& value) {
+  leading_detached_comments_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+inline void SourceCodeInfo_Location::add_leading_detached_comments(const char* value) {
+  leading_detached_comments_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+inline void SourceCodeInfo_Location::add_leading_detached_comments(const char* value, size_t size) {
+  leading_detached_comments_.Add()->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_add_pointer:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+SourceCodeInfo_Location::leading_detached_comments() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+  return leading_detached_comments_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+SourceCodeInfo_Location::mutable_leading_detached_comments() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+  return &leading_detached_comments_;
+}
+
 // -------------------------------------------------------------------
 
 // SourceCodeInfo
@@ -6537,6 +6677,7 @@
   return &location_;
 }
 
+#endif  // !PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // @@protoc_insertion_point(namespace_scope)
 
diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto
index e17c0cc..367b16e 100644
--- a/src/google/protobuf/descriptor.proto
+++ b/src/google/protobuf/descriptor.proto
@@ -172,9 +172,7 @@
   optional string default_value = 7;
 
   // If set, gives the index of a oneof in the containing type's oneof_decl
-  // list.  This field is a member of that oneof.  Extensions of a oneof should
-  // not set this since the oneof to which they belong will be inferred based
-  // on the extension range containing the extension's field number.
+  // list.  This field is a member of that oneof.
   optional int32 oneof_index = 9;
 
   optional FieldOptions options = 8;
@@ -344,12 +342,15 @@
   // least, this is a formalization for deprecating files.
   optional bool deprecated = 23 [default=false];
 
-
   // Enables the use of arenas for the proto messages in this file. This applies
   // only to generated classes for C++.
   optional bool cc_enable_arenas = 31 [default=false];
 
 
+  // Sets the objective c class prefix which is prepended to all objective c
+  // generated classes from this .proto. There is no default.
+  optional string objc_class_prefix = 36;
+
   // The parser stores options it doesn't recognize here. See above.
   repeated UninterpretedOption uninterpreted_option = 999;
 
@@ -681,6 +682,11 @@
     // A series of line comments appearing on consecutive lines, with no other
     // tokens appearing on those lines, will be treated as a single comment.
     //
+    // leading_detached_comments will keep paragraphs of comments that appear
+    // before (but not connected to) the current element. Each paragraph,
+    // separated by empty lines, will be one comment element in the repeated
+    // field.
+    //
     // Only the comment content is provided; comment markers (e.g. //) are
     // stripped out.  For block comments, leading whitespace and an asterisk
     // will be stripped from the beginning of each line other than the first.
@@ -701,6 +707,12 @@
     //   // Another line attached to qux.
     //   optional double qux = 4;
     //
+    //   // Detached comment for corge. This is not leading or trailing comments
+    //   // to qux or corge because there are blank lines separating it from
+    //   // both.
+    //
+    //   // Detached comment for corge paragraph 2.
+    //
     //   optional string corge = 5;
     //   /* Block comment attached
     //    * to corge.  Leading asterisks
@@ -708,7 +720,10 @@
     //   /* Block comment attached to
     //    * grault. */
     //   optional int32 grault = 6;
+    //
+    //   // ignored detached comments.
     optional string leading_comments = 3;
     optional string trailing_comments = 4;
+    repeated string leading_detached_comments = 6;
   }
 }
diff --git a/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc
index d024eab..2117c02 100644
--- a/src/google/protobuf/descriptor_database.cc
+++ b/src/google/protobuf/descriptor_database.cc
@@ -153,10 +153,10 @@
   if (!field.extendee().empty() && field.extendee()[0] == '.') {
     // The extension is fully-qualified.  We can use it as a lookup key in
     // the by_symbol_ table.
-    if (!InsertIfNotPresent(&by_extension_,
-                            make_pair(field.extendee().substr(1),
-                                      field.number()),
-                            value)) {
+    if (!InsertIfNotPresent(
+            &by_extension_,
+            std::make_pair(field.extendee().substr(1), field.number()),
+            value)) {
       GOOGLE_LOG(ERROR) << "Extension conflicts with extension already in database: "
                     "extend " << field.extendee() << " { "
                  << field.name() << " = " << field.number() << " }";
@@ -189,17 +189,16 @@
 Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindExtension(
     const string& containing_type,
     int field_number) {
-  return FindWithDefault(by_extension_,
-                         make_pair(containing_type, field_number),
-                         Value());
+  return FindWithDefault(
+      by_extension_, std::make_pair(containing_type, field_number), Value());
 }
 
 template <typename Value>
 bool SimpleDescriptorDatabase::DescriptorIndex<Value>::FindAllExtensionNumbers(
     const string& containing_type,
     vector<int>* output) {
-  typename map<pair<string, int>, Value >::const_iterator it =
-      by_extension_.lower_bound(make_pair(containing_type, 0));
+  typename map<pair<string, int>, Value>::const_iterator it =
+      by_extension_.lower_bound(std::make_pair(containing_type, 0));
   bool success = false;
 
   for (; it != by_extension_.end() && it->first.first == containing_type;
@@ -310,7 +309,7 @@
     const void* encoded_file_descriptor, int size) {
   FileDescriptorProto file;
   if (file.ParseFromArray(encoded_file_descriptor, size)) {
-    return index_.AddFile(file, make_pair(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().";
@@ -525,15 +524,16 @@
 
   for (int i = 0; i < sources_.size(); i++) {
     if (sources_[i]->FindAllExtensionNumbers(extendee_type, &results)) {
-      copy(results.begin(), results.end(),
-           insert_iterator<set<int> >(merged_results, merged_results.begin()));
+      std::copy(
+          results.begin(), results.end(),
+          insert_iterator<set<int> >(merged_results, merged_results.begin()));
       success = true;
     }
     results.clear();
   }
 
-  copy(merged_results.begin(), merged_results.end(),
-       insert_iterator<vector<int> >(*output, output->end()));
+  std::copy(merged_results.begin(), merged_results.end(),
+            insert_iterator<vector<int> >(*output, output->end()));
 
   return success;
 }
diff --git a/src/google/protobuf/descriptor_database_unittest.cc b/src/google/protobuf/descriptor_database_unittest.cc
index 6642d71..1c03c44 100644
--- a/src/google/protobuf/descriptor_database_unittest.cc
+++ b/src/google/protobuf/descriptor_database_unittest.cc
@@ -408,7 +408,7 @@
     vector<int> numbers;
     EXPECT_TRUE(database_->FindAllExtensionNumbers("Foo", &numbers));
     ASSERT_EQ(2, numbers.size());
-    sort(numbers.begin(), numbers.end());
+    std::sort(numbers.begin(), numbers.end());
     EXPECT_EQ(5, numbers[0]);
     EXPECT_EQ(32, numbers[1]);
   }
@@ -722,7 +722,7 @@
     vector<int> numbers;
     EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Baz", &numbers));
     ASSERT_EQ(2, numbers.size());
-    sort(numbers.begin(), numbers.end());
+    std::sort(numbers.begin(), numbers.end());
     EXPECT_EQ(12, numbers[0]);
     EXPECT_EQ(13, numbers[1]);
   }
@@ -731,7 +731,7 @@
     vector<int> numbers;
     EXPECT_TRUE(reverse_merged_.FindAllExtensionNumbers("Baz", &numbers));
     ASSERT_EQ(2, numbers.size());
-    sort(numbers.begin(), numbers.end());
+    std::sort(numbers.begin(), numbers.end());
     EXPECT_EQ(12, numbers[0]);
     EXPECT_EQ(13, numbers[1]);
   }
diff --git a/src/google/protobuf/descriptor_pb2_test.py b/src/google/protobuf/descriptor_pb2_test.py
deleted file mode 100644
index c5a8d8a..0000000
--- a/src/google/protobuf/descriptor_pb2_test.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#! /usr/bin/python
-#
-# Protocol Buffers - Google's data interchange format
-# Copyright 2008 Google Inc.  All rights reserved.
-# https://developers.google.com/protocol-buffers/
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# Verify that prebuild and checkedin version of descriptor_pb2.py is up to date.
-
-from google3.pyglib import resources
-from google.apputils import basetest
-
-_DESC = 'google3/net/proto2/proto/descriptor_pb2.'
-_OLD = _DESC + 'py-prebuilt'
-_NEW = _DESC + 'compiled'
-
-
-class PregeneratedFileChanged(basetest.TestCase):
-
-  def testSameText(self):
-    generated = resources.GetResource(_NEW)
-    checkedin = resources.GetResource(_OLD)
-    self.assertMultiLineEqual(
-        generated, checkedin, 'It seems that protoc _pb2 generator changed. '
-        'Please run google/protobuf/generate_descriptor_proto.sh to '
-        'regnerate a new version of %s and add it to your CL' % _OLD)
-
-if __name__ == '__main__':
-  basetest.main()
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
index 2ceb41e..fdce3d7 100644
--- a/src/google/protobuf/descriptor_unittest.cc
+++ b/src/google/protobuf/descriptor_unittest.cc
@@ -6104,9 +6104,9 @@
 
   file_desc->CopySourceCodeInfoTo(&file_desc_proto);
   const SourceCodeInfo& info = file_desc_proto.source_code_info();
-  ASSERT_EQ(3, info.location_size());
+  ASSERT_EQ(4, info.location_size());
   // Get the Foo message location
-  const SourceCodeInfo_Location& foo_location = info.location(1);
+  const SourceCodeInfo_Location& foo_location = info.location(2);
   ASSERT_EQ(2, foo_location.path_size());
   EXPECT_EQ(FileDescriptorProto::kMessageTypeFieldNumber, foo_location.path(0));
   EXPECT_EQ(0, foo_location.path(1));      // Foo is the first message defined
diff --git a/src/google/protobuf/duration.proto b/src/google/protobuf/duration.proto
new file mode 100644
index 0000000..868c732
--- /dev/null
+++ b/src/google/protobuf/duration.proto
@@ -0,0 +1,93 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+syntax = "proto3";
+
+package google.protobuf;
+
+option java_generate_equals_and_hash = true;
+option java_multiple_files = true;
+option java_outer_classname = "DurationProto";
+option java_package = "com.google.protobuf";
+
+
+// A Duration represents a signed, fixed-length span of time represented
+// as a count of seconds and fractions of seconds at nanosecond
+// resolution. It is independent of any calendar and concepts like "day"
+// or "month". It is related to Timestamp in that the difference between
+// two Timestamp values is a Duration and it can be added or subtracted
+// from a Timestamp. Range is approximately +-10,000 years.
+//
+// Example 1: compute Duration from two Timestamps in pseudo code.
+//
+//     Timestamp start = ...;
+//     Timestamp end = ...;
+//     Duration duration = ...;
+//
+//     duration.seconds = end.seconds - start.seconds;
+//     duration.nanos = end.nanos - start.nanos;
+//
+//     if (duration.seconds < 0 && duration.nanos > 0) {
+//       duration.seconds += 1;
+//       duration.nanos -= 1000000000;
+//     } else if (durations.seconds > 0 && duration.nanos < 0) {
+//       duration.seconds -= 1;
+//       duration.nanos += 1000000000;
+//     }
+//
+// Example 2: compute Timestamp from Timestamp + Duration in pseudo code.
+//
+//     Timestamp start = ...;
+//     Duration duration = ...;
+//     Timestamp end = ...;
+//
+//     end.seconds = start.seconds + duration.seconds;
+//     end.nanos = start.nanos + duration.nanos;
+//
+//     if (end.nanos < 0) {
+//       end.seconds -= 1;
+//       end.nanos += 1000000000;
+//     } else if (end.nanos >= 1000000000) {
+//       end.seconds += 1;
+//       end.nanos -= 1000000000;
+//     }
+//
+message Duration {
+  // Signed seconds of the span of time. Must be from -315,576,000,000
+  // to +315,576,000,000 inclusive.
+  int64 seconds = 1;
+
+  // Signed fractions of a second at nanosecond resolution of the span
+  // of time. Durations less than one second are represented with a 0
+  // seconds field and a positive or negative nanos field. For durations
+  // of one second or more, a non-zero value for the nanos field must be
+  // of the same sign as the seconds field. Must be from -999,999,999
+  // to +999,999,999 inclusive.
+  int32 nanos = 2;
+}
diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc
index 4908713..03b38dd 100644
--- a/src/google/protobuf/extension_set.cc
+++ b/src/google/protobuf/extension_set.cc
@@ -97,7 +97,7 @@
               int number, ExtensionInfo info) {
   ::google::protobuf::GoogleOnceInit(&registry_init_, &InitRegistry);
 
-  if (!InsertIfNotPresent(registry_, make_pair(containing_type, number),
+  if (!InsertIfNotPresent(registry_, std::make_pair(containing_type, number),
                           info)) {
     GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
                << containing_type->GetTypeName()
@@ -107,8 +107,9 @@
 
 const ExtensionInfo* FindRegisteredExtension(
     const MessageLite* containing_type, int number) {
-  return (registry_ == NULL) ? NULL :
-         FindOrNull(*registry_, make_pair(containing_type, number));
+  return (registry_ == NULL)
+             ? NULL
+             : FindOrNull(*registry_, std::make_pair(containing_type, number));
 }
 
 }  // namespace
@@ -1032,7 +1033,7 @@
 
   if (this_iter == extensions_.end()) {
     if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
-      extensions_.insert(make_pair(number, other_iter->second));
+      extensions_.insert(std::make_pair(number, other_iter->second));
     } else {
       InternalExtensionMergeFrom(number, other_iter->second);
     }
@@ -1042,7 +1043,7 @@
 
   if (other_iter == other->extensions_.end()) {
     if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
-      other->extensions_.insert(make_pair(number, this_iter->second));
+      other->extensions_.insert(std::make_pair(number, this_iter->second));
     } else {
       other->InternalExtensionMergeFrom(number, this_iter->second);
     }
@@ -1175,6 +1176,9 @@
                   extension.enum_validity_check.arg, value)) {
             AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed,
                     value, extension.descriptor);
+          } else {
+            // Invalid value.  Treat as unknown.
+            field_skipper->SkipUnknownEnum(number, value);
           }
         }
         break;
@@ -1337,7 +1341,7 @@
                                      const FieldDescriptor* descriptor,
                                      Extension** result) {
   pair<map<int, Extension>::iterator, bool> insert_result =
-    extensions_.insert(make_pair(number, Extension()));
+      extensions_.insert(std::make_pair(number, Extension()));
   *result = &insert_result.first->second;
   (*result)->descriptor = descriptor;
   return insert_result.second;
diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc
index 5f4ca1c..796e7a5 100644
--- a/src/google/protobuf/extension_set_heavy.cc
+++ b/src/google/protobuf/extension_set_heavy.cc
@@ -91,9 +91,10 @@
   const Descriptor* containing_type_;
 };
 
-void ExtensionSet::AppendToList(const Descriptor* containing_type,
-                                const DescriptorPool* pool,
-                                vector<const FieldDescriptor*>* output) const {
+void ExtensionSet::AppendToList(
+    const Descriptor* containing_type,
+    const DescriptorPool* pool,
+    std::vector<const FieldDescriptor*>* output) const {
   for (map<int, Extension>::const_iterator iter = extensions_.begin();
        iter != extensions_.end(); ++iter) {
     bool has = false;
diff --git a/src/google/protobuf/field_mask.proto b/src/google/protobuf/field_mask.proto
new file mode 100644
index 0000000..492d4b0
--- /dev/null
+++ b/src/google/protobuf/field_mask.proto
@@ -0,0 +1,161 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+syntax = "proto3";
+
+package google.protobuf;
+
+option java_multiple_files = true;
+option java_outer_classname = "FieldMaskProto";
+option java_package = "com.google.protobuf";
+
+
+// `FieldMask` represents a set of symbolic field paths, for example:
+//
+//     paths: "f.a"
+//     paths: "f.b.d"
+//
+// Here `f` represents a field in some root message, `a` and `b`
+// fields in the message found in `f`, and `d` a field found in the
+// message in `f.b`.
+//
+// Field masks are used to specify a subset of fields that should be
+// returned by a get operation or modified by an update operation.
+// Field masks also have a custom JSON encoding (see below).
+//
+// # Field Masks in Projections
+// When used in the context of a projection, a response message or
+// sub-message is filtered by the API to only contain those fields as
+// specified in the mask. For example, if the mask in the previous
+// example is applied to a response message as follows:
+//
+//     f {
+//       a : 22
+//       b {
+//         d : 1
+//         x : 2
+//       }
+//       y : 13
+//     }
+//     z: 8
+//
+// The result will not contain specific values for fields x,y and z
+// (there value will be set to the default, and omitted in proto text
+// output):
+//
+//
+//     f {
+//       a : 22
+//       b {
+//         d : 1
+//       }
+//     }
+//
+// A repeated field is not allowed except at the last position of a
+// field mask.
+//
+// If a FieldMask object is not present in a get operation, the
+// operation applies to all fields (as if a FieldMask of all fields
+// had been specified).
+//
+// Note that a field mask does not necessarily applies to the
+// top-level response message. In case of a REST get operation, the
+// field mask applies directly to the response, but in case of a REST
+// list operation, the mask instead applies to each individual message
+// in the returned resource list. In case of a REST custom method,
+// other definitions may be used. Where the mask applies will be
+// clearly documented together with its declaration in the API.  In
+// any case, the effect on the returned resource/resources is required
+// behavior for APIs.
+//
+// # Field Masks in Update Operations
+// A field mask in update operations specifies which fields of the
+// targeted resource are going to be updated. The API is required
+// to only change the values of the fields as specified in the mask
+// and leave the others untouched. If a resource is passed in to
+// describe the updated values, the API ignores the values of all
+// fields not covered by the mask.
+//
+// In order to reset a field's value to the default, the field must
+// be in the mask and set to the default value in the provided resource.
+// Hence, in order to reset all fields of a resource, provide a default
+// instance of the resource and set all fields in the mask, or do
+// not provide a mask as described below.
+//
+// If a field mask is not present on update, the operation applies to
+// all fields (as if a field mask of all fields has been specified).
+// Note that in the presence of schema evolution, this may mean that
+// fields the client does not know and has therefore not filled into
+// the request will be reset to their default. If this is unwanted
+// behavior, a specific service may require a client to always specify
+// a field mask, producing an error if not.
+//
+// As with get operations, the location of the resource which
+// describes the updated values in the request message depends on the
+// operation kind. In any case, the effect of the field mask is
+// required to be honored by the API.
+//
+// ## Considerations for HTTP REST
+// The HTTP kind of an update operation which uses a field mask must
+// be set to PATCH instead of PUT in order to satisfy HTTP semantics
+// (PUT must only be used for full updates).
+//
+// # JSON Encoding of Field Masks
+// In JSON, a field mask is encoded as a single string where paths are
+// separated by a comma. Fields name in each path are converted
+// to/from lower-camel naming conventions.
+//
+// As an example, consider the following message declarations:
+//
+//     message Profile {
+//       User user = 1;
+//       Photo photo = 2;
+//     }
+//     message User {
+//       string display_name = 1;
+//       string address = 2;
+//     }
+//
+// In proto a field mask for `Profile` may look as such:
+//
+//     mask {
+//       paths: "user.display_name"
+//       paths: "photo"
+//     }
+//
+// In JSON, the same mask is represented as below:
+//
+//     {
+//       mask: "user.displayName,photo"
+//     }
+//
+message FieldMask {
+  // The set of field mask paths.
+  repeated string paths = 1;
+}
diff --git a/src/google/protobuf/generated_enum_reflection.h b/src/google/protobuf/generated_enum_reflection.h
index 3852cea..fdcdc27 100644
--- a/src/google/protobuf/generated_enum_reflection.h
+++ b/src/google/protobuf/generated_enum_reflection.h
@@ -42,6 +42,7 @@
 #include <string>
 
 #include <google/protobuf/stubs/template_util.h>
+#include <google/protobuf/generated_enum_util.h>
 
 namespace google {
 namespace protobuf {
@@ -50,10 +51,6 @@
 
 namespace protobuf {
 
-// This type trait can be used to cause templates to only match proto2 enum
-// types.
-template <typename T> struct is_proto_enum : ::google::protobuf::internal::false_type {};
-
 // Returns the EnumDescriptor for enum type E, which must be a
 // proto-declared enum type.  Code generated by the protocol compiler
 // will include specializations of this template for each enum type declared.
diff --git a/src/google/protobuf/generated_enum_util.h b/src/google/protobuf/generated_enum_util.h
new file mode 100644
index 0000000..e424205
--- /dev/null
+++ b/src/google/protobuf/generated_enum_util.h
@@ -0,0 +1,46 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__
+#define GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__
+
+#include <google/protobuf/stubs/template_util.h>
+
+namespace google {
+namespace protobuf {
+
+// This type trait can be used to cause templates to only match proto2 enum
+// types.
+template <typename T> struct is_proto_enum : ::google::protobuf::internal::false_type {};
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc
index 3482680..412c48a 100644
--- a/src/google/protobuf/generated_message_reflection.cc
+++ b/src/google/protobuf/generated_message_reflection.cc
@@ -995,6 +995,7 @@
   // Optimization:  The default instance never has any fields set.
   if (&message == default_instance_) return;
 
+  output->reserve(descriptor_->field_count());
   for (int i = 0; i < descriptor_->field_count(); i++) {
     const FieldDescriptor* field = descriptor_->field(i);
     if (field->is_repeated()) {
@@ -1018,7 +1019,7 @@
   }
 
   // ListFields() must sort output by field number.
-  sort(output->begin(), output->end(), FieldNumberSorter());
+  std::sort(output->begin(), output->end(), FieldNumberSorter());
 }
 
 // -------------------------------------------------------------------
@@ -1434,6 +1435,8 @@
 Message* GeneratedMessageReflection::MutableMessage(
     Message* message, const FieldDescriptor* field,
     MessageFactory* factory) const {
+  USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE);
+
   if (factory == NULL) factory = message_factory_;
 
   if (field->is_extension()) {
@@ -1972,26 +1975,28 @@
   uint32 oneof_case = GetOneofCase(*message, oneof_descriptor);
   if (oneof_case > 0) {
     const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case);
-    switch (field->cpp_type()) {
-      case FieldDescriptor::CPPTYPE_STRING: {
-        switch (field->options().ctype()) {
-          default:  // TODO(kenton):  Support other string reps.
-          case FieldOptions::STRING: {
-            const string* default_ptr =
-                &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
-            MutableField<ArenaStringPtr>(message, field)->
-                Destroy(default_ptr, GetArena(message));
-            break;
+    if (GetArena(message) == NULL) {
+      switch (field->cpp_type()) {
+        case FieldDescriptor::CPPTYPE_STRING: {
+          switch (field->options().ctype()) {
+            default:  // TODO(kenton):  Support other string reps.
+            case FieldOptions::STRING: {
+              const string* default_ptr =
+                  &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
+              MutableField<ArenaStringPtr>(message, field)->
+                  Destroy(default_ptr, GetArena(message));
+              break;
+            }
           }
+          break;
         }
-        break;
-      }
 
-      case FieldDescriptor::CPPTYPE_MESSAGE:
-        delete *MutableRaw<Message*>(message, field);
-        break;
-      default:
-        break;
+        case FieldDescriptor::CPPTYPE_MESSAGE:
+          delete *MutableRaw<Message*>(message, field);
+          break;
+        default:
+          break;
+      }
     }
 
     *MutableOneofCase(message, oneof_descriptor) = 0;
diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc
index df88205..93e1a22 100644
--- a/src/google/protobuf/io/coded_stream.cc
+++ b/src/google/protobuf/io/coded_stream.cc
@@ -153,7 +153,7 @@
 
 std::pair<CodedInputStream::Limit, int>
 CodedInputStream::IncrementRecursionDepthAndPushLimit(int byte_limit) {
-  return make_pair(PushLimit(byte_limit), --recursion_budget_);
+  return std::make_pair(PushLimit(byte_limit), --recursion_budget_);
 }
 
 bool CodedInputStream::DecrementRecursionDepthAndPopLimit(Limit limit) {
@@ -613,8 +613,15 @@
 }
 
 CodedOutputStream::~CodedOutputStream() {
+  Trim();
+}
+
+void CodedOutputStream::Trim() {
   if (buffer_size_ > 0) {
     output_->BackUp(buffer_size_);
+    total_bytes_ -= buffer_size_;
+    buffer_size_ = 0;
+    buffer_ = NULL;
   }
 }
 
@@ -662,12 +669,7 @@
       ) {
     WriteRaw(data, size);
   } else {
-    if (buffer_size_ > 0) {
-      output_->BackUp(buffer_size_);
-      total_bytes_ -= buffer_size_;
-      buffer_ = NULL;
-      buffer_size_ = 0;
-    }
+    Trim();
 
     total_bytes_ += size;
     had_error_ |= !output_->WriteAliasedRaw(data, size);
@@ -704,61 +706,12 @@
   }
 }
 
-inline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline(
-    uint32 value, uint8* target) {
-  target[0] = static_cast<uint8>(value | 0x80);
-  if (value >= (1 << 7)) {
-    target[1] = static_cast<uint8>((value >>  7) | 0x80);
-    if (value >= (1 << 14)) {
-      target[2] = static_cast<uint8>((value >> 14) | 0x80);
-      if (value >= (1 << 21)) {
-        target[3] = static_cast<uint8>((value >> 21) | 0x80);
-        if (value >= (1 << 28)) {
-          target[4] = static_cast<uint8>(value >> 28);
-          return target + 5;
-        } else {
-          target[3] &= 0x7F;
-          return target + 4;
-        }
-      } else {
-        target[2] &= 0x7F;
-        return target + 3;
-      }
-    } else {
-      target[1] &= 0x7F;
-      return target + 2;
-    }
-  } else {
-    target[0] &= 0x7F;
-    return target + 1;
-  }
-}
-
-void CodedOutputStream::WriteVarint32(uint32 value) {
-  if (buffer_size_ >= kMaxVarint32Bytes) {
-    // Fast path:  We have enough bytes left in the buffer to guarantee that
-    // this write won't cross the end, so we can skip the checks.
-    uint8* target = buffer_;
-    uint8* end = WriteVarint32FallbackToArrayInline(value, target);
-    int size = end - target;
-    Advance(size);
-  } else {
-    // Slow path:  This write might cross the end of the buffer, so we
-    // compose the bytes first then use WriteRaw().
-    uint8 bytes[kMaxVarint32Bytes];
-    int size = 0;
-    while (value > 0x7F) {
-      bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80;
-      value >>= 7;
-    }
-    bytes[size++] = static_cast<uint8>(value) & 0x7F;
-    WriteRaw(bytes, size);
-  }
-}
-
-uint8* CodedOutputStream::WriteVarint32FallbackToArray(
-    uint32 value, uint8* target) {
-  return WriteVarint32FallbackToArrayInline(value, target);
+void CodedOutputStream::WriteVarint32SlowPath(uint32 value) {
+  uint8 bytes[kMaxVarint32Bytes];
+  uint8* target = &bytes[0];
+  uint8* end = WriteVarint32ToArray(value, target);
+  int size = end - target;
+  WriteRaw(bytes, size);
 }
 
 inline uint8* CodedOutputStream::WriteVarint64ToArrayInline(
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h
index 978cc19..dea4b65 100644
--- a/src/google/protobuf/io/coded_stream.h
+++ b/src/google/protobuf/io/coded_stream.h
@@ -647,6 +647,13 @@
   // ZeroCopyOutputStream immediately after the last byte written.
   ~CodedOutputStream();
 
+  // Trims any unused space in the underlying buffer so that its size matches
+  // the number of bytes written by this stream. The underlying buffer will
+  // automatically be trimmed when this stream is destroyed; this call is only
+  // necessary if the underlying buffer is accessed *before* the stream is
+  // destroyed.
+  void Trim();
+
   // Skips a number of bytes, leaving the bytes unmodified in the underlying
   // buffer.  Returns false if an underlying write error occurs.  This is
   // mainly useful with GetDirectBufferPointer().
@@ -789,7 +796,9 @@
   // ZeroCopyOutputStream supports it.
   void WriteAliasedRaw(const void* buffer, int size);
 
-  static uint8* WriteVarint32FallbackToArray(uint32 value, uint8* target);
+  // If this write might cross the end of the buffer, we compose the bytes first
+  // then use WriteRaw().
+  void WriteVarint32SlowPath(uint32 value);
 
   // Always-inlined versions of WriteVarint* functions so that code can be
   // reused, while still controlling size. For instance, WriteVarint32ToArray()
@@ -798,8 +807,6 @@
   // WriteVarint32FallbackToArray.  Meanwhile, WriteVarint32() is already
   // out-of-line, so it should just invoke this directly to avoid any extra
   // function call overhead.
-  static uint8* WriteVarint32FallbackToArrayInline(
-      uint32 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
   static uint8* WriteVarint64ToArrayInline(
       uint64 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
 
@@ -919,7 +926,7 @@
       const uint32 kMax1ByteVarint = 0x7f;
       uint32 tag = last_tag_ = buffer_[0];
       Advance(1);
-      return make_pair(tag, cutoff >= kMax1ByteVarint || tag <= cutoff);
+      return std::make_pair(tag, cutoff >= kMax1ByteVarint || tag <= cutoff);
     }
     // Other hot case: cutoff >= 0x80, buffer_ has at least two bytes available,
     // and tag is two bytes.  The latter is tested by bitwise-and-not of the
@@ -937,12 +944,12 @@
       // so we don't have to check for tag == 0.  We may need to check whether
       // it exceeds cutoff.
       bool at_or_below_cutoff = cutoff >= kMax2ByteVarint || tag <= cutoff;
-      return make_pair(tag, at_or_below_cutoff);
+      return std::make_pair(tag, at_or_below_cutoff);
     }
   }
   // Slow path
   last_tag_ = ReadTagFallback();
-  return make_pair(last_tag_, static_cast<uint32>(last_tag_ - 1) < cutoff);
+  return std::make_pair(last_tag_, static_cast<uint32>(last_tag_ - 1) < cutoff);
 }
 
 inline bool CodedInputStream::LastTagWas(uint32 expected) {
@@ -1027,13 +1034,14 @@
 }
 
 inline uint8* CodedOutputStream::WriteVarint32ToArray(uint32 value,
-                                                        uint8* target) {
-  if (value < 0x80) {
-    *target = value;
-    return target + 1;
-  } else {
-    return WriteVarint32FallbackToArray(value, target);
+                                                      uint8* target) {
+  while (value >= 0x80) {
+    *target = static_cast<uint8>(value | 0x80);
+    value >>= 7;
+    ++target;
   }
+  *target = static_cast<uint8>(value);
+  return target + 1;
 }
 
 inline void CodedOutputStream::WriteVarint32SignExtended(int32 value) {
@@ -1086,22 +1094,26 @@
   return target + sizeof(value);
 }
 
+inline void CodedOutputStream::WriteVarint32(uint32 value) {
+  if (buffer_size_ >= 5) {
+    // Fast path:  We have enough bytes left in the buffer to guarantee that
+    // this write won't cross the end, so we can skip the checks.
+    uint8* target = buffer_;
+    uint8* end = WriteVarint32ToArray(value, target);
+    int size = end - target;
+    Advance(size);
+  } else {
+    WriteVarint32SlowPath(value);
+  }
+}
+
 inline void CodedOutputStream::WriteTag(uint32 value) {
   WriteVarint32(value);
 }
 
 inline uint8* CodedOutputStream::WriteTagToArray(
     uint32 value, uint8* target) {
-  if (value < (1 << 7)) {
-    target[0] = value;
-    return target + 1;
-  } else if (value < (1 << 14)) {
-    target[0] = static_cast<uint8>(value | 0x80);
-    target[1] = static_cast<uint8>(value >> 7);
-    return target + 2;
-  } else {
-    return WriteVarint32FallbackToArray(value, target);
-  }
+  return WriteVarint32ToArray(value, target);
 }
 
 inline int CodedOutputStream::VarintSize32(uint32 value) {
diff --git a/src/google/protobuf/io/coded_stream_unittest.cc b/src/google/protobuf/io/coded_stream_unittest.cc
index bbe5e39..02d5bad 100644
--- a/src/google/protobuf/io/coded_stream_unittest.cc
+++ b/src/google/protobuf/io/coded_stream_unittest.cc
@@ -502,11 +502,11 @@
 };
 
 inline std::ostream& operator<<(std::ostream& os, const Fixed32Case& c) {
-  return os << "0x" << hex << c.value << dec;
+  return os << "0x" << std::hex << c.value << std::dec;
 }
 
 inline std::ostream& operator<<(std::ostream& os, const Fixed64Case& c) {
-  return os << "0x" << hex << c.value << dec;
+  return os << "0x" << std::hex << c.value << std::dec;
 }
 
 Fixed32Case kFixed32Cases[] = {
diff --git a/src/google/protobuf/io/gzip_stream.cc b/src/google/protobuf/io/gzip_stream.cc
index e603786..c9f4ca7 100644
--- a/src/google/protobuf/io/gzip_stream.cc
+++ b/src/google/protobuf/io/gzip_stream.cc
@@ -49,6 +49,7 @@
 GzipInputStream::GzipInputStream(
     ZeroCopyInputStream* sub_stream, Format format, int buffer_size)
     : format_(format), sub_stream_(sub_stream), zerror_(Z_OK), byte_count_(0) {
+  zcontext_.state = Z_NULL;
   zcontext_.zalloc = Z_NULL;
   zcontext_.zfree = Z_NULL;
   zcontext_.opaque = Z_NULL;
diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/src/google/protobuf/io/zero_copy_stream_impl_lite.h
index 3e25edf..4360b18 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl_lite.h
+++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.h
@@ -368,7 +368,7 @@
 inline std::pair<char*, bool> as_string_data(string* s) {
   char *p = mutable_string_data(s);
 #ifdef LANG_CXX11
-  return make_pair(p, true);
+  return std::make_pair(p, true);
 #else
   return make_pair(p, p != NULL);
 #endif
diff --git a/src/google/protobuf/lite_unittest.cc b/src/google/protobuf/lite_unittest.cc
index a370526..4ea2100 100644
--- a/src/google/protobuf/lite_unittest.cc
+++ b/src/google/protobuf/lite_unittest.cc
@@ -345,6 +345,6 @@
     GOOGLE_CHECK_EQ(0, empty_message.unknown_fields().size());
   }
 
-  cout << "PASS" << endl;
+  std::cout << "PASS" << std::endl;
   return 0;
 }
diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h
index 6d8a9d0..e56af3f 100644
--- a/src/google/protobuf/map.h
+++ b/src/google/protobuf/map.h
@@ -34,6 +34,8 @@
 #include <iterator>
 #include <google/protobuf/stubs/hash.h>
 
+#include <google/protobuf/arena.h>
+#include <google/protobuf/generated_enum_util.h>
 #include <google/protobuf/map_type_handler.h>
 
 namespace google {
@@ -45,10 +47,12 @@
 template <typename Enum> struct is_proto_enum;
 
 namespace internal {
-template <typename K, typename V, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-class MapField;
-}  // namespace internal
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value>
+class MapFieldLite;
+}
 
 // This is the class for google::protobuf::Map's internal value_type. Instead of using
 // std::pair as value_type, we use this class which provides us more control of
@@ -61,23 +65,24 @@
 
   MapPair(const Key& other_first, const T& other_second)
       : first(other_first), second(other_second) {}
-
   explicit MapPair(const Key& other_first) : first(other_first), second() {}
-
   MapPair(const MapPair& other)
       : first(other.first), second(other.second) {}
 
   ~MapPair() {}
 
-  // Implicitly convertible to std::pair.
-  operator std::pair<const Key, T>() const {
-    return std::pair<const Key, T>(first, second);
+  // Implicitly convertible to std::pair of compatible types.
+  template <typename T1, typename T2>
+  operator std::pair<T1, T2>() const {
+    return std::pair<T1, T2>(first, second);
   }
 
   const Key first;
   T second;
 
  private:
+  typedef void DestructorSkippable_;
+  friend class ::google::protobuf::Arena;
   friend class Map<Key, T>;
 };
 
@@ -86,6 +91,7 @@
 // interface directly to visit or change map fields.
 template <typename Key, typename T>
 class Map {
+  typedef internal::MapCppTypeHandler<Key> KeyTypeHandler;
   typedef internal::MapCppTypeHandler<T> ValueTypeHandler;
 
  public:
@@ -100,20 +106,104 @@
 
   typedef size_t size_type;
   typedef hash<Key> hasher;
+  typedef equal_to<Key> key_equal;
 
-  Map() : default_enum_value_(0) {}
+  Map()
+      : arena_(NULL),
+        allocator_(arena_),
+        elements_(0, hasher(), key_equal(), allocator_),
+        default_enum_value_(0) {}
+  explicit Map(Arena* arena)
+      : arena_(arena),
+        allocator_(arena_),
+        elements_(0, hasher(), key_equal(), allocator_),
+        default_enum_value_(0) {}
 
-  Map(const Map& other) {
+  Map(const Map& other)
+      : arena_(NULL),
+        allocator_(arena_),
+        elements_(0, hasher(), key_equal(), allocator_),
+        default_enum_value_(other.default_enum_value_) {
     insert(other.begin(), other.end());
   }
 
   ~Map() { clear(); }
 
+ private:
+  // re-implement std::allocator to use arena allocator for memory allocation.
+  // Used for google::protobuf::Map implementation. Users should not use this class
+  // directly.
+  template <typename U>
+  class MapAllocator {
+   public:
+    typedef U value_type;
+    typedef value_type* pointer;
+    typedef const value_type* const_pointer;
+    typedef value_type& reference;
+    typedef const value_type& const_reference;
+    typedef size_t size_type;
+    typedef ptrdiff_t difference_type;
+
+    MapAllocator() : arena_(NULL) {}
+    explicit MapAllocator(Arena* arena) : arena_(arena) {}
+    template <typename X>
+    MapAllocator(const MapAllocator<X>& allocator)
+        : arena_(allocator.arena_) {}
+
+    pointer allocate(size_type n, const_pointer hint = 0) {
+      // If arena is not given, malloc needs to be called which doesn't
+      // construct element object.
+      if (arena_ == NULL) {
+        return reinterpret_cast<pointer>(malloc(n * sizeof(value_type)));
+      } else {
+        return reinterpret_cast<pointer>(
+            Arena::CreateArray<uint8>(arena_, n * sizeof(value_type)));
+      }
+    }
+
+    void deallocate(pointer p, size_type n) {
+      if (arena_ == NULL) {
+        free(p);
+      }
+    }
+
+    void construct(pointer p, const_reference t) { new (p) value_type(t); }
+
+    void destroy(pointer p) {
+      if (arena_ == NULL) p->~value_type();
+    }
+
+    template <typename X>
+    struct rebind {
+      typedef MapAllocator<X> other;
+    };
+
+    template <typename X>
+    bool operator==(const MapAllocator<X>& other) const {
+      return arena_ == other.arena_;
+    }
+
+    template <typename X>
+    bool operator!=(const MapAllocator<X>& other) const {
+      return arena_ != other.arena_;
+    }
+
+   private:
+    Arena* arena_;
+
+    template <typename X>
+    friend class MapAllocator;
+  };
+
+ public:
+  typedef MapAllocator<std::pair<const Key, MapPair<Key, T>*> > Allocator;
+
   // Iterators
-  class const_iterator
+  class LIBPROTOBUF_EXPORT const_iterator
       : public std::iterator<std::forward_iterator_tag, value_type, ptrdiff_t,
                              const value_type*, const value_type&> {
-    typedef typename hash_map<Key, value_type*>::const_iterator InnerIt;
+    typedef typename hash_map<Key, value_type*, hash<Key>, equal_to<Key>,
+                              Allocator>::const_iterator InnerIt;
 
    public:
     const_iterator() {}
@@ -139,8 +229,9 @@
     InnerIt it_;
   };
 
-  class iterator : public std::iterator<std::forward_iterator_tag, value_type> {
-    typedef typename hash_map<Key, value_type*>::iterator InnerIt;
+  class LIBPROTOBUF_EXPORT iterator : public std::iterator<std::forward_iterator_tag, value_type> {
+    typedef typename hash_map<Key, value_type*, hasher, equal_to<Key>,
+                              Allocator>::iterator InnerIt;
 
    public:
     iterator() {}
@@ -185,7 +276,7 @@
   T& operator[](const key_type& key) {
     value_type** value = &elements_[key];
     if (*value == NULL) {
-      *value = new value_type(key);
+      *value = CreateValueTypeInternal(key);
       internal::MapValueInitializer<google::protobuf::is_proto_enum<T>::value,
                                     T>::Initialize((*value)->second,
                                                    default_enum_value_);
@@ -241,7 +332,7 @@
     } else {
       return std::pair<iterator, bool>(
           iterator(elements_.insert(std::pair<Key, value_type*>(
-              value.first, new value_type(value))).first), true);
+              value.first, CreateValueTypeInternal(value))).first), true);
     }
   }
   template <class InputIt>
@@ -256,28 +347,29 @@
 
   // Erase
   size_type erase(const key_type& key) {
-    typename hash_map<Key, value_type*>::iterator it = elements_.find(key);
+    typename hash_map<Key, value_type*, hash<Key>, equal_to<Key>,
+                      Allocator>::iterator it = elements_.find(key);
     if (it == elements_.end()) {
       return 0;
     } else {
-      delete it->second;
+      if (arena_ == NULL) delete it->second;
       elements_.erase(it);
       return 1;
     }
   }
   void erase(iterator pos) {
-    delete pos.it_->second;
+    if (arena_ == NULL) delete pos.it_->second;
     elements_.erase(pos.it_);
   }
   void erase(iterator first, iterator last) {
     for (iterator it = first; it != last;) {
-      delete it.it_->second;
+      if (arena_ == NULL) delete it.it_->second;
       elements_.erase((it++).it_);
     }
   }
   void clear() {
     for (iterator it = begin(); it != end(); ++it) {
-      delete it.it_->second;
+      if (arena_ == NULL) delete it.it_->second;
     }
     elements_.clear();
   }
@@ -297,12 +389,45 @@
     default_enum_value_ = default_enum_value;
   }
 
-  hash_map<Key, value_type*> elements_;
+  value_type* CreateValueTypeInternal(const Key& key) {
+    if (arena_ == NULL) {
+      return new value_type(key);
+    } else {
+      value_type* value = reinterpret_cast<value_type*>(
+          Arena::CreateArray<uint8>(arena_, sizeof(value_type)));
+      Arena::CreateInArenaStorage(const_cast<Key*>(&value->first), arena_);
+      Arena::CreateInArenaStorage(&value->second, arena_);
+      const_cast<Key&>(value->first) = key;
+      return value;
+    }
+  }
+
+  value_type* CreateValueTypeInternal(const value_type& value) {
+    if (arena_ == NULL) {
+      return new value_type(value);
+    } else {
+      value_type* p = reinterpret_cast<value_type*>(
+          Arena::CreateArray<uint8>(arena_, sizeof(value_type)));
+      Arena::CreateInArenaStorage(const_cast<Key*>(&p->first), arena_);
+      Arena::CreateInArenaStorage(&p->second, arena_);
+      const_cast<Key&>(p->first) = value.first;
+      p->second = value.second;
+      return p;
+    }
+  }
+
+  Arena* arena_;
+  Allocator allocator_;
+  hash_map<Key, value_type*, hash<Key>, equal_to<Key>, Allocator> elements_;
   int default_enum_value_;
 
-  template <typename K, typename V, FieldDescriptor::Type KeyProto,
-            FieldDescriptor::Type ValueProto, int default_enum>
-  friend class internal::MapField;
+  friend class ::google::protobuf::Arena;
+  typedef void DestructorSkippable_;
+  template <typename K, typename V,
+            internal::WireFormatLite::FieldType key_wire_type,
+            internal::WireFormatLite::FieldType value_wire_type,
+            int default_enum_value>
+  friend class LIBPROTOBUF_EXPORT internal::MapFieldLite;
 };
 
 }  // namespace protobuf
diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h
index 30302a0..f78a4f4 100644
--- a/src/google/protobuf/map_entry.h
+++ b/src/google/protobuf/map_entry.h
@@ -31,13 +31,23 @@
 #ifndef GOOGLE_PROTOBUF_MAP_ENTRY_H__
 #define GOOGLE_PROTOBUF_MAP_ENTRY_H__
 
-#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/map_entry_lite.h>
 #include <google/protobuf/map_type_handler.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/unknown_field_set.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 
 namespace google {
 namespace protobuf {
 class Arena;
+namespace internal {
+template <typename Key, typename Value,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+class MapField;
+}
 }
 
 namespace protobuf {
@@ -83,179 +93,103 @@
 // while we need to explicitly tell cpp type if proto type is TYPE_MESSAGE to
 // get internal layout.
 // Moreover, default_enum_value is used to initialize enum field in proto2.
-template <typename Key, typename Value, FieldDescriptor::Type KeyProtoType,
-          FieldDescriptor::Type ValueProtoType, int default_enum_value>
-class MapEntry : public MapEntryBase {
-  // Handlers for key/value's proto field type. Used to infer internal layout
-  // and provide parsing/serialization support.
-  typedef MapProtoTypeHandler<KeyProtoType> KeyProtoHandler;
-  typedef MapProtoTypeHandler<ValueProtoType> ValueProtoHandler;
+template <typename Key, typename Value,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase {
+  // Handlers for key/value wire type. Provide utilities to parse/serialize
+  // key/value.
+  typedef MapWireFieldTypeHandler<kKeyFieldType> KeyWireHandler;
+  typedef MapWireFieldTypeHandler<kValueFieldType> ValueWireHandler;
 
   // Define key/value's internal stored type. Message is the only one whose
   // internal stored type cannot be inferred from its proto type.
-  typedef typename KeyProtoHandler::CppType KeyProtoHandlerCppType;
-  typedef typename ValueProtoHandler::CppType ValueProtoHandlerCppType;
-  static const bool kIsKeyMessage = KeyProtoHandler::kIsMessage;
-  static const bool kIsValueMessage = ValueProtoHandler::kIsMessage;
-  typedef typename MapIf<kIsKeyMessage, Key, KeyProtoHandlerCppType>::type
+  static const bool kIsKeyMessage = KeyWireHandler::kIsMessage;
+  static const bool kIsValueMessage = ValueWireHandler::kIsMessage;
+  typedef typename KeyWireHandler::CppType KeyInternalType;
+  typedef typename ValueWireHandler::CppType ValueInternalType;
+  typedef typename MapIf<kIsKeyMessage, Key, KeyInternalType>::type
       KeyCppType;
-  typedef typename MapIf<kIsValueMessage, Value, ValueProtoHandlerCppType>::type
+  typedef typename MapIf<kIsValueMessage, Value, ValueInternalType>::type
       ValCppType;
 
-  // Handlers for key/value's internal stored type. Provide utilities to
-  // manipulate internal stored type. We need it because some types are stored
-  // as values and others are stored as pointers (Message and string), but we
-  // need to keep the code in MapEntry unified instead of providing different
-  // codes for each type.
-  typedef MapCppTypeHandler<KeyCppType> KeyCppHandler;
-  typedef MapCppTypeHandler<ValCppType> ValueCppHandler;
-
-  // Define internal memory layout. Strings and messages are stored as
-  // pointers, while other types are stored as values.
-  static const bool kKeyIsStringOrMessage = KeyCppHandler::kIsStringOrMessage;
-  static const bool kValIsStringOrMessage = ValueCppHandler::kIsStringOrMessage;
-  typedef typename MapIf<kKeyIsStringOrMessage, KeyCppType*, KeyCppType>::type
-      KeyBase;
-  typedef typename MapIf<kValIsStringOrMessage, ValCppType*, ValCppType>::type
-      ValueBase;
-
   // Abbreviation for MapEntry
   typedef typename google::protobuf::internal::MapEntry<
-      Key, Value, KeyProtoType, ValueProtoType, default_enum_value> EntryType;
+      Key, Value, kKeyFieldType, kValueFieldType, default_enum_value> EntryType;
 
-  // Constants for field number.
-  static const int kKeyFieldNumber = 1;
-  static const int kValueFieldNumber = 2;
-
-  // Constants for field tag.
-  static const uint8 kKeyTag   = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
-      kKeyFieldNumber,   KeyProtoHandler::kWireType);
-  static const uint8 kValueTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
-      kValueFieldNumber, ValueProtoHandler::kWireType);
-  static const int kTagSize = 1;
+  // Abbreviation for MapEntryLite
+  typedef typename google::protobuf::internal::MapEntryLite<
+      Key, Value, kKeyFieldType, kValueFieldType, default_enum_value>
+      EntryLiteType;
 
  public:
   ~MapEntry() {
     if (this == default_instance_) {
       delete reflection_;
-    } else {
-      KeyCppHandler::Delete(key_);
-      ValueCppHandler::Delete(value_);
     }
   }
 
   // accessors ======================================================
 
-  inline void set_key(const KeyCppType& key) {
-    KeyCppHandler::EnsureMutable(&key_);
-    KeyCppHandler::Merge(key, &key_);
-    set_has_key();
-  }
   virtual inline const KeyCppType& key() const {
-    return KeyCppHandler::Reference(key_);
+    return entry_lite_.key();
   }
   inline KeyCppType* mutable_key() {
-    set_has_key();
-    KeyCppHandler::EnsureMutable(&key_);
-    return KeyCppHandler::Pointer(key_);
-  }
-  inline void set_value(const ValCppType& value) {
-    ValueCppHandler::EnsureMutable(&value_);
-    ValueCppHandler::Merge(value, &value_);
-    set_has_value();
+    return entry_lite_.mutable_key();
   }
   virtual inline const ValCppType& value() const {
-    GOOGLE_CHECK(default_instance_ != NULL);
-    return ValueCppHandler::DefaultIfNotInitialized(value_,
-                                               default_instance_->value_);
+    return entry_lite_.value();
   }
   inline ValCppType* mutable_value() {
-    set_has_value();
-    ValueCppHandler::EnsureMutable(&value_);
-    return ValueCppHandler::Pointer(value_);
+    return entry_lite_.mutable_value();
   }
 
   // implements Message =============================================
 
   bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) {
-    uint32 tag;
-
-    for (;;) {
-      // 1) corrupted data: return false;
-      // 2) unknown field: skip without putting into unknown field set;
-      // 3) unknown enum value: keep it in parsing. In proto2, caller should
-      // check the value and put this entry into containing message's unknown
-      // field set if the value is an unknown enum. In proto3, caller doesn't
-      // need to care whether the value is unknown enum;
-      // 4) missing key/value: missed key/value will have default value. caller
-      // should take this entry as if key/value is set to default value.
-      tag = input->ReadTag();
-      switch (tag) {
-        case kKeyTag:
-          if (!KeyProtoHandler::Read(input, mutable_key())) return false;
-          set_has_key();
-          if (!input->ExpectTag(kValueTag)) break;
-          GOOGLE_FALLTHROUGH_INTENDED;
-
-        case kValueTag:
-          if (!ValueProtoHandler::Read(input, mutable_value())) return false;
-          set_has_value();
-          if (input->ExpectAtEnd()) return true;
-          break;
-
-        default:
-          if (tag == 0 ||
-              WireFormatLite::GetTagWireType(tag) ==
-              WireFormatLite::WIRETYPE_END_GROUP) {
-            return true;
-          }
-          if (!WireFormatLite::SkipField(input, tag)) return false;
-          break;
-      }
-    }
+    return entry_lite_.MergePartialFromCodedStream(input);
   }
 
   int ByteSize() const {
-    int size = 0;
-    size += has_key() ? kTagSize + KeyProtoHandler::ByteSize(key()) : 0;
-    size += has_value() ? kTagSize + ValueProtoHandler::ByteSize(value()) : 0;
-    return size;
+    return entry_lite_.ByteSize();
   }
 
   void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const {
-    KeyProtoHandler::Write(kKeyFieldNumber, key(), output);
-    ValueProtoHandler::Write(kValueFieldNumber, value(), output);
+    entry_lite_.SerializeWithCachedSizes(output);
   }
 
   ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
-    output = KeyProtoHandler::WriteToArray(kKeyFieldNumber, key(), output);
-    output =
-        ValueProtoHandler::WriteToArray(kValueFieldNumber, value(), output);
-    return output;
+    return entry_lite_.SerializeWithCachedSizesToArray(output);
   }
 
   int GetCachedSize() const {
-    int size = 0;
-    size += has_key() ? kTagSize + KeyProtoHandler::GetCachedSize(key()) : 0;
-    size +=
-        has_value() ? kTagSize + ValueProtoHandler::GetCachedSize(value()) : 0;
-    return size;
+    return entry_lite_.GetCachedSize();
   }
 
-  bool IsInitialized() const { return ValueCppHandler::IsInitialized(value_); }
+  bool IsInitialized() const {
+    return entry_lite_.IsInitialized();
+  }
 
   Message* New() const {
     MapEntry* entry = new MapEntry;
     entry->descriptor_ = descriptor_;
     entry->reflection_ = reflection_;
-    entry->default_instance_ = default_instance_;
+    entry->set_default_instance(default_instance_);
+    return entry;
+  }
+
+  Message* New(Arena* arena) const {
+    MapEntry* entry = Arena::CreateMessage<MapEntry>(arena);
+    entry->descriptor_ = descriptor_;
+    entry->reflection_ = reflection_;
+    entry->set_default_instance(default_instance_);
     return entry;
   }
 
   int SpaceUsed() const {
     int size = sizeof(MapEntry);
-    size += KeyCppHandler::SpaceUsedInMapEntry(key_);
-    size += ValueCppHandler::SpaceUsedInMapEntry(value_);
+    size += entry_lite_.SpaceUsed();
     return size;
   }
 
@@ -280,30 +214,19 @@
   }
 
   void MergeFrom(const MapEntry& from) {
-    if (from._has_bits_[0]) {
-      if (from.has_key()) {
-        KeyCppHandler::EnsureMutable(&key_);
-        KeyCppHandler::Merge(from.key(), &key_);
-        set_has_key();
-      }
-      if (from.has_value()) {
-        ValueCppHandler::EnsureMutable(&value_);
-        ValueCppHandler::Merge(from.value(), &value_);
-        set_has_value();
-      }
-    }
+    entry_lite_.MergeFrom(from.entry_lite_);
   }
 
   void Clear() {
-    KeyCppHandler::Clear(&key_);
-    ValueCppHandler::ClearMaybeByDefaultEnum(&value_, default_enum_value);
-    clear_has_key();
-    clear_has_value();
+    entry_lite_.Clear();
   }
 
   void InitAsDefaultInstance() {
-    KeyCppHandler::AssignDefaultValue(&key_);
-    ValueCppHandler::AssignDefaultValue(&value_);
+    entry_lite_.InitAsDefaultInstance();
+  }
+
+  Arena* GetArena() const {
+    return entry_lite_.GetArena();
   }
 
   // Create default MapEntry instance for given descriptor. Descriptor has to be
@@ -311,141 +234,58 @@
   // may have the same type and MapEntry class. The given descriptor is needed
   // to distinguish instances of the same MapEntry class.
   static MapEntry* CreateDefaultInstance(const Descriptor* descriptor) {
-    MapEntry* entry = new MapEntry();
+    MapEntry* entry = new MapEntry;
     const Reflection* reflection = new GeneratedMessageReflection(
         descriptor, entry, offsets_,
-        GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _has_bits_),
+        GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_._has_bits_),
         GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _unknown_fields_), -1,
         DescriptorPool::generated_pool(),
         ::google::protobuf::MessageFactory::generated_factory(), sizeof(MapEntry), -1);
     entry->descriptor_ = descriptor;
     entry->reflection_ = reflection;
-    entry->default_instance_ = entry;
+    entry->set_default_instance(entry);
     entry->InitAsDefaultInstance();
     RegisterMapEntryDefaultInstance(entry);
     return entry;
   }
 
-  // Create a MapEntry for given key and value from google::protobuf::Map in
-  // serialization. This function is only called when value is enum. Enum is
-  // treated differently because its type in MapEntry is int and its type in
-  // google::protobuf::Map is enum. We cannot create a reference to int from an enum.
-  static MapEntry* EnumWrap(const Key& key, const Value value) {
-    return new MapEnumEntryWrapper<Key, Value, KeyProtoType, ValueProtoType,
-                                   default_enum_value>(key, value);
-  }
-
-  // Like above, but for all the other types. This avoids value copy to create
-  // MapEntry from google::protobuf::Map in serialization.
-  static MapEntry* Wrap(const Key& key, const Value& value) {
-    return new MapEntryWrapper<Key, Value, KeyProtoType, ValueProtoType,
-                               default_enum_value>(key, value);
-  }
-
- protected:
-  void set_has_key() { _has_bits_[0] |= 0x00000001u; }
-  bool has_key() const { return (_has_bits_[0] & 0x00000001u) != 0; }
-  void clear_has_key() { _has_bits_[0] &= ~0x00000001u; }
-  void set_has_value() { _has_bits_[0] |= 0x00000002u; }
-  bool has_value() const { return (_has_bits_[0] & 0x00000002u) != 0; }
-  void clear_has_value() { _has_bits_[0] &= ~0x00000002u; }
-
  private:
-  // Serializing a generated message containing map field involves serializing
-  // key-value pairs from google::protobuf::Map. The wire format of each key-value pair
-  // after serialization should be the same as that of a MapEntry message
-  // containing the same key and value inside it.  However, google::protobuf::Map doesn't
-  // store key and value as MapEntry message, which disables us to use existing
-  // code to serialize message. In order to use existing code to serialize
-  // message, we need to construct a MapEntry from key-value pair. But it
-  // involves copy of key and value to construct a MapEntry. In order to avoid
-  // this copy in constructing a MapEntry, we need the following class which
-  // only takes references of given key and value.
-  template <typename KeyNested, typename ValueNested,
-            FieldDescriptor::Type KeyProtoNested,
-            FieldDescriptor::Type ValueProtoNested, int default_enum>
-  class MapEntryWrapper
-      : public MapEntry<KeyNested, ValueNested, KeyProtoNested,
-                        ValueProtoNested, default_enum> {
-    typedef MapEntry<KeyNested, ValueNested, KeyProtoNested, ValueProtoNested,
-                     default_enum_value> Base;
-    typedef typename Base::KeyCppType KeyCppType;
-    typedef typename Base::ValCppType ValCppType;
+  MapEntry() : default_instance_(NULL), entry_lite_() {}
 
-   public:
-    MapEntryWrapper(const KeyNested& key, const ValueNested& value)
-        : key_(key), value_(value) {
-      Base::set_has_key();
-      Base::set_has_value();
-    }
-    inline const KeyCppType& key() const { return key_; }
-    inline const ValCppType& value() const { return value_; }
+  explicit MapEntry(Arena* arena)
+      : default_instance_(NULL), entry_lite_(arena) {}
 
-   private:
-    const Key& key_;
-    const Value& value_;
-  };
-
-  // Like above, but for enum value only, which stores value instead of
-  // reference of value field inside. This is needed because the type of value
-  // field in constructor is an enum, while we need to store it as an int. If we
-  // initialize a reference to int with a reference to enum, compiler will
-  // generate a temporary int from enum and initialize the reference to int with
-  // the temporary.
-  template <typename KeyNested, typename ValueNested,
-            FieldDescriptor::Type KeyProtoNested,
-            FieldDescriptor::Type ValueProtoNested, int default_enum>
-  class MapEnumEntryWrapper
-      : public MapEntry<KeyNested, ValueNested, KeyProtoNested,
-                        ValueProtoNested, default_enum> {
-    typedef MapEntry<KeyNested, ValueNested, KeyProtoNested, ValueProtoNested,
-                     default_enum> Base;
-    typedef typename Base::KeyCppType KeyCppType;
-    typedef typename Base::ValCppType ValCppType;
-
-   public:
-    MapEnumEntryWrapper(const KeyNested& key, const ValueNested& value)
-        : key_(key), value_(value) {
-      Base::set_has_key();
-      Base::set_has_value();
-    }
-    inline const KeyCppType& key() const { return key_; }
-    inline const ValCppType& value() const { return value_; }
-
-   private:
-    const KeyCppType& key_;
-    const ValCppType value_;
-  };
-
-  MapEntry() : default_instance_(NULL) {
-    KeyCppHandler::Initialize(&key_);
-    ValueCppHandler::InitializeMaybeByDefaultEnum(&value_, default_enum_value);
-    _has_bits_[0] = 0;
+  inline Arena* GetArenaNoVirtual() const {
+    return entry_lite_.GetArenaNoVirtual();
   }
 
-  KeyBase key_;
-  ValueBase value_;
+  void set_default_instance(MapEntry* default_instance) {
+    default_instance_ = default_instance;
+    entry_lite_.set_default_instance(&default_instance->entry_lite_);
+  }
+
   static int offsets_[2];
   UnknownFieldSet _unknown_fields_;
-  uint32 _has_bits_[1];
   MapEntry* default_instance_;
+  EntryLiteType entry_lite_;
 
   friend class ::google::protobuf::Arena;
-  template <typename K, typename V,
-            FieldDescriptor::Type KType,
-            FieldDescriptor::Type VType, int default_enum>
-  friend class internal::MapField;
+  typedef void InternalArenaConstructable_;
+  typedef void DestructorSkippable_;
+  template <typename K, typename V, WireFormatLite::FieldType k_wire_type,
+            WireFormatLite::FieldType, int default_enum>
+  friend class LIBPROTOBUF_EXPORT internal::MapField;
   friend class LIBPROTOBUF_EXPORT internal::GeneratedMessageReflection;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry);
 };
 
-template <typename Key, typename Value, FieldDescriptor::Type KeyProtoType,
-          FieldDescriptor::Type ValueProtoType, int default_enum_value>
-int MapEntry<Key, Value, KeyProtoType, ValueProtoType,
+template <typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+int MapEntry<Key, Value, kKeyFieldType, kValueFieldType,
              default_enum_value>::offsets_[2] = {
-    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, key_),
-    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, value_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_.key_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_.value_),
 };
 
 }  // namespace internal
diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h
new file mode 100644
index 0000000..304fba8
--- /dev/null
+++ b/src/google/protobuf/map_entry_lite.h
@@ -0,0 +1,409 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
+#define GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
+
+#include <google/protobuf/map_type_handler.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+
+namespace google {
+namespace protobuf {
+class Arena;
+namespace internal {
+template <typename Key, typename Value,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+class MapEntry;
+template <typename Key, typename Value,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+class MapFieldLite;
+}  // namespace internal
+}  // namespace protobuf
+
+namespace protobuf {
+namespace internal {
+
+// MapEntryLite is used to implement parsing and serialization of map for lite
+// runtime.
+template <typename Key, typename Value,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+class LIBPROTOBUF_EXPORT MapEntryLite : public MessageLite {
+  // Handlers for key/value wire type. Provide utilities to parse/serialize
+  // key/value.
+  typedef MapWireFieldTypeHandler<kKeyFieldType> KeyWireHandler;
+  typedef MapWireFieldTypeHandler<kValueFieldType> ValueWireHandler;
+
+  // Define key/value's internal stored type. Message is the only one whose
+  // internal stored type cannot be inferred from its proto type
+  static const bool kIsKeyMessage = KeyWireHandler::kIsMessage;
+  static const bool kIsValueMessage = ValueWireHandler::kIsMessage;
+  typedef typename KeyWireHandler::CppType KeyInternalType;
+  typedef typename ValueWireHandler::CppType ValueInternalType;
+  typedef typename MapIf<kIsKeyMessage, Key, KeyInternalType>::type
+      KeyCppType;
+  typedef typename MapIf<kIsValueMessage, Value, ValueInternalType>::type
+      ValCppType;
+
+  // Handlers for key/value's internal stored type. Provide utilities to
+  // manipulate internal stored type. We need it because some types are stored
+  // as values and others are stored as pointers (Message and string), but we
+  // need to keep the code in MapEntry unified instead of providing different
+  // codes for each type.
+  typedef MapCppTypeHandler<KeyCppType> KeyCppHandler;
+  typedef MapCppTypeHandler<ValCppType> ValueCppHandler;
+
+  // Define internal memory layout. Strings and messages are stored as
+  // pointers, while other types are stored as values.
+  static const bool kKeyIsStringOrMessage = KeyCppHandler::kIsStringOrMessage;
+  static const bool kValIsStringOrMessage = ValueCppHandler::kIsStringOrMessage;
+  typedef typename MapIf<kKeyIsStringOrMessage, KeyCppType*, KeyCppType>::type
+      KeyBase;
+  typedef typename MapIf<kValIsStringOrMessage, ValCppType*, ValCppType>::type
+      ValueBase;
+
+  // Constants for field number.
+  static const int kKeyFieldNumber = 1;
+  static const int kValueFieldNumber = 2;
+
+  // Constants for field tag.
+  static const uint8 kKeyTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
+      kKeyFieldNumber, KeyWireHandler::kWireType);
+  static const uint8 kValueTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
+      kValueFieldNumber, ValueWireHandler::kWireType);
+  static const int kTagSize = 1;
+
+ public:
+  ~MapEntryLite() {
+    if (this != default_instance_) {
+      KeyCppHandler::Delete(key_);
+      ValueCppHandler::Delete(value_);
+    }
+  }
+
+  // accessors ======================================================
+
+  virtual inline const KeyCppType& key() const {
+    return KeyCppHandler::Reference(key_);
+  }
+  inline KeyCppType* mutable_key() {
+    set_has_key();
+    KeyCppHandler::EnsureMutable(&key_, GetArenaNoVirtual());
+    return KeyCppHandler::Pointer(key_);
+  }
+  virtual inline const ValCppType& value() const {
+    GOOGLE_CHECK(default_instance_ != NULL);
+    return ValueCppHandler::DefaultIfNotInitialized(value_,
+                                                    default_instance_->value_);
+  }
+  inline ValCppType* mutable_value() {
+    set_has_value();
+    ValueCppHandler::EnsureMutable(&value_, GetArenaNoVirtual());
+    return ValueCppHandler::Pointer(value_);
+  }
+
+  // implements MessageLite =========================================
+
+  // MapEntryLite is for implementation only and this function isn't called
+  // anywhere. Just provide a fake implementation here for MessageLite.
+  string GetTypeName() const { return ""; }
+
+  void CheckTypeAndMergeFrom(const MessageLite& other) {
+    MergeFrom(*::google::protobuf::down_cast<const MapEntryLite*>(&other));
+  }
+
+  bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) {
+    uint32 tag;
+
+    for (;;) {
+      // 1) corrupted data: return false;
+      // 2) unknown field: skip without putting into unknown field set;
+      // 3) unknown enum value: keep it in parsing. In proto2, caller should
+      // check the value and put this entry into containing message's unknown
+      // field set if the value is an unknown enum. In proto3, caller doesn't
+      // need to care whether the value is unknown enum;
+      // 4) missing key/value: missed key/value will have default value. caller
+      // should take this entry as if key/value is set to default value.
+      tag = input->ReadTag();
+      switch (tag) {
+        case kKeyTag:
+          if (!KeyWireHandler::Read(input, mutable_key())) return false;
+          set_has_key();
+          if (!input->ExpectTag(kValueTag)) break;
+          GOOGLE_FALLTHROUGH_INTENDED;
+
+        case kValueTag:
+          if (!ValueWireHandler::Read(input, mutable_value())) return false;
+          set_has_value();
+          if (input->ExpectAtEnd()) return true;
+          break;
+
+        default:
+          if (tag == 0 ||
+              WireFormatLite::GetTagWireType(tag) ==
+              WireFormatLite::WIRETYPE_END_GROUP) {
+            return true;
+          }
+          if (!WireFormatLite::SkipField(input, tag)) return false;
+          break;
+      }
+    }
+  }
+
+  int ByteSize() const {
+    int size = 0;
+    size += has_key() ? kTagSize + KeyWireHandler::ByteSize(key()) : 0;
+    size += has_value() ? kTagSize + ValueWireHandler::ByteSize(value()) : 0;
+    return size;
+  }
+
+  void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const {
+    KeyWireHandler::Write(kKeyFieldNumber, key(), output);
+    ValueWireHandler::Write(kValueFieldNumber, value(), output);
+  }
+
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+    output = KeyWireHandler::WriteToArray(kKeyFieldNumber, key(), output);
+    output =
+        ValueWireHandler::WriteToArray(kValueFieldNumber, value(), output);
+    return output;
+  }
+
+  int GetCachedSize() const {
+    int size = 0;
+    size += has_key() ? kTagSize + KeyWireHandler::GetCachedSize(key()) : 0;
+    size +=
+        has_value() ? kTagSize + ValueWireHandler::GetCachedSize(value()) : 0;
+    return size;
+  }
+
+  bool IsInitialized() const { return ValueCppHandler::IsInitialized(value_); }
+
+  MessageLite* New() const {
+    MapEntryLite* entry = new MapEntryLite;
+    entry->default_instance_ = default_instance_;
+    return entry;
+  }
+
+  MessageLite* New(Arena* arena) const {
+    MapEntryLite* entry = Arena::CreateMessage<MapEntryLite>(arena);
+    entry->default_instance_ = default_instance_;
+    return entry;
+  }
+
+  int SpaceUsed() const {
+    int size = sizeof(MapEntryLite);
+    size += KeyCppHandler::SpaceUsedInMapEntry(key_);
+    size += ValueCppHandler::SpaceUsedInMapEntry(value_);
+    return size;
+  }
+
+  void MergeFrom(const MapEntryLite& from) {
+    if (from._has_bits_[0]) {
+      if (from.has_key()) {
+        KeyCppHandler::EnsureMutable(&key_, GetArenaNoVirtual());
+        KeyCppHandler::Merge(from.key(), &key_);
+        set_has_key();
+      }
+      if (from.has_value()) {
+        ValueCppHandler::EnsureMutable(&value_, GetArenaNoVirtual());
+        ValueCppHandler::Merge(from.value(), &value_);
+        set_has_value();
+      }
+    }
+  }
+
+  void Clear() {
+    KeyCppHandler::Clear(&key_);
+    ValueCppHandler::ClearMaybeByDefaultEnum(&value_, default_enum_value);
+    clear_has_key();
+    clear_has_value();
+  }
+
+  void InitAsDefaultInstance() {
+    KeyCppHandler::AssignDefaultValue(&key_);
+    ValueCppHandler::AssignDefaultValue(&value_);
+  }
+
+  Arena* GetArena() const {
+    return GetArenaNoVirtual();
+  }
+
+  // Create a MapEntryLite for given key and value from google::protobuf::Map in
+  // serialization. This function is only called when value is enum. Enum is
+  // treated differently because its type in MapEntry is int and its type in
+  // google::protobuf::Map is enum. We cannot create a reference to int from an enum.
+  static MapEntryLite* EnumWrap(const Key& key, const Value value,
+                                Arena* arena) {
+    return Arena::Create<MapEnumEntryWrapper<
+        Key, Value, kKeyFieldType, kValueFieldType, default_enum_value> >(
+        arena, key, value, arena);
+  }
+
+  // Like above, but for all the other types. This avoids value copy to create
+  // MapEntryLite from google::protobuf::Map in serialization.
+  static MapEntryLite* Wrap(const Key& key, const Value& value, Arena* arena) {
+    return Arena::Create<MapEntryWrapper<Key, Value, kKeyFieldType,
+                                         kValueFieldType, default_enum_value> >(
+        arena, key, value, arena);
+  }
+
+ protected:
+  void set_has_key() { _has_bits_[0] |= 0x00000001u; }
+  bool has_key() const { return (_has_bits_[0] & 0x00000001u) != 0; }
+  void clear_has_key() { _has_bits_[0] &= ~0x00000001u; }
+  void set_has_value() { _has_bits_[0] |= 0x00000002u; }
+  bool has_value() const { return (_has_bits_[0] & 0x00000002u) != 0; }
+  void clear_has_value() { _has_bits_[0] &= ~0x00000002u; }
+
+ private:
+  // Serializing a generated message containing map field involves serializing
+  // key-value pairs from google::protobuf::Map. The wire format of each key-value pair
+  // after serialization should be the same as that of a MapEntry message
+  // containing the same key and value inside it.  However, google::protobuf::Map doesn't
+  // store key and value as MapEntry message, which disables us to use existing
+  // code to serialize message. In order to use existing code to serialize
+  // message, we need to construct a MapEntry from key-value pair. But it
+  // involves copy of key and value to construct a MapEntry. In order to avoid
+  // this copy in constructing a MapEntry, we need the following class which
+  // only takes references of given key and value.
+  template <typename K, typename V, WireFormatLite::FieldType k_wire_type,
+            WireFormatLite::FieldType v_wire_type, int default_enum>
+  class LIBPROTOBUF_EXPORT MapEntryWrapper
+      : public MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum> {
+    typedef MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum> Base;
+    typedef typename Base::KeyCppType KeyCppType;
+    typedef typename Base::ValCppType ValCppType;
+
+   public:
+    MapEntryWrapper(const K& key, const V& value, Arena* arena)
+        : MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum>(arena),
+          key_(key),
+          value_(value) {
+      Base::set_has_key();
+      Base::set_has_value();
+    }
+    inline const KeyCppType& key() const { return key_; }
+    inline const ValCppType& value() const { return value_; }
+
+   private:
+    const Key& key_;
+    const Value& value_;
+
+    friend class ::google::protobuf::Arena;
+    typedef void DestructorSkippable_;
+  };
+
+  // Like above, but for enum value only, which stores value instead of
+  // reference of value field inside. This is needed because the type of value
+  // field in constructor is an enum, while we need to store it as an int. If we
+  // initialize a reference to int with a reference to enum, compiler will
+  // generate a temporary int from enum and initialize the reference to int with
+  // the temporary.
+  template <typename K, typename V, WireFormatLite::FieldType k_wire_type,
+            WireFormatLite::FieldType v_wire_type, int default_enum>
+  class LIBPROTOBUF_EXPORT MapEnumEntryWrapper
+      : public MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum> {
+    typedef MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum> Base;
+    typedef typename Base::KeyCppType KeyCppType;
+    typedef typename Base::ValCppType ValCppType;
+
+   public:
+    MapEnumEntryWrapper(const K& key, const V& value, Arena* arena)
+        : MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum>(arena),
+          key_(key),
+          value_(value) {
+      Base::set_has_key();
+      Base::set_has_value();
+    }
+    inline const KeyCppType& key() const { return key_; }
+    inline const ValCppType& value() const { return value_; }
+
+   private:
+    const KeyCppType& key_;
+    const ValCppType value_;
+
+    friend class ::google::protobuf::Arena;
+    typedef void DestructorSkippable_;
+  };
+
+  MapEntryLite() : default_instance_(NULL), arena_(NULL) {
+    KeyCppHandler::Initialize(&key_, NULL);
+    ValueCppHandler::InitializeMaybeByDefaultEnum(
+        &value_, default_enum_value, NULL);
+    _has_bits_[0] = 0;
+  }
+
+  explicit MapEntryLite(Arena* arena)
+      : default_instance_(NULL), arena_(arena) {
+    KeyCppHandler::Initialize(&key_, arena);
+    ValueCppHandler::InitializeMaybeByDefaultEnum(
+        &value_, default_enum_value, arena);
+    _has_bits_[0] = 0;
+  }
+
+  inline Arena* GetArenaNoVirtual() const {
+    return arena_;
+  }
+
+  void set_default_instance(MapEntryLite* default_instance) {
+    default_instance_ = default_instance;
+  }
+
+  MapEntryLite* default_instance_;
+
+  KeyBase key_;
+  ValueBase value_;
+  Arena* arena_;
+  uint32 _has_bits_[1];
+
+  friend class ::google::protobuf::Arena;
+  typedef void InternalArenaConstructable_;
+  typedef void DestructorSkippable_;
+  template <typename K, typename V, WireFormatLite::FieldType,
+            WireFormatLite::FieldType, int>
+  friend class LIBPROTOBUF_EXPORT internal::MapEntry;
+  template <typename K, typename V, WireFormatLite::FieldType,
+            WireFormatLite::FieldType, int>
+  friend class LIBPROTOBUF_EXPORT internal::MapFieldLite;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryLite);
+};
+
+}  // namespace internal
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
diff --git a/src/google/protobuf/map_field.cc b/src/google/protobuf/map_field.cc
index b535ec2..fd40c0d 100644
--- a/src/google/protobuf/map_field.cc
+++ b/src/google/protobuf/map_field.cc
@@ -55,14 +55,14 @@
 }
 
 void RegisterMapEntryDefaultInstance(MessageLite* default_instance) {
-  GoogleOnceInit(&map_entry_default_instances_once_,
+  ::google::protobuf::GoogleOnceInit(&map_entry_default_instances_once_,
                  &InitMapEntryDefaultInstances);
   MutexLock lock(map_entry_default_instances_mutex_);
   map_entry_default_instances_->push_back(default_instance);
 }
 
 MapFieldBase::~MapFieldBase() {
-  if (repeated_field_ != NULL) delete repeated_field_;
+  if (repeated_field_ != NULL && arena_ == NULL) delete repeated_field_;
 }
 
 const RepeatedPtrFieldBase& MapFieldBase::GetRepeatedField() const {
@@ -118,7 +118,9 @@
 }
 
 void MapFieldBase::SyncRepeatedFieldWithMapNoLock() const {
-  if (repeated_field_ == NULL) repeated_field_ = new RepeatedPtrField<Message>;
+  if (repeated_field_ == NULL) {
+    repeated_field_ = Arena::Create<RepeatedPtrField<Message> >(arena_, arena_);
+  }
 }
 
 void MapFieldBase::SyncMapWithRepeatedField() const {
diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h
index 8516d74..6d8b6ec 100644
--- a/src/google/protobuf/map_field.h
+++ b/src/google/protobuf/map_field.h
@@ -34,8 +34,10 @@
 #include <google/protobuf/stubs/atomicops.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/generated_message_reflection.h>
-#include <google/protobuf/map.h>
+#include <google/protobuf/arena.h>
 #include <google/protobuf/map_entry.h>
+#include <google/protobuf/map_field_lite.h>
+#include <google/protobuf/map_type_handler.h>
 #include <google/protobuf/message.h>
 #include <google/protobuf/repeated_field.h>
 #include <google/protobuf/unknown_field_set.h>
@@ -56,7 +58,13 @@
 class LIBPROTOBUF_EXPORT MapFieldBase {
  public:
   MapFieldBase()
-      : base_map_(NULL),
+      : arena_(NULL),
+        repeated_field_(NULL),
+        entry_descriptor_(NULL),
+        assign_descriptor_callback_(NULL),
+        state_(STATE_MODIFIED_MAP) {}
+  explicit MapFieldBase(Arena* arena)
+      : arena_(arena),
         repeated_field_(NULL),
         entry_descriptor_(NULL),
         assign_descriptor_callback_(NULL),
@@ -109,7 +117,7 @@
     CLEAN = 2,  // data in map and repeated field are same
   };
 
-  mutable void* base_map_;
+  Arena* arena_;
   mutable RepeatedPtrField<Message>* repeated_field_;
   // MapEntry can only be created from MapField. To create MapEntry, MapField
   // needs to know its descriptor, because MapEntry is not generated class which
@@ -134,41 +142,55 @@
 // This class provides accesss to map field using generated api. It is used for
 // internal generated message implentation only. Users should never use this
 // directly.
-template<typename Key, typename T,
-         FieldDescriptor::Type KeyProto,
-         FieldDescriptor::Type ValueProto, int default_enum_value = 0>
-class MapField : public MapFieldBase {
-  // Handlers for key/value's proto field type.
-  typedef MapProtoTypeHandler<KeyProto> KeyProtoHandler;
-  typedef MapProtoTypeHandler<ValueProto> ValueProtoHandler;
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value = 0>
+class LIBPROTOBUF_EXPORT MapField : public MapFieldBase,
+                 public MapFieldLite<Key, T, kKeyFieldType, kValueFieldType,
+                                     default_enum_value> {
+  // Handlers for key/value wire type. Provide utilities to parse/serialize
+  // key/value.
+  typedef MapWireFieldTypeHandler<kKeyFieldType> KeyWireHandler;
+  typedef MapWireFieldTypeHandler<kValueFieldType> ValueWireHandler;
 
   // Define key/value's internal stored type.
-  typedef typename KeyProtoHandler::CppType KeyHandlerCpp;
-  typedef typename ValueProtoHandler::CppType ValHandlerCpp;
-  static const bool kIsKeyMessage = KeyProtoHandler::kIsMessage;
-  static const bool kIsValMessage = ValueProtoHandler::kIsMessage;
-  typedef typename MapIf<kIsKeyMessage, Key, KeyHandlerCpp>::type KeyCpp;
-  typedef typename MapIf<kIsValMessage, T  , ValHandlerCpp>::type ValCpp;
+  static const bool kIsKeyMessage = KeyWireHandler::kIsMessage;
+  static const bool kIsValMessage = ValueWireHandler::kIsMessage;
+  typedef typename KeyWireHandler::CppType KeyInternalType;
+  typedef typename ValueWireHandler::CppType ValueInternalType;
+  typedef typename MapIf<kIsKeyMessage, Key, KeyInternalType>::type KeyCpp;
+  typedef typename MapIf<kIsValMessage, T  , ValueInternalType>::type ValCpp;
 
   // Handlers for key/value's internal stored type.
   typedef MapCppTypeHandler<KeyCpp> KeyHandler;
   typedef MapCppTypeHandler<ValCpp> ValHandler;
 
   // Define message type for internal repeated field.
-  typedef MapEntry<Key, T, KeyProto, ValueProto, default_enum_value> EntryType;
+  typedef MapEntry<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>
+      EntryType;
+  typedef MapEntryLite<Key, T, kKeyFieldType, kValueFieldType,
+                       default_enum_value> EntryLiteType;
+
+  // Define abbreviation for parent MapFieldLite
+  typedef MapFieldLite<Key, T, kKeyFieldType, kValueFieldType,
+                       default_enum_value> MapFieldLiteType;
 
   // Enum needs to be handled differently from other types because it has
   // different exposed type in google::protobuf::Map's api and repeated field's api. For
   // details see the comment in the implementation of
   // SyncMapWithRepeatedFieldNoLocki.
-  static const bool kIsValueEnum = ValueProtoHandler::kIsEnum;
+  static const bool kIsValueEnum = ValueWireHandler::kIsEnum;
   typedef typename MapIf<kIsValueEnum, T, const T&>::type CastValueType;
 
  public:
   MapField();
+  explicit MapField(Arena* arena);
   // MapField doesn't own the default_entry, which means default_entry must
   // outlive the lifetime of MapField.
   MapField(const Message* default_entry);
+  // For tests only.
+  MapField(Arena* arena, const Message* default_entry);
   ~MapField();
 
   // Accessors
@@ -178,29 +200,22 @@
   // Convenient methods for generated message implementation.
   int size() const;
   void Clear();
-  void MergeFrom(const MapField& other);
-  void Swap(MapField* other);
+  void MergeFrom(const MapFieldLiteType& other);
+  void Swap(MapFieldLiteType* other);
 
   // Allocates metadata only if this MapField is part of a generated message.
   void SetEntryDescriptor(const Descriptor** descriptor);
   void SetAssignDescriptorCallback(void (*callback)());
 
-  // Set default enum value only for proto2 map field whose value is enum type.
-  void SetDefaultEnumValue();
-
-  // Used in the implementation of parsing. Caller should take the ownership.
-  EntryType* NewEntry() const;
-  // Used in the implementation of serializing enum value type. Caller should
-  // take the ownership.
-  EntryType* NewEnumEntryWrapper(const Key& key, const T t) const;
-  // Used in the implementation of serializing other value types. Caller should
-  // take the ownership.
-  EntryType* NewEntryWrapper(const Key& key, const T& t) const;
-
  private:
+  typedef void DestructorSkippable_;
+
   // MapField needs MapEntry's default instance to create new MapEntry.
   void InitDefaultEntryOnce() const;
 
+  // Manually set default entry instance. For test only.
+  void SetDefaultEntryOnce(const EntryType* default_entry) const;
+
   // Convenient methods to get internal google::protobuf::Map
   const Map<Key, T>& GetInternalMap() const;
   Map<Key, T>* MutableInternalMap();
@@ -211,14 +226,9 @@
   int SpaceUsedExcludingSelfNoLock() const;
 
   mutable const EntryType* default_entry_;
-};
 
-// True if IsInitialized() is true for value field in all elements of t. T is
-// expected to be message.  It's useful to have this helper here to keep the
-// protobuf compiler from ever having to emit loops in IsInitialized() methods.
-// We want the C++ compiler to inline this or not as it sees fit.
-template <typename Key, typename T>
-bool AllAreInitialized(const Map<Key, T>& t);
+  friend class ::google::protobuf::Arena;
+};
 
 }  // namespace internal
 }  // namespace protobuf
diff --git a/src/google/protobuf/map_field_inl.h b/src/google/protobuf/map_field_inl.h
index 79302e4..ae63c72 100644
--- a/src/google/protobuf/map_field_inl.h
+++ b/src/google/protobuf/map_field_inl.h
@@ -43,160 +43,183 @@
 namespace protobuf {
 namespace internal {
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-MapField<Key, T, KeyProto, ValueProto, default_enum_value>::MapField()
-    : default_entry_(NULL) {
-  MapFieldBase::base_map_ = new Map<Key, T>;
-  SetDefaultEnumValue();
-}
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::MapField()
+    : default_entry_(NULL) {}
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-MapField<Key, T, KeyProto, ValueProto, default_enum_value>::MapField(
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::MapField(
+    Arena* arena)
+    : MapFieldBase(arena),
+      MapFieldLite<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>(
+          arena),
+      default_entry_(NULL) {}
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::MapField(
     const Message* default_entry)
-    : default_entry_(down_cast<const EntryType*>(default_entry)) {
-  MapFieldBase::base_map_ = new Map<Key, T>;
-  SetDefaultEnumValue();
-}
+    : default_entry_(down_cast<const EntryType*>(default_entry)) {}
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-MapField<Key, T, KeyProto, ValueProto, default_enum_value>::~MapField() {
-  delete reinterpret_cast<Map<Key, T>*>(MapFieldBase::base_map_);
-}
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::MapField(
+    Arena* arena, const Message* default_entry)
+    : MapFieldBase(arena),
+      MapFieldLite<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>(
+          arena),
+      default_entry_(down_cast<const EntryType*>(default_entry)) {}
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-int MapField<Key, T, KeyProto, ValueProto, default_enum_value>::size() const {
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+MapField<Key, T, kKeyFieldType, kValueFieldType,
+         default_enum_value>::~MapField() {}
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+int
+MapField<Key, T, kKeyFieldType, kValueFieldType,
+         default_enum_value>::size() const {
   SyncMapWithRepeatedField();
-  return GetInternalMap().size();
+  return MapFieldLiteType::GetInternalMap().size();
 }
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-void MapField<Key, T, KeyProto, ValueProto, default_enum_value>::Clear() {
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+void
+MapField<Key, T, kKeyFieldType, kValueFieldType,
+         default_enum_value>::Clear() {
   SyncMapWithRepeatedField();
-  MutableInternalMap()->clear();
+  MapFieldLiteType::MutableInternalMap()->clear();
   SetMapDirty();
 }
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
 const Map<Key, T>&
-MapField<Key, T, KeyProto, ValueProto, default_enum_value>::GetMap() const {
+MapField<Key, T, kKeyFieldType, kValueFieldType,
+         default_enum_value>::GetMap() const {
   SyncMapWithRepeatedField();
-  return GetInternalMap();
+  return MapFieldLiteType::GetInternalMap();
 }
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
 Map<Key, T>*
-MapField<Key, T, KeyProto, ValueProto, default_enum_value>::MutableMap() {
+MapField<Key, T, kKeyFieldType, kValueFieldType,
+         default_enum_value>::MutableMap() {
   SyncMapWithRepeatedField();
-  Map<Key, T>* result = MutableInternalMap();
+  Map<Key, T>* result = MapFieldLiteType::MutableInternalMap();
   SetMapDirty();
   return result;
 }
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-void MapField<Key, T, KeyProto, ValueProto, default_enum_value>::MergeFrom(
-    const MapField& other) {
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+void
+MapField<Key, T, kKeyFieldType, kValueFieldType,
+         default_enum_value>::MergeFrom(
+    const MapFieldLiteType& other) {
+  const MapField& down_other = down_cast<const MapField&>(other);
   SyncMapWithRepeatedField();
-  other.SyncMapWithRepeatedField();
-
-  Map<Key, T>* map = MutableInternalMap();
-  const Map<Key, T>& other_map = other.GetInternalMap();
-  for (typename Map<Key, T>::const_iterator it = other_map.begin();
-       it != other_map.end(); ++it) {
-    (*map)[it->first] = it->second;
-  }
+  down_other.SyncMapWithRepeatedField();
+  MapFieldLiteType::MergeFrom(other);
   SetMapDirty();
 }
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-void MapField<Key, T, KeyProto, ValueProto, default_enum_value>::Swap(
-    MapField* other) {
-  std::swap(repeated_field_, other->repeated_field_);
-  std::swap(base_map_, other->base_map_);
-  std::swap(state_, other->state_);
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+void
+MapField<Key, T, kKeyFieldType, kValueFieldType,
+         default_enum_value>::Swap(
+    MapFieldLiteType* other) {
+  MapField* down_other = down_cast<MapField*>(other);
+  std::swap(repeated_field_, down_other->repeated_field_);
+  MapFieldLiteType::Swap(other);
+  std::swap(state_, down_other->state_);
 }
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
 void
-MapField<Key, T, KeyProto, ValueProto, default_enum_value>::SetEntryDescriptor(
+MapField<Key, T, kKeyFieldType, kValueFieldType,
+         default_enum_value>::SetEntryDescriptor(
     const Descriptor** descriptor) {
   entry_descriptor_ = descriptor;
 }
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
 void
-MapField<Key, T, KeyProto, ValueProto,
+MapField<Key, T, kKeyFieldType, kValueFieldType,
          default_enum_value>::SetAssignDescriptorCallback(void (*callback)()) {
   assign_descriptor_callback_ = callback;
 }
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-void MapField<Key, T, KeyProto, ValueProto,
-              default_enum_value>::SetDefaultEnumValue() {
-  MutableInternalMap()->SetDefaultEnumValue(default_enum_value);
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+const Map<Key, T>&
+MapField<Key, T, kKeyFieldType, kValueFieldType,
+         default_enum_value>::GetInternalMap() const {
+  return MapFieldLiteType::GetInternalMap();
 }
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-MapEntry<Key, T, KeyProto, ValueProto, default_enum_value>*
-MapField<Key, T, KeyProto, ValueProto, default_enum_value>::NewEntry() const {
-  // The MapEntry instance created here is only used in generated code for
-  // parsing. It doesn't have default instance, descriptor or reflection,
-  // because these are not needed in parsing and will prevent us from using it
-  // for parsing MessageLite.
-  return new EntryType();
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+Map<Key, T>*
+MapField<Key, T, kKeyFieldType, kValueFieldType,
+         default_enum_value>::MutableInternalMap() {
+  return MapFieldLiteType::MutableInternalMap();
 }
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-MapEntry<Key, T, KeyProto, ValueProto, default_enum_value>*
-MapField<Key, T, KeyProto, ValueProto, default_enum_value>::NewEntryWrapper(
-    const Key& key, const T& t) const {
-  return EntryType::Wrap(key, t);
-}
-
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-MapEntry<Key, T, KeyProto, ValueProto, default_enum_value>*
-MapField<Key, T, KeyProto, ValueProto, default_enum_value>::NewEnumEntryWrapper(
-    const Key& key, const T t) const {
-  return EntryType::EnumWrap(key, t);
-}
-
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-const Map<Key, T>& MapField<Key, T, KeyProto, ValueProto,
-                            default_enum_value>::GetInternalMap() const {
-  return *reinterpret_cast<Map<Key, T>*>(MapFieldBase::base_map_);
-}
-
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-Map<Key, T>* MapField<Key, T, KeyProto, ValueProto,
-                      default_enum_value>::MutableInternalMap() {
-  return reinterpret_cast<Map<Key, T>*>(MapFieldBase::base_map_);
-}
-
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-void MapField<Key, T, KeyProto, ValueProto,
-              default_enum_value>::SyncRepeatedFieldWithMapNoLock() const {
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+void
+MapField<Key, T, kKeyFieldType, kValueFieldType,
+         default_enum_value>::SyncRepeatedFieldWithMapNoLock() const {
   if (repeated_field_ == NULL) {
-    repeated_field_ = new RepeatedPtrField<Message>();
+    if (arena_ == NULL) {
+      repeated_field_ = new RepeatedPtrField<Message>();
+    } else {
+      repeated_field_ =
+          Arena::Create<RepeatedPtrField<Message> >(arena_, arena_);
+    }
   }
-  const Map<Key, T>& map =
-      *static_cast<const Map<Key, T>*>(MapFieldBase::base_map_);
+  const Map<Key, T>& map = GetInternalMap();
   RepeatedPtrField<EntryType>* repeated_field =
       reinterpret_cast<RepeatedPtrField<EntryType>*>(repeated_field_);
 
@@ -206,18 +229,21 @@
        it != map.end(); ++it) {
     InitDefaultEntryOnce();
     GOOGLE_CHECK(default_entry_ != NULL);
-    EntryType* new_entry = down_cast<EntryType*>(default_entry_->New());
+    EntryType* new_entry = down_cast<EntryType*>(default_entry_->New(arena_));
     repeated_field->AddAllocated(new_entry);
-    new_entry->set_key(it->first);
-    new_entry->set_value(it->second);
+    (*new_entry->mutable_key()) = it->first;
+    (*new_entry->mutable_value()) = it->second;
   }
 }
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-void MapField<Key, T, KeyProto, ValueProto,
-              default_enum_value>::SyncMapWithRepeatedFieldNoLock() const {
-  Map<Key, T>* map = reinterpret_cast<Map<Key, T>*>(MapFieldBase::base_map_);
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+void
+MapField<Key, T, kKeyFieldType, kValueFieldType,
+         default_enum_value>::SyncMapWithRepeatedFieldNoLock() const {
+  Map<Key, T>* map = const_cast<MapField*>(this)->MutableInternalMap();
   RepeatedPtrField<EntryType>* repeated_field =
       reinterpret_cast<RepeatedPtrField<EntryType>*>(repeated_field_);
   map->clear();
@@ -232,15 +258,18 @@
   }
 }
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-int MapField<Key, T, KeyProto, ValueProto,
-             default_enum_value>::SpaceUsedExcludingSelfNoLock() const {
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+int
+MapField<Key, T, kKeyFieldType, kValueFieldType,
+         default_enum_value>::SpaceUsedExcludingSelfNoLock() const {
   int size = 0;
   if (repeated_field_ != NULL) {
     size += repeated_field_->SpaceUsedExcludingSelf();
   }
-  Map<Key, T>* map = reinterpret_cast<Map<Key, T>*>(MapFieldBase::base_map_);
+  Map<Key, T>* map = const_cast<MapField*>(this)->MutableInternalMap();
   size += sizeof(*map);
   for (typename Map<Key, T>::iterator it = map->begin();
        it != map->end(); ++it) {
@@ -250,10 +279,14 @@
   return size;
 }
 
-template <typename Key, typename T, FieldDescriptor::Type KeyProto,
-          FieldDescriptor::Type ValueProto, int default_enum_value>
-void MapField<Key, T, KeyProto, ValueProto,
-              default_enum_value>::InitDefaultEntryOnce() const {
+template <typename Key, typename T,
+          WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType,
+          int default_enum_value>
+void
+MapField<Key, T, kKeyFieldType, kValueFieldType,
+         default_enum_value>::InitDefaultEntryOnce()
+    const {
   if (default_entry_ == NULL) {
     InitMetadataOnce();
     GOOGLE_CHECK(*entry_descriptor_ != NULL);
@@ -262,15 +295,6 @@
   }
 }
 
-template <typename Key, typename T>
-bool AllAreInitialized(const Map<Key, T>& t) {
-  for (typename Map<Key, T>::const_iterator it = t.begin(); it != t.end();
-       ++it) {
-    if (!it->second.IsInitialized()) return false;
-  }
-  return true;
-}
-
 }  // namespace internal
 }  // namespace protobuf
 
diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h
new file mode 100644
index 0000000..549ecc0
--- /dev/null
+++ b/src/google/protobuf/map_field_lite.h
@@ -0,0 +1,278 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
+#define GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
+
+#include <google/protobuf/map.h>
+#include <google/protobuf/map_entry_lite.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// This class provides accesss to map field using generated api. It is used for
+// internal generated message implentation only. Users should never use this
+// directly.
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value = 0>
+class LIBPROTOBUF_EXPORT MapFieldLite {
+  // Define message type for internal repeated field.
+  typedef MapEntryLite<Key, T, key_wire_type, value_wire_type,
+                       default_enum_value> EntryType;
+
+ public:
+  MapFieldLite();
+  explicit MapFieldLite(Arena* arena);
+  virtual ~MapFieldLite();
+
+  // Accessors
+  virtual const Map<Key, T>& GetMap() const;
+  virtual Map<Key, T>* MutableMap();
+
+  // Convenient methods for generated message implementation.
+  virtual int size() const;
+  virtual void Clear();
+  virtual void MergeFrom(const MapFieldLite& other);
+  virtual void Swap(MapFieldLite* other);
+
+  // Set default enum value only for proto2 map field whose value is enum type.
+  void SetDefaultEnumValue();
+
+  // Used in the implementation of parsing. Caller should take the ownership.
+  EntryType* NewEntry() const;
+  // Used in the implementation of serializing enum value type. Caller should
+  // take the ownership.
+  EntryType* NewEnumEntryWrapper(const Key& key, const T t) const;
+  // Used in the implementation of serializing other value types. Caller should
+  // take the ownership.
+  EntryType* NewEntryWrapper(const Key& key, const T& t) const;
+
+ protected:
+  // Convenient methods to get internal google::protobuf::Map
+  virtual const Map<Key, T>& GetInternalMap() const;
+  virtual Map<Key, T>* MutableInternalMap();
+
+ private:
+  typedef void DestructorSkippable_;
+
+  Arena* arena_;
+  Map<Key, T>* map_;
+
+  friend class ::google::protobuf::Arena;
+};
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value>
+MapFieldLite<Key, T, key_wire_type, value_wire_type,
+             default_enum_value>::MapFieldLite()
+    : arena_(NULL) {
+  map_ = new Map<Key, T>;
+  SetDefaultEnumValue();
+}
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value>
+MapFieldLite<Key, T, key_wire_type, value_wire_type,
+             default_enum_value>::MapFieldLite(Arena* arena)
+  : arena_(arena) {
+  map_ = Arena::Create<Map<Key, T> >(arena, arena);
+  SetDefaultEnumValue();
+}
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value>
+MapFieldLite<Key, T, key_wire_type, value_wire_type,
+             default_enum_value>::~MapFieldLite() {
+  delete map_;
+}
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value>
+const Map<Key, T>&
+MapFieldLite<Key, T, key_wire_type, value_wire_type,
+             default_enum_value>::GetMap() const {
+  return *map_;
+}
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value>
+Map<Key, T>*
+MapFieldLite<Key, T, key_wire_type, value_wire_type,
+             default_enum_value>::MutableMap() {
+  return map_;
+}
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value>
+int
+MapFieldLite<Key, T, key_wire_type, value_wire_type,
+             default_enum_value>::size() const {
+  return map_->size();
+}
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value>
+void
+MapFieldLite<Key, T, key_wire_type, value_wire_type,
+             default_enum_value>::Clear() {
+  map_->clear();
+}
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value>
+void
+MapFieldLite<Key, T, key_wire_type, value_wire_type,
+             default_enum_value>::MergeFrom(
+    const MapFieldLite& other) {
+  for (typename Map<Key, T>::const_iterator it = other.map_->begin();
+       it != other.map_->end(); ++it) {
+    (*map_)[it->first] = it->second;
+  }
+}
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value>
+void
+MapFieldLite<Key, T, key_wire_type, value_wire_type,
+             default_enum_value>::Swap(
+    MapFieldLite* other) {
+  std::swap(map_, other->map_);
+}
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value>
+void
+MapFieldLite<Key, T, key_wire_type, value_wire_type,
+             default_enum_value>::SetDefaultEnumValue() {
+  MutableInternalMap()->SetDefaultEnumValue(default_enum_value);
+}
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value>
+const Map<Key, T>&
+MapFieldLite<Key, T, key_wire_type, value_wire_type,
+             default_enum_value>::GetInternalMap() const {
+  return *map_;
+}
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value>
+Map<Key, T>*
+MapFieldLite<Key, T, key_wire_type, value_wire_type,
+             default_enum_value>::MutableInternalMap() {
+  return map_;
+}
+
+#define EntryType \
+  MapEntryLite<Key, T, key_wire_type, value_wire_type, default_enum_value>
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value>
+EntryType*
+MapFieldLite<Key, T, key_wire_type, value_wire_type,
+             default_enum_value>::NewEntry() const {
+  if (arena_ == NULL) {
+    return new EntryType();
+  } else {
+    return Arena::CreateMessage<EntryType>(arena_);
+  }
+}
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value>
+EntryType*
+MapFieldLite<Key, T, key_wire_type, value_wire_type,
+             default_enum_value>::NewEnumEntryWrapper(const Key& key,
+                                                      const T t) const {
+  return EntryType::EnumWrap(key, t, arena_);
+}
+
+template <typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type,
+          int default_enum_value>
+EntryType*
+MapFieldLite<Key, T, key_wire_type, value_wire_type,
+             default_enum_value>::NewEntryWrapper(const Key& key,
+                                                  const T& t) const {
+  return EntryType::Wrap(key, t, arena_);
+}
+
+#undef EntryType
+
+// True if IsInitialized() is true for value field in all elements of t. T is
+// expected to be message.  It's useful to have this helper here to keep the
+// protobuf compiler from ever having to emit loops in IsInitialized() methods.
+// We want the C++ compiler to inline this or not as it sees fit.
+template <typename Key, typename T>
+bool AllAreInitialized(const Map<Key, T>& t) {
+  for (typename Map<Key, T>::const_iterator it = t.begin(); it != t.end();
+       ++it) {
+    if (!it->second.IsInitialized()) return false;
+  }
+  return true;
+}
+
+}  // namespace internal
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc
index 045f8f2..61344cb 100644
--- a/src/google/protobuf/map_field_test.cc
+++ b/src/google/protobuf/map_field_test.cc
@@ -35,13 +35,16 @@
 #endif
 
 #include <google/protobuf/stubs/common.h>
+#include <google/protobuf/arena.h>
 #include <google/protobuf/map.h>
+#include <google/protobuf/arena_test_util.h>
 #include <google/protobuf/map_unittest.pb.h>
 #include <google/protobuf/map_test_util.h>
 #include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/map_field_inl.h>
 #include <google/protobuf/message.h>
 #include <google/protobuf/repeated_field.h>
+#include <google/protobuf/wire_format_lite_inl.h>
 #include <gtest/gtest.h>
 
 namespace google {
@@ -53,6 +56,9 @@
 
 class MapFieldBaseStub : public MapFieldBase {
  public:
+  typedef void DestructorSkippable_;
+  MapFieldBaseStub() {}
+  explicit MapFieldBaseStub(Arena* arena) : MapFieldBase(arena) {}
   void SyncRepeatedFieldWithMap() const {
     MapFieldBase::SyncRepeatedFieldWithMap();
   }
@@ -63,16 +69,6 @@
   RepeatedPtrField<Message>* InternalRepeatedField() {
     return repeated_field_;
   }
-  // Get underlined map without synchronizing repeated field.
-  template <typename MapType>
-  const MapType& GetMap() {
-    return *reinterpret_cast<MapType*>(base_map_);
-  }
-  // Get underlined map without synchronizing repeated field.
-  template <typename MapType>
-  MapType* MutableMap() {
-    return reinterpret_cast<MapType*>(base_map_);
-  }
   bool IsMapClean() { return state_ != 0; }
   bool IsRepeatedClean() { return state_ != 1; }
   void SetMapDirty() { state_ = 0; }
@@ -81,8 +77,8 @@
 
 class MapFieldBasePrimitiveTest : public ::testing::Test {
  protected:
-  typedef MapField<int32, int32, FieldDescriptor::TYPE_INT32,
-                   FieldDescriptor::TYPE_INT32> MapFieldType;
+  typedef MapField<int32, int32, WireFormatLite::TYPE_INT32,
+                   WireFormatLite::TYPE_INT32, false> MapFieldType;
 
   MapFieldBasePrimitiveTest() {
     // Get descriptors
@@ -144,6 +140,38 @@
   }
 }
 
+TEST_F(MapFieldBasePrimitiveTest, Arena) {
+  // Allocate a large initial block to avoid mallocs during hooked test.
+  std::vector<char> arena_block(128 * 1024);
+  ArenaOptions options;
+  options.initial_block = arena_block.data();
+  options.initial_block_size = arena_block.size();
+  Arena arena(options);
+
+  {
+    NoHeapChecker no_heap;
+
+    MapFieldType* map_field =
+        Arena::Create<MapFieldType>(&arena, &arena, default_entry_);
+
+    // Set content in map
+    (*map_field->MutableMap())[100] = 101;
+
+    // Trigger conversion to repeated field.
+    map_field->GetRepeatedField();
+  }
+
+  {
+    NoHeapChecker no_heap;
+
+    MapFieldBaseStub* map_field =
+        Arena::Create<MapFieldBaseStub>(&arena, &arena);
+
+    // Trigger conversion to repeated field.
+    EXPECT_TRUE(map_field->MutableRepeatedField() != NULL);
+  }
+}
+
 namespace {
 enum State { CLEAN, MAP_DIRTY, REPEATED_DIRTY };
 }  // anonymous namespace
@@ -152,8 +180,10 @@
     : public testing::TestWithParam<State> {
  public:
  protected:
-  typedef MapField<int32, int32, FieldDescriptor::TYPE_INT32,
-                FieldDescriptor::TYPE_INT32> MapFieldType;
+  typedef MapField<int32, int32, WireFormatLite::TYPE_INT32,
+                   WireFormatLite::TYPE_INT32, false> MapFieldType;
+  typedef MapFieldLite<int32, int32, WireFormatLite::TYPE_INT32,
+                       WireFormatLite::TYPE_INT32, false> MapFieldLiteType;
   MapFieldStateTest() : state_(GetParam()) {
     // Build map field
     const Descriptor* map_descriptor =
@@ -199,9 +229,8 @@
     MakeMapDirty(map_field);
     MapFieldBase* map_field_base = map_field;
     map_field_base->MutableRepeatedField();
-    MapFieldBaseStub* stub =
-        reinterpret_cast<MapFieldBaseStub*>(map_field_base);
-    Map<int32, int32>* map = stub->MutableMap<Map<int32, int32> >();
+    Map<int32, int32>* map = implicit_cast<MapFieldLiteType*>(map_field)
+                                 ->MapFieldLiteType::MutableMap();
     map->clear();
 
     Expect(map_field, REPEATED_DIRTY, 0, 1, false);
@@ -213,7 +242,8 @@
     MapFieldBaseStub* stub =
         reinterpret_cast<MapFieldBaseStub*>(map_field_base);
 
-    Map<int32, int32>* map = stub->MutableMap<Map<int32, int32> >();
+    Map<int32, int32>* map = implicit_cast<MapFieldLiteType*>(map_field)
+                                 ->MapFieldLiteType::MutableMap();
     RepeatedPtrField<Message>* repeated_field = stub->InternalRepeatedField();
 
     switch (state) {
@@ -430,6 +460,7 @@
   }
 }
 
+
 }  // namespace internal
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/map_lite_test_util.cc b/src/google/protobuf/map_lite_test_util.cc
new file mode 100644
index 0000000..b65b4d6
--- /dev/null
+++ b/src/google/protobuf/map_lite_test_util.cc
@@ -0,0 +1,93 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/map_lite_test_util.h>
+#include <google/protobuf/map_lite_unittest.pb.h>
+#include <google/protobuf/map_test_util_impl.h>
+
+namespace google {
+namespace protobuf {
+
+void MapLiteTestUtil::SetMapFields(unittest::TestMapLite* message) {
+  MapTestUtilImpl::SetMapFields<unittest::MapEnumLite,
+                                unittest::MAP_ENUM_BAR_LITE,
+                                unittest::MAP_ENUM_BAZ_LITE>(message);
+}
+
+void MapLiteTestUtil::SetArenaMapFields(unittest::TestArenaMapLite* message) {
+  MapTestUtilImpl::SetArenaMapFields<unittest::MapEnumLite,
+                                     unittest::MAP_ENUM_BAR_LITE,
+                                     unittest::MAP_ENUM_BAZ_LITE>(message);
+}
+
+void MapLiteTestUtil::SetMapFieldsInitialized(unittest::TestMapLite* message) {
+  MapTestUtilImpl::SetMapFieldsInitialized(message);
+}
+
+void MapLiteTestUtil::ModifyMapFields(unittest::TestMapLite* message) {
+  MapTestUtilImpl::ModifyMapFields<unittest::MapEnumLite,
+                                   unittest::MAP_ENUM_FOO_LITE>(message);
+}
+
+void MapLiteTestUtil::ExpectClear(const unittest::TestMapLite& message) {
+  MapTestUtilImpl::ExpectClear(message);
+}
+
+void MapLiteTestUtil::ExpectMapFieldsSet(const unittest::TestMapLite& message) {
+  MapTestUtilImpl::ExpectMapFieldsSet<unittest::MapEnumLite,
+                                      unittest::MAP_ENUM_BAR_LITE,
+                                      unittest::MAP_ENUM_BAZ_LITE>(message);
+}
+
+void MapLiteTestUtil::ExpectArenaMapFieldsSet(
+    const unittest::TestArenaMapLite& message) {
+  MapTestUtilImpl::ExpectArenaMapFieldsSet<unittest::MapEnumLite,
+                                           unittest::MAP_ENUM_BAR_LITE,
+                                           unittest::MAP_ENUM_BAZ_LITE>(
+      message);
+}
+
+void MapLiteTestUtil::ExpectMapFieldsSetInitialized(
+    const unittest::TestMapLite& message) {
+  MapTestUtilImpl::ExpectMapFieldsSetInitialized<unittest::MapEnumLite,
+                                                 unittest::MAP_ENUM_FOO_LITE>(
+      message);
+}
+
+void MapLiteTestUtil::ExpectMapFieldsModified(
+    const unittest::TestMapLite& message) {
+  MapTestUtilImpl::ExpectMapFieldsModified<unittest::MapEnumLite,
+                                           unittest::MAP_ENUM_BAR_LITE,
+                                           unittest::MAP_ENUM_FOO_LITE>(
+      message);
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/map_lite_test_util.h b/src/google/protobuf/map_lite_test_util.h
new file mode 100644
index 0000000..77b5336
--- /dev/null
+++ b/src/google/protobuf/map_lite_test_util.h
@@ -0,0 +1,80 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_MAP_LITE_TEST_UTIL_H__
+#define GOOGLE_PROTOBUF_MAP_LITE_TEST_UTIL_H__
+
+#include <google/protobuf/map_lite_unittest.pb.h>
+
+namespace google {
+namespace protobuf {
+
+class MapLiteTestUtil {
+ public:
+  // Set every field in the TestMapLite message to a unique value.
+  static void SetMapFields(protobuf_unittest::TestMapLite* message);
+
+  // Set every field in the TestArenaMapLite message to a unique value.
+  static void SetArenaMapFields(protobuf_unittest::TestArenaMapLite* message);
+
+  // Set every field in the message to a default value.
+  static void SetMapFieldsInitialized(protobuf_unittest::TestMapLite* message);
+
+  // Modify all the map fields of the messsage (which should already have been
+  // initialized with SetMapFields()).
+  static void ModifyMapFields(protobuf_unittest::TestMapLite* message);
+
+  // Check that all fields have the values that they should have after
+  // SetMapFields() is called.
+  static void ExpectMapFieldsSet(const protobuf_unittest::TestMapLite& message);
+
+  // Check that all fields have the values that they should have after
+  // SetMapFields() is called for TestArenaMapLite.
+  static void ExpectArenaMapFieldsSet(
+      const protobuf_unittest::TestArenaMapLite& message);
+
+  // Check that all fields have the values that they should have after
+  // SetMapFieldsInitialized() is called.
+  static void ExpectMapFieldsSetInitialized(
+      const protobuf_unittest::TestMapLite& message);
+
+  // Expect that the message is modified as would be expected from
+  // ModifyMapFields().
+  static void ExpectMapFieldsModified(
+      const protobuf_unittest::TestMapLite& message);
+
+  // Check that all fields are empty.
+  static void ExpectClear(const protobuf_unittest::TestMapLite& message);
+};
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_MAP_LITE_TEST_UTIL_H__
diff --git a/src/google/protobuf/map_lite_unittest.proto b/src/google/protobuf/map_lite_unittest.proto
index cc71555..c69e8d9 100644
--- a/src/google/protobuf/map_lite_unittest.proto
+++ b/src/google/protobuf/map_lite_unittest.proto
@@ -30,10 +30,104 @@
 
 syntax = "proto2";
 
+option cc_enable_arenas = true;
 option optimize_for = LITE_RUNTIME;
 
+import "google/protobuf/unittest_lite.proto";
+
 package protobuf_unittest;
 
-message MapLite {
-  map<int32, int32> map_field = 1;
+message TestMapLite {
+  map<int32   , int32   > map_int32_int32       = 1;
+  map<int64   , int64   > map_int64_int64       = 2;
+  map<uint32  , uint32  > map_uint32_uint32     = 3;
+  map<uint64  , uint64  > map_uint64_uint64     = 4;
+  map<sint32  , sint32  > map_sint32_sint32     = 5;
+  map<sint64  , sint64  > map_sint64_sint64     = 6;
+  map<fixed32 , fixed32 > map_fixed32_fixed32   = 7;
+  map<fixed64 , fixed64 > map_fixed64_fixed64   = 8;
+  map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 9;
+  map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 10;
+  map<int32   , float   > map_int32_float       = 11;
+  map<int32   , double  > map_int32_double      = 12;
+  map<bool    , bool    > map_bool_bool         = 13;
+  map<string  , string  > map_string_string     = 14;
+  map<int32   , bytes   > map_int32_bytes       = 15;
+  map<int32   , MapEnumLite> map_int32_enum     = 16;
+  map<int32   , ForeignMessageLite> map_int32_foreign_message = 17;
+  map<int32, int32> teboring = 18;
+}
+
+message TestArenaMapLite {
+  map<int32   , int32   > map_int32_int32       = 1;
+  map<int64   , int64   > map_int64_int64       = 2;
+  map<uint32  , uint32  > map_uint32_uint32     = 3;
+  map<uint64  , uint64  > map_uint64_uint64     = 4;
+  map<sint32  , sint32  > map_sint32_sint32     = 5;
+  map<sint64  , sint64  > map_sint64_sint64     = 6;
+  map<fixed32 , fixed32 > map_fixed32_fixed32   = 7;
+  map<fixed64 , fixed64 > map_fixed64_fixed64   = 8;
+  map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 9;
+  map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 10;
+  map<int32   , float   > map_int32_float       = 11;
+  map<int32   , double  > map_int32_double      = 12;
+  map<bool    , bool    > map_bool_bool         = 13;
+  map<int32   , MapEnumLite> map_int32_enum     = 14;
+  map<int32   , ForeignMessageArenaLite> map_int32_foreign_message = 15;
+}
+
+// Test embeded message with required fields
+message TestRequiredMessageMapLite {
+  map<int32, TestRequiredLite> map_field = 1;
+}
+
+message TestEnumStartWithNonZeroMapLite {
+  map<int32, Proto2MapEnumStartWithNonZeroLite> map_field = 101;
+}
+
+message TestEnumMapLite {
+  map<int32, Proto2MapEnumLite> known_map_field = 101;
+  map<int32, Proto2MapEnumLite> unknown_map_field = 102;
+}
+
+message TestEnumMapPlusExtraLite {
+  map<int32, Proto2MapEnumPlusExtraLite> known_map_field = 101;
+  map<int32, Proto2MapEnumPlusExtraLite> unknown_map_field = 102;
+}
+
+message TestMessageMapLite {
+  map<int32, TestAllTypesLite> map_int32_message = 1;
+}
+
+enum Proto2MapEnumLite {
+  PROTO2_MAP_ENUM_FOO_LITE = 0;
+  PROTO2_MAP_ENUM_BAR_LITE = 1;
+  PROTO2_MAP_ENUM_BAZ_LITE = 2;
+}
+
+enum Proto2MapEnumPlusExtraLite {
+  E_PROTO2_MAP_ENUM_FOO_LITE   = 0;
+  E_PROTO2_MAP_ENUM_BAR_LITE   = 1;
+  E_PROTO2_MAP_ENUM_BAZ_LITE   = 2;
+  E_PROTO2_MAP_ENUM_EXTRA_LITE = 3;
+}
+
+enum Proto2MapEnumStartWithNonZeroLite {
+  PROTO2_NON_ZERO_MAP_ENUM_FOO_LITE = 1;
+}
+
+enum MapEnumLite {
+  MAP_ENUM_FOO_LITE = 0;
+  MAP_ENUM_BAR_LITE = 1;
+  MAP_ENUM_BAZ_LITE = 2;
+}
+
+message TestRequiredLite {
+  required int32 a = 1;
+  required int32 b = 2;
+  required int32 c = 3;
+}
+
+message ForeignMessageArenaLite {
+  optional int32 c = 1;
 }
diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc
index 9db6752..88cba1f 100644
--- a/src/google/protobuf/map_test.cc
+++ b/src/google/protobuf/map_test.cc
@@ -39,7 +39,7 @@
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/stringprintf.h>
 #include <google/protobuf/testing/file.h>
-#include <google/protobuf/map_lite_unittest.pb.h>
+#include <google/protobuf/arena_test_util.h>
 #include <google/protobuf/map_proto2_unittest.pb.h>
 #include <google/protobuf/map_unittest.pb.h>
 #include <google/protobuf/map_test_util.h>
@@ -191,6 +191,7 @@
 }
 
 #ifdef PROTOBUF_HAS_DEATH_TEST
+
 TEST_F(MapImplTest, MutableAtNonExistDeathTest) {
   EXPECT_DEATH(map_.at(0), "");
 }
@@ -198,6 +199,7 @@
 TEST_F(MapImplTest, ImmutableAtNonExistDeathTest) {
   EXPECT_DEATH(const_map_.at(0), "");
 }
+
 #endif  // PROTOBUF_HAS_DEATH_TEST
 
 TEST_F(MapImplTest, CountNonExist) {
@@ -553,6 +555,14 @@
   EXPECT_EQ(101, std_map[100]);
 }
 
+TEST_F(MapImplTest, ConvertToStdVectorOfPairs) {
+  map_[100] = 101;
+  std::vector<std::pair<int32, int32> > std_vec(map_.begin(), map_.end());
+  EXPECT_EQ(1, std_vec.size());
+  EXPECT_EQ(100, std_vec[0].first);
+  EXPECT_EQ(101, std_vec[0].second);
+}
+
 // Map Field Reflection Test ========================================
 
 static int Func(int i, int j) {
@@ -1717,6 +1727,20 @@
   EXPECT_EQ(0, message.map_int32_int32().at(1));
 }
 
+TEST(GeneratedMapFieldTest, MissedValueTextFormat) {
+  unittest::TestMap message;
+
+  // No value field in text format
+  string text =
+      "map_int32_foreign_message {\n"
+      "  key: 1234567890\n"
+      "}";
+
+  EXPECT_TRUE(google::protobuf::TextFormat::ParseFromString(text, &message));
+  EXPECT_EQ(1, message.map_int32_foreign_message().size());
+  EXPECT_EQ(11, message.ByteSize());
+}
+
 TEST(GeneratedMapFieldTest, UnknownFieldWireFormat) {
   unittest::TestMap message;
 
@@ -1737,18 +1761,6 @@
   EXPECT_FALSE(message.ParseFromString(data));
 }
 
-TEST(GeneratedMapFieldTest, MessageLiteMap) {
-  unittest::MapLite from, to;
-  (*from.mutable_map_field())[1] = 1;
-
-  string data;
-  from.SerializeToString(&data);
-  to.ParseFromString(data);
-
-  EXPECT_EQ(1, to.map_field().size());
-  EXPECT_EQ(1, to.map_field().at(1));
-}
-
 TEST(GeneratedMapFieldTest, IsInitialized) {
   unittest::TestRequiredMessageMap map_message;
 
@@ -2247,6 +2259,52 @@
 }
 
 
+// arena support =================================================
+TEST(ArenaTest, ParsingAndSerializingNoHeapAllocation) {
+  // Allocate a large initial block to avoid mallocs during hooked test.
+  std::vector<char> arena_block(128 * 1024);
+  ArenaOptions options;
+  options.initial_block = arena_block.data();
+  options.initial_block_size = arena_block.size();
+  Arena arena(options);
+  string data;
+  data.reserve(128 * 1024);
+
+  {
+    NoHeapChecker no_heap;
+
+    unittest::TestArenaMap* from =
+        Arena::CreateMessage<unittest::TestArenaMap>(&arena);
+    MapTestUtil::SetArenaMapFields(from);
+    from->SerializeToString(&data);
+
+    unittest::TestArenaMap* to =
+        Arena::CreateMessage<unittest::TestArenaMap>(&arena);
+    to->ParseFromString(data);
+    MapTestUtil::ExpectArenaMapFieldsSet(*to);
+  }
+}
+
+// Use text format parsing and serializing to test reflection api.
+TEST(ArenaTest, RelfectionInTextFormat) {
+  Arena arena;
+  string data;
+
+  TextFormat::Printer printer;
+  TextFormat::Parser parser;
+
+  unittest::TestArenaMap* from =
+      Arena::CreateMessage<unittest::TestArenaMap>(&arena);
+  unittest::TestArenaMap* to =
+      Arena::CreateMessage<unittest::TestArenaMap>(&arena);
+
+  MapTestUtil::SetArenaMapFields(from);
+  printer.PrintToString(*from, &data);
+
+  EXPECT_TRUE(parser.ParseFromString(data, to));
+  MapTestUtil::ExpectArenaMapFieldsSet(*to);
+}
+
 }  // namespace internal
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/map_test_util.cc b/src/google/protobuf/map_test_util.cc
index eb7ea51..1713e37 100644
--- a/src/google/protobuf/map_test_util.cc
+++ b/src/google/protobuf/map_test_util.cc
@@ -29,275 +29,60 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <google/protobuf/map_test_util.h>
+#include <google/protobuf/map_test_util_impl.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/message.h>
 
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/testing/googletest.h>
-#include <gtest/gtest.h>
-
 namespace google {
 namespace protobuf {
 
 void MapTestUtil::SetMapFields(unittest::TestMap* message) {
-  // Add first element.
-  (*message->mutable_map_int32_int32())[0] = 0;
-  (*message->mutable_map_int64_int64())[0] = 0;
-  (*message->mutable_map_uint32_uint32())[0] = 0;
-  (*message->mutable_map_uint64_uint64())[0] = 0;
-  (*message->mutable_map_sint32_sint32())[0] = 0;
-  (*message->mutable_map_sint64_sint64())[0] = 0;
-  (*message->mutable_map_fixed32_fixed32())[0] = 0;
-  (*message->mutable_map_fixed64_fixed64())[0] = 0;
-  (*message->mutable_map_sfixed32_sfixed32())[0] = 0;
-  (*message->mutable_map_sfixed64_sfixed64())[0] = 0;
-  (*message->mutable_map_int32_float())[0] = 0.0;
-  (*message->mutable_map_int32_double())[0] = 0.0;
-  (*message->mutable_map_bool_bool())[0] = false;
-  (*message->mutable_map_string_string())["0"] = "0";
-  (*message->mutable_map_int32_bytes())[0] = "0";
-  (*message->mutable_map_int32_enum())[0] =
-      unittest::MAP_ENUM_BAR;
-  (*message->mutable_map_int32_foreign_message())[0].set_c(0);
+  MapTestUtilImpl::SetMapFields<unittest::MapEnum, unittest::MAP_ENUM_BAR,
+                                unittest::MAP_ENUM_BAZ>(message);
+}
 
-  // Add second element
-  (*message->mutable_map_int32_int32())[1] = 1;
-  (*message->mutable_map_int64_int64())[1] = 1;
-  (*message->mutable_map_uint32_uint32())[1] = 1;
-  (*message->mutable_map_uint64_uint64())[1] = 1;
-  (*message->mutable_map_sint32_sint32())[1] = 1;
-  (*message->mutable_map_sint64_sint64())[1] = 1;
-  (*message->mutable_map_fixed32_fixed32())[1] = 1;
-  (*message->mutable_map_fixed64_fixed64())[1] = 1;
-  (*message->mutable_map_sfixed32_sfixed32())[1] = 1;
-  (*message->mutable_map_sfixed64_sfixed64())[1] = 1;
-  (*message->mutable_map_int32_float())[1] = 1.0;
-  (*message->mutable_map_int32_double())[1] = 1.0;
-  (*message->mutable_map_bool_bool())[1] = true;
-  (*message->mutable_map_string_string())["1"] = "1";
-  (*message->mutable_map_int32_bytes())[1] = "1";
-  (*message->mutable_map_int32_enum())[1] =
-      unittest::MAP_ENUM_BAZ;
-  (*message->mutable_map_int32_foreign_message())[1].set_c(1);
+void MapTestUtil::SetArenaMapFields(unittest::TestArenaMap* message) {
+  MapTestUtilImpl::SetArenaMapFields<unittest::MapEnum, unittest::MAP_ENUM_BAR,
+                                     unittest::MAP_ENUM_BAZ>(message);
 }
 
 void MapTestUtil::SetMapFieldsInitialized(unittest::TestMap* message) {
-  // Add first element using bracket operator, which should assign default
-  // value automatically.
-  (*message->mutable_map_int32_int32())[0];
-  (*message->mutable_map_int64_int64())[0];
-  (*message->mutable_map_uint32_uint32())[0];
-  (*message->mutable_map_uint64_uint64())[0];
-  (*message->mutable_map_sint32_sint32())[0];
-  (*message->mutable_map_sint64_sint64())[0];
-  (*message->mutable_map_fixed32_fixed32())[0];
-  (*message->mutable_map_fixed64_fixed64())[0];
-  (*message->mutable_map_sfixed32_sfixed32())[0];
-  (*message->mutable_map_sfixed64_sfixed64())[0];
-  (*message->mutable_map_int32_float())[0];
-  (*message->mutable_map_int32_double())[0];
-  (*message->mutable_map_bool_bool())[0];
-  (*message->mutable_map_string_string())["0"];
-  (*message->mutable_map_int32_bytes())[0];
-  (*message->mutable_map_int32_enum())[0];
-  (*message->mutable_map_int32_foreign_message())[0];
+  MapTestUtilImpl::SetMapFieldsInitialized(message);
 }
 
 void MapTestUtil::ModifyMapFields(unittest::TestMap* message) {
-  (*message->mutable_map_int32_int32())[1] = 2;
-  (*message->mutable_map_int64_int64())[1] = 2;
-  (*message->mutable_map_uint32_uint32())[1] = 2;
-  (*message->mutable_map_uint64_uint64())[1] = 2;
-  (*message->mutable_map_sint32_sint32())[1] = 2;
-  (*message->mutable_map_sint64_sint64())[1] = 2;
-  (*message->mutable_map_fixed32_fixed32())[1] = 2;
-  (*message->mutable_map_fixed64_fixed64())[1] = 2;
-  (*message->mutable_map_sfixed32_sfixed32())[1] = 2;
-  (*message->mutable_map_sfixed64_sfixed64())[1] = 2;
-  (*message->mutable_map_int32_float())[1] = 2.0;
-  (*message->mutable_map_int32_double())[1] = 2.0;
-  (*message->mutable_map_bool_bool())[1] = false;
-  (*message->mutable_map_string_string())["1"] = "2";
-  (*message->mutable_map_int32_bytes())[1] = "2";
-  (*message->mutable_map_int32_enum())[1] =
-      unittest::MAP_ENUM_FOO;
-  (*message->mutable_map_int32_foreign_message())[1].set_c(2);
+  MapTestUtilImpl::ModifyMapFields<unittest::MapEnum, unittest::MAP_ENUM_FOO>(
+      message);
 }
 
 void MapTestUtil::ExpectClear(const unittest::TestMap& message) {
-  EXPECT_EQ(0, message.map_int32_int32().size());
-  EXPECT_EQ(0, message.map_int64_int64().size());
-  EXPECT_EQ(0, message.map_uint32_uint32().size());
-  EXPECT_EQ(0, message.map_uint64_uint64().size());
-  EXPECT_EQ(0, message.map_sint32_sint32().size());
-  EXPECT_EQ(0, message.map_sint64_sint64().size());
-  EXPECT_EQ(0, message.map_fixed32_fixed32().size());
-  EXPECT_EQ(0, message.map_fixed64_fixed64().size());
-  EXPECT_EQ(0, message.map_sfixed32_sfixed32().size());
-  EXPECT_EQ(0, message.map_sfixed64_sfixed64().size());
-  EXPECT_EQ(0, message.map_int32_float().size());
-  EXPECT_EQ(0, message.map_int32_double().size());
-  EXPECT_EQ(0, message.map_bool_bool().size());
-  EXPECT_EQ(0, message.map_string_string().size());
-  EXPECT_EQ(0, message.map_int32_bytes().size());
-  EXPECT_EQ(0, message.map_int32_enum().size());
-  EXPECT_EQ(0, message.map_int32_foreign_message().size());
+  MapTestUtilImpl::ExpectClear(message);
 }
 
 void MapTestUtil::ExpectMapFieldsSet(const unittest::TestMap& message) {
-  EXPECT_EQ(2, message.map_int32_int32().size());
-  EXPECT_EQ(2, message.map_int64_int64().size());
-  EXPECT_EQ(2, message.map_uint32_uint32().size());
-  EXPECT_EQ(2, message.map_uint64_uint64().size());
-  EXPECT_EQ(2, message.map_sint32_sint32().size());
-  EXPECT_EQ(2, message.map_sint64_sint64().size());
-  EXPECT_EQ(2, message.map_fixed32_fixed32().size());
-  EXPECT_EQ(2, message.map_fixed64_fixed64().size());
-  EXPECT_EQ(2, message.map_sfixed32_sfixed32().size());
-  EXPECT_EQ(2, message.map_sfixed64_sfixed64().size());
-  EXPECT_EQ(2, message.map_int32_float().size());
-  EXPECT_EQ(2, message.map_int32_double().size());
-  EXPECT_EQ(2, message.map_bool_bool().size());
-  EXPECT_EQ(2, message.map_string_string().size());
-  EXPECT_EQ(2, message.map_int32_bytes().size());
-  EXPECT_EQ(2, message.map_int32_enum().size());
-  EXPECT_EQ(2, message.map_int32_foreign_message().size());
+  MapTestUtilImpl::ExpectMapFieldsSet<unittest::MapEnum, unittest::MAP_ENUM_BAR,
+                                      unittest::MAP_ENUM_BAZ>(message);
+}
 
-  EXPECT_EQ(0, message.map_int32_int32().at(0));
-  EXPECT_EQ(0, message.map_int64_int64().at(0));
-  EXPECT_EQ(0, message.map_uint32_uint32().at(0));
-  EXPECT_EQ(0, message.map_uint64_uint64().at(0));
-  EXPECT_EQ(0, message.map_sint32_sint32().at(0));
-  EXPECT_EQ(0, message.map_sint64_sint64().at(0));
-  EXPECT_EQ(0, message.map_fixed32_fixed32().at(0));
-  EXPECT_EQ(0, message.map_fixed64_fixed64().at(0));
-  EXPECT_EQ(0, message.map_sfixed32_sfixed32().at(0));
-  EXPECT_EQ(0, message.map_sfixed64_sfixed64().at(0));
-  EXPECT_EQ(0, message.map_int32_float().at(0));
-  EXPECT_EQ(0, message.map_int32_double().at(0));
-  EXPECT_EQ(false, message.map_bool_bool().at(0));
-  EXPECT_EQ("0", message.map_string_string().at("0"));
-  EXPECT_EQ("0", message.map_int32_bytes().at(0));
-  EXPECT_EQ(unittest::MAP_ENUM_BAR, message.map_int32_enum().at(0));
-  EXPECT_EQ(0, message.map_int32_foreign_message().at(0).c());
-
-  EXPECT_EQ(1, message.map_int32_int32().at(1));
-  EXPECT_EQ(1, message.map_int64_int64().at(1));
-  EXPECT_EQ(1, message.map_uint32_uint32().at(1));
-  EXPECT_EQ(1, message.map_uint64_uint64().at(1));
-  EXPECT_EQ(1, message.map_sint32_sint32().at(1));
-  EXPECT_EQ(1, message.map_sint64_sint64().at(1));
-  EXPECT_EQ(1, message.map_fixed32_fixed32().at(1));
-  EXPECT_EQ(1, message.map_fixed64_fixed64().at(1));
-  EXPECT_EQ(1, message.map_sfixed32_sfixed32().at(1));
-  EXPECT_EQ(1, message.map_sfixed64_sfixed64().at(1));
-  EXPECT_EQ(1, message.map_int32_float().at(1));
-  EXPECT_EQ(1, message.map_int32_double().at(1));
-  EXPECT_EQ(true, message.map_bool_bool().at(1));
-  EXPECT_EQ("1", message.map_string_string().at("1"));
-  EXPECT_EQ("1", message.map_int32_bytes().at(1));
-  EXPECT_EQ(unittest::MAP_ENUM_BAZ, message.map_int32_enum().at(1));
-  EXPECT_EQ(1, message.map_int32_foreign_message().at(1).c());
+void MapTestUtil::ExpectArenaMapFieldsSet(
+    const unittest::TestArenaMap& message) {
+  MapTestUtilImpl::ExpectArenaMapFieldsSet<
+      unittest::MapEnum, unittest::MAP_ENUM_BAR, unittest::MAP_ENUM_BAZ>(
+      message);
 }
 
 void MapTestUtil::ExpectMapFieldsSetInitialized(
     const unittest::TestMap& message) {
-  EXPECT_EQ(1, message.map_int32_int32().size());
-  EXPECT_EQ(1, message.map_int64_int64().size());
-  EXPECT_EQ(1, message.map_uint32_uint32().size());
-  EXPECT_EQ(1, message.map_uint64_uint64().size());
-  EXPECT_EQ(1, message.map_sint32_sint32().size());
-  EXPECT_EQ(1, message.map_sint64_sint64().size());
-  EXPECT_EQ(1, message.map_fixed32_fixed32().size());
-  EXPECT_EQ(1, message.map_fixed64_fixed64().size());
-  EXPECT_EQ(1, message.map_sfixed32_sfixed32().size());
-  EXPECT_EQ(1, message.map_sfixed64_sfixed64().size());
-  EXPECT_EQ(1, message.map_int32_float().size());
-  EXPECT_EQ(1, message.map_int32_double().size());
-  EXPECT_EQ(1, message.map_bool_bool().size());
-  EXPECT_EQ(1, message.map_string_string().size());
-  EXPECT_EQ(1, message.map_int32_bytes().size());
-  EXPECT_EQ(1, message.map_int32_enum().size());
-  EXPECT_EQ(1, message.map_int32_foreign_message().size());
-
-  EXPECT_EQ(0, message.map_int32_int32().at(0));
-  EXPECT_EQ(0, message.map_int64_int64().at(0));
-  EXPECT_EQ(0, message.map_uint32_uint32().at(0));
-  EXPECT_EQ(0, message.map_uint64_uint64().at(0));
-  EXPECT_EQ(0, message.map_sint32_sint32().at(0));
-  EXPECT_EQ(0, message.map_sint64_sint64().at(0));
-  EXPECT_EQ(0, message.map_fixed32_fixed32().at(0));
-  EXPECT_EQ(0, message.map_fixed64_fixed64().at(0));
-  EXPECT_EQ(0, message.map_sfixed32_sfixed32().at(0));
-  EXPECT_EQ(0, message.map_sfixed64_sfixed64().at(0));
-  EXPECT_EQ(0, message.map_int32_float().at(0));
-  EXPECT_EQ(0, message.map_int32_double().at(0));
-  EXPECT_EQ(false, message.map_bool_bool().at(0));
-  EXPECT_EQ("", message.map_string_string().at("0"));
-  EXPECT_EQ("", message.map_int32_bytes().at(0));
-  EXPECT_EQ(unittest::MAP_ENUM_FOO, message.map_int32_enum().at(0));
-  EXPECT_EQ(0, message.map_int32_foreign_message().at(0).ByteSize());
+  MapTestUtilImpl::ExpectMapFieldsSetInitialized<unittest::MapEnum,
+                                                 unittest::MAP_ENUM_FOO>(
+      message);
 }
 
 void MapTestUtil::ExpectMapFieldsModified(
     const unittest::TestMap& message) {
-  // ModifyMapFields only sets the second element of each field.  In addition to
-  // verifying this, we also verify that the first element and size were *not*
-  // modified.
-  EXPECT_EQ(2, message.map_int32_int32().size());
-  EXPECT_EQ(2, message.map_int64_int64().size());
-  EXPECT_EQ(2, message.map_uint32_uint32().size());
-  EXPECT_EQ(2, message.map_uint64_uint64().size());
-  EXPECT_EQ(2, message.map_sint32_sint32().size());
-  EXPECT_EQ(2, message.map_sint64_sint64().size());
-  EXPECT_EQ(2, message.map_fixed32_fixed32().size());
-  EXPECT_EQ(2, message.map_fixed64_fixed64().size());
-  EXPECT_EQ(2, message.map_sfixed32_sfixed32().size());
-  EXPECT_EQ(2, message.map_sfixed64_sfixed64().size());
-  EXPECT_EQ(2, message.map_int32_float().size());
-  EXPECT_EQ(2, message.map_int32_double().size());
-  EXPECT_EQ(2, message.map_bool_bool().size());
-  EXPECT_EQ(2, message.map_string_string().size());
-  EXPECT_EQ(2, message.map_int32_bytes().size());
-  EXPECT_EQ(2, message.map_int32_enum().size());
-  EXPECT_EQ(2, message.map_int32_foreign_message().size());
-
-  EXPECT_EQ(0, message.map_int32_int32().at(0));
-  EXPECT_EQ(0, message.map_int64_int64().at(0));
-  EXPECT_EQ(0, message.map_uint32_uint32().at(0));
-  EXPECT_EQ(0, message.map_uint64_uint64().at(0));
-  EXPECT_EQ(0, message.map_sint32_sint32().at(0));
-  EXPECT_EQ(0, message.map_sint64_sint64().at(0));
-  EXPECT_EQ(0, message.map_fixed32_fixed32().at(0));
-  EXPECT_EQ(0, message.map_fixed64_fixed64().at(0));
-  EXPECT_EQ(0, message.map_sfixed32_sfixed32().at(0));
-  EXPECT_EQ(0, message.map_sfixed64_sfixed64().at(0));
-  EXPECT_EQ(0, message.map_int32_float().at(0));
-  EXPECT_EQ(0, message.map_int32_double().at(0));
-  EXPECT_EQ(false, message.map_bool_bool().at(0));
-  EXPECT_EQ("0", message.map_string_string().at("0"));
-  EXPECT_EQ("0", message.map_int32_bytes().at(0));
-  EXPECT_EQ(unittest::MAP_ENUM_BAR, message.map_int32_enum().at(0));
-  EXPECT_EQ(0, message.map_int32_foreign_message().at(0).c());
-
-  // Actually verify the second (modified) elements now.
-  EXPECT_EQ(2, message.map_int32_int32().at(1));
-  EXPECT_EQ(2, message.map_int64_int64().at(1));
-  EXPECT_EQ(2, message.map_uint32_uint32().at(1));
-  EXPECT_EQ(2, message.map_uint64_uint64().at(1));
-  EXPECT_EQ(2, message.map_sint32_sint32().at(1));
-  EXPECT_EQ(2, message.map_sint64_sint64().at(1));
-  EXPECT_EQ(2, message.map_fixed32_fixed32().at(1));
-  EXPECT_EQ(2, message.map_fixed64_fixed64().at(1));
-  EXPECT_EQ(2, message.map_sfixed32_sfixed32().at(1));
-  EXPECT_EQ(2, message.map_sfixed64_sfixed64().at(1));
-  EXPECT_EQ(2, message.map_int32_float().at(1));
-  EXPECT_EQ(2, message.map_int32_double().at(1));
-  EXPECT_EQ(false, message.map_bool_bool().at(1));
-  EXPECT_EQ("2", message.map_string_string().at("1"));
-  EXPECT_EQ("2", message.map_int32_bytes().at(1));
-  EXPECT_EQ(unittest::MAP_ENUM_FOO, message.map_int32_enum().at(1));
-  EXPECT_EQ(2, message.map_int32_foreign_message().at(1).c());
+  MapTestUtilImpl::ExpectMapFieldsModified<
+      unittest::MapEnum, unittest::MAP_ENUM_BAR, unittest::MAP_ENUM_FOO>(
+      message);
 }
 
 void MapTestUtil::ExpectMapsSize(
@@ -1468,8 +1253,9 @@
     sub_message = reflection->AddMessage(message, F("map_int32_enum"));
     EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message,
                                                         key_descriptor));
-    EXPECT_EQ(0, sub_message->GetReflection()->GetEnum(*sub_message,
-                                                        value_descriptor));
+    EXPECT_EQ(0, sub_message->GetReflection()
+                     ->GetEnum(*sub_message, value_descriptor)
+                     ->number());
   }
   // Map using message as value has been tested in other place. Thus, we don't
   // test it here.
diff --git a/src/google/protobuf/map_test_util.h b/src/google/protobuf/map_test_util.h
index 653cf10..f437e33 100644
--- a/src/google/protobuf/map_test_util.h
+++ b/src/google/protobuf/map_test_util.h
@@ -40,9 +40,12 @@
 
 class MapTestUtil {
  public:
-  // Set every field in the message to a unique value.
+  // Set every field in the TestMap message to a unique value.
   static void SetMapFields(unittest::TestMap* message);
 
+  // Set every field in the TestArenaMap message to a unique value.
+  static void SetArenaMapFields(unittest::TestArenaMap* message);
+
   // Set every field in the message to a default value.
   static void SetMapFieldsInitialized(unittest::TestMap* message);
 
@@ -55,6 +58,10 @@
   static void ExpectMapFieldsSet(const unittest::TestMap& message);
 
   // Check that all fields have the values that they should have after
+  // SetMapFields() is called for TestArenaMap.
+  static void ExpectArenaMapFieldsSet(const unittest::TestArenaMap& message);
+
+  // Check that all fields have the values that they should have after
   // SetMapFieldsInitialized() is called.
   static void ExpectMapFieldsSetInitialized(
       const unittest::TestMap& message);
diff --git a/src/google/protobuf/map_test_util_impl.h b/src/google/protobuf/map_test_util_impl.h
new file mode 100644
index 0000000..5e7882a
--- /dev/null
+++ b/src/google/protobuf/map_test_util_impl.h
@@ -0,0 +1,474 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_MAP_TEST_UTIL_IMPL_H__
+#define GOOGLE_PROTOBUF_MAP_TEST_UTIL_IMPL_H__
+
+#include <google/protobuf/stubs/common.h>
+
+
+#define EXPECT_TRUE GOOGLE_CHECK
+#define ASSERT_TRUE GOOGLE_CHECK
+#define EXPECT_FALSE(COND) GOOGLE_CHECK(!(COND))
+#define EXPECT_EQ GOOGLE_CHECK_EQ
+#define ASSERT_EQ GOOGLE_CHECK_EQ
+
+namespace google {
+namespace protobuf_unittest {}  // forward declaration
+
+namespace protobuf {
+
+namespace unittest = ::protobuf_unittest;
+
+class MapTestUtilImpl {
+ public:
+  // Set every field in the TestMap message to a unique value.
+  template <typename EnumType, EnumType enum_value0,
+            EnumType enum_value1, typename MapMessage>
+  static void SetMapFields(MapMessage* message);
+
+  // Set every field in the TestArenaMap message to a unique value.
+  template <typename EnumType, EnumType enum_value0,
+            EnumType enum_value1, typename MapMessage>
+  static void SetArenaMapFields(MapMessage* message);
+
+  // Set every field in the message to a default value.
+  template <typename MapMessage>
+  static void SetMapFieldsInitialized(MapMessage* message);
+
+  // Modify all the map fields of the messsage (which should already have been
+  // initialized with SetMapFields()).
+  template <typename EnumType, EnumType enum_value, typename MapMessage>
+  static void ModifyMapFields(MapMessage* message);
+
+  // Check that all fields have the values that they should have after
+  // SetMapFields() is called.
+  template <typename EnumType, EnumType enum_value0,
+            EnumType enum_value1, typename MapMessage>
+  static void ExpectMapFieldsSet(const MapMessage& message);
+
+  // Check that all fields have the values that they should have after
+  // SetMapFields() is called for TestArenaMap.
+  template <typename EnumType, EnumType enum_value0,
+            EnumType enum_value1, typename MapMessage>
+  static void ExpectArenaMapFieldsSet(const MapMessage& message);
+
+  // Check that all fields have the values that they should have after
+  // SetMapFieldsInitialized() is called.
+  template <typename EnumType, EnumType enum_value, typename MapMessage>
+  static void ExpectMapFieldsSetInitialized(const MapMessage& message);
+
+  // Expect that the message is modified as would be expected from
+  // ModifyMapFields().
+  template <typename EnumType, EnumType enum_value0,
+            EnumType enum_value1, typename MapMessage>
+  static void ExpectMapFieldsModified(const MapMessage& message);
+
+  // Check that all fields are empty.
+  template <typename MapMessage>
+  static void ExpectClear(const MapMessage& message);
+
+  // // Check that all map fields have the given size.
+  // template <typename MapMessage>
+  // static void ExpectMapsSize(const MapMessage& message, int size);
+
+  // // Get pointers of map entries at given index.
+  // static std::vector<const Message*> GetMapEntries(
+  //     const MapMessage& message, int index);
+
+  // // Get pointers of map entries from release.
+  // static std::vector<const Message*> GetMapEntriesFromRelease(
+  //     MapMessage* message);
+};
+
+template <typename EnumType, EnumType enum_value0,
+          EnumType enum_value1, typename MapMessage>
+void MapTestUtilImpl::SetMapFields(MapMessage* message) {
+  // Add first element.
+  (*message->mutable_map_int32_int32())[0] = 0;
+  (*message->mutable_map_int64_int64())[0] = 0;
+  (*message->mutable_map_uint32_uint32())[0] = 0;
+  (*message->mutable_map_uint64_uint64())[0] = 0;
+  (*message->mutable_map_sint32_sint32())[0] = 0;
+  (*message->mutable_map_sint64_sint64())[0] = 0;
+  (*message->mutable_map_fixed32_fixed32())[0] = 0;
+  (*message->mutable_map_fixed64_fixed64())[0] = 0;
+  (*message->mutable_map_sfixed32_sfixed32())[0] = 0;
+  (*message->mutable_map_sfixed64_sfixed64())[0] = 0;
+  (*message->mutable_map_int32_float())[0] = 0.0;
+  (*message->mutable_map_int32_double())[0] = 0.0;
+  (*message->mutable_map_bool_bool())[0] = false;
+  (*message->mutable_map_string_string())["0"] = "0";
+  (*message->mutable_map_int32_bytes())[0] = "0";
+  (*message->mutable_map_int32_enum())[0] = enum_value0;
+  (*message->mutable_map_int32_foreign_message())[0].set_c(0);
+
+  // Add second element
+  (*message->mutable_map_int32_int32())[1] = 1;
+  (*message->mutable_map_int64_int64())[1] = 1;
+  (*message->mutable_map_uint32_uint32())[1] = 1;
+  (*message->mutable_map_uint64_uint64())[1] = 1;
+  (*message->mutable_map_sint32_sint32())[1] = 1;
+  (*message->mutable_map_sint64_sint64())[1] = 1;
+  (*message->mutable_map_fixed32_fixed32())[1] = 1;
+  (*message->mutable_map_fixed64_fixed64())[1] = 1;
+  (*message->mutable_map_sfixed32_sfixed32())[1] = 1;
+  (*message->mutable_map_sfixed64_sfixed64())[1] = 1;
+  (*message->mutable_map_int32_float())[1] = 1.0;
+  (*message->mutable_map_int32_double())[1] = 1.0;
+  (*message->mutable_map_bool_bool())[1] = true;
+  (*message->mutable_map_string_string())["1"] = "1";
+  (*message->mutable_map_int32_bytes())[1] = "1";
+  (*message->mutable_map_int32_enum())[1] = enum_value1;
+  (*message->mutable_map_int32_foreign_message())[1].set_c(1);
+}
+
+template <typename EnumType, EnumType enum_value0,
+          EnumType enum_value1, typename MapMessage>
+void MapTestUtilImpl::SetArenaMapFields(MapMessage* message) {
+  // Add first element.
+  (*message->mutable_map_int32_int32())[0] = 0;
+  (*message->mutable_map_int64_int64())[0] = 0;
+  (*message->mutable_map_uint32_uint32())[0] = 0;
+  (*message->mutable_map_uint64_uint64())[0] = 0;
+  (*message->mutable_map_sint32_sint32())[0] = 0;
+  (*message->mutable_map_sint64_sint64())[0] = 0;
+  (*message->mutable_map_fixed32_fixed32())[0] = 0;
+  (*message->mutable_map_fixed64_fixed64())[0] = 0;
+  (*message->mutable_map_sfixed32_sfixed32())[0] = 0;
+  (*message->mutable_map_sfixed64_sfixed64())[0] = 0;
+  (*message->mutable_map_int32_float())[0] = 0.0;
+  (*message->mutable_map_int32_double())[0] = 0.0;
+  (*message->mutable_map_bool_bool())[0] = false;
+  (*message->mutable_map_int32_enum())[0] = enum_value0;
+  (*message->mutable_map_int32_foreign_message())[0].set_c(0);
+
+  // Add second element
+  (*message->mutable_map_int32_int32())[1] = 1;
+  (*message->mutable_map_int64_int64())[1] = 1;
+  (*message->mutable_map_uint32_uint32())[1] = 1;
+  (*message->mutable_map_uint64_uint64())[1] = 1;
+  (*message->mutable_map_sint32_sint32())[1] = 1;
+  (*message->mutable_map_sint64_sint64())[1] = 1;
+  (*message->mutable_map_fixed32_fixed32())[1] = 1;
+  (*message->mutable_map_fixed64_fixed64())[1] = 1;
+  (*message->mutable_map_sfixed32_sfixed32())[1] = 1;
+  (*message->mutable_map_sfixed64_sfixed64())[1] = 1;
+  (*message->mutable_map_int32_float())[1] = 1.0;
+  (*message->mutable_map_int32_double())[1] = 1.0;
+  (*message->mutable_map_bool_bool())[1] = true;
+  (*message->mutable_map_int32_enum())[1] = enum_value1;
+  (*message->mutable_map_int32_foreign_message())[1].set_c(1);
+}
+
+template <typename MapMessage>
+void MapTestUtilImpl::SetMapFieldsInitialized(MapMessage* message) {
+  // Add first element using bracket operator, which should assign default
+  // value automatically.
+  (*message->mutable_map_int32_int32())[0];
+  (*message->mutable_map_int64_int64())[0];
+  (*message->mutable_map_uint32_uint32())[0];
+  (*message->mutable_map_uint64_uint64())[0];
+  (*message->mutable_map_sint32_sint32())[0];
+  (*message->mutable_map_sint64_sint64())[0];
+  (*message->mutable_map_fixed32_fixed32())[0];
+  (*message->mutable_map_fixed64_fixed64())[0];
+  (*message->mutable_map_sfixed32_sfixed32())[0];
+  (*message->mutable_map_sfixed64_sfixed64())[0];
+  (*message->mutable_map_int32_float())[0];
+  (*message->mutable_map_int32_double())[0];
+  (*message->mutable_map_bool_bool())[0];
+  (*message->mutable_map_string_string())["0"];
+  (*message->mutable_map_int32_bytes())[0];
+  (*message->mutable_map_int32_enum())[0];
+  (*message->mutable_map_int32_foreign_message())[0];
+}
+
+template <typename EnumType, EnumType enum_value, typename MapMessage>
+void MapTestUtilImpl::ModifyMapFields(MapMessage* message) {
+  (*message->mutable_map_int32_int32())[1] = 2;
+  (*message->mutable_map_int64_int64())[1] = 2;
+  (*message->mutable_map_uint32_uint32())[1] = 2;
+  (*message->mutable_map_uint64_uint64())[1] = 2;
+  (*message->mutable_map_sint32_sint32())[1] = 2;
+  (*message->mutable_map_sint64_sint64())[1] = 2;
+  (*message->mutable_map_fixed32_fixed32())[1] = 2;
+  (*message->mutable_map_fixed64_fixed64())[1] = 2;
+  (*message->mutable_map_sfixed32_sfixed32())[1] = 2;
+  (*message->mutable_map_sfixed64_sfixed64())[1] = 2;
+  (*message->mutable_map_int32_float())[1] = 2.0;
+  (*message->mutable_map_int32_double())[1] = 2.0;
+  (*message->mutable_map_bool_bool())[1] = false;
+  (*message->mutable_map_string_string())["1"] = "2";
+  (*message->mutable_map_int32_bytes())[1] = "2";
+  (*message->mutable_map_int32_enum())[1] = enum_value;
+  (*message->mutable_map_int32_foreign_message())[1].set_c(2);
+}
+
+template <typename MapMessage>
+void MapTestUtilImpl::ExpectClear(const MapMessage& message) {
+  EXPECT_EQ(0, message.map_int32_int32().size());
+  EXPECT_EQ(0, message.map_int64_int64().size());
+  EXPECT_EQ(0, message.map_uint32_uint32().size());
+  EXPECT_EQ(0, message.map_uint64_uint64().size());
+  EXPECT_EQ(0, message.map_sint32_sint32().size());
+  EXPECT_EQ(0, message.map_sint64_sint64().size());
+  EXPECT_EQ(0, message.map_fixed32_fixed32().size());
+  EXPECT_EQ(0, message.map_fixed64_fixed64().size());
+  EXPECT_EQ(0, message.map_sfixed32_sfixed32().size());
+  EXPECT_EQ(0, message.map_sfixed64_sfixed64().size());
+  EXPECT_EQ(0, message.map_int32_float().size());
+  EXPECT_EQ(0, message.map_int32_double().size());
+  EXPECT_EQ(0, message.map_bool_bool().size());
+  EXPECT_EQ(0, message.map_string_string().size());
+  EXPECT_EQ(0, message.map_int32_bytes().size());
+  EXPECT_EQ(0, message.map_int32_enum().size());
+  EXPECT_EQ(0, message.map_int32_foreign_message().size());
+}
+
+
+
+template <typename EnumType, EnumType enum_value0,
+          EnumType enum_value1, typename MapMessage>
+void MapTestUtilImpl::ExpectMapFieldsSet(const MapMessage& message) {
+  EXPECT_EQ(2, message.map_int32_int32().size());
+  EXPECT_EQ(2, message.map_int64_int64().size());
+  EXPECT_EQ(2, message.map_uint32_uint32().size());
+  EXPECT_EQ(2, message.map_uint64_uint64().size());
+  EXPECT_EQ(2, message.map_sint32_sint32().size());
+  EXPECT_EQ(2, message.map_sint64_sint64().size());
+  EXPECT_EQ(2, message.map_fixed32_fixed32().size());
+  EXPECT_EQ(2, message.map_fixed64_fixed64().size());
+  EXPECT_EQ(2, message.map_sfixed32_sfixed32().size());
+  EXPECT_EQ(2, message.map_sfixed64_sfixed64().size());
+  EXPECT_EQ(2, message.map_int32_float().size());
+  EXPECT_EQ(2, message.map_int32_double().size());
+  EXPECT_EQ(2, message.map_bool_bool().size());
+  EXPECT_EQ(2, message.map_string_string().size());
+  EXPECT_EQ(2, message.map_int32_bytes().size());
+  EXPECT_EQ(2, message.map_int32_enum().size());
+  EXPECT_EQ(2, message.map_int32_foreign_message().size());
+
+  EXPECT_EQ(0, message.map_int32_int32().at(0));
+  EXPECT_EQ(0, message.map_int64_int64().at(0));
+  EXPECT_EQ(0, message.map_uint32_uint32().at(0));
+  EXPECT_EQ(0, message.map_uint64_uint64().at(0));
+  EXPECT_EQ(0, message.map_sint32_sint32().at(0));
+  EXPECT_EQ(0, message.map_sint64_sint64().at(0));
+  EXPECT_EQ(0, message.map_fixed32_fixed32().at(0));
+  EXPECT_EQ(0, message.map_fixed64_fixed64().at(0));
+  EXPECT_EQ(0, message.map_sfixed32_sfixed32().at(0));
+  EXPECT_EQ(0, message.map_sfixed64_sfixed64().at(0));
+  EXPECT_EQ(0, message.map_int32_float().at(0));
+  EXPECT_EQ(0, message.map_int32_double().at(0));
+  EXPECT_EQ(false, message.map_bool_bool().at(0));
+  EXPECT_EQ("0", message.map_string_string().at("0"));
+  EXPECT_EQ("0", message.map_int32_bytes().at(0));
+  EXPECT_EQ(enum_value0, message.map_int32_enum().at(0));
+  EXPECT_EQ(0, message.map_int32_foreign_message().at(0).c());
+
+  EXPECT_EQ(1, message.map_int32_int32().at(1));
+  EXPECT_EQ(1, message.map_int64_int64().at(1));
+  EXPECT_EQ(1, message.map_uint32_uint32().at(1));
+  EXPECT_EQ(1, message.map_uint64_uint64().at(1));
+  EXPECT_EQ(1, message.map_sint32_sint32().at(1));
+  EXPECT_EQ(1, message.map_sint64_sint64().at(1));
+  EXPECT_EQ(1, message.map_fixed32_fixed32().at(1));
+  EXPECT_EQ(1, message.map_fixed64_fixed64().at(1));
+  EXPECT_EQ(1, message.map_sfixed32_sfixed32().at(1));
+  EXPECT_EQ(1, message.map_sfixed64_sfixed64().at(1));
+  EXPECT_EQ(1, message.map_int32_float().at(1));
+  EXPECT_EQ(1, message.map_int32_double().at(1));
+  EXPECT_EQ(true, message.map_bool_bool().at(1));
+  EXPECT_EQ("1", message.map_string_string().at("1"));
+  EXPECT_EQ("1", message.map_int32_bytes().at(1));
+  EXPECT_EQ(enum_value1, message.map_int32_enum().at(1));
+  EXPECT_EQ(1, message.map_int32_foreign_message().at(1).c());
+}
+
+template <typename EnumType, EnumType enum_value0,
+          EnumType enum_value1, typename MapMessage>
+void MapTestUtilImpl::ExpectArenaMapFieldsSet(const MapMessage& message) {
+  EXPECT_EQ(2, message.map_int32_int32().size());
+  EXPECT_EQ(2, message.map_int64_int64().size());
+  EXPECT_EQ(2, message.map_uint32_uint32().size());
+  EXPECT_EQ(2, message.map_uint64_uint64().size());
+  EXPECT_EQ(2, message.map_sint32_sint32().size());
+  EXPECT_EQ(2, message.map_sint64_sint64().size());
+  EXPECT_EQ(2, message.map_fixed32_fixed32().size());
+  EXPECT_EQ(2, message.map_fixed64_fixed64().size());
+  EXPECT_EQ(2, message.map_sfixed32_sfixed32().size());
+  EXPECT_EQ(2, message.map_sfixed64_sfixed64().size());
+  EXPECT_EQ(2, message.map_int32_float().size());
+  EXPECT_EQ(2, message.map_int32_double().size());
+  EXPECT_EQ(2, message.map_bool_bool().size());
+  EXPECT_EQ(2, message.map_int32_enum().size());
+  EXPECT_EQ(2, message.map_int32_foreign_message().size());
+
+  EXPECT_EQ(0, message.map_int32_int32().at(0));
+  EXPECT_EQ(0, message.map_int64_int64().at(0));
+  EXPECT_EQ(0, message.map_uint32_uint32().at(0));
+  EXPECT_EQ(0, message.map_uint64_uint64().at(0));
+  EXPECT_EQ(0, message.map_sint32_sint32().at(0));
+  EXPECT_EQ(0, message.map_sint64_sint64().at(0));
+  EXPECT_EQ(0, message.map_fixed32_fixed32().at(0));
+  EXPECT_EQ(0, message.map_fixed64_fixed64().at(0));
+  EXPECT_EQ(0, message.map_sfixed32_sfixed32().at(0));
+  EXPECT_EQ(0, message.map_sfixed64_sfixed64().at(0));
+  EXPECT_EQ(0, message.map_int32_float().at(0));
+  EXPECT_EQ(0, message.map_int32_double().at(0));
+  EXPECT_EQ(false, message.map_bool_bool().at(0));
+  EXPECT_EQ(enum_value0, message.map_int32_enum().at(0));
+  EXPECT_EQ(0, message.map_int32_foreign_message().at(0).c());
+
+  EXPECT_EQ(1, message.map_int32_int32().at(1));
+  EXPECT_EQ(1, message.map_int64_int64().at(1));
+  EXPECT_EQ(1, message.map_uint32_uint32().at(1));
+  EXPECT_EQ(1, message.map_uint64_uint64().at(1));
+  EXPECT_EQ(1, message.map_sint32_sint32().at(1));
+  EXPECT_EQ(1, message.map_sint64_sint64().at(1));
+  EXPECT_EQ(1, message.map_fixed32_fixed32().at(1));
+  EXPECT_EQ(1, message.map_fixed64_fixed64().at(1));
+  EXPECT_EQ(1, message.map_sfixed32_sfixed32().at(1));
+  EXPECT_EQ(1, message.map_sfixed64_sfixed64().at(1));
+  EXPECT_EQ(1, message.map_int32_float().at(1));
+  EXPECT_EQ(1, message.map_int32_double().at(1));
+  EXPECT_EQ(true, message.map_bool_bool().at(1));
+  EXPECT_EQ(enum_value1, message.map_int32_enum().at(1));
+  EXPECT_EQ(1, message.map_int32_foreign_message().at(1).c());
+}
+
+template <typename EnumType, EnumType enum_value, typename MapMessage>
+void MapTestUtilImpl::ExpectMapFieldsSetInitialized(
+    const MapMessage& message) {
+  EXPECT_EQ(1, message.map_int32_int32().size());
+  EXPECT_EQ(1, message.map_int64_int64().size());
+  EXPECT_EQ(1, message.map_uint32_uint32().size());
+  EXPECT_EQ(1, message.map_uint64_uint64().size());
+  EXPECT_EQ(1, message.map_sint32_sint32().size());
+  EXPECT_EQ(1, message.map_sint64_sint64().size());
+  EXPECT_EQ(1, message.map_fixed32_fixed32().size());
+  EXPECT_EQ(1, message.map_fixed64_fixed64().size());
+  EXPECT_EQ(1, message.map_sfixed32_sfixed32().size());
+  EXPECT_EQ(1, message.map_sfixed64_sfixed64().size());
+  EXPECT_EQ(1, message.map_int32_float().size());
+  EXPECT_EQ(1, message.map_int32_double().size());
+  EXPECT_EQ(1, message.map_bool_bool().size());
+  EXPECT_EQ(1, message.map_string_string().size());
+  EXPECT_EQ(1, message.map_int32_bytes().size());
+  EXPECT_EQ(1, message.map_int32_enum().size());
+  EXPECT_EQ(1, message.map_int32_foreign_message().size());
+
+  EXPECT_EQ(0, message.map_int32_int32().at(0));
+  EXPECT_EQ(0, message.map_int64_int64().at(0));
+  EXPECT_EQ(0, message.map_uint32_uint32().at(0));
+  EXPECT_EQ(0, message.map_uint64_uint64().at(0));
+  EXPECT_EQ(0, message.map_sint32_sint32().at(0));
+  EXPECT_EQ(0, message.map_sint64_sint64().at(0));
+  EXPECT_EQ(0, message.map_fixed32_fixed32().at(0));
+  EXPECT_EQ(0, message.map_fixed64_fixed64().at(0));
+  EXPECT_EQ(0, message.map_sfixed32_sfixed32().at(0));
+  EXPECT_EQ(0, message.map_sfixed64_sfixed64().at(0));
+  EXPECT_EQ(0, message.map_int32_float().at(0));
+  EXPECT_EQ(0, message.map_int32_double().at(0));
+  EXPECT_EQ(false, message.map_bool_bool().at(0));
+  EXPECT_EQ("", message.map_string_string().at("0"));
+  EXPECT_EQ("", message.map_int32_bytes().at(0));
+  EXPECT_EQ(enum_value, message.map_int32_enum().at(0));
+  EXPECT_EQ(0, message.map_int32_foreign_message().at(0).ByteSize());
+}
+
+template <typename EnumType, EnumType enum_value0,
+            EnumType enum_value1, typename MapMessage>
+void MapTestUtilImpl::ExpectMapFieldsModified(
+    const MapMessage& message) {
+  // ModifyMapFields only sets the second element of each field.  In addition to
+  // verifying this, we also verify that the first element and size were *not*
+  // modified.
+  EXPECT_EQ(2, message.map_int32_int32().size());
+  EXPECT_EQ(2, message.map_int64_int64().size());
+  EXPECT_EQ(2, message.map_uint32_uint32().size());
+  EXPECT_EQ(2, message.map_uint64_uint64().size());
+  EXPECT_EQ(2, message.map_sint32_sint32().size());
+  EXPECT_EQ(2, message.map_sint64_sint64().size());
+  EXPECT_EQ(2, message.map_fixed32_fixed32().size());
+  EXPECT_EQ(2, message.map_fixed64_fixed64().size());
+  EXPECT_EQ(2, message.map_sfixed32_sfixed32().size());
+  EXPECT_EQ(2, message.map_sfixed64_sfixed64().size());
+  EXPECT_EQ(2, message.map_int32_float().size());
+  EXPECT_EQ(2, message.map_int32_double().size());
+  EXPECT_EQ(2, message.map_bool_bool().size());
+  EXPECT_EQ(2, message.map_string_string().size());
+  EXPECT_EQ(2, message.map_int32_bytes().size());
+  EXPECT_EQ(2, message.map_int32_enum().size());
+  EXPECT_EQ(2, message.map_int32_foreign_message().size());
+
+  EXPECT_EQ(0, message.map_int32_int32().at(0));
+  EXPECT_EQ(0, message.map_int64_int64().at(0));
+  EXPECT_EQ(0, message.map_uint32_uint32().at(0));
+  EXPECT_EQ(0, message.map_uint64_uint64().at(0));
+  EXPECT_EQ(0, message.map_sint32_sint32().at(0));
+  EXPECT_EQ(0, message.map_sint64_sint64().at(0));
+  EXPECT_EQ(0, message.map_fixed32_fixed32().at(0));
+  EXPECT_EQ(0, message.map_fixed64_fixed64().at(0));
+  EXPECT_EQ(0, message.map_sfixed32_sfixed32().at(0));
+  EXPECT_EQ(0, message.map_sfixed64_sfixed64().at(0));
+  EXPECT_EQ(0, message.map_int32_float().at(0));
+  EXPECT_EQ(0, message.map_int32_double().at(0));
+  EXPECT_EQ(false, message.map_bool_bool().at(0));
+  EXPECT_EQ("0", message.map_string_string().at("0"));
+  EXPECT_EQ("0", message.map_int32_bytes().at(0));
+  EXPECT_EQ(enum_value0, message.map_int32_enum().at(0));
+  EXPECT_EQ(0, message.map_int32_foreign_message().at(0).c());
+
+  // Actually verify the second (modified) elements now.
+  EXPECT_EQ(2, message.map_int32_int32().at(1));
+  EXPECT_EQ(2, message.map_int64_int64().at(1));
+  EXPECT_EQ(2, message.map_uint32_uint32().at(1));
+  EXPECT_EQ(2, message.map_uint64_uint64().at(1));
+  EXPECT_EQ(2, message.map_sint32_sint32().at(1));
+  EXPECT_EQ(2, message.map_sint64_sint64().at(1));
+  EXPECT_EQ(2, message.map_fixed32_fixed32().at(1));
+  EXPECT_EQ(2, message.map_fixed64_fixed64().at(1));
+  EXPECT_EQ(2, message.map_sfixed32_sfixed32().at(1));
+  EXPECT_EQ(2, message.map_sfixed64_sfixed64().at(1));
+  EXPECT_EQ(2, message.map_int32_float().at(1));
+  EXPECT_EQ(2, message.map_int32_double().at(1));
+  EXPECT_EQ(false, message.map_bool_bool().at(1));
+  EXPECT_EQ("2", message.map_string_string().at("1"));
+  EXPECT_EQ("2", message.map_int32_bytes().at(1));
+  EXPECT_EQ(enum_value1, message.map_int32_enum().at(1));
+  EXPECT_EQ(2, message.map_int32_foreign_message().at(1).c());
+}
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_MAP_TEST_UTIL_IMPL_H__
diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h
index 88a6d7b..278b78a 100644
--- a/src/google/protobuf/map_type_handler.h
+++ b/src/google/protobuf/map_type_handler.h
@@ -31,8 +31,8 @@
 #ifndef GOOGLE_PROTOBUF_TYPE_HANDLER_H__
 #define GOOGLE_PROTOBUF_TYPE_HANDLER_H__
 
+#include <google/protobuf/arena.h>
 #include <google/protobuf/generated_message_util.h>
-#include <google/protobuf/message.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 
 namespace google {
@@ -92,6 +92,28 @@
   static inline void Initialize(Type& value, int default_enum_value) {}
 };
 
+template <typename Type, bool is_arena_constructable>
+class MapArenaMessageCreator {
+ public:
+  // Use arena to create message if Type is arena constructable. Otherwise,
+  // create the message on heap.
+  static inline Type* CreateMessage(Arena* arena);
+};
+template <typename Type>
+class MapArenaMessageCreator<Type, true> {
+ public:
+  static inline Type* CreateMessage(Arena* arena) {
+    return Arena::CreateMessage<Type>(arena);
+  }
+};
+template <typename Type>
+class MapArenaMessageCreator<Type, false> {
+ public:
+  static inline Type* CreateMessage(Arena* arena) {
+    return new Type;
+  }
+};
+
 // Handlers for key/value stored type in MapField. ==================
 
 // Handler for message
@@ -124,20 +146,24 @@
     *value = const_cast<Type*>(&Type::default_instance());
   }
   // Initialize value when constructing MapEntry
-  static inline void Initialize(Type** x) { *x = NULL; }
+  static inline void Initialize(Type** x, Arena* arena) { *x = NULL; }
   // Same as above, but use default_enum_value to initialize enum type value.
   static inline void InitializeMaybeByDefaultEnum(
-      Type** x, int default_enum_value) {
+      Type** x, int default_enum_value, Arena* arena) {
     *x = NULL;
   }
   // Initialize value for the first time mutable accessor is called.
-  static inline void EnsureMutable(Type** value) {
-    if (*value == NULL) *value = new Type;
+  static inline void EnsureMutable(Type** value, Arena* arena) {
+    if (*value == NULL) {
+      *value =
+          MapArenaMessageCreator<Type, Arena::is_arena_constructable<Type>::
+                                           type::value>::CreateMessage(arena);
+    }
   }
   // Return default instance if value is not initialized when calling const
   // reference accessor.
-  static inline const Type& DefaultIfNotInitialized(Type* value,
-                                                    Type* default_value) {
+  static inline const Type& DefaultIfNotInitialized(const Type* value,
+                                                    const Type* default_value) {
     return value != NULL ? *value : *default_value;
   }
   // Check if all required fields have values set.
@@ -166,18 +192,23 @@
     if (ptr != &::google::protobuf::internal::GetEmptyString()) delete ptr;
   }
   static inline void AssignDefaultValue(string** value) {}
-  static inline void Initialize(string** value) {
+  static inline void Initialize(string** value, Arena* arena) {
     *value = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyString());
+    if (arena != NULL) arena->Own(*value);
   }
   static inline void InitializeMaybeByDefaultEnum(
-      string** value, int default_enum_value) {
+      string** value, int default_enum_value, Arena* arena) {
     *value = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyString());
+    if (arena != NULL) arena->Own(*value);
   }
-  static inline void EnsureMutable(string** value) {
-    if (*value == &::google::protobuf::internal::GetEmptyString()) *value = new string;
+  static inline void EnsureMutable(string** value, Arena* arena) {
+    if (*value == &::google::protobuf::internal::GetEmptyString()) {
+      *value = Arena::Create<string>(arena);
+    }
   }
-  static inline const string& DefaultIfNotInitialized(string* value,
-                                                      string* default_value) {
+  static inline const string& DefaultIfNotInitialized(
+      const string* value,
+      const string* default_value) {
     return value != default_value ? *value : *default_value;
   }
   static inline bool IsInitialized(string* value) { return true; }
@@ -210,12 +241,13 @@
                                                int default_enum_value) {      \
       *value = static_cast<CType>(default_enum_value);                        \
     }                                                                         \
-    static inline void Initialize(CType* value) { *value = 0; }               \
+    static inline void Initialize(CType* value, Arena* arena) { *value = 0; } \
     static inline void InitializeMaybeByDefaultEnum(CType* value,             \
-                                                    int default_enum_value) { \
+                                                    int default_enum_value,   \
+                                                    Arena* arena) {           \
       *value = static_cast<CType>(default_enum_value);                        \
     }                                                                         \
-    static inline void EnsureMutable(CType* value) {}                         \
+    static inline void EnsureMutable(CType* value, Arena* arena) {}           \
   };
 
 PRIMITIVE_HANDLER(int32 )
@@ -228,13 +260,13 @@
 
 #undef PRIMITIVE_HANDLER
 
-// Define constants for given proto field type
-template <FieldDescriptor::Type Type>
-class MapFieldTypeTraits {};
+// Define constants for given wire field type
+template <WireFormatLite::FieldType field_type>
+class MapWireFieldTypeTraits {};
 
 #define TYPE_TRAITS(FieldType, CType, WireFormatType, IsMessage, IsEnum) \
   template <>                                                            \
-  class MapFieldTypeTraits<FieldDescriptor::TYPE_##FieldType> {          \
+  class MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType> {       \
    public:                                                               \
     typedef CType CppType;                                               \
     static const bool kIsMessage = IsMessage;                            \
@@ -243,7 +275,7 @@
         WireFormatLite::WIRETYPE_##WireFormatType;                       \
   };
 
-TYPE_TRAITS(MESSAGE , Message,  LENGTH_DELIMITED, true, false)
+TYPE_TRAITS(MESSAGE , MessageLite, LENGTH_DELIMITED, true, false)
 TYPE_TRAITS(STRING  , string ,  LENGTH_DELIMITED, false, false)
 TYPE_TRAITS(BYTES   , string ,  LENGTH_DELIMITED, false, false)
 TYPE_TRAITS(INT64   , int64  ,  VARINT , false, false)
@@ -263,51 +295,46 @@
 
 #undef TYPE_TRAITS
 
-// Handler for proto field type. Define types and constants used in compile
-// time. Also define functions used in parsing and serializing.
-template <FieldDescriptor::Type Type>
-class MapProtoTypeHandler {
+template <WireFormatLite::FieldType field_type>
+class MapWireFieldTypeHandler {
  public:
-  // Internal stored type in MapEntry for given proto field type.
-  typedef typename MapFieldTypeTraits<Type>::CppType CppType;
-
-  // Whether given type is a message.
-  static const bool kIsMessage = MapFieldTypeTraits<Type>::kIsMessage;
-
-  // Whether given type is an enum.
-  static const bool kIsEnum = MapFieldTypeTraits<Type>::kIsEnum;
-
-  // The wire type of given proto field type.
+  // Internal stored type in MapEntryLite for given wire field type.
+  typedef typename MapWireFieldTypeTraits<field_type>::CppType CppType;
+  // Corresponding wire type for field type.
   static const WireFormatLite::WireType kWireType =
-      MapFieldTypeTraits<Type>::kWireType;
+      MapWireFieldTypeTraits<field_type>::kWireType;
+  // Whether wire type is for message.
+  static const bool kIsMessage = MapWireFieldTypeTraits<field_type>::kIsMessage;
+  // Whether wire type is for enum.
+  static const bool kIsEnum = MapWireFieldTypeTraits<field_type>::kIsEnum;
 
   // Functions used in parsing and serialization. ===================
-
   template <typename ValueType>
   static inline int ByteSize(const ValueType& value);
   template <typename ValueType>
   static inline int GetCachedSize(const ValueType& value);
+  template <typename ValueType>
+  static inline bool Read(io::CodedInputStream* input, ValueType* value);
   static inline void Write(int field, const CppType& value,
                            io::CodedOutputStream* output);
   static inline uint8* WriteToArray(int field, const CppType& value,
                                     uint8* output);
-  template <typename ValueType>
-  static inline bool Read(io::CodedInputStream* input, ValueType* value);
 };
 
 template <>
 template <typename ValueType>
-inline int MapProtoTypeHandler<FieldDescriptor::TYPE_MESSAGE>::ByteSize(
+inline int MapWireFieldTypeHandler<WireFormatLite::TYPE_MESSAGE>::ByteSize(
     const ValueType& value) {
   return WireFormatLite::MessageSizeNoVirtual(value);
 }
 
-#define BYTE_SIZE(FieldType, DeclaredType)                                     \
-  template <>                                                                  \
-  template <typename ValueType>                                                \
-  inline int MapProtoTypeHandler<FieldDescriptor::TYPE_##FieldType>::ByteSize( \
-      const ValueType& value) {                                                \
-    return WireFormatLite::DeclaredType##Size(value);                          \
+#define BYTE_SIZE(FieldType, DeclaredType)                             \
+  template <>                                                          \
+  template <typename ValueType>                                        \
+  inline int                                                           \
+  MapWireFieldTypeHandler<WireFormatLite::TYPE_##FieldType>::ByteSize( \
+      const ValueType& value) {                                        \
+    return WireFormatLite::DeclaredType##Size(value);                  \
   }
 
 BYTE_SIZE(STRING, String)
@@ -322,12 +349,13 @@
 
 #undef BYTE_SIZE
 
-#define FIXED_BYTE_SIZE(FieldType, DeclaredType)                               \
-  template <>                                                                  \
-  template <typename ValueType>                                                \
-  inline int MapProtoTypeHandler<FieldDescriptor::TYPE_##FieldType>::ByteSize( \
-      const ValueType& value) {                                                \
-    return WireFormatLite::k##DeclaredType##Size;                              \
+#define FIXED_BYTE_SIZE(FieldType, DeclaredType)                       \
+  template <>                                                          \
+  template <typename ValueType>                                        \
+  inline int                                                           \
+  MapWireFieldTypeHandler<WireFormatLite::TYPE_##FieldType>::ByteSize( \
+      const ValueType& value) {                                        \
+    return WireFormatLite::k##DeclaredType##Size;                      \
   }
 
 FIXED_BYTE_SIZE(DOUBLE  , Double)
@@ -342,18 +370,18 @@
 
 template <>
 template <typename ValueType>
-inline int MapProtoTypeHandler<FieldDescriptor::TYPE_MESSAGE>::GetCachedSize(
-    const ValueType& value) {
+inline int MapWireFieldTypeHandler<
+    WireFormatLite::TYPE_MESSAGE>::GetCachedSize(const ValueType& value) {
   return WireFormatLite::LengthDelimitedSize(value.GetCachedSize());
 }
 
-#define GET_CACHED_SIZE(FieldType, DeclaredType)                         \
-  template <>                                                            \
-  template <typename ValueType>                                          \
-  inline int                                                             \
-  MapProtoTypeHandler<FieldDescriptor::TYPE_##FieldType>::GetCachedSize( \
-      const ValueType& value) {                                          \
-    return WireFormatLite::DeclaredType##Size(value);                    \
+#define GET_CACHED_SIZE(FieldType, DeclaredType)                            \
+  template <>                                                               \
+  template <typename ValueType>                                             \
+  inline int                                                                \
+  MapWireFieldTypeHandler<WireFormatLite::TYPE_##FieldType>::GetCachedSize( \
+      const ValueType& value) {                                             \
+    return WireFormatLite::DeclaredType##Size(value);                       \
   }
 
 GET_CACHED_SIZE(STRING, String)
@@ -368,13 +396,13 @@
 
 #undef GET_CACHED_SIZE
 
-#define GET_FIXED_CACHED_SIZE(FieldType, DeclaredType)                   \
-  template <>                                                            \
-  template <typename ValueType>                                          \
-  inline int                                                             \
-  MapProtoTypeHandler<FieldDescriptor::TYPE_##FieldType>::GetCachedSize( \
-      const ValueType& value) {                                          \
-    return WireFormatLite::k##DeclaredType##Size;                        \
+#define GET_FIXED_CACHED_SIZE(FieldType, DeclaredType)                      \
+  template <>                                                               \
+  template <typename ValueType>                                             \
+  inline int                                                                \
+  MapWireFieldTypeHandler<WireFormatLite::TYPE_##FieldType>::GetCachedSize( \
+      const ValueType& value) {                                             \
+    return WireFormatLite::k##DeclaredType##Size;                           \
   }
 
 GET_FIXED_CACHED_SIZE(DOUBLE  , Double)
@@ -388,26 +416,28 @@
 #undef GET_FIXED_CACHED_SIZE
 
 template <>
-inline void MapProtoTypeHandler<FieldDescriptor::TYPE_MESSAGE>::Write(
-    int field, const Message& value, io::CodedOutputStream* output) {
+inline void MapWireFieldTypeHandler<WireFormatLite::TYPE_MESSAGE>::Write(
+    int field, const MessageLite& value, io::CodedOutputStream* output) {
   WireFormatLite::WriteMessageMaybeToArray(field, value, output);
 }
 
 template <>
-inline uint8* MapProtoTypeHandler<FieldDescriptor::TYPE_MESSAGE>::WriteToArray(
-    int field, const Message& value, uint8* output) {
+inline uint8*
+MapWireFieldTypeHandler<WireFormatLite::TYPE_MESSAGE>::WriteToArray(
+    int field, const MessageLite& value, uint8* output) {
   return WireFormatLite::WriteMessageToArray(field, value, output);
 }
 
 #define WRITE_METHOD(FieldType, DeclaredType)                                  \
   template <>                                                                  \
-  inline void MapProtoTypeHandler<FieldDescriptor::TYPE_##FieldType>::Write(   \
+  inline void                                                                  \
+  MapWireFieldTypeHandler<WireFormatLite::TYPE_##FieldType>::Write(            \
       int field, const CppType& value, io::CodedOutputStream* output) {        \
     return WireFormatLite::Write##DeclaredType(field, value, output);          \
   }                                                                            \
   template <>                                                                  \
   inline uint8*                                                                \
-  MapProtoTypeHandler<FieldDescriptor::TYPE_##FieldType>::WriteToArray(        \
+  MapWireFieldTypeHandler<WireFormatLite::TYPE_##FieldType>::WriteToArray(     \
       int field, const CppType& value, uint8* output) {                        \
     return WireFormatLite::Write##DeclaredType##ToArray(field, value, output); \
   }
@@ -433,33 +463,33 @@
 
 template <>
 template <typename ValueType>
-inline bool MapProtoTypeHandler<FieldDescriptor::TYPE_MESSAGE>::Read(
+inline bool MapWireFieldTypeHandler<WireFormatLite::TYPE_MESSAGE>::Read(
     io::CodedInputStream* input, ValueType* value) {
   return WireFormatLite::ReadMessageNoVirtual(input, value);
 }
 
 template <>
 template <typename ValueType>
-inline bool MapProtoTypeHandler<FieldDescriptor::TYPE_STRING>::Read(
+inline bool MapWireFieldTypeHandler<WireFormatLite::TYPE_STRING>::Read(
     io::CodedInputStream* input, ValueType* value) {
   return WireFormatLite::ReadString(input, value);
 }
 
 template <>
 template <typename ValueType>
-inline bool MapProtoTypeHandler<FieldDescriptor::TYPE_BYTES>::Read(
+inline bool MapWireFieldTypeHandler<WireFormatLite::TYPE_BYTES>::Read(
     io::CodedInputStream* input, ValueType* value) {
   return WireFormatLite::ReadBytes(input, value);
 }
 
-#define READ_METHOD(FieldType)                                              \
-  template <>                                                               \
-  template <typename ValueType>                                             \
-  inline bool MapProtoTypeHandler<FieldDescriptor::TYPE_##FieldType>::Read( \
-      io::CodedInputStream* input, ValueType* value) {                      \
-    return WireFormatLite::ReadPrimitive<CppType,                           \
-                                         WireFormatLite::TYPE_##FieldType>( \
-        input, value);                                                      \
+#define READ_METHOD(FieldType)                                                 \
+  template <>                                                                  \
+  template <typename ValueType>                                                \
+  inline bool MapWireFieldTypeHandler<WireFormatLite::TYPE_##FieldType>::Read( \
+      io::CodedInputStream* input, ValueType* value) {                         \
+    return WireFormatLite::ReadPrimitive<CppType,                              \
+                                         WireFormatLite::TYPE_##FieldType>(    \
+        input, value);                                                         \
   }
 
 READ_METHOD(INT64)
diff --git a/src/google/protobuf/map_unittest.proto b/src/google/protobuf/map_unittest.proto
index 9232d58..830f672 100644
--- a/src/google/protobuf/map_unittest.proto
+++ b/src/google/protobuf/map_unittest.proto
@@ -30,6 +30,7 @@
 
 syntax = "proto3";
 
+option cc_enable_arenas = true;
 
 import "google/protobuf/unittest.proto";
 
@@ -59,6 +60,10 @@
   map<int32   , ForeignMessage> map_int32_foreign_message = 17;
 }
 
+message TestMapSubmessage {
+  optional TestMap test_map = 1;
+}
+
 message TestMessageMap {
   map<int32, TestAllTypes> map_int32_message = 1;
 }
@@ -80,3 +85,21 @@
 message TestRequiredMessageMap {
   map<int32, TestRequired> map_field = 1;
 }
+
+message TestArenaMap {
+  map<int32   , int32   > map_int32_int32       = 1;
+  map<int64   , int64   > map_int64_int64       = 2;
+  map<uint32  , uint32  > map_uint32_uint32     = 3;
+  map<uint64  , uint64  > map_uint64_uint64     = 4;
+  map<sint32  , sint32  > map_sint32_sint32     = 5;
+  map<sint64  , sint64  > map_sint64_sint64     = 6;
+  map<fixed32 , fixed32 > map_fixed32_fixed32   = 7;
+  map<fixed64 , fixed64 > map_fixed64_fixed64   = 8;
+  map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 9;
+  map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 10;
+  map<int32   , float   > map_int32_float       = 11;
+  map<int32   , double  > map_int32_double      = 12;
+  map<bool    , bool    > map_bool_bool         = 13;
+  map<int32   , MapEnum > map_int32_enum        = 14;
+  map<int32   , ForeignMessage> map_int32_foreign_message = 15;
+}
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc
index 28955b3..f58be84 100644
--- a/src/google/protobuf/message.cc
+++ b/src/google/protobuf/message.cc
@@ -443,17 +443,17 @@
 namespace internal {
 namespace {
 void ShutdownRepeatedFieldAccessor() {
-  Singleton<internal::RepeatedFieldPrimitiveAccessor<int32> >::ShutDown();
-  Singleton<internal::RepeatedFieldPrimitiveAccessor<uint32> >::ShutDown();
-  Singleton<internal::RepeatedFieldPrimitiveAccessor<int64> >::ShutDown();
-  Singleton<internal::RepeatedFieldPrimitiveAccessor<uint64> >::ShutDown();
-  Singleton<internal::RepeatedFieldPrimitiveAccessor<float> >::ShutDown();
-  Singleton<internal::RepeatedFieldPrimitiveAccessor<double> >::ShutDown();
-  Singleton<internal::RepeatedFieldPrimitiveAccessor<bool> >::ShutDown();
-  Singleton<internal::RepeatedPtrFieldStringAccessor>::ShutDown();
-  Singleton<internal::RepeatedPtrFieldMessageAccessor>::ShutDown();
-  Singleton<internal::MapFieldAccessor>::ShutDown();
-};
+  internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<int32> >::ShutDown();
+  internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<uint32> >::ShutDown();
+  internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<int64> >::ShutDown();
+  internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<uint64> >::ShutDown();
+  internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<float> >::ShutDown();
+  internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<double> >::ShutDown();
+  internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<bool> >::ShutDown();
+  internal::Singleton<internal::RepeatedPtrFieldStringAccessor>::ShutDown();
+  internal::Singleton<internal::RepeatedPtrFieldMessageAccessor>::ShutDown();
+  internal::Singleton<internal::MapFieldAccessor>::ShutDown();
+}
 
 struct ShutdownRepeatedFieldRegister {
   ShutdownRepeatedFieldRegister() {
@@ -461,7 +461,7 @@
   }
 } shutdown_;
 
-}  // namesapce
+}  // namespace
 }  // namespace internal
 
 namespace internal {
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index a200bc9..6e1929e 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -208,7 +208,7 @@
   // This is much, much slower than IsInitialized() as it is implemented
   // purely via reflection.  Generally, you should not call this unless you
   // have already determined that an error exists by calling IsInitialized().
-  void FindInitializationErrors(vector<string>* errors) const;
+  void FindInitializationErrors(std::vector<string>* errors) const;
 
   // Like FindInitializationErrors, but joins all the strings, delimited by
   // commas, and returns them.
@@ -456,7 +456,7 @@
   // Swap fields listed in fields vector of two messages.
   virtual void SwapFields(Message* message1,
                           Message* message2,
-                          const vector<const FieldDescriptor*>& fields)
+                          const std::vector<const FieldDescriptor*>& fields)
       const = 0;
 
   // Swap two elements of a repeated field.
@@ -470,8 +470,9 @@
   // return true and repeated fields will only be listed if FieldSize(field)
   // would return non-zero.  Fields (both normal fields and extension fields)
   // will be listed ordered by field number.
-  virtual void ListFields(const Message& message,
-                          vector<const FieldDescriptor*>* output) const = 0;
+  virtual void ListFields(
+      const Message& message,
+      std::vector<const FieldDescriptor*>* output) const = 0;
 
   // Singular field getters ------------------------------------------
   // These get the value of a non-repeated field.  They return the default
@@ -523,7 +524,7 @@
   //   regardless of the field's underlying representation.  When initializing
   //   a newly-constructed string, though, it's just as fast and more readable
   //   to use code like:
-  //     string str = reflection->GetString(field);
+  //     string str = reflection->GetString(message, field);
   virtual const string& GetStringReference(const Message& message,
                                            const FieldDescriptor* field,
                                            string* scratch) const = 0;
@@ -842,6 +843,19 @@
   // }
   virtual bool SupportsUnknownEnumValues() const { return false; }
 
+  // Returns the MessageFactory associated with this message.  This can be
+  // useful for determining if a message is a generated message or not, for
+  // example:
+  //
+  // if (message->GetReflection()->GetMessageFactory() ==
+  //     google::protobuf::MessageFactory::generated_factory()) {
+  //   // This is a generated message.
+  // }
+  //
+  // It can also be used to create more messages of this type, though
+  // Message::New() is an easier way to accomplish this.
+  virtual MessageFactory* GetMessageFactory() const;
+
   // ---------------------------------------------------------------------------
 
  protected:
@@ -854,8 +868,6 @@
       Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
       int ctype, const Descriptor* message_type) const = 0;
 
-  virtual MessageFactory* GetMessageFactory() const;
-
   // The following methods are used to implement (Mutable)RepeatedFieldRef.
   // A Ref object will store a raw pointer to the repeated field data (obtained
   // from RepeatedFieldData()) and a pointer to a Accessor (obtained from
diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h
index 106982c..eab61c1 100644
--- a/src/google/protobuf/message_lite.h
+++ b/src/google/protobuf/message_lite.h
@@ -41,6 +41,7 @@
 
 #include <google/protobuf/stubs/common.h>
 
+
 namespace google {
 namespace protobuf {
   class Arena;
@@ -133,9 +134,10 @@
   // just simple wrappers around MergeFromCodedStream().  Clear() will be called
   // before merging the input.
 
-  // Fill the message with a protocol buffer parsed from the given input
-  // stream.  Returns false on a read error or if the input is in the
-  // wrong format.
+  // Fill the message with a protocol buffer parsed from the given input stream.
+  // Returns false on a read error or if the input is in the wrong format.  A
+  // successful return does not indicate the entire input is consumed, ensure
+  // you call ConsumedEntireMessage() to check that if applicable.
   bool ParseFromCodedStream(io::CodedInputStream* input);
   // Like ParseFromCodedStream(), but accepts messages that are missing
   // required fields.
@@ -154,7 +156,11 @@
   // missing required fields.
   bool ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input,
                                              int size);
-  // Parse a protocol buffer contained in a string.
+  // Parses a protocol buffer contained in a string. Returns true on success.
+  // This function takes a string in the (non-human-readable) binary wire
+  // format, matching the encoding output by MessageLite::SerializeToString().
+  // If you'd like to convert a human-readable string into a protocol buffer
+  // object, see google::protobuf::TextFormat::ParseFromString().
   bool ParseFromString(const string& data);
   // Like ParseFromString(), but accepts messages that are missing
   // required fields.
diff --git a/src/google/protobuf/new_delete_capture.cc b/src/google/protobuf/new_delete_capture.cc
deleted file mode 100644
index baf42ff..0000000
--- a/src/google/protobuf/new_delete_capture.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file exists for testing allocation behavior when using arenas by hooking
-// new/delete. It is a copy of //experimental/mvels/util/new_delete_capture.cc.
-
-#include <google/protobuf/new_delete_capture.h>
-
-#include <pthread.h>
-
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/malloc_hook.h>
-#include <google/protobuf/stubs/spinlock.h>
-
-namespace google {
-namespace {
-
-pthread_t gthread;
-protobuf_unittest::NewDeleteCapture *ghooked_instance = NULL;
-SpinLock gspinlock(base::LINKER_INITIALIZED);
-
-}  // namespace
-
-namespace protobuf_unittest {
-
-NewDeleteCapture::NewDeleteCapture()
-    : alloc_count_(0),
-      alloc_size_(0),
-      alloc_ptr_(NULL),
-      free_count_(0),
-      free_ptr_(NULL) {}
-
-NewDeleteCapture::~NewDeleteCapture() { Unhook(); }
-
-void NewDeleteCapture::Reset() {
-  alloc_count_ = 0;
-  alloc_size_ = 0;
-  free_count_ = 0;
-  alloc_ptr_ = NULL;
-  free_ptr_ = NULL;
-}
-
-bool NewDeleteCapture::Hook(bool reset) {
-  SpinLockHolder spinlock(&gspinlock);
-  if (ghooked_instance != this) {
-    GOOGLE_CHECK(ghooked_instance == NULL)
-        << " NewDeleteCapture can have only 1 active instance";
-    GOOGLE_CHECK(MallocHook::AddNewHook(NewHook));
-    GOOGLE_CHECK(MallocHook::AddDeleteHook(DeleteHook));
-    gthread = pthread_self();
-    ghooked_instance = this;
-    if (reset) {
-      Reset();
-    }
-    return true;
-  }
-  return false;
-}
-
-bool NewDeleteCapture::Unhook() {
-  SpinLockHolder spinlock(&gspinlock);
-  if (ghooked_instance == this) {
-    gthread = pthread_t();
-    ghooked_instance = NULL;
-    GOOGLE_CHECK(MallocHook::RemoveDeleteHook(DeleteHook));
-    GOOGLE_CHECK(MallocHook::RemoveNewHook(NewHook));
-    return true;
-  }
-  return false;
-}
-
-void NewDeleteCapture::NewHook(const void *ptr, size_t size) {
-  SpinLockHolder spinlock(&gspinlock);
-  if (gthread == pthread_self()) {
-    auto &rthis = *ghooked_instance;
-    if (++rthis.alloc_count_ == 1) {
-      rthis.alloc_size_ = size;
-      rthis.alloc_ptr_ = ptr;
-    }
-  }
-}
-
-void NewDeleteCapture::DeleteHook(const void *ptr) {
-  SpinLockHolder spinlock(&gspinlock);
-  if (gthread == pthread_self()) {
-    auto &rthis = *ghooked_instance;
-    if (++rthis.free_count_ == 1) {
-      rthis.free_ptr_ = ptr;
-    }
-  }
-}
-
-}  // namespace protobuf_unittest
-}  // namespace google
diff --git a/src/google/protobuf/new_delete_capture.h b/src/google/protobuf/new_delete_capture.h
deleted file mode 100644
index 4ab550c..0000000
--- a/src/google/protobuf/new_delete_capture.h
+++ /dev/null
@@ -1,175 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file exists for testing allocation behavior when using arenas by hooking
-// new/delete. It is a copy of //experimental/mvels/util/new_delete_capture.h.
-//
-// Copyright 2014 Google Inc.
-//
-// Author: Martijn Vels
-//
-// A simple class that captures memory allocations and deletes.
-//
-// This class is private to //strings and only intended to be used inside
-// unit tests. It uses the MallocHook functionality to capture memory
-// allocation and delete operations performed by the thread that activated
-// a hook on a specific instance.
-//
-// The class  captures the following information:
-// - Total allocation count (new, malloc(), etc).
-// - Total delete count (delete, free(), etc).
-// - The size and returned pointer for the first memory allocation.
-// - The pointer for the first delete operation.
-//
-// The latter 2 infos (size and pointer of first new/delete) are usefull in
-// cases where you can closely scope a Hook() / Unhook sequence around a
-// specific piece of code where you expect no more than 1 pair of new / delete
-// operations.
-//
-// Sample usage where we expect a single unique alloc / free:
-//
-//   NewDeleteCapture capture_alloc;
-//   const void *ptr;
-//   {
-//     capture_alloc.Hook();
-//     MyAllocationClass my_instance(size);
-//     capture_alloc.Unhook();
-//
-//     ptr = my_instance.ptr();
-//     GOOGLE_CHECK_EQ(1, capture_alloc.alloc_count());
-//     GOOGLE_CHECK_EQ(0, capture_alloc.free_count());
-//     GOOGLE_CHECK_EQ(size, capture_alloc.alloc_size());
-//     GOOGLE_CHECK_EQ(ptr, capture_alloc.alloc_ptr());
-//
-//     capture_alloc.Hook();
-//   }
-//   capture_alloc.Unhook();
-//   GOOGLE_CHECK_EQ(1, capture_alloc.alloc_count());
-//   GOOGLE_CHECK_EQ(1, capture_alloc.free_count());
-//   GOOGLE_CHECK_EQ(ptr, capture_alloc.free_ptr());
-//
-// You can only have one NewDeleteCapture instance active at the time. It is
-// total valid to have many instances in different threads, but only one
-// instance can have a hook active.
-//
-// Legal:
-//
-//   NewDeleteCapture capture_alloc1;
-//   NewDeleteCapture capture_alloc2;
-//   const void *ptr;
-//   {
-//     capture_alloc1.Hook();
-//     MyAllocationClass my_instance(size);
-//     capture_alloc1.Unhook();
-//
-//     capture_alloc2.Hook();
-//     my_instance.reset(size);
-//     capture_alloc2.Unhook();
-//   }
-//
-// Illegal:
-//
-//   NewDeleteCapture capture_alloc1;
-//   NewDeleteCapture capture_alloc2;
-//   const void *ptr;
-//   {
-//     capture_alloc1.Hook();
-//     MyAllocationClass my_instance(size);
-//
-//     capture_alloc2.Hook();
-//     my_instance.reset(size);
-//
-//     capture_alloc1.Unhook();
-//     capture_alloc2.Unhook();
-//   }
-//
-#ifndef GOOGLE_PROTOBUF_NEW_DELETE_CAPTURE_H__
-#define GOOGLE_PROTOBUF_NEW_DELETE_CAPTURE_H__
-
-#include <stddef.h>
-
-namespace google {
-namespace protobuf_unittest {
-
-class NewDeleteCapture {
- public:
-  // Creates a new inactive capture instance
-  NewDeleteCapture();
-
-  // Destroys this capture instance. Active hooks are automatically removed.
-  ~NewDeleteCapture();
-
-  // Activates a hook on this instance. If reset is true (the default), all
-  // internal counters will be reset to 0.
-  // Returns true if the hook was activated, false if this instance already
-  // owned the hook.
-  // Requires no other instance owning the hook (check fails)
-  bool Hook(bool reset = true);
-
-  // De-activate the hook on this instance.
-  // Returns true if the hook was removed, false if this instance did not own
-  // the hook.
-  bool Unhook();
-
-  // Resets all counters to 0
-  void Reset();
-
-  // Returns the total number of allocations (new, malloc(), etc)
-  size_t alloc_count() const { return alloc_count_; }
-
-  // Returns the total number of deletes (delete, free(), etc)
-  size_t free_count() const { return free_count_; }
-
-  // Returns the size of the first observed allocation
-  size_t alloc_size() const { return alloc_size_; }
-
-  // Returns the allocated ptr of the first observed allocation
-  const void *alloc_ptr() const { return alloc_ptr_; }
-
-  // Returns the ptr of the first observed delete
-  const void* free_ptr() const { return free_ptr_; }
-
- private:
-  static void NewHook(const void *ptr, size_t size);
-  static void DeleteHook(const void *ptr);
-
- private:
-  size_t alloc_count_;
-  size_t alloc_size_;
-  const void *alloc_ptr_;
-
-  size_t free_count_;
-  const void *free_ptr_;
-};
-
-}  // namespace protobuf_unittest
-
-}  // namespace google
-#endif  // GOOGLE_PROTOBUF_NEW_DELETE_CAPTURE_H__
diff --git a/src/google/protobuf/preserve_unknown_enum_test.cc b/src/google/protobuf/preserve_unknown_enum_test.cc
index 816e52c..9f8703a 100644
--- a/src/google/protobuf/preserve_unknown_enum_test.cc
+++ b/src/google/protobuf/preserve_unknown_enum_test.cc
@@ -30,6 +30,7 @@
 
 #include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/unittest_preserve_unknown_enum.pb.h>
+#include <google/protobuf/unittest_preserve_unknown_enum2.pb.h>
 #include <google/protobuf/dynamic_message.h>
 #include <google/protobuf/descriptor.h>
 #include <gtest/gtest.h>
@@ -39,46 +40,55 @@
 namespace {
 
 void FillMessage(
-    proto2_preserve_unknown_enum_unittest::MyMessagePlusExtra* message) {
+    proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra* message) {
   message->set_e(
-      proto2_preserve_unknown_enum_unittest::E_EXTRA);
+      proto3_preserve_unknown_enum_unittest::E_EXTRA);
   message->add_repeated_e(
-      proto2_preserve_unknown_enum_unittest::E_EXTRA);
+      proto3_preserve_unknown_enum_unittest::E_EXTRA);
   message->add_repeated_packed_e(
-      proto2_preserve_unknown_enum_unittest::E_EXTRA);
+      proto3_preserve_unknown_enum_unittest::E_EXTRA);
+  message->add_repeated_packed_unexpected_e(
+      proto3_preserve_unknown_enum_unittest::E_EXTRA);
   message->set_oneof_e_1(
-      proto2_preserve_unknown_enum_unittest::E_EXTRA);
+      proto3_preserve_unknown_enum_unittest::E_EXTRA);
 }
 
 void CheckMessage(
-    const proto2_preserve_unknown_enum_unittest::MyMessagePlusExtra& message) {
-  EXPECT_EQ(proto2_preserve_unknown_enum_unittest::E_EXTRA,
+    const proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra& message) {
+  EXPECT_EQ(proto3_preserve_unknown_enum_unittest::E_EXTRA,
             message.e());
   EXPECT_EQ(1, message.repeated_e_size());
-  EXPECT_EQ(proto2_preserve_unknown_enum_unittest::E_EXTRA,
+  EXPECT_EQ(proto3_preserve_unknown_enum_unittest::E_EXTRA,
             message.repeated_e(0));
   EXPECT_EQ(1, message.repeated_packed_e_size());
-  EXPECT_EQ(proto2_preserve_unknown_enum_unittest::E_EXTRA,
+  EXPECT_EQ(proto3_preserve_unknown_enum_unittest::E_EXTRA,
             message.repeated_packed_e(0));
-  EXPECT_EQ(proto2_preserve_unknown_enum_unittest::E_EXTRA,
+  EXPECT_EQ(1, message.repeated_packed_unexpected_e_size());
+  EXPECT_EQ(proto3_preserve_unknown_enum_unittest::E_EXTRA,
+            message.repeated_packed_unexpected_e(0));
+  EXPECT_EQ(proto3_preserve_unknown_enum_unittest::E_EXTRA,
             message.oneof_e_1());
 }
 
 void CheckMessage(
-    const proto2_preserve_unknown_enum_unittest::MyMessage& message) {
+    const proto3_preserve_unknown_enum_unittest::MyMessage& message) {
   EXPECT_EQ(static_cast<int>(
-              proto2_preserve_unknown_enum_unittest::E_EXTRA),
+              proto3_preserve_unknown_enum_unittest::E_EXTRA),
             static_cast<int>(message.e()));
   EXPECT_EQ(1, message.repeated_e_size());
   EXPECT_EQ(static_cast<int>(
-              proto2_preserve_unknown_enum_unittest::E_EXTRA),
+              proto3_preserve_unknown_enum_unittest::E_EXTRA),
             static_cast<int>(message.repeated_e(0)));
   EXPECT_EQ(1, message.repeated_packed_e_size());
   EXPECT_EQ(static_cast<int>(
-              proto2_preserve_unknown_enum_unittest::E_EXTRA),
+              proto3_preserve_unknown_enum_unittest::E_EXTRA),
             static_cast<int>(message.repeated_packed_e(0)));
+  EXPECT_EQ(1, message.repeated_packed_unexpected_e_size());
   EXPECT_EQ(static_cast<int>(
-              proto2_preserve_unknown_enum_unittest::E_EXTRA),
+              proto3_preserve_unknown_enum_unittest::E_EXTRA),
+            static_cast<int>(message.repeated_packed_unexpected_e(0)));
+  EXPECT_EQ(static_cast<int>(
+              proto3_preserve_unknown_enum_unittest::E_EXTRA),
             static_cast<int>(message.oneof_e_1()));
 }
 
@@ -87,12 +97,12 @@
 // Test that parsing preserves an unknown value in the enum field and does not
 // punt it to the UnknownFieldSet.
 TEST(PreserveUnknownEnumTest, PreserveParseAndSerialize) {
-  proto2_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
+  proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
   FillMessage(&orig_message);
   string serialized;
   orig_message.SerializeToString(&serialized);
 
-  proto2_preserve_unknown_enum_unittest::MyMessage message;
+  proto3_preserve_unknown_enum_unittest::MyMessage message;
   EXPECT_EQ(true, message.ParseFromString(serialized));
   CheckMessage(message);
 
@@ -105,13 +115,13 @@
 // Test that reflection based implementation also keeps unknown enum values and
 // doesn't put them into UnknownFieldSet.
 TEST(PreserveUnknownEnumTest, PreserveParseAndSerializeDynamicMessage) {
-  proto2_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
+  proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
   FillMessage(&orig_message);
   string serialized = orig_message.SerializeAsString();
 
   google::protobuf::DynamicMessageFactory factory;
   google::protobuf::scoped_ptr<google::protobuf::Message> message(factory.GetPrototype(
-      proto2_preserve_unknown_enum_unittest::MyMessage::descriptor())->New());
+      proto3_preserve_unknown_enum_unittest::MyMessage::descriptor())->New());
   EXPECT_EQ(true, message->ParseFromString(serialized));
   message->DiscardUnknownFields();
 
@@ -120,15 +130,62 @@
   CheckMessage(orig_message);
 }
 
-// Test that reflection provides EnumValueDescriptors for unknown values.
-TEST(PreserveUnknownEnumTest, DynamicEnumValueDescriptors) {
-  proto2_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
+// Test that for proto2 messages, unknown values are in unknown fields.
+TEST(PreserveUnknownEnumTest, Proto2HidesUnknownValues) {
+  proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
   FillMessage(&orig_message);
+
   string serialized;
   orig_message.SerializeToString(&serialized);
 
   proto2_preserve_unknown_enum_unittest::MyMessage message;
   EXPECT_EQ(true, message.ParseFromString(serialized));
+  // The intermediate message has everything in its "unknown fields".
+  proto2_preserve_unknown_enum_unittest::MyMessage message2 = message;
+  message2.DiscardUnknownFields();
+  EXPECT_EQ(0, message2.ByteSize());
+
+  // But when we pass it to the correct structure, all values are there.
+  serialized.clear();
+  message.SerializeToString(&serialized);
+  EXPECT_EQ(true, orig_message.ParseFromString(serialized));
+  CheckMessage(orig_message);
+}
+
+// Same as before, for a dynamic message.
+TEST(PreserveUnknownEnumTest, DynamicProto2HidesUnknownValues) {
+  proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
+  FillMessage(&orig_message);
+
+  string serialized;
+  orig_message.SerializeToString(&serialized);
+
+  google::protobuf::DynamicMessageFactory factory;
+  google::protobuf::scoped_ptr<google::protobuf::Message> message(factory.GetPrototype(
+      proto2_preserve_unknown_enum_unittest::MyMessage::descriptor())->New());
+  EXPECT_EQ(true, message->ParseFromString(serialized));
+  // The intermediate message has everything in its "unknown fields".
+  proto2_preserve_unknown_enum_unittest::MyMessage message2;
+  message2.CopyFrom(*message);
+  message2.DiscardUnknownFields();
+  EXPECT_EQ(0, message2.ByteSize());
+
+  // But when we pass it to the correct structure, all values are there.
+  serialized.clear();
+  message->SerializeToString(&serialized);
+  EXPECT_EQ(true, orig_message.ParseFromString(serialized));
+  CheckMessage(orig_message);
+}
+
+// Test that reflection provides EnumValueDescriptors for unknown values.
+TEST(PreserveUnknownEnumTest, DynamicEnumValueDescriptors) {
+  proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
+  FillMessage(&orig_message);
+  string serialized;
+  orig_message.SerializeToString(&serialized);
+
+  proto3_preserve_unknown_enum_unittest::MyMessage message;
+  EXPECT_EQ(true, message.ParseFromString(serialized));
   CheckMessage(message);
 
   const google::protobuf::Reflection* r = message.GetReflection();
@@ -138,7 +195,7 @@
   // This should dynamically create an EnumValueDescriptor.
   const google::protobuf::EnumValueDescriptor* enum_value = r->GetEnum(message, field);
   EXPECT_EQ(enum_value->number(),
-            static_cast<int>(proto2_preserve_unknown_enum_unittest::E_EXTRA));
+            static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA));
 
   // Fetching value for a second time should return the same pointer.
   const google::protobuf::EnumValueDescriptor* enum_value_second =
@@ -150,7 +207,7 @@
       d->FindFieldByName("repeated_e");
   enum_value = r->GetRepeatedEnum(message, repeated_field, 0);
   EXPECT_EQ(enum_value->number(),
-            static_cast<int>(proto2_preserve_unknown_enum_unittest::E_EXTRA));
+            static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA));
   // Should reuse the same EnumValueDescriptor, even for a different field.
   EXPECT_EQ(enum_value, enum_value_second);
 
@@ -164,7 +221,7 @@
 
 // Test that the new integer-based enum reflection API works.
 TEST(PreserveUnknownEnumTest, IntegerEnumReflectionAPI) {
-  proto2_preserve_unknown_enum_unittest::MyMessage message;
+  proto3_preserve_unknown_enum_unittest::MyMessage message;
   const google::protobuf::Reflection* r = message.GetReflection();
   const google::protobuf::Descriptor* d = message.GetDescriptor();
 
@@ -220,7 +277,7 @@
 
 TEST(PreserveUnknownEnumTest, SupportsUnknownEnumValuesAPI) {
   protobuf_unittest::TestAllTypes proto2_message;
-  proto2_preserve_unknown_enum_unittest::MyMessage new_message;
+  proto3_preserve_unknown_enum_unittest::MyMessage new_message;
 
   const google::protobuf::Reflection* proto2_reflection = proto2_message.GetReflection();
   const google::protobuf::Reflection* new_reflection = new_message.GetReflection();
diff --git a/src/google/protobuf/reflection.h b/src/google/protobuf/reflection.h
old mode 100644
new mode 100755
index 17d89a1..03c761c
--- a/src/google/protobuf/reflection.h
+++ b/src/google/protobuf/reflection.h
@@ -33,6 +33,11 @@
 #ifndef GOOGLE_PROTOBUF_REFLECTION_H__
 #define GOOGLE_PROTOBUF_REFLECTION_H__
 
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+
 #include <google/protobuf/message.h>
 
 namespace google {
@@ -223,7 +228,7 @@
   const Message* default_instance_;
 };
 
-// MutableRepeatedFieldRef definition for non-message types.
+// MutableRepeatedFieldRef definition for message types.
 template<typename T>
 class MutableRepeatedFieldRef<
     T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
@@ -297,10 +302,298 @@
   const AccessorType* accessor_;
   const Message* default_instance_;
 };
+
+namespace internal {
+// Interfaces used to implement reflection RepeatedFieldRef API.
+// Reflection::GetRepeatedAccessor() should return a pointer to an singleton
+// object that implements the below interface.
+//
+// This interface passes/returns values using void pointers. The actual type
+// of the value depends on the field's cpp_type. Following is a mapping from
+// cpp_type to the type that should be used in this interface:
+//
+//   field->cpp_type()      T                Actual type of void*
+//   CPPTYPE_INT32        int32                   int32
+//   CPPTYPE_UINT32       uint32                  uint32
+//   CPPTYPE_INT64        int64                   int64
+//   CPPTYPE_UINT64       uint64                  uint64
+//   CPPTYPE_DOUBLE       double                  double
+//   CPPTYPE_FLOAT        float                   float
+//   CPPTYPE_BOOL         bool                    bool
+//   CPPTYPE_ENUM         generated enum type     int32
+//   CPPTYPE_STRING       string                  string
+//   CPPTYPE_MESSAGE      generated message type  google::protobuf::Message
+//                        or google::protobuf::Message
+//
+// Note that for enums we use int32 in the interface.
+//
+// You can map from T to the actual type using RefTypeTraits:
+//   typedef RefTypeTraits<T>::AccessorValueType ActualType;
+class LIBPROTOBUF_EXPORT RepeatedFieldAccessor {
+ public:
+  // Typedefs for clarity.
+  typedef void Field;
+  typedef void Value;
+  typedef void Iterator;
+
+  virtual ~RepeatedFieldAccessor();
+  virtual bool IsEmpty(const Field* data) const = 0;
+  virtual int Size(const Field* data) const = 0;
+  // Depends on the underlying representation of the repeated field, this
+  // method can return a pointer to the underlying object if such an object
+  // exists, or fill the data into scratch_space and return scratch_space.
+  // Callers of this method must ensure scratch_space is a valid pointer
+  // to a mutable object of the correct type.
+  virtual const Value* Get(
+      const Field* data, int index, Value* scratch_space) const = 0;
+
+  virtual void Clear(Field* data) const = 0;
+  virtual void Set(Field* data, int index, const Value* value) const = 0;
+  virtual void Add(Field* data, const Value* value) const = 0;
+  virtual void RemoveLast(Field* data) const = 0;
+  virtual void SwapElements(Field* data, int index1, int index2) const = 0;
+  virtual void Swap(Field* data, const RepeatedFieldAccessor* other_mutator,
+                    Field* other_data) const = 0;
+
+  // Create an iterator that points at the begining of the repeated field.
+  virtual Iterator* BeginIterator(const Field* data) const = 0;
+  // Create an iterator that points at the end of the repeated field.
+  virtual Iterator* EndIterator(const Field* data) const = 0;
+  // Make a copy of an iterator and return the new copy.
+  virtual Iterator* CopyIterator(const Field* data,
+                                 const Iterator* iterator) const = 0;
+  // Move an iterator to point to the next element.
+  virtual Iterator* AdvanceIterator(const Field* data,
+                                    Iterator* iterator) const = 0;
+  // Compare whether two iterators point to the same element.
+  virtual bool EqualsIterator(const Field* data, const Iterator* a,
+                              const Iterator* b) const = 0;
+  // Delete an iterator created by BeginIterator(), EndIterator() and
+  // CopyIterator().
+  virtual void DeleteIterator(const Field* data, Iterator* iterator) const = 0;
+  // Like Get() but for iterators.
+  virtual const Value* GetIteratorValue(const Field* data,
+                                        const Iterator* iterator,
+                                        Value* scratch_space) const = 0;
+
+  // Templated methods that make using this interface easier for non-message
+  // types.
+  template<typename T>
+  T Get(const Field* data, int index) const {
+    typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
+    ActualType scratch_space;
+    return static_cast<T>(
+        *reinterpret_cast<const ActualType*>(
+            Get(data, index, static_cast<Value*>(&scratch_space))));
+  }
+
+  template<typename T, typename ValueType>
+  void Set(Field* data, int index, const ValueType& value) const {
+    typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
+    // In this RepeatedFieldAccessor interface we pass/return data using
+    // raw pointers. Type of the data these raw pointers point to should
+    // be ActualType. Here we have a ValueType object and want a ActualType
+    // pointer. We can't cast a ValueType pointer to an ActualType pointer
+    // directly because their type might be different (for enums ValueType
+    // may be a generated enum type while ActualType is int32). To be safe
+    // we make a copy to get a temporary ActualType object and use it.
+    ActualType tmp = static_cast<ActualType>(value);
+    Set(data, index, static_cast<const Value*>(&tmp));
+  }
+
+  template<typename T, typename ValueType>
+  void Add(Field* data, const ValueType& value) const {
+    typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
+    // In this RepeatedFieldAccessor interface we pass/return data using
+    // raw pointers. Type of the data these raw pointers point to should
+    // be ActualType. Here we have a ValueType object and want a ActualType
+    // pointer. We can't cast a ValueType pointer to an ActualType pointer
+    // directly because their type might be different (for enums ValueType
+    // may be a generated enum type while ActualType is int32). To be safe
+    // we make a copy to get a temporary ActualType object and use it.
+    ActualType tmp = static_cast<ActualType>(value);
+    Add(data, static_cast<const Value*>(&tmp));
+  }
+};
+
+// Implement (Mutable)RepeatedFieldRef::iterator
+template<typename T>
+class RepeatedFieldRefIterator
+    : public std::iterator<std::forward_iterator_tag, T> {
+  typedef typename RefTypeTraits<T>::AccessorValueType AccessorValueType;
+  typedef typename RefTypeTraits<T>::IteratorValueType IteratorValueType;
+  typedef typename RefTypeTraits<T>::IteratorPointerType IteratorPointerType;
+
+ public:
+  // Constructor for non-message fields.
+  RepeatedFieldRefIterator(const void* data,
+                           const RepeatedFieldAccessor* accessor,
+                           bool begin)
+      : data_(data), accessor_(accessor),
+        iterator_(begin ? accessor->BeginIterator(data) :
+                          accessor->EndIterator(data)),
+        scratch_space_(new AccessorValueType) {
+  }
+  // Constructor for message fields.
+  RepeatedFieldRefIterator(const void* data,
+                           const RepeatedFieldAccessor* accessor,
+                           bool begin,
+                           AccessorValueType* scratch_space)
+      : data_(data), accessor_(accessor),
+        iterator_(begin ? accessor->BeginIterator(data) :
+                          accessor->EndIterator(data)),
+        scratch_space_(scratch_space) {
+  }
+  ~RepeatedFieldRefIterator() {
+    accessor_->DeleteIterator(data_, iterator_);
+  }
+  RepeatedFieldRefIterator operator++(int) {
+    RepeatedFieldRefIterator tmp(*this);
+    iterator_ = accessor_->AdvanceIterator(data_, iterator_);
+    return tmp;
+  }
+  RepeatedFieldRefIterator& operator++() {
+    iterator_ = accessor_->AdvanceIterator(data_, iterator_);
+    return *this;
+  }
+  IteratorValueType operator*() const {
+    return static_cast<IteratorValueType>(
+        *static_cast<const AccessorValueType*>(
+            accessor_->GetIteratorValue(
+                data_, iterator_, scratch_space_.get())));
+  }
+  IteratorPointerType operator->() const {
+    return static_cast<IteratorPointerType>(
+        accessor_->GetIteratorValue(
+            data_, iterator_, scratch_space_.get()));
+  }
+  bool operator!=(const RepeatedFieldRefIterator& other) const {
+    assert(data_ == other.data_);
+    assert(accessor_ == other.accessor_);
+    return !accessor_->EqualsIterator(data_, iterator_, other.iterator_);
+  }
+  bool operator==(const RepeatedFieldRefIterator& other) const {
+    return !this->operator!=(other);
+  }
+
+  RepeatedFieldRefIterator(const RepeatedFieldRefIterator& other)
+      : data_(other.data_), accessor_(other.accessor_),
+        iterator_(accessor_->CopyIterator(data_, other.iterator_)) {
+  }
+  RepeatedFieldRefIterator& operator=(const RepeatedFieldRefIterator& other) {
+    if (this != &other) {
+      accessor_->DeleteIterator(data_, iterator_);
+      data_ = other.data_;
+      accessor_ = other.accessor_;
+      iterator_ = accessor_->CopyIterator(data_, other.iterator_);
+    }
+    return *this;
+  }
+
+ protected:
+  const void* data_;
+  const RepeatedFieldAccessor* accessor_;
+  void* iterator_;
+  google::protobuf::scoped_ptr<AccessorValueType> scratch_space_;
+};
+
+// TypeTraits that maps the type parameter T of RepeatedFieldRef or
+// MutableRepeatedFieldRef to corresponding iterator type,
+// RepeatedFieldAccessor type, etc.
+template<typename T>
+struct PrimitiveTraits {
+  static const bool is_primitive = false;
+};
+#define DEFINE_PRIMITIVE(TYPE, type) \
+    template<> struct PrimitiveTraits<type> { \
+      static const bool is_primitive = true; \
+      static const FieldDescriptor::CppType cpp_type = \
+          FieldDescriptor::CPPTYPE_ ## TYPE; \
+    };
+DEFINE_PRIMITIVE(INT32, int32)
+DEFINE_PRIMITIVE(UINT32, uint32)
+DEFINE_PRIMITIVE(INT64, int64)
+DEFINE_PRIMITIVE(UINT64, uint64)
+DEFINE_PRIMITIVE(FLOAT, float)
+DEFINE_PRIMITIVE(DOUBLE, double)
+DEFINE_PRIMITIVE(BOOL, bool)
+#undef DEFINE_PRIMITIVE
+
+template<typename T>
+struct RefTypeTraits<
+    T, typename internal::enable_if<PrimitiveTraits<T>::is_primitive>::type> {
+  typedef RepeatedFieldRefIterator<T> iterator;
+  typedef RepeatedFieldAccessor AccessorType;
+  typedef T AccessorValueType;
+  typedef T IteratorValueType;
+  typedef T* IteratorPointerType;
+  static const FieldDescriptor::CppType cpp_type =
+      PrimitiveTraits<T>::cpp_type;
+  static const Descriptor* GetMessageFieldDescriptor() {
+    return NULL;
+  }
+};
+
+template<typename T>
+struct RefTypeTraits<
+    T, typename internal::enable_if<is_proto_enum<T>::value>::type> {
+  typedef RepeatedFieldRefIterator<T> iterator;
+  typedef RepeatedFieldAccessor AccessorType;
+  // We use int32 for repeated enums in RepeatedFieldAccessor.
+  typedef int32 AccessorValueType;
+  typedef T IteratorValueType;
+  typedef int32* IteratorPointerType;
+  static const FieldDescriptor::CppType cpp_type =
+      FieldDescriptor::CPPTYPE_ENUM;
+  static const Descriptor* GetMessageFieldDescriptor() {
+    return NULL;
+  }
+};
+
+template<typename T>
+struct RefTypeTraits<
+    T, typename internal::enable_if<internal::is_same<string, T>::value>::type> {
+  typedef RepeatedFieldRefIterator<T> iterator;
+  typedef RepeatedFieldAccessor AccessorType;
+  typedef string AccessorValueType;
+  typedef string IteratorValueType;
+  typedef string* IteratorPointerType;
+  static const FieldDescriptor::CppType cpp_type =
+      FieldDescriptor::CPPTYPE_STRING;
+  static const Descriptor* GetMessageFieldDescriptor() {
+    return NULL;
+  }
+};
+
+template<typename T>
+struct MessageDescriptorGetter {
+  static const Descriptor* get() {
+    return T::default_instance().GetDescriptor();
+  }
+};
+template<>
+struct MessageDescriptorGetter<Message> {
+  static const Descriptor* get() {
+    return NULL;
+  }
+};
+
+template<typename T>
+struct RefTypeTraits<
+    T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
+  typedef RepeatedFieldRefIterator<T> iterator;
+  typedef RepeatedFieldAccessor AccessorType;
+  typedef Message AccessorValueType;
+  typedef const T& IteratorValueType;
+  typedef const T* IteratorPointerType;
+  static const FieldDescriptor::CppType cpp_type =
+      FieldDescriptor::CPPTYPE_MESSAGE;
+  static const Descriptor* GetMessageFieldDescriptor() {
+    return MessageDescriptorGetter<T>::get();
+  }
+};
+}  // namespace internal
 }  // namespace protobuf
 }  // namespace google
 
-// Implementation details for (Mutable)RepeatedFieldRef.
-#include <google/protobuf/repeated_field_reflection.h>
-
 #endif  // GOOGLE_PROTOBUF_REFLECTION_H__
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index 4798eed..f5f5d3f 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -2264,7 +2264,7 @@
 
 // Iterators and helper functions that follow the spirit of the STL
 // std::back_insert_iterator and std::back_inserter but are tailor-made
-// for RepeatedField and RepatedPtrField. Typical usage would be:
+// for RepeatedField and RepeatedPtrField. Typical usage would be:
 //
 //   std::copy(some_sequence.begin(), some_sequence.end(),
 //             google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence()));
diff --git a/src/google/protobuf/repeated_field_reflection_unittest.cc b/src/google/protobuf/repeated_field_reflection_unittest.cc
index 8b82180..fcebe5c 100644
--- a/src/google/protobuf/repeated_field_reflection_unittest.cc
+++ b/src/google/protobuf/repeated_field_reflection_unittest.cc
@@ -410,6 +410,7 @@
   EXPECT_TRUE(mrf_message.empty());
 
 #ifdef PROTOBUF_HAS_DEATH_TEST
+
   // Make sure types are checked correctly at runtime.
   const FieldDescriptor* fd_optional_int32 =
       desc->FindFieldByName("optional_int32");
@@ -419,6 +420,7 @@
       message, fd_repeated_int32), "");
   EXPECT_DEATH(refl->GetRepeatedFieldRef<TestAllTypes>(
       message, fd_repeated_foreign_message), "");
+
 #endif  // PROTOBUF_HAS_DEATH_TEST
 }
 
diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc
index 15c0c93..66e7452 100644
--- a/src/google/protobuf/repeated_field_unittest.cc
+++ b/src/google/protobuf/repeated_field_unittest.cc
@@ -1131,7 +1131,7 @@
 
   string v = "f";
   RepeatedPtrField<string>::const_iterator it =
-      lower_bound(proto_array_.begin(), proto_array_.end(), v);
+      std::lower_bound(proto_array_.begin(), proto_array_.end(), v);
 
   EXPECT_EQ(*it, "n");
   EXPECT_TRUE(it == proto_array_.begin() + 3);
@@ -1292,8 +1292,8 @@
   {
     string v = "f";
     RepeatedPtrField<string>::pointer_iterator it =
-        lower_bound(proto_array_.pointer_begin(), proto_array_.pointer_end(),
-                    &v, StringLessThan());
+        std::lower_bound(proto_array_.pointer_begin(),
+                         proto_array_.pointer_end(), &v, StringLessThan());
 
     GOOGLE_CHECK(*it != NULL);
 
@@ -1302,10 +1302,9 @@
   }
   {
     string v = "f";
-    RepeatedPtrField<string>::const_pointer_iterator it =
-        lower_bound(const_proto_array_->pointer_begin(),
-                    const_proto_array_->pointer_end(),
-                    &v, StringLessThan());
+    RepeatedPtrField<string>::const_pointer_iterator it = std::lower_bound(
+        const_proto_array_->pointer_begin(), const_proto_array_->pointer_end(),
+        &v, StringLessThan());
 
     GOOGLE_CHECK(*it != NULL);
 
@@ -1343,9 +1342,8 @@
   EXPECT_EQ("foo", proto_array_.Get(0));
   EXPECT_EQ("n", proto_array_.Get(5));
   EXPECT_EQ("x", proto_array_.Get(9));
-  sort(proto_array_.pointer_begin(),
-       proto_array_.pointer_end(),
-       StringLessThan());
+  std::sort(proto_array_.pointer_begin(), proto_array_.pointer_end(),
+            StringLessThan());
   EXPECT_EQ("a", proto_array_.Get(0));
   EXPECT_EQ("baz", proto_array_.Get(2));
   EXPECT_EQ("y", proto_array_.Get(9));
@@ -1478,9 +1476,9 @@
     new_data->set_bb(i);
   }
   TestAllTypes testproto;
-  copy(data.begin(), data.end(),
-       AllocatedRepeatedPtrFieldBackInserter(
-           testproto.mutable_repeated_nested_message()));
+  std::copy(data.begin(), data.end(),
+            AllocatedRepeatedPtrFieldBackInserter(
+                testproto.mutable_repeated_nested_message()));
   EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
 }
 
@@ -1497,9 +1495,8 @@
     *new_data = "name-" + SimpleItoa(i);
   }
   TestAllTypes testproto;
-  copy(data.begin(), data.end(),
-       AllocatedRepeatedPtrFieldBackInserter(
-           testproto.mutable_repeated_string()));
+  std::copy(data.begin(), data.end(), AllocatedRepeatedPtrFieldBackInserter(
+                                          testproto.mutable_repeated_string()));
   EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
 }
 
diff --git a/src/google/protobuf/struct.proto b/src/google/protobuf/struct.proto
new file mode 100644
index 0000000..9f27eb4
--- /dev/null
+++ b/src/google/protobuf/struct.proto
@@ -0,0 +1,83 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+syntax = "proto3";
+
+package google.protobuf;
+
+option java_generate_equals_and_hash = true;
+option java_multiple_files = true;
+option java_outer_classname = "StructProto";
+option java_package = "com.google.protobuf";
+
+
+// `Struct` represents a structured data value, consisting of fields
+// which map to dynamically typed values. In some languages, `Struct`
+// might be supported by a native representation. For example, in
+// scripting languages like JS a struct is represented as an
+// object. The details of that representation are described together
+// with the proto support for the language.
+message Struct {
+  // Map of dynamically typed values.
+  map<string, Value> fields = 1;
+}
+
+// `Value` represents a dynamically typed value which can be either
+// null, a number, a string, a boolean, a recursive struct value, or a
+// list of values. A producer of value is expected to set one of that
+// variants, absence of any variant indicates an error.
+message Value {
+  oneof kind {
+    // Represents a null value.
+    NullValue null_value = 1;
+    // Represents a double value.
+    double number_value = 2;
+    // Represents a string value.
+    string string_value = 3;
+    // Represents a boolean value.
+    bool bool_value = 4;
+    // Represents a structured value.
+    Struct struct_value = 5;
+    // Represents a repeated `Value`.
+    ListValue list_value = 6;
+  }
+}
+
+// `NullValue` is a singleton enumeration to represent the null
+// value for the `Value` type union.
+enum NullValue {
+  // Null value.
+  NULL_VALUE = 0;
+}
+
+// `ListValue` is a wrapper around a repeated field of values.
+message ListValue {
+  // Repeated field of dynamically typed values.
+  repeated Value values = 1;
+}
diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h
old mode 100644
new mode 100755
index badcb6a..82d5052
--- a/src/google/protobuf/stubs/hash.h
+++ b/src/google/protobuf/stubs/hash.h
@@ -89,15 +89,17 @@
 
 template <typename Key, typename Data,
           typename HashFcn = hash<Key>,
-          typename EqualKey = int >
-class hash_map : public std::map<Key, Data, HashFcn> {
+          typename EqualKey = std::equal_to<Key>,
+          typename Alloc = std::allocator< std::pair<const Key, Data> > >
+class hash_map : public std::map<Key, Data, HashFcn, EqualKey, Alloc> {
  public:
-  hash_map(int = 0) {}
+  hash_map(int = 0, const HashFcn& = HashFcn(), const EqualKey& = EqualKey(),
+           const Alloc& = Alloc()) {}
 };
 
 template <typename Key,
           typename HashFcn = hash<Key>,
-          typename EqualKey = int >
+          typename EqualKey = std::equal_to<Key> >
 class hash_set : public std::set<Key, HashFcn> {
  public:
   hash_set(int = 0) {}
@@ -125,18 +127,21 @@
 
 template <typename Key, typename Data,
           typename HashFcn = hash<Key>,
-          typename EqualKey = int >
-class hash_map : public GOOGLE_PROTOBUF_HASH_NAMESPACE::hash_map<
-    Key, Data, HashFcn> {
+          typename EqualKey = std::equal_to<Key>,
+          typename Alloc = std::allocator< std::pair<const Key, Data> > >
+class hash_map
+    : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
+          Key, Data, HashFcn, EqualKey, Alloc> {
  public:
-  hash_map(int = 0) {}
+  hash_map(int = 0, const HashFcn& = HashFcn(), const EqualKey& = EqualKey(),
+           const Alloc& = Alloc()) {}
 };
 
-template <typename Key,
-          typename HashFcn = hash<Key>,
-          typename EqualKey = int >
-class hash_set : public GOOGLE_PROTOBUF_HASH_NAMESPACE::hash_set<
-    Key, HashFcn> {
+template <typename Key, typename HashFcn = hash<Key>,
+          typename EqualKey = std::equal_to<Key> >
+class hash_set
+    : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS<
+          Key, HashFcn, EqualKey> {
  public:
   hash_set(int = 0) {}
 };
@@ -167,13 +172,16 @@
   }
 };
 
-template <typename Key, typename Data, typename HashFcn = hash<Key>,
-          typename EqualKey = std::equal_to<Key> >
+template <typename Key, typename Data,
+          typename HashFcn = hash<Key>,
+          typename EqualKey = std::equal_to<Key>,
+          typename Alloc = std::allocator< std::pair<const Key, Data> > >
 class hash_map
     : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
-          Key, Data, HashFcn, EqualKey> {
+          Key, Data, HashFcn, EqualKey, Alloc> {
  public:
-  hash_map(int = 0) {}
+  hash_map(int = 0, const HashFcn& = HashFcn(), const EqualKey& = EqualKey(),
+           const Alloc& = Alloc()) {}
 };
 
 template <typename Key, typename HashFcn = hash<Key>,
diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc
index 86d4568..7955d26 100644
--- a/src/google/protobuf/stubs/strutil.cc
+++ b/src/google/protobuf/stubs/strutil.cc
@@ -1303,6 +1303,211 @@
   return string(bufptr, buf + 16 - bufptr);
 }
 
+namespace strings {
+
+AlphaNum::AlphaNum(strings::Hex hex) {
+  char *const end = &digits[kFastToBufferSize];
+  char *writer = end;
+  uint64 value = hex.value;
+  uint64 width = hex.spec;
+  // We accomplish minimum width by OR'ing in 0x10000 to the user's value,
+  // where 0x10000 is the smallest hex number that is as wide as the user
+  // asked for.
+  uint64 mask = ((static_cast<uint64>(1) << (width - 1) * 4)) | value;
+  static const char hexdigits[] = "0123456789abcdef";
+  do {
+    *--writer = hexdigits[value & 0xF];
+    value >>= 4;
+    mask >>= 4;
+  } while (mask != 0);
+  piece_data_ = writer;
+  piece_size_ = end - writer;
+}
+
+}  // namespace strings
+
+// ----------------------------------------------------------------------
+// StrCat()
+//    This merges the given strings or integers, with no delimiter.  This
+//    is designed to be the fastest possible way to construct a string out
+//    of a mix of raw C strings, C++ strings, and integer values.
+// ----------------------------------------------------------------------
+
+// Append is merely a version of memcpy that returns the address of the byte
+// after the area just overwritten.  It comes in multiple flavors to minimize
+// call overhead.
+static char *Append1(char *out, const AlphaNum &x) {
+  memcpy(out, x.data(), x.size());
+  return out + x.size();
+}
+
+static char *Append2(char *out, const AlphaNum &x1, const AlphaNum &x2) {
+  memcpy(out, x1.data(), x1.size());
+  out += x1.size();
+
+  memcpy(out, x2.data(), x2.size());
+  return out + x2.size();
+}
+
+static char *Append4(char *out,
+                     const AlphaNum &x1, const AlphaNum &x2,
+                     const AlphaNum &x3, const AlphaNum &x4) {
+  memcpy(out, x1.data(), x1.size());
+  out += x1.size();
+
+  memcpy(out, x2.data(), x2.size());
+  out += x2.size();
+
+  memcpy(out, x3.data(), x3.size());
+  out += x3.size();
+
+  memcpy(out, x4.data(), x4.size());
+  return out + x4.size();
+}
+
+string StrCat(const AlphaNum &a, const AlphaNum &b) {
+  string result;
+  result.resize(a.size() + b.size());
+  char *const begin = &*result.begin();
+  char *out = Append2(begin, a, b);
+  GOOGLE_DCHECK_EQ(out, begin + result.size());
+  return result;
+}
+
+string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) {
+  string result;
+  result.resize(a.size() + b.size() + c.size());
+  char *const begin = &*result.begin();
+  char *out = Append2(begin, a, b);
+  out = Append1(out, c);
+  GOOGLE_DCHECK_EQ(out, begin + result.size());
+  return result;
+}
+
+string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+              const AlphaNum &d) {
+  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);
+  GOOGLE_DCHECK_EQ(out, begin + result.size());
+  return result;
+}
+
+string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+              const AlphaNum &d, const AlphaNum &e) {
+  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);
+  out = Append1(out, e);
+  GOOGLE_DCHECK_EQ(out, begin + result.size());
+  return result;
+}
+
+string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+              const AlphaNum &d, const AlphaNum &e, const AlphaNum &f) {
+  string result;
+  result.resize(a.size() + b.size() + c.size() + d.size() + e.size() +
+                f.size());
+  char *const begin = &*result.begin();
+  char *out = Append4(begin, a, b, c, d);
+  out = Append2(out, e, f);
+  GOOGLE_DCHECK_EQ(out, begin + result.size());
+  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;
+  result.resize(a.size() + b.size() + c.size() + d.size() + e.size() +
+                f.size() + g.size());
+  char *const begin = &*result.begin();
+  char *out = Append4(begin, a, b, c, d);
+  out = Append2(out, e, f);
+  out = Append1(out, g);
+  GOOGLE_DCHECK_EQ(out, begin + result.size());
+  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;
+  result.resize(a.size() + b.size() + c.size() + d.size() + e.size() +
+                f.size() + g.size() + h.size());
+  char *const begin = &*result.begin();
+  char *out = Append4(begin, a, b, c, d);
+  out = Append4(out, e, f, g, h);
+  GOOGLE_DCHECK_EQ(out, begin + result.size());
+  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;
+  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();
+  char *out = Append4(begin, a, b, c, d);
+  out = Append4(out, e, f, g, h);
+  out = Append1(out, i);
+  GOOGLE_DCHECK_EQ(out, begin + result.size());
+  return result;
+}
+
+// It's possible to call StrAppend with a char * pointer that is partway into
+// the string we're appending to.  However the results of this are random.
+// Therefore, check for this in debug mode.  Use unsigned math so we only have
+// to do one comparison.
+#define GOOGLE_DCHECK_NO_OVERLAP(dest, src) \
+    GOOGLE_DCHECK_GT(uintptr_t((src).data() - (dest).data()), \
+                     uintptr_t((dest).size()))
+
+void StrAppend(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) {
+  GOOGLE_DCHECK_NO_OVERLAP(*result, a);
+  GOOGLE_DCHECK_NO_OVERLAP(*result, b);
+  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) {
+  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();
+  result->resize(old_size + a.size() + b.size() + c.size());
+  char *const begin = &*result->begin();
+  char *out = Append2(begin + old_size, a, b);
+  out = Append1(out, c);
+  GOOGLE_DCHECK_EQ(out, begin + result->size());
+}
+
+void StrAppend(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();
+  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) {
diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h
index f2e1a94..920701e 100644
--- a/src/google/protobuf/stubs/strutil.h
+++ b/src/google/protobuf/stubs/strutil.h
@@ -495,57 +495,168 @@
 static const int kDoubleToBufferSize = 32;
 static const int kFloatToBufferSize = 24;
 
-// ----------------------------------------------------------------------
-// ToString() are internal help methods used in StrCat() and Join()
-// ----------------------------------------------------------------------
-namespace internal {
-inline string ToString(int i) {
-  return SimpleItoa(i);
-}
+namespace strings {
 
-inline string ToString(string a) {
-  return a;
-}
-}  // namespace internal
+struct Hex {
+  uint64 value;
+  enum PadSpec {
+    NONE = 1,
+    ZERO_PAD_2,
+    ZERO_PAD_3,
+    ZERO_PAD_4,
+    ZERO_PAD_5,
+    ZERO_PAD_6,
+    ZERO_PAD_7,
+    ZERO_PAD_8,
+    ZERO_PAD_9,
+    ZERO_PAD_10,
+    ZERO_PAD_11,
+    ZERO_PAD_12,
+    ZERO_PAD_13,
+    ZERO_PAD_14,
+    ZERO_PAD_15,
+    ZERO_PAD_16,
+  } spec;
+  template <class Int>
+  explicit Hex(Int v, PadSpec s = NONE)
+      : spec(s) {
+    // Prevent sign-extension by casting integers to
+    // their unsigned counterparts.
+#ifdef LANG_CXX11
+    static_assert(
+        sizeof(v) == 1 || sizeof(v) == 2 || sizeof(v) == 4 || sizeof(v) == 8,
+        "Unknown integer type");
+#endif
+    value = sizeof(v) == 1 ? static_cast<uint8>(v)
+          : sizeof(v) == 2 ? static_cast<uint16>(v)
+          : sizeof(v) == 4 ? static_cast<uint32>(v)
+          : static_cast<uint64>(v);
+  }
+};
+
+struct AlphaNum {
+  const char *piece_data_;  // move these to string_ref eventually
+  size_t piece_size_;       // move these to string_ref eventually
+
+  char digits[kFastToBufferSize];
+
+  // No bool ctor -- bools convert to an integral type.
+  // A bool ctor would also convert incoming pointers (bletch).
+
+  AlphaNum(int32 i32)
+      : piece_data_(digits),
+        piece_size_(FastInt32ToBufferLeft(i32, digits) - &digits[0]) {}
+  AlphaNum(uint32 u32)
+      : piece_data_(digits),
+        piece_size_(FastUInt32ToBufferLeft(u32, digits) - &digits[0]) {}
+  AlphaNum(int64 i64)
+      : piece_data_(digits),
+        piece_size_(FastInt64ToBufferLeft(i64, digits) - &digits[0]) {}
+  AlphaNum(uint64 u64)
+      : piece_data_(digits),
+        piece_size_(FastUInt64ToBufferLeft(u64, digits) - &digits[0]) {}
+
+  AlphaNum(float f)
+    : piece_data_(digits), piece_size_(strlen(FloatToBuffer(f, digits))) {}
+  AlphaNum(double f)
+    : piece_data_(digits), piece_size_(strlen(DoubleToBuffer(f, digits))) {}
+
+  AlphaNum(Hex hex);
+
+  AlphaNum(const char* c_str)
+      : piece_data_(c_str), piece_size_(strlen(c_str)) {}
+  // TODO: Add a string_ref constructor, eventually
+  // AlphaNum(const StringPiece &pc) : piece(pc) {}
+
+  AlphaNum(const string& str)
+      : piece_data_(str.data()), piece_size_(str.size()) {}
+
+  size_t size() const { return piece_size_; }
+  const char *data() const { return piece_data_; }
+
+ private:
+  // Use ":" not ':'
+  AlphaNum(char c);  // NOLINT(runtime/explicit)
+
+  // Disallow copy and assign.
+  AlphaNum(const AlphaNum&);
+  void operator=(const AlphaNum&);
+};
+
+}  // namespace strings
+
+using strings::AlphaNum;
 
 // ----------------------------------------------------------------------
 // StrCat()
-//    These methods join some strings together.
+//    This merges the given strings or numbers, with no delimiter.  This
+//    is designed to be the fastest possible way to construct a string out
+//    of a mix of raw C strings, strings, bool values,
+//    and numeric values.
+//
+//    Don't use this for user-visible strings.  The localization process
+//    works poorly on strings built up out of fragments.
+//
+//    For clarity and performance, don't use StrCat when appending to a
+//    string.  In particular, avoid using any of these (anti-)patterns:
+//      str.append(StrCat(...)
+//      str += StrCat(...)
+//      str = StrCat(str, ...)
+//    where the last is the worse, with the potential to change a loop
+//    from a linear time operation with O(1) dynamic allocations into a
+//    quadratic time operation with O(n) dynamic allocations.  StrAppend
+//    is a better choice than any of the above, subject to the restriction
+//    of StrAppend(&str, a, b, c, ...) that none of the a, b, c, ... may
+//    be a reference into str.
 // ----------------------------------------------------------------------
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-          typename T6, typename T7>
-string StrCat(
-    const T1& a, const T2& b, const T3& c, const T4& d, const T5& e,
-    const T6& f, const T7& g) {
-  return internal::ToString(a) + internal::ToString(b) +
-      internal::ToString(c) + internal::ToString(d) + internal::ToString(e) +
-      internal::ToString(f) + internal::ToString(g);
-}
 
-template <typename T1, typename T2, typename T3, typename T4, typename T5>
-string StrCat(
-    const T1& a, const T2& b, const T3& c, const T4& d, const T5& e) {
-  return internal::ToString(a) + internal::ToString(b) +
-      internal::ToString(c) + internal::ToString(d) + internal::ToString(e);
-}
+string StrCat(const AlphaNum &a, const AlphaNum &b);
+string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c);
+string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+              const AlphaNum &d);
+string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+              const AlphaNum &d, const AlphaNum &e);
+string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+              const AlphaNum &d, const AlphaNum &e, const AlphaNum &f);
+string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c,
+              const AlphaNum &d, const AlphaNum &e, const AlphaNum &f,
+              const AlphaNum &g);
+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 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);
 
-template <typename T1, typename T2, typename T3, typename T4>
-string StrCat(
-    const T1& a, const T2& b, const T3& c, const T4& d) {
-  return internal::ToString(a) + internal::ToString(b) +
-      internal::ToString(c) + internal::ToString(d);
-}
+inline string StrCat(const AlphaNum& a) { return string(a.data(), a.size()); }
 
-template <typename T1, typename T2, typename T3>
-string StrCat(const T1& a, const T2& b, const T3& c) {
-  return internal::ToString(a) + internal::ToString(b) +
-      internal::ToString(c);
-}
+// ----------------------------------------------------------------------
+// StrAppend()
+//    Same as above, but adds the output to the given string.
+//    WARNING: For speed, StrAppend does not try to check each of its input
+//    arguments to be sure that they are not a subset of the string being
+//    appended to.  That is, while this will work:
+//
+//    string s = "foo";
+//    s += s;
+//
+//    This will not (necessarily) work:
+//
+//    string s = "foo";
+//    StrAppend(&s, s);
+//
+//    Note: while StrCat supports appending up to 9 arguments, StrAppend
+//    is currently limited to 4.  That's rarely an issue except when
+//    automatically transforming StrCat to StrAppend, and can easily be
+//    worked around as consecutive calls to StrAppend are quite efficient.
+// ----------------------------------------------------------------------
 
-template <typename T1, typename T2>
-string StrCat(const T1& a, const T2& b) {
-  return internal::ToString(a) + internal::ToString(b);
-}
+void StrAppend(string* dest, const AlphaNum& a);
+void StrAppend(string* dest, const AlphaNum& a, const AlphaNum& b);
+void StrAppend(string* dest, const AlphaNum& a, const AlphaNum& b,
+               const AlphaNum& c);
+void StrAppend(string* dest, const AlphaNum& a, const AlphaNum& b,
+               const AlphaNum& c, const AlphaNum& d);
 
 // ----------------------------------------------------------------------
 // Join()
@@ -559,7 +670,7 @@
     if (it != start) {
       result->append(delim);
     }
-    result->append(internal::ToString(*it));
+    StrAppend(result, *it);
   }
 }
 
diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc
index 8e867c0..ec070c5 100644
--- a/src/google/protobuf/text_format.cc
+++ b/src/google/protobuf/text_format.cc
@@ -1360,9 +1360,8 @@
 bool TextFormat::Printer::RegisterFieldValuePrinter(
     const FieldDescriptor* field,
     const FieldValuePrinter* printer) {
-  return field != NULL
-      && printer != NULL
-      && custom_printers_.insert(make_pair(field, printer)).second;
+  return field != NULL && printer != NULL &&
+         custom_printers_.insert(std::make_pair(field, printer)).second;
 }
 
 bool TextFormat::Printer::PrintToString(const Message& message,
@@ -1422,7 +1421,7 @@
   vector<const FieldDescriptor*> fields;
   reflection->ListFields(message, &fields);
   if (print_message_fields_in_index_order_) {
-    sort(fields.begin(), fields.end(), FieldIndexSorter());
+    std::sort(fields.begin(), fields.end(), FieldIndexSorter());
   }
   for (int i = 0; i < fields.size(); i++) {
     PrintField(message, reflection, fields[i], generator);
diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h
index 44d68ca..9e2cb07 100644
--- a/src/google/protobuf/text_format.h
+++ b/src/google/protobuf/text_format.h
@@ -278,8 +278,20 @@
   };
 
   // Parses a text-format protocol message from the given input stream to
-  // the given message object.  This function parses the format written
-  // by Print().
+  // the given message object. This function parses the human-readable format
+  // written by Print(). Returns true on success. The message is cleared first,
+  // even if the function fails -- See Merge() to avoid this behavior.
+  //
+  // Example input: "user {\n id: 123 extra { gender: MALE language: 'en' }\n}"
+  //
+  // One use for this function is parsing handwritten strings in test code.
+  // Another use is to parse the output from google::protobuf::Message::DebugString()
+  // (or ShortDebugString()), because these functions output using
+  // google::protobuf::TextFormat::Print().
+  //
+  // If you would like to read a protocol buffer serialized in the
+  // (non-human-readable) binary wire format, see
+  // google::protobuf::MessageLite::ParseFromString().
   static bool Parse(io::ZeroCopyInputStream* input, Message* output);
   // Like Parse(), but reads directly from a string.
   static bool ParseFromString(const string& input, Message* output);
diff --git a/src/google/protobuf/timestamp.proto b/src/google/protobuf/timestamp.proto
new file mode 100644
index 0000000..ac8e009c
--- /dev/null
+++ b/src/google/protobuf/timestamp.proto
@@ -0,0 +1,103 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+syntax = "proto3";
+
+package google.protobuf;
+
+option java_generate_equals_and_hash = true;
+option java_multiple_files = true;
+option java_outer_classname = "TimestampProto";
+option java_package = "com.google.protobuf";
+
+
+// A Timestamp represents a point in time independent of any time zone
+// or calendar, represented as seconds and fractions of seconds at
+// nanosecond resolution in UTC Epoch time. It is encoded using the
+// Proleptic Gregorian Calendar which extends the Gregorian calendar
+// backwards to year one. It is encoded assuming all minutes are 60
+// seconds long, i.e. leap seconds are "smeared" so that no leap second
+// table is needed for interpretation. Range is from
+// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
+// By restricting to that range, we ensure that we can convert to
+// and from  RFC 3339 date strings. (See https://www.ietf.org/rfc/rfc3339.txt.)
+//
+// Example 1: compute Timestamp from POSIX `time()`.
+//
+//     Timestamp timestamp;
+//     timestamp.set_seconds(time(NULL));
+//     timestamp.set_nanos(0);
+//
+// Example 2: compute Timestamp from POSIX `gettimeofday()`.
+//
+//     struct timeval tv;
+//     gettimeofday(&tv, NULL);
+//
+//     Timestamp timestamp;
+//     timestamp.set_seconds(tv.tv_sec);
+//     timestamp.set_nanos(tv.tv_usec * 1000);
+//
+// Example 3: compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
+//
+//     FILETIME ft;
+//     GetSystemTimeAsFileTime(&ft);
+//     UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
+//
+//     // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
+//     // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
+//     Timestamp timestamp;
+//     timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
+//     timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
+//
+// Example 4: compute Timestamp from Java `System.currentTimeMillis()`.
+//
+//     long millis = System.currentTimeMillis();
+//
+//     Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
+//         .setNanos((int) ((millis % 1000) * 1000000)).build();
+//
+// Example 5: compute Timestamp from Python `datetime.datetime`.
+//
+//     now = datetime.datetime.utcnow()
+//     seconds = int(time.mktime(now.timetuple()))
+//     nanos = now.microsecond * 1000
+//     timestamp = Timestamp(seconds=seconds, nanos=nanos)
+//
+message Timestamp {
+  // Represents seconds of UTC time since Unix epoch
+  // 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
+  // 9999-12-31T23:59:59Z inclusive.
+  int64 seconds = 1;
+
+  // Non-negative fractions of a second at nanosecond resolution. Negative
+  // second values with fractions must still have non-negative nanos values
+  // that count forward in time. Must be from 0 to 999,999,999
+  // inclusive.
+  int32 nanos = 2;
+}
diff --git a/src/google/protobuf/unittest_no_arena.proto b/src/google/protobuf/unittest_no_arena.proto
index 1a42083..36fb865 100644
--- a/src/google/protobuf/unittest_no_arena.proto
+++ b/src/google/protobuf/unittest_no_arena.proto
@@ -113,7 +113,7 @@
   optional protobuf_unittest_import.PublicImportMessage
       optional_public_import_message = 26;
 
-  optional NestedMessage optional_lazy_message = 27 [lazy=true];
+  optional NestedMessage optional_message = 27 [lazy=true];
 
   // Repeated
   repeated    int32 repeated_int32    = 31;
@@ -180,6 +180,7 @@
     NestedMessage oneof_nested_message = 112;
     string oneof_string = 113;
     bytes oneof_bytes = 114;
+    NestedMessage lazy_oneof_nested_message = 115 [lazy=true];
   }
 }
 
diff --git a/src/google/protobuf/unittest_preserve_unknown_enum.proto b/src/google/protobuf/unittest_preserve_unknown_enum.proto
index ba050d7..67e5749 100644
--- a/src/google/protobuf/unittest_preserve_unknown_enum.proto
+++ b/src/google/protobuf/unittest_preserve_unknown_enum.proto
@@ -30,7 +30,7 @@
 
 syntax = "proto3";
 
-package proto2_preserve_unknown_enum_unittest;
+package proto3_preserve_unknown_enum_unittest;
 
 enum MyEnum {
   FOO = 0;
@@ -49,9 +49,10 @@
   optional MyEnum e = 1;
   repeated MyEnum repeated_e = 2;
   repeated MyEnum repeated_packed_e = 3 [packed=true];
+  repeated MyEnumPlusExtra repeated_packed_unexpected_e = 4;  // not packed
   oneof o {
-    MyEnum oneof_e_1 = 4;
-    MyEnum oneof_e_2 = 5;
+    MyEnum oneof_e_1 = 5;
+    MyEnum oneof_e_2 = 6;
   }
 }
 
@@ -59,8 +60,9 @@
   optional MyEnumPlusExtra e = 1;
   repeated MyEnumPlusExtra repeated_e = 2;
   repeated MyEnumPlusExtra repeated_packed_e = 3 [packed=true];
+  repeated MyEnumPlusExtra repeated_packed_unexpected_e = 4 [packed=true];
   oneof o {
-    MyEnumPlusExtra oneof_e_1 = 4;
-    MyEnumPlusExtra oneof_e_2 = 5;
+    MyEnumPlusExtra oneof_e_1 = 5;
+    MyEnumPlusExtra oneof_e_2 = 6;
   }
 }
diff --git a/src/google/protobuf/unittest_preserve_unknown_enum2.proto b/src/google/protobuf/unittest_preserve_unknown_enum2.proto
new file mode 100644
index 0000000..adf4296
--- /dev/null
+++ b/src/google/protobuf/unittest_preserve_unknown_enum2.proto
@@ -0,0 +1,50 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto2";
+
+package proto2_preserve_unknown_enum_unittest;
+
+enum MyEnum {
+  FOO = 0;
+  BAR = 1;
+  BAZ = 2;
+}
+
+message MyMessage {
+  optional MyEnum e = 1;
+  repeated MyEnum repeated_e = 2;
+  repeated MyEnum repeated_packed_e = 3 [packed=true];
+  repeated MyEnum repeated_packed_unexpected_e = 4;  // not packed
+  oneof o {
+    MyEnum oneof_e_1 = 5;
+    MyEnum oneof_e_2 = 6;
+  }
+}
diff --git a/src/google/protobuf/unknown_enum_impl.h b/src/google/protobuf/unknown_enum_impl.h
index fb5380a..39c10cb 100644
--- a/src/google/protobuf/unknown_enum_impl.h
+++ b/src/google/protobuf/unknown_enum_impl.h
@@ -99,6 +99,29 @@
 }
 
 // NOTE: You should not call these functions directly.  Instead use
+// CLEAR_UNKNOWN_ENUM(), defined in the public header.  The macro-versions
+// operate in a type-safe manner and behave appropriately for the proto
+// version of the message, whereas these versions assume a specific proto
+// version and allow the caller to pass in any arbitrary integer value as a
+// field number.
+//
+// Clears the unknown entries of the given field of the message.
+void ClearUnknownEnum(Message* message, int32 field_number);
+// In proto1, clears the field if the value is out of range.
+// TODO(karner): Delete this or make it proto2-only once the migration
+// to proto2 is complete.
+void ClearUnknownEnumProto1(Message* message, int32 field_number);
+template <typename T>
+void ClearUnknownEnum_Template(T* message, int32 field_number) {
+  if (internal::is_base_of<bridge::internal::Proto1CompatibleMessage, T>::value ||
+      !internal::is_base_of<ProtocolMessage, T>::value) {
+    ClearUnknownEnum(message, field_number);
+  } else {
+    ClearUnknownEnumProto1(message, field_number);
+  }
+}
+
+// NOTE: You should not call these functions directly.  Instead use
 // SET_UNKNOWN_ENUM(), defined in the public header.  The macro-versions
 // operate in a type-safe manner and behave appropriately for the proto
 // version of the message, whereas these versions assume a specific proto
diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h
index e8c0a13..987b197 100644
--- a/src/google/protobuf/unknown_field_set.h
+++ b/src/google/protobuf/unknown_field_set.h
@@ -222,13 +222,12 @@
   // UnknownField is being created.
   inline void SetType(Type type);
 
-  uint32 number_;
-  uint32 type_;
-
   union LengthDelimited {
     string* string_value_;
   };
 
+  uint32 number_;
+  uint32 type_;
   union {
     uint64 varint_;
     uint32 fixed32_;
diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc
index f4f0215..c5bbbf2 100644
--- a/src/google/protobuf/wire_format.cc
+++ b/src/google/protobuf/wire_format.cc
@@ -141,7 +141,7 @@
 
 bool WireFormat::SkipMessage(io::CodedInputStream* input,
                              UnknownFieldSet* unknown_fields) {
-  while(true) {
+  while (true) {
     uint32 tag = input->ReadTag();
     if (tag == 0) {
       // End of input.  This is a valid place to end, so return true.
@@ -159,6 +159,31 @@
   }
 }
 
+bool WireFormat::ReadPackedEnumPreserveUnknowns(io::CodedInputStream* input,
+                                                uint32 field_number,
+                                                bool (*is_valid)(int),
+                                                UnknownFieldSet* unknown_fields,
+                                                RepeatedField<int>* values) {
+  uint32 length;
+  if (!input->ReadVarint32(&length)) return false;
+  io::CodedInputStream::Limit limit = input->PushLimit(length);
+  while (input->BytesUntilLimit() > 0) {
+    int value;
+    if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
+        int, WireFormatLite::TYPE_ENUM>(input, &value)) {
+      return false;
+    }
+    if (is_valid == NULL || is_valid(value)) {
+      values->Add(value);
+    } else {
+      unknown_fields->AddVarint(field_number, value);
+    }
+  }
+  input->PopLimit(limit);
+  return true;
+}
+
+
 void WireFormat::SerializeUnknownFields(const UnknownFieldSet& unknown_fields,
                                         io::CodedOutputStream* output) {
   for (int i = 0; i < unknown_fields.field_count(); i++) {
@@ -520,6 +545,14 @@
                 field->enum_type()->FindValueByNumber(value);
             if (enum_value != NULL) {
               message_reflection->AddEnum(message, field, enum_value);
+            } else {
+              // The enum value is not one of the known values.  Add it to the
+              // UnknownFieldSet.
+              int64 sign_extended_value = static_cast<int64>(value);
+              message_reflection->MutableUnknownFields(message)
+                  ->AddVarint(
+                      WireFormatLite::GetTagFieldNumber(tag),
+                      sign_extended_value);
             }
           }
         }
diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h
index 9f26eb2..8de491a 100644
--- a/src/google/protobuf/wire_format.h
+++ b/src/google/protobuf/wire_format.h
@@ -138,6 +138,14 @@
   static bool SkipMessage(io::CodedInputStream* input,
                           UnknownFieldSet* unknown_fields);
 
+  // Read a packed enum field. If the is_valid function is not NULL, values for
+  // which is_valid(value) returns false are appended to unknown_fields_stream.
+  static bool ReadPackedEnumPreserveUnknowns(io::CodedInputStream* input,
+                                             uint32 field_number,
+                                             bool (*is_valid)(int),
+                                             UnknownFieldSet* unknown_fields,
+                                             RepeatedField<int>* values);
+
   // Write the contents of an UnknownFieldSet to the output.
   static void SerializeUnknownFields(const UnknownFieldSet& unknown_fields,
                                      io::CodedOutputStream* output);
diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc
index 5061655..2ce4920 100644
--- a/src/google/protobuf/wire_format_lite.cc
+++ b/src/google/protobuf/wire_format_lite.cc
@@ -304,6 +304,34 @@
   return true;
 }
 
+bool WireFormatLite::ReadPackedEnumPreserveUnknowns(
+    io::CodedInputStream* input,
+    int field_number,
+    bool (*is_valid)(int),
+    io::CodedOutputStream* unknown_fields_stream,
+    RepeatedField<int>* values) {
+  uint32 length;
+  if (!input->ReadVarint32(&length)) return false;
+  io::CodedInputStream::Limit limit = input->PushLimit(length);
+  while (input->BytesUntilLimit() > 0) {
+    int value;
+    if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
+        int, WireFormatLite::TYPE_ENUM>(input, &value)) {
+      return false;
+    }
+    if (is_valid == NULL || is_valid(value)) {
+      values->Add(value);
+    } else {
+      uint32 tag = WireFormatLite::MakeTag(field_number,
+                                           WireFormatLite::WIRETYPE_VARINT);
+      unknown_fields_stream->WriteVarint32(tag);
+      unknown_fields_stream->WriteVarint32(value);
+    }
+  }
+  input->PopLimit(limit);
+  return true;
+}
+
 void WireFormatLite::WriteInt32(int field_number, int32 value,
                                 io::CodedOutputStream* output) {
   WriteTag(field_number, WIRETYPE_VARINT, output);
diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h
index acf88ea..76bc75a 100644
--- a/src/google/protobuf/wire_format_lite.h
+++ b/src/google/protobuf/wire_format_lite.h
@@ -291,11 +291,20 @@
   template <typename CType, enum FieldType DeclaredType>
   static bool ReadPackedPrimitiveNoInline(input, RepeatedField<CType>* value);
 
-  // Read a packed enum field. Values for which is_valid() returns false are
-  // dropped. If is_valid == NULL, no values are dropped.
+  // Read a packed enum field. If the is_valid function is not NULL, values for
+  // which is_valid(value) returns false are silently dropped.
   static bool ReadPackedEnumNoInline(input,
                                      bool (*is_valid)(int),
-                                     RepeatedField<int>* value);
+                                     RepeatedField<int>* values);
+
+  // Read a packed enum field. If the is_valid function is not NULL, values for
+  // which is_valid(value) returns false are appended to unknown_fields_stream.
+  static bool ReadPackedEnumPreserveUnknowns(
+      input,
+      field_number,
+      bool (*is_valid)(int),
+      io::CodedOutputStream* unknown_fields_stream,
+      RepeatedField<int>* values);
 
   // Read a string.  ReadString(..., string* value) requires an existing string.
   static inline bool ReadString(input, string* value);
@@ -647,7 +656,7 @@
 
 inline uint32 WireFormatLite::ZigZagEncode32(int32 n) {
   // Note:  the right-shift must be arithmetic
-  return (n << 1) ^ (n >> 31);
+  return (static_cast<uint32>(n) << 1) ^ (n >> 31);
 }
 
 inline int32 WireFormatLite::ZigZagDecode32(uint32 n) {
@@ -656,7 +665,7 @@
 
 inline uint64 WireFormatLite::ZigZagEncode64(int64 n) {
   // Note:  the right-shift must be arithmetic
-  return (n << 1) ^ (n >> 63);
+  return (static_cast<uint64>(n) << 1) ^ (n >> 63);
 }
 
 inline int64 WireFormatLite::ZigZagDecode64(uint64 n) {
diff --git a/src/google/protobuf/wrappers.proto b/src/google/protobuf/wrappers.proto
new file mode 100644
index 0000000..5164c24
--- /dev/null
+++ b/src/google/protobuf/wrappers.proto
@@ -0,0 +1,97 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Wrappers for primitive (non-message) types. These types are useful
+// for embedding primitives in the `google.protobuf.Any` type and for places
+// where we need to distinguish between the absence of a primitive
+// typed field and its default value.
+
+syntax = "proto3";
+
+package google.protobuf;
+
+option java_multiple_files = true;
+option java_outer_classname = "WrappersProto";
+option java_package = "com.google.protobuf";
+
+
+// Wrapper message for double.
+message DoubleValue {
+  // The double value.
+  double value = 1;
+}
+
+// Wrapper message for float.
+message FloatValue {
+  // The float value.
+  float value = 1;
+}
+
+// Wrapper message for int64.
+message Int64Value {
+  // The int64 value.
+  int64 value = 1;
+}
+
+// Wrapper message for uint64.
+message UInt64Value {
+  // The uint64 value.
+  uint64 value = 1;
+}
+
+// Wrapper message for int32.
+message Int32Value {
+  // The int32 value.
+  int32 value = 1;
+}
+
+// Wrapper message for uint32.
+message UInt32Value {
+  // The uint32 value.
+  uint32 value = 1;
+}
+
+// Wrapper message for bool.
+message BoolValue {
+  // The bool value.
+  bool value = 1;
+}
+
+// Wrapper message for string.
+message StringValue {
+  // The string value.
+  string value = 1;
+}
+
+// Wrapper message for bytes.
+message BytesValue {
+  // The bytes value.
+  bytes value = 1;
+}
diff --git a/vsprojects/config.h b/vsprojects/config.h
old mode 100644
new mode 100755
index 2c64450..a93bb03
--- a/vsprojects/config.h
+++ b/vsprojects/config.h
@@ -1,28 +1,19 @@
 /* protobuf config.h for MSVC.  On other platforms, this is generated
  * automatically by autoheader / autoconf / configure. */
 
-/* the location of <hash_map> */
-#define HASH_MAP_H <hash_map>
+#include <google/protobuf/stubs/pbconfig.h>
 
-/* the namespace of hash_map/hash_set */
-// Apparently Microsoft decided to move hash_map *back* to the std namespace
-// in MSVC 2010:
-//   http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx
-// TODO(kenton):  Use unordered_map instead, which is available in MSVC 2010.
-#if _MSC_VER < 1310 || _MSC_VER >= 1600
-#define HASH_NAMESPACE std
-#else
-#define HASH_NAMESPACE stdext
+#define HASH_MAP_H GOOGLE_PROTOBUF_HASH_MAP_H
+#define HASH_NAMESPACE GOOGLE_PROTOBUF_HASH_NAMESPACE
+#define HASH_SET_H GOOGLE_PROTOBUF_HASH_SET_H
+
+#ifdef GOOGLE_PROTOBUF_HAVE_HASH_MAP
+#define HAVE_HASH_MAP GOOGLE_PROTOBUF_HAVE_HASH_MAP
 #endif
 
-/* the location of <hash_set> */
-#define HASH_SET_H <hash_set>
-
-/* define if the compiler has hash_map */
-#define HAVE_HASH_MAP 1
-
-/* define if the compiler has hash_set */
-#define HAVE_HASH_SET 1
+#ifdef GOOGLE_PROTOBUF_HAVE_HASH_SET
+#define HAVE_HASH_SET GOOGLE_PROTOBUF_HAVE_HASH_SET
+#endif
 
 /* define if you want to use zlib.  See readme.txt for additional
  * requirements. */
diff --git a/vsprojects/extract_includes.bat b/vsprojects/extract_includes.bat
index e9d762c..ddf7f33 100755
--- a/vsprojects/extract_includes.bat
+++ b/vsprojects/extract_includes.bat
@@ -28,6 +28,7 @@
 copy ..\src\google\protobuf\dynamic_message.h include\google\protobuf\dynamic_message.h
 copy ..\src\google\protobuf\extension_set.h include\google\protobuf\extension_set.h
 copy ..\src\google\protobuf\generated_enum_reflection.h include\google\protobuf\generated_enum_reflection.h
+copy ..\src\google\protobuf\generated_enum_util.h include\google\protobuf\generated_enum_util.h
 copy ..\src\google\protobuf\generated_message_reflection.h include\google\protobuf\generated_message_reflection.h
 copy ..\src\google\protobuf\generated_message_util.h include\google\protobuf\generated_message_util.h
 copy ..\src\google\protobuf\io\coded_stream.h include\google\protobuf\io\coded_stream.h
@@ -39,7 +40,9 @@
 copy ..\src\google\protobuf\io\zero_copy_stream_impl.h include\google\protobuf\io\zero_copy_stream_impl.h
 copy ..\src\google\protobuf\io\zero_copy_stream_impl_lite.h include\google\protobuf\io\zero_copy_stream_impl_lite.h
 copy ..\src\google\protobuf\map_entry.h include\google\protobuf\map_entry.h
+copy ..\src\google\protobuf\map_entry_lite.h include\google\protobuf\map_entry_lite.h
 copy ..\src\google\protobuf\map_field.h include\google\protobuf\map_field.h
+copy ..\src\google\protobuf\map_field_lite.h include\google\protobuf\map_field_lite.h
 copy ..\src\google\protobuf\map_field_inl.h include\google\protobuf\map_field_inl.h
 copy ..\src\google\protobuf\map.h include\google\protobuf\map.h
 copy ..\src\google\protobuf\map_type_handler.h include\google\protobuf\map_type_handler.h
diff --git a/vsprojects/google/protobuf/stubs/pbconfig.h b/vsprojects/google/protobuf/stubs/pbconfig.h
old mode 100644
new mode 100755
index c49d26b..18250a2
--- a/vsprojects/google/protobuf/stubs/pbconfig.h
+++ b/vsprojects/google/protobuf/stubs/pbconfig.h
@@ -1,29 +1,39 @@
 /* protobuf config.h for MSVC.  On other platforms, this is generated
  * automatically by autoheader / autoconf / configure. */
 
-/* the location of <hash_map> */
-#define GOOGLE_PROTOBUF_HASH_MAP_H <hash_map>
+// NOTE: if you add new macros in this file manually, please propagate the macro
+// to vsprojects/config.h.
 
 /* the namespace of hash_map/hash_set */
 // Apparently Microsoft decided to move hash_map *back* to the std namespace
 // in MSVC 2010:
 //   http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx
-// TODO(kenton):  Use unordered_map instead, which is available in MSVC 2010.
-#if _MSC_VER < 1310 || _MSC_VER >= 1600
+// And.. they are moved back to stdext in MSVC 2013 (haven't checked 2012). That
+// said, use unordered_map for MSVC 2010 and beyond is our safest bet.
+#if _MSC_VER >= 1600
 #define GOOGLE_PROTOBUF_HASH_NAMESPACE std
-#else
+#define GOOGLE_PROTOBUF_HASH_MAP_H <unordered_map>
+#define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map
+#define GOOGLE_PROTOBUF_HASH_SET_H <unordered_set>
+#define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set
+#elif _MSC_VER >= 1310
 #define GOOGLE_PROTOBUF_HASH_NAMESPACE stdext
+#define GOOGLE_PROTOBUF_HASH_MAP_H <hash_map>
+#define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
+#define GOOGLE_PROTOBUF_HASH_SET_H <hash_set>
+#define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
+#else
+#define GOOGLE_PROTOBUF_HASH_NAMESPACE std
+#define GOOGLE_PROTOBUF_HASH_MAP_H <hash_map>
+#define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
+#define GOOGLE_PROTOBUF_HASH_SET_H <hash_set>
+#define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
 #endif
 
 /* the location of <hash_set> */
-#define GOOGLE_PROTOBUF_HASH_SET_H <hash_set>
 
 /* define if the compiler has hash_map */
 #define GOOGLE_PROTOBUF_HAVE_HASH_MAP 1
 
 /* define if the compiler has hash_set */
 #define GOOGLE_PROTOBUF_HAVE_HASH_SET 1
-
-/* define if you want to use zlib.  See readme.txt for additional
- * requirements. */
-// #define HAVE_ZLIB 1
diff --git a/vsprojects/libprotobuf-lite.vcproj b/vsprojects/libprotobuf-lite.vcproj
index 339d03f..d245448 100644
--- a/vsprojects/libprotobuf-lite.vcproj
+++ b/vsprojects/libprotobuf-lite.vcproj
@@ -183,6 +183,9 @@
 				RelativePath="..\src\google\protobuf\stubs\map-util.h"
 				>
 			</File>
+			<File RelativePath="..\src\google\protobuf\generated_enum_util.h"></File>
+			<File RelativePath="..\src\google\protobuf\map_entry_lite.h"></File>
+			<File RelativePath="..\src\google\protobuf\map_field_lite.h"></File>
 			<File
 				RelativePath="..\src\google\protobuf\message_lite.h"
 				>
diff --git a/vsprojects/libprotobuf.vcproj b/vsprojects/libprotobuf.vcproj
index 6712647..e782885 100644
--- a/vsprojects/libprotobuf.vcproj
+++ b/vsprojects/libprotobuf.vcproj
@@ -223,6 +223,9 @@
 				RelativePath="..\src\google\protobuf\message_lite.h"
 				>
 			</File>
+			<File RelativePath="..\src\google\protobuf\generated_enum_util.h"></File>
+			<File RelativePath="..\src\google\protobuf\map_entry_lite.h"></File>
+			<File RelativePath="..\src\google\protobuf\map_field_lite.h"></File>
 			<File
 				RelativePath="..\src\google\protobuf\stubs\atomicops.h"
 			>
diff --git a/vsprojects/lite-test.vcproj b/vsprojects/lite-test.vcproj
index bb33809..8d17224 100644
--- a/vsprojects/lite-test.vcproj
+++ b/vsprojects/lite-test.vcproj
@@ -182,6 +182,8 @@
 				RelativePath="..\src\google\protobuf\test_util_lite.h"
 				>
 			</File>
+			<File RelativePath=".\google\protobuf\map_lite_unittest.pb.h"></File>
+			<File RelativePath="..\src\google\protobuf\map_lite_test_util.h"></File>
 			<File
 				RelativePath=".\google\protobuf\unittest_lite.pb.h"
 				>
@@ -218,6 +220,8 @@
 				RelativePath=".\google\protobuf\unittest_lite.pb.cc"
 				>
 			</File>
+			<File RelativePath=".\google\protobuf\map_lite_unittest.pb.cc"></File>
+			<File RelativePath="..\src\google\protobuf\map_lite_test_util.cc"></File>
 			<File
 				RelativePath=".\google\protobuf\unittest_import_lite.pb.cc"
 				>
@@ -299,6 +303,30 @@
 				/>
 			</FileConfiguration>
 		</File>
+		<File
+			RelativePath="..\src\google\protobuf\map_lite_unittest.proto"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating map_lite_unittest.pb.{h,cc}..."
+					CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/map_lite_unittest.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\map_lite_unittest.pb.h;google\protobuf\map_lite_unittest.pb.cc"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating map_lite_unittest.pb.{h,cc}..."
+					CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/map_lite_unittest.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\map_lite_unittest.pb.h;google\protobuf\map_lite_unittest.pb.cc"
+				/>
+			</FileConfiguration>
+		</File>
 	</Files>
 	<Globals>
 	</Globals>
diff --git a/vsprojects/tests.vcproj b/vsprojects/tests.vcproj
index 23c81f0..0d42949 100644
--- a/vsprojects/tests.vcproj
+++ b/vsprojects/tests.vcproj
@@ -194,6 +194,9 @@
 				RelativePath="..\src\google\protobuf\test_util.h"
 				>
 			</File>
+			<File RelativePath="..\src\google\protobuf\map_test_util_impl.h"></File>
+			<File RelativePath="..\src\google\protobuf\map_test_util.h"></File>
+			<File RelativePath="..\src\google\protobuf\arena_test_util.h"></File>
 			<File
 				RelativePath="..\src\google\protobuf\compiler\mock_code_generator.h"
 				>
@@ -346,6 +349,7 @@
 				RelativePath="..\src\google\protobuf\map_test_util.cc"
 				>
 			</File>
+			<File RelativePath="..\src\google\protobuf\arena_test_util.cc"></File>
 			<File
 				RelativePath="..\src\google\protobuf\message_unittest.cc"
 				>
@@ -431,7 +435,7 @@
 				>
 			</File>
 			<File
-				RelativePath=".\google\protobuf\map_lite_unittest.pb.cc"
+				RelativePath=".\google\protobuf\unittest_preserve_unknown_enum2.pb.cc"
 				>
 			</File>
 			<File
@@ -524,16 +528,16 @@
 			</File>
 		</Filter>
 		<File
-			RelativePath="..\src\google\protobuf\map_lite_unittest.proto"
+			RelativePath="..\src\google\protobuf\unittest_preserve_unknown_enum2.proto"
 			>
 			<FileConfiguration
 				Name="Debug|Win32"
 				>
 				<Tool
 					Name="VCCustomBuildTool"
-					Description="Generating map_lite_unittest.pb.{h,cc}..."
-					CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/map_lite_unittest.proto"
-					Outputs="google\protobuf\map_lite_unittest.pb.h;google\protobuf\map_lite_unittest.pb.cc"
+					Description="Generating unittest_preserve_unknown_enum2.pb.{h,cc}..."
+					CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_preserve_unknown_enum2.proto"
+					Outputs="google\protobuf\unittest_preserve_unknown_enum2.pb.h;google\protobuf\unittest_preserve_unknown_enum2.pb.cc"
 				/>
 			</FileConfiguration>
 			<FileConfiguration
@@ -541,9 +545,9 @@
 				>
 				<Tool
 					Name="VCCustomBuildTool"
-					Description="Generating map_lite_unittest.pb.{h,cc}..."
-					CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/map_lite_unittest.proto"
-					Outputs="google\protobuf\map_lite_unittest.pb.h;google\protobuf\map_lite_unittest.pb.cc"
+					Description="Generating unittest_preserve_unknown_enum2.pb.{h,cc}..."
+					CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_preserve_unknown_enum2.proto"
+					Outputs="google\protobuf\unittest_preserve_unknown_enum2.pb.h;google\protobuf\unittest_preserve_unknown_enum2.pb.cc"
 				/>
 			</FileConfiguration>
 		</File>