Down-integrate from google3.
diff --git a/Makefile.am b/Makefile.am
index 0b2511f..564bff4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -247,6 +247,7 @@
   java/core/src/main/java/com/google/protobuf/MutabilityOracle.java                \
   java/core/src/main/java/com/google/protobuf/NioByteString.java                   \
   java/core/src/main/java/com/google/protobuf/Parser.java                          \
+  java/core/src/main/java/com/google/protobuf/PrimitiveNonBoxingCollection.java    \
   java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java               \
   java/core/src/main/java/com/google/protobuf/ProtocolMessageEnum.java             \
   java/core/src/main/java/com/google/protobuf/ProtocolStringList.java              \
@@ -710,6 +711,7 @@
   python/google/protobuf/internal/packed_field_test.proto                    \
   python/google/protobuf/internal/proto_builder_test.py                      \
   python/google/protobuf/internal/python_message.py                          \
+  python/google/protobuf/internal/python_protobuf.cc                         \
   python/google/protobuf/internal/reflection_test.py                         \
   python/google/protobuf/internal/service_reflection_test.py                 \
   python/google/protobuf/internal/symbol_database_test.py                    \
@@ -752,13 +754,13 @@
   python/google/protobuf/pyext/message_module.cc                             \
   python/google/protobuf/pyext/proto2_api_test.proto                         \
   python/google/protobuf/pyext/python.proto                                  \
-  python/google/protobuf/pyext/python_protobuf.h                             \
   python/google/protobuf/pyext/repeated_composite_container.cc               \
   python/google/protobuf/pyext/repeated_composite_container.h                \
   python/google/protobuf/pyext/repeated_scalar_container.cc                  \
   python/google/protobuf/pyext/repeated_scalar_container.h                   \
   python/google/protobuf/pyext/safe_numerics.h                               \
   python/google/protobuf/pyext/scoped_pyobject_ptr.h                         \
+  python/google/protobuf/python_protobuf.h                                   \
   python/google/protobuf/reflection.py                                       \
   python/google/protobuf/service.py                                          \
   python/google/protobuf/service_reflection.py                               \
diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake
index 29b3253..b663e35 100644
--- a/cmake/libprotoc.cmake
+++ b/cmake/libprotoc.cmake
@@ -88,6 +88,7 @@
   ${protobuf_source_dir}/src/google/protobuf/compiler/php/php_generator.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.pb.cc
+  ${protobuf_source_dir}/src/google/protobuf/compiler/profile.pb.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/python/python_generator.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/ruby/ruby_generator.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/subprocess.cc
diff --git a/cmake/tests.cmake b/cmake/tests.cmake
index 1470e4b..38dc0b5 100644
--- a/cmake/tests.cmake
+++ b/cmake/tests.cmake
@@ -43,6 +43,9 @@
   google/protobuf/unittest_empty.proto
   google/protobuf/unittest_import.proto
   google/protobuf/unittest_import_public.proto
+  google/protobuf/unittest_lazy_dependencies.proto
+  google/protobuf/unittest_lazy_dependencies_custom_option.proto
+  google/protobuf/unittest_lazy_dependencies_enum.proto
   google/protobuf/unittest_lite_imports_nonlite.proto
   google/protobuf/unittest_mset.proto
   google/protobuf/unittest_mset_wire_format.proto
@@ -207,7 +210,7 @@
   ${protobuf_source_dir}/src/google/protobuf/lite_unittest.cc
 )
 add_executable(lite-test ${lite_test_files} ${common_lite_test_files} ${lite_test_proto_files})
-target_link_libraries(lite-test libprotobuf-lite)
+target_link_libraries(lite-test libprotobuf-lite gmock_main)
 
 set(lite_arena_test_files
   ${protobuf_source_dir}/src/google/protobuf/lite_arena_unittest.cc
diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc
index 1e5387a..0dd7787 100644
--- a/conformance/conformance_test.cc
+++ b/conformance/conformance_test.cc
@@ -708,6 +708,21 @@
   }
 }
 
+void ConformanceTestSuite::TestIllegalTags() {
+  // field num 0 is illegal
+  string nullfield[] = {
+    "\1DEADBEEF",
+    "\2\1\1",
+    "\3\4",
+    "\5DEAD"
+  };
+  for (int i = 0; i < 4; i++) {
+    string name = "IllegalZeroFieldNum_Case_0";
+    name.back() += i;
+    ExpectParseFailureForProto(nullfield[i], name, REQUIRED);
+  }
+}
+
 bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
                                     std::string* output) {
   runner_ = runner;
@@ -728,6 +743,8 @@
     TestPrematureEOFForType(static_cast<FieldDescriptor::Type>(i));
   }
 
+  TestIllegalTags();
+
   int64 kInt64Min = -9223372036854775808ULL;
   int64 kInt64Max = 9223372036854775807ULL;
   uint64 kUint64Max = 18446744073709551615ULL;
diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h
index 5f05a25..4e40a6a 100644
--- a/conformance/conformance_test.h
+++ b/conformance/conformance_test.h
@@ -201,6 +201,7 @@
                                       const std::string& test_name,
                                       ConformanceLevel level);
   void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type);
+  void TestIllegalTags();
   void TestValidDataForType(
       google::protobuf::FieldDescriptor::Type,
       std::vector<std::pair<std::string, std::string>> values);
diff --git a/conformance/failure_list_cpp.txt b/conformance/failure_list_cpp.txt
index 8cfd74d..8a4fa7e 100644
--- a/conformance/failure_list_cpp.txt
+++ b/conformance/failure_list_cpp.txt
@@ -32,7 +32,6 @@
 Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines
 Recommended.JsonInput.TrailingCommaInAnObjectWithSpace
 Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
 Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
 Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
 Required.ProtobufInput.PrematureEofInPackedField.BOOL
@@ -43,4 +42,3 @@
 Required.ProtobufInput.PrematureEofInPackedField.SINT64
 Required.ProtobufInput.PrematureEofInPackedField.UINT32
 Required.ProtobufInput.PrematureEofInPackedField.UINT64
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE
diff --git a/conformance/failure_list_java.txt b/conformance/failure_list_java.txt
index 632940e..a4f0f10 100644
--- a/conformance/failure_list_java.txt
+++ b/conformance/failure_list_java.txt
@@ -32,6 +32,7 @@
 Recommended.JsonInput.StringFieldSurrogateInWrongOrder
 Recommended.JsonInput.StringFieldUnpairedHighSurrogate
 Recommended.JsonInput.StringFieldUnpairedLowSurrogate
+Recommended.JsonInput.StringFieldUppercaseEscapeLetter
 Recommended.JsonInput.Uint32MapFieldKeyNotQuoted
 Recommended.JsonInput.Uint64MapFieldKeyNotQuoted
 Required.JsonInput.EnumFieldNotQuoted
diff --git a/conformance/failure_list_python.txt b/conformance/failure_list_python.txt
index 9d556a0..0e907fe 100644
--- a/conformance/failure_list_python.txt
+++ b/conformance/failure_list_python.txt
@@ -1,13 +1,615 @@
+Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
+Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
+Recommended.FieldMaskTooManyUnderscore.JsonOutput
+Recommended.JsonInput.BoolFieldAllCapitalFalse
+Recommended.JsonInput.BoolFieldAllCapitalTrue
+Recommended.JsonInput.BoolFieldCamelCaseFalse
+Recommended.JsonInput.BoolFieldCamelCaseTrue
+Recommended.JsonInput.BoolFieldDoubleQuotedFalse
+Recommended.JsonInput.BoolFieldDoubleQuotedTrue
+Recommended.JsonInput.BoolFieldIntegerOne
+Recommended.JsonInput.BoolFieldIntegerZero
+Recommended.JsonInput.BoolMapFieldKeyNotQuoted
 Recommended.JsonInput.DoubleFieldInfinityNotQuoted
 Recommended.JsonInput.DoubleFieldNanNotQuoted
 Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
+Recommended.JsonInput.DurationHas3FractionalDigits.Validator
+Recommended.JsonInput.DurationHas6FractionalDigits.Validator
+Recommended.JsonInput.DurationHas9FractionalDigits.Validator
+Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator
+Recommended.JsonInput.FieldMaskInvalidCharacter
+Recommended.JsonInput.FieldNameDuplicate
+Recommended.JsonInput.FieldNameDuplicateDifferentCasing1
+Recommended.JsonInput.FieldNameDuplicateDifferentCasing2
+Recommended.JsonInput.FieldNameNotQuoted
+Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
+Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
+Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
 Recommended.JsonInput.FloatFieldInfinityNotQuoted
 Recommended.JsonInput.FloatFieldNanNotQuoted
 Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
+Recommended.JsonInput.Int32MapFieldKeyNotQuoted
+Recommended.JsonInput.Int64FieldBeString.Validator
+Recommended.JsonInput.Int64MapFieldKeyNotQuoted
+Recommended.JsonInput.JsonWithComments
+Recommended.JsonInput.MapFieldKeyIsNull
+Recommended.JsonInput.MapFieldValueIsNull
+Recommended.JsonInput.MissingCommaMultiline
+Recommended.JsonInput.MissingCommaOneLine
+Recommended.JsonInput.MultilineNoSpaces.JsonOutput
+Recommended.JsonInput.MultilineNoSpaces.ProtobufOutput
+Recommended.JsonInput.MultilineWithSpaces.JsonOutput
+Recommended.JsonInput.MultilineWithSpaces.ProtobufOutput
+Recommended.JsonInput.OneLineNoSpaces.JsonOutput
+Recommended.JsonInput.OneLineNoSpaces.ProtobufOutput
+Recommended.JsonInput.OneLineWithSpaces.JsonOutput
+Recommended.JsonInput.OneLineWithSpaces.ProtobufOutput
+Recommended.JsonInput.OneofZeroBool.JsonOutput
+Recommended.JsonInput.OneofZeroBool.ProtobufOutput
+Recommended.JsonInput.OneofZeroBytes.JsonOutput
+Recommended.JsonInput.OneofZeroBytes.ProtobufOutput
+Recommended.JsonInput.OneofZeroDouble.JsonOutput
+Recommended.JsonInput.OneofZeroDouble.ProtobufOutput
+Recommended.JsonInput.OneofZeroEnum.JsonOutput
+Recommended.JsonInput.OneofZeroEnum.ProtobufOutput
+Recommended.JsonInput.OneofZeroFloat.JsonOutput
+Recommended.JsonInput.OneofZeroFloat.ProtobufOutput
+Recommended.JsonInput.OneofZeroMessage.JsonOutput
+Recommended.JsonInput.OneofZeroMessage.ProtobufOutput
+Recommended.JsonInput.OneofZeroString.JsonOutput
+Recommended.JsonInput.OneofZeroString.ProtobufOutput
+Recommended.JsonInput.OneofZeroUint32.JsonOutput
+Recommended.JsonInput.OneofZeroUint32.ProtobufOutput
+Recommended.JsonInput.OneofZeroUint64.JsonOutput
+Recommended.JsonInput.OneofZeroUint64.ProtobufOutput
+Recommended.JsonInput.RepeatedFieldMessageElementIsNull
+Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull
+Recommended.JsonInput.RepeatedFieldTrailingComma
+Recommended.JsonInput.RepeatedFieldTrailingCommaWithNewlines
+Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpace
+Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace
+Recommended.JsonInput.StringEndsWithEscapeChar
+Recommended.JsonInput.StringFieldInvalidEscape
+Recommended.JsonInput.StringFieldSingleQuoteBoth
+Recommended.JsonInput.StringFieldSingleQuoteKey
+Recommended.JsonInput.StringFieldSingleQuoteValue
+Recommended.JsonInput.StringFieldSurrogateInWrongOrder
+Recommended.JsonInput.StringFieldUnpairedHighSurrogate
+Recommended.JsonInput.StringFieldUnpairedLowSurrogate
+Recommended.JsonInput.StringFieldUnterminatedEscape
+Recommended.JsonInput.StringFieldUppercaseEscapeLetter
+Recommended.JsonInput.TimestampHas3FractionalDigits.Validator
+Recommended.JsonInput.TimestampHas6FractionalDigits.Validator
+Recommended.JsonInput.TimestampHas9FractionalDigits.Validator
+Recommended.JsonInput.TimestampHasZeroFractionalDigit.Validator
+Recommended.JsonInput.TimestampZeroNormalized.Validator
+Recommended.JsonInput.TrailingCommaInAnObject
+Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines
+Recommended.JsonInput.TrailingCommaInAnObjectWithSpace
+Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
+Recommended.JsonInput.Uint32MapFieldKeyNotQuoted
+Recommended.JsonInput.Uint64FieldBeString.Validator
+Recommended.JsonInput.Uint64MapFieldKeyNotQuoted
+Recommended.ProtobufInput.OneofZeroBool.JsonOutput
+Recommended.ProtobufInput.OneofZeroBool.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroBytes.JsonOutput
+Recommended.ProtobufInput.OneofZeroBytes.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroDouble.JsonOutput
+Recommended.ProtobufInput.OneofZeroDouble.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroEnum.JsonOutput
+Recommended.ProtobufInput.OneofZeroEnum.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroFloat.JsonOutput
+Recommended.ProtobufInput.OneofZeroFloat.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroMessage.JsonOutput
+Recommended.ProtobufInput.OneofZeroMessage.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroString.JsonOutput
+Recommended.ProtobufInput.OneofZeroString.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroUint32.JsonOutput
+Recommended.ProtobufInput.OneofZeroUint32.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroUint64.JsonOutput
+Recommended.ProtobufInput.OneofZeroUint64.ProtobufOutput
+Required.DurationProtoInputTooLarge.JsonOutput
+Required.DurationProtoInputTooSmall.JsonOutput
+Required.JsonInput.AllFieldAcceptNull.JsonOutput
+Required.JsonInput.AllFieldAcceptNull.ProtobufOutput
+Required.JsonInput.Any.JsonOutput
+Required.JsonInput.Any.ProtobufOutput
+Required.JsonInput.AnyNested.JsonOutput
+Required.JsonInput.AnyNested.ProtobufOutput
+Required.JsonInput.AnyUnorderedTypeTag.JsonOutput
+Required.JsonInput.AnyUnorderedTypeTag.ProtobufOutput
+Required.JsonInput.AnyWithDuration.JsonOutput
+Required.JsonInput.AnyWithDuration.ProtobufOutput
+Required.JsonInput.AnyWithFieldMask.JsonOutput
+Required.JsonInput.AnyWithFieldMask.ProtobufOutput
+Required.JsonInput.AnyWithInt32ValueWrapper.JsonOutput
+Required.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
+Required.JsonInput.AnyWithStruct.JsonOutput
+Required.JsonInput.AnyWithStruct.ProtobufOutput
+Required.JsonInput.AnyWithTimestamp.JsonOutput
+Required.JsonInput.AnyWithTimestamp.ProtobufOutput
+Required.JsonInput.AnyWithValueForInteger.JsonOutput
+Required.JsonInput.AnyWithValueForInteger.ProtobufOutput
+Required.JsonInput.AnyWithValueForJsonObject.JsonOutput
+Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
+Required.JsonInput.BoolFieldFalse.JsonOutput
+Required.JsonInput.BoolFieldFalse.ProtobufOutput
+Required.JsonInput.BoolFieldTrue.JsonOutput
+Required.JsonInput.BoolFieldTrue.ProtobufOutput
+Required.JsonInput.BoolMapEscapedKey.JsonOutput
+Required.JsonInput.BoolMapEscapedKey.ProtobufOutput
+Required.JsonInput.BoolMapField.JsonOutput
+Required.JsonInput.BoolMapField.ProtobufOutput
+Required.JsonInput.BytesField.JsonOutput
+Required.JsonInput.BytesField.ProtobufOutput
 Required.JsonInput.BytesFieldInvalidBase64Characters
+Required.JsonInput.BytesRepeatedField.JsonOutput
+Required.JsonInput.BytesRepeatedField.ProtobufOutput
+Required.JsonInput.DoubleFieldInfinity.JsonOutput
+Required.JsonInput.DoubleFieldInfinity.ProtobufOutput
+Required.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
+Required.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
+Required.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
+Required.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput
+Required.JsonInput.DoubleFieldMinNegativeValue.JsonOutput
+Required.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput
+Required.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
+Required.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
+Required.JsonInput.DoubleFieldNan.JsonOutput
+Required.JsonInput.DoubleFieldNan.ProtobufOutput
+Required.JsonInput.DoubleFieldNegativeInfinity.JsonOutput
+Required.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput
+Required.JsonInput.DoubleFieldQuotedValue.JsonOutput
+Required.JsonInput.DoubleFieldQuotedValue.ProtobufOutput
+Required.JsonInput.DoubleFieldTooLarge
 Required.JsonInput.DoubleFieldTooSmall
+Required.JsonInput.DurationJsonInputTooLarge
+Required.JsonInput.DurationJsonInputTooSmall
+Required.JsonInput.DurationMaxValue.JsonOutput
+Required.JsonInput.DurationMaxValue.ProtobufOutput
+Required.JsonInput.DurationMinValue.JsonOutput
+Required.JsonInput.DurationMinValue.ProtobufOutput
+Required.JsonInput.DurationMissingS
+Required.JsonInput.DurationRepeatedValue.JsonOutput
+Required.JsonInput.DurationRepeatedValue.ProtobufOutput
+Required.JsonInput.EnumField.JsonOutput
+Required.JsonInput.EnumField.ProtobufOutput
+Required.JsonInput.EnumFieldNotQuoted
+Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput
+Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
+Required.JsonInput.EnumFieldNumericValueZero.JsonOutput
+Required.JsonInput.EnumFieldNumericValueZero.ProtobufOutput
 Required.JsonInput.EnumFieldUnknownValue.Validator
+Required.JsonInput.EnumRepeatedField.JsonOutput
+Required.JsonInput.EnumRepeatedField.ProtobufOutput
+Required.JsonInput.FieldMask.JsonOutput
+Required.JsonInput.FieldMask.ProtobufOutput
+Required.JsonInput.FieldNameEscaped.JsonOutput
+Required.JsonInput.FieldNameEscaped.ProtobufOutput
+Required.JsonInput.FieldNameInLowerCamelCase.Validator
+Required.JsonInput.FieldNameInSnakeCase.JsonOutput
+Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
+Required.JsonInput.FieldNameWithMixedCases.JsonOutput
+Required.JsonInput.FieldNameWithMixedCases.ProtobufOutput
+Required.JsonInput.FieldNameWithMixedCases.Validator
+Required.JsonInput.FieldNameWithNumbers.JsonOutput
+Required.JsonInput.FieldNameWithNumbers.ProtobufOutput
+Required.JsonInput.FieldNameWithNumbers.Validator
+Required.JsonInput.FloatFieldInfinity.JsonOutput
+Required.JsonInput.FloatFieldInfinity.ProtobufOutput
+Required.JsonInput.FloatFieldMaxNegativeValue.JsonOutput
+Required.JsonInput.FloatFieldMaxNegativeValue.ProtobufOutput
+Required.JsonInput.FloatFieldMaxPositiveValue.JsonOutput
+Required.JsonInput.FloatFieldMaxPositiveValue.ProtobufOutput
+Required.JsonInput.FloatFieldMinNegativeValue.JsonOutput
+Required.JsonInput.FloatFieldMinNegativeValue.ProtobufOutput
+Required.JsonInput.FloatFieldMinPositiveValue.JsonOutput
+Required.JsonInput.FloatFieldMinPositiveValue.ProtobufOutput
+Required.JsonInput.FloatFieldNan.JsonOutput
+Required.JsonInput.FloatFieldNan.ProtobufOutput
+Required.JsonInput.FloatFieldNegativeInfinity.JsonOutput
+Required.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput
+Required.JsonInput.FloatFieldQuotedValue.JsonOutput
+Required.JsonInput.FloatFieldQuotedValue.ProtobufOutput
 Required.JsonInput.FloatFieldTooLarge
 Required.JsonInput.FloatFieldTooSmall
+Required.JsonInput.HelloWorld.JsonOutput
+Required.JsonInput.HelloWorld.ProtobufOutput
+Required.JsonInput.Int32FieldExponentialFormat.JsonOutput
+Required.JsonInput.Int32FieldExponentialFormat.ProtobufOutput
+Required.JsonInput.Int32FieldFloatTrailingZero.JsonOutput
+Required.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
+Required.JsonInput.Int32FieldLeadingSpace
+Required.JsonInput.Int32FieldLeadingZero
+Required.JsonInput.Int32FieldMaxFloatValue.JsonOutput
+Required.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
+Required.JsonInput.Int32FieldMaxValue.JsonOutput
+Required.JsonInput.Int32FieldMaxValue.ProtobufOutput
+Required.JsonInput.Int32FieldMinFloatValue.JsonOutput
+Required.JsonInput.Int32FieldMinFloatValue.ProtobufOutput
+Required.JsonInput.Int32FieldMinValue.JsonOutput
+Required.JsonInput.Int32FieldMinValue.ProtobufOutput
+Required.JsonInput.Int32FieldNegativeWithLeadingZero
+Required.JsonInput.Int32FieldNotInteger
+Required.JsonInput.Int32FieldNotNumber
+Required.JsonInput.Int32FieldPlusSign
+Required.JsonInput.Int32FieldStringValue.JsonOutput
+Required.JsonInput.Int32FieldStringValue.ProtobufOutput
+Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput
+Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
+Required.JsonInput.Int32FieldTooLarge
+Required.JsonInput.Int32FieldTooSmall
+Required.JsonInput.Int32FieldTrailingSpace
+Required.JsonInput.Int32MapEscapedKey.JsonOutput
+Required.JsonInput.Int32MapEscapedKey.ProtobufOutput
+Required.JsonInput.Int32MapField.JsonOutput
+Required.JsonInput.Int32MapField.ProtobufOutput
+Required.JsonInput.Int64FieldMaxValue.JsonOutput
+Required.JsonInput.Int64FieldMaxValue.ProtobufOutput
+Required.JsonInput.Int64FieldMaxValueNotQuoted.JsonOutput
+Required.JsonInput.Int64FieldMaxValueNotQuoted.ProtobufOutput
+Required.JsonInput.Int64FieldMinValue.JsonOutput
+Required.JsonInput.Int64FieldMinValue.ProtobufOutput
+Required.JsonInput.Int64FieldMinValueNotQuoted.JsonOutput
+Required.JsonInput.Int64FieldMinValueNotQuoted.ProtobufOutput
+Required.JsonInput.Int64FieldNotInteger
+Required.JsonInput.Int64FieldNotNumber
+Required.JsonInput.Int64FieldTooLarge
+Required.JsonInput.Int64FieldTooSmall
+Required.JsonInput.Int64MapEscapedKey.JsonOutput
+Required.JsonInput.Int64MapEscapedKey.ProtobufOutput
+Required.JsonInput.Int64MapField.JsonOutput
+Required.JsonInput.Int64MapField.ProtobufOutput
+Required.JsonInput.MessageField.JsonOutput
+Required.JsonInput.MessageField.ProtobufOutput
+Required.JsonInput.MessageMapField.JsonOutput
+Required.JsonInput.MessageMapField.ProtobufOutput
+Required.JsonInput.MessageRepeatedField.JsonOutput
+Required.JsonInput.MessageRepeatedField.ProtobufOutput
+Required.JsonInput.OneofFieldDuplicate
+Required.JsonInput.OptionalBoolWrapper.JsonOutput
+Required.JsonInput.OptionalBoolWrapper.ProtobufOutput
+Required.JsonInput.OptionalBytesWrapper.JsonOutput
+Required.JsonInput.OptionalBytesWrapper.ProtobufOutput
+Required.JsonInput.OptionalDoubleWrapper.JsonOutput
+Required.JsonInput.OptionalDoubleWrapper.ProtobufOutput
+Required.JsonInput.OptionalFloatWrapper.JsonOutput
+Required.JsonInput.OptionalFloatWrapper.ProtobufOutput
+Required.JsonInput.OptionalInt32Wrapper.JsonOutput
+Required.JsonInput.OptionalInt32Wrapper.ProtobufOutput
+Required.JsonInput.OptionalInt64Wrapper.JsonOutput
+Required.JsonInput.OptionalInt64Wrapper.ProtobufOutput
+Required.JsonInput.OptionalStringWrapper.JsonOutput
+Required.JsonInput.OptionalStringWrapper.ProtobufOutput
+Required.JsonInput.OptionalUint32Wrapper.JsonOutput
+Required.JsonInput.OptionalUint32Wrapper.ProtobufOutput
+Required.JsonInput.OptionalUint64Wrapper.JsonOutput
+Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput
+Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
+Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
+Required.JsonInput.OriginalProtoFieldName.JsonOutput
+Required.JsonInput.OriginalProtoFieldName.ProtobufOutput
+Required.JsonInput.PrimitiveRepeatedField.JsonOutput
+Required.JsonInput.PrimitiveRepeatedField.ProtobufOutput
+Required.JsonInput.RepeatedBoolWrapper.JsonOutput
+Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput
+Required.JsonInput.RepeatedBytesWrapper.JsonOutput
+Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput
+Required.JsonInput.RepeatedDoubleWrapper.JsonOutput
+Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput
 Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotMessage
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotString
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotBool
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotInt
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotString
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotMessage
+Required.JsonInput.RepeatedFloatWrapper.JsonOutput
+Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput
+Required.JsonInput.RepeatedInt32Wrapper.JsonOutput
+Required.JsonInput.RepeatedInt32Wrapper.ProtobufOutput
+Required.JsonInput.RepeatedInt64Wrapper.JsonOutput
+Required.JsonInput.RepeatedInt64Wrapper.ProtobufOutput
+Required.JsonInput.RepeatedStringWrapper.JsonOutput
+Required.JsonInput.RepeatedStringWrapper.ProtobufOutput
+Required.JsonInput.RepeatedUint32Wrapper.JsonOutput
+Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput
+Required.JsonInput.RepeatedUint64Wrapper.JsonOutput
+Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput
+Required.JsonInput.StringField.JsonOutput
+Required.JsonInput.StringField.ProtobufOutput
+Required.JsonInput.StringFieldEscape.JsonOutput
+Required.JsonInput.StringFieldEscape.ProtobufOutput
+Required.JsonInput.StringFieldNotAString
+Required.JsonInput.StringFieldSurrogatePair.JsonOutput
+Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput
+Required.JsonInput.StringFieldUnicode.JsonOutput
+Required.JsonInput.StringFieldUnicode.ProtobufOutput
+Required.JsonInput.StringFieldUnicodeEscape.JsonOutput
+Required.JsonInput.StringFieldUnicodeEscape.ProtobufOutput
+Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput
+Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput
+Required.JsonInput.StringRepeatedField.JsonOutput
+Required.JsonInput.StringRepeatedField.ProtobufOutput
+Required.JsonInput.Struct.JsonOutput
+Required.JsonInput.Struct.ProtobufOutput
 Required.JsonInput.TimestampJsonInputLowercaseT
+Required.JsonInput.TimestampJsonInputLowercaseZ
+Required.JsonInput.TimestampJsonInputMissingT
+Required.JsonInput.TimestampJsonInputMissingZ
+Required.JsonInput.TimestampJsonInputTooLarge
+Required.JsonInput.TimestampJsonInputTooSmall
+Required.JsonInput.TimestampMaxValue.JsonOutput
+Required.JsonInput.TimestampMaxValue.ProtobufOutput
+Required.JsonInput.TimestampMinValue.JsonOutput
+Required.JsonInput.TimestampMinValue.ProtobufOutput
+Required.JsonInput.TimestampRepeatedValue.JsonOutput
+Required.JsonInput.TimestampRepeatedValue.ProtobufOutput
+Required.JsonInput.TimestampWithNegativeOffset.JsonOutput
+Required.JsonInput.TimestampWithNegativeOffset.ProtobufOutput
+Required.JsonInput.TimestampWithPositiveOffset.JsonOutput
+Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput
+Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput
+Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
+Required.JsonInput.Uint32FieldMaxValue.JsonOutput
+Required.JsonInput.Uint32FieldMaxValue.ProtobufOutput
+Required.JsonInput.Uint32FieldNotInteger
+Required.JsonInput.Uint32FieldNotNumber
+Required.JsonInput.Uint32FieldTooLarge
+Required.JsonInput.Uint32MapField.JsonOutput
+Required.JsonInput.Uint32MapField.ProtobufOutput
+Required.JsonInput.Uint64FieldMaxValue.JsonOutput
+Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput
+Required.JsonInput.Uint64FieldMaxValueNotQuoted.JsonOutput
+Required.JsonInput.Uint64FieldMaxValueNotQuoted.ProtobufOutput
+Required.JsonInput.Uint64FieldNotInteger
+Required.JsonInput.Uint64FieldNotNumber
+Required.JsonInput.Uint64FieldTooLarge
+Required.JsonInput.Uint64MapField.JsonOutput
+Required.JsonInput.Uint64MapField.ProtobufOutput
+Required.JsonInput.ValueAcceptBool.JsonOutput
+Required.JsonInput.ValueAcceptBool.ProtobufOutput
+Required.JsonInput.ValueAcceptFloat.JsonOutput
+Required.JsonInput.ValueAcceptFloat.ProtobufOutput
+Required.JsonInput.ValueAcceptInteger.JsonOutput
+Required.JsonInput.ValueAcceptInteger.ProtobufOutput
+Required.JsonInput.ValueAcceptList.JsonOutput
+Required.JsonInput.ValueAcceptList.ProtobufOutput
+Required.JsonInput.ValueAcceptNull.JsonOutput
+Required.JsonInput.ValueAcceptNull.ProtobufOutput
+Required.JsonInput.ValueAcceptObject.JsonOutput
+Required.JsonInput.ValueAcceptObject.ProtobufOutput
+Required.JsonInput.ValueAcceptString.JsonOutput
+Required.JsonInput.ValueAcceptString.ProtobufOutput
+Required.JsonInput.WrapperTypesWithNullValue.JsonOutput
+Required.JsonInput.WrapperTypesWithNullValue.ProtobufOutput
+Required.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
+Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
+Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
+Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
+Required.ProtobufInput.IllegalZeroFieldNum_Case_0
+Required.ProtobufInput.IllegalZeroFieldNum_Case_1
+Required.ProtobufInput.IllegalZeroFieldNum_Case_2
+Required.ProtobufInput.IllegalZeroFieldNum_Case_3
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BOOL
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BYTES
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.DOUBLE
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.ENUM
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED32
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED64
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FLOAT
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT32
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT64
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.MESSAGE
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED32
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED64
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT32
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT64
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.STRING
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT32
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT64
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BOOL
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BYTES
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.DOUBLE
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.ENUM
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED32
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED64
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FLOAT
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT32
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT64
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED32
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED64
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT32
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT64
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.STRING
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT32
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT64
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.BOOL
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.BYTES
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.DOUBLE
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.ENUM
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED32
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED64
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.FLOAT
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT32
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT64
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.MESSAGE
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED32
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED64
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT32
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT64
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.STRING
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT32
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT64
+Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.BYTES
+Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
+Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.STRING
+Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.BYTES
+Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
+Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.STRING
+Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.BYTES
+Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.MESSAGE
+Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.STRING
+Required.ProtobufInput.PrematureEofInPackedField.BOOL
+Required.ProtobufInput.PrematureEofInPackedField.DOUBLE
+Required.ProtobufInput.PrematureEofInPackedField.ENUM
+Required.ProtobufInput.PrematureEofInPackedField.FIXED32
+Required.ProtobufInput.PrematureEofInPackedField.FIXED64
+Required.ProtobufInput.PrematureEofInPackedField.FLOAT
+Required.ProtobufInput.PrematureEofInPackedField.INT32
+Required.ProtobufInput.PrematureEofInPackedField.INT64
+Required.ProtobufInput.PrematureEofInPackedField.SFIXED32
+Required.ProtobufInput.PrematureEofInPackedField.SFIXED64
+Required.ProtobufInput.PrematureEofInPackedField.SINT32
+Required.ProtobufInput.PrematureEofInPackedField.SINT64
+Required.ProtobufInput.PrematureEofInPackedField.UINT32
+Required.ProtobufInput.PrematureEofInPackedField.UINT64
+Required.ProtobufInput.PrematureEofInPackedFieldValue.BOOL
+Required.ProtobufInput.PrematureEofInPackedFieldValue.DOUBLE
+Required.ProtobufInput.PrematureEofInPackedFieldValue.ENUM
+Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED32
+Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED64
+Required.ProtobufInput.PrematureEofInPackedFieldValue.FLOAT
+Required.ProtobufInput.PrematureEofInPackedFieldValue.INT32
+Required.ProtobufInput.PrematureEofInPackedFieldValue.INT64
+Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED32
+Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED64
+Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT32
+Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT64
+Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT32
+Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT64
+Required.ProtobufInput.PrematureEofInSubmessageValue.MESSAGE
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BOOL
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BYTES
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.DOUBLE
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.ENUM
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED32
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED64
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FLOAT
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT32
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT64
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.MESSAGE
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED32
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED64
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT32
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT64
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.STRING
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT32
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT64
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BOOL
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BYTES
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.DOUBLE
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.ENUM
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED32
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED64
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FLOAT
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT32
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT64
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED32
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED64
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT32
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT64
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.STRING
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT32
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT64
+Required.ProtobufInput.PrematureEofInsideUnknownValue.BOOL
+Required.ProtobufInput.PrematureEofInsideUnknownValue.BYTES
+Required.ProtobufInput.PrematureEofInsideUnknownValue.DOUBLE
+Required.ProtobufInput.PrematureEofInsideUnknownValue.ENUM
+Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED32
+Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED64
+Required.ProtobufInput.PrematureEofInsideUnknownValue.FLOAT
+Required.ProtobufInput.PrematureEofInsideUnknownValue.INT32
+Required.ProtobufInput.PrematureEofInsideUnknownValue.INT64
+Required.ProtobufInput.PrematureEofInsideUnknownValue.MESSAGE
+Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED32
+Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED64
+Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT32
+Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT64
+Required.ProtobufInput.PrematureEofInsideUnknownValue.STRING
+Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT32
+Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT64
+Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.BOOL.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.BOOL.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.DOUBLE.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.DOUBLE.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.FIXED32.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.FIXED32.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.FIXED64.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.FIXED64.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.FLOAT.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.FLOAT.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.INT32.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.INT32.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.INT64.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.INT64.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.SFIXED32.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.SFIXED32.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.SFIXED64.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.SFIXED64.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.SINT32.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.SINT32.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.SINT64.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.SINT64.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.UINT32.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.UINT32.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.UINT64.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.UINT64.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.BOOL.JsonOutput
+Required.ProtobufInput.ValidDataScalar.BOOL.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.DOUBLE.JsonOutput
+Required.ProtobufInput.ValidDataScalar.DOUBLE.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.FIXED32.JsonOutput
+Required.ProtobufInput.ValidDataScalar.FIXED32.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.FIXED64.JsonOutput
+Required.ProtobufInput.ValidDataScalar.FIXED64.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.FLOAT.JsonOutput
+Required.ProtobufInput.ValidDataScalar.FLOAT.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.INT32.JsonOutput
+Required.ProtobufInput.ValidDataScalar.INT32.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.INT64.JsonOutput
+Required.ProtobufInput.ValidDataScalar.INT64.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.SFIXED32.JsonOutput
+Required.ProtobufInput.ValidDataScalar.SFIXED32.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.SFIXED64.JsonOutput
+Required.ProtobufInput.ValidDataScalar.SFIXED64.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.SINT32.JsonOutput
+Required.ProtobufInput.ValidDataScalar.SINT32.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.SINT64.JsonOutput
+Required.ProtobufInput.ValidDataScalar.SINT64.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.UINT32.JsonOutput
+Required.ProtobufInput.ValidDataScalar.UINT32.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.UINT64.JsonOutput
+Required.ProtobufInput.ValidDataScalar.UINT64.ProtobufOutput
+Required.TimestampProtoInputTooLarge.JsonOutput
+Required.TimestampProtoInputTooSmall.JsonOutput
diff --git a/conformance/failure_list_python_cpp.txt b/conformance/failure_list_python_cpp.txt
index 92404d2..d72d79c 100644
--- a/conformance/failure_list_python_cpp.txt
+++ b/conformance/failure_list_python_cpp.txt
@@ -7,21 +7,461 @@
 # TODO(haberman): insert links to corresponding bugs tracking the issue.
 # Should we use GitHub issues or the Google-internal bug tracker?
 
+Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
+Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
+Recommended.FieldMaskTooManyUnderscore.JsonOutput
+Recommended.JsonInput.BoolFieldAllCapitalFalse
+Recommended.JsonInput.BoolFieldAllCapitalTrue
+Recommended.JsonInput.BoolFieldCamelCaseFalse
+Recommended.JsonInput.BoolFieldCamelCaseTrue
+Recommended.JsonInput.BoolFieldDoubleQuotedFalse
+Recommended.JsonInput.BoolFieldDoubleQuotedTrue
+Recommended.JsonInput.BoolFieldIntegerOne
+Recommended.JsonInput.BoolFieldIntegerZero
+Recommended.JsonInput.BoolMapFieldKeyNotQuoted
 Recommended.JsonInput.DoubleFieldInfinityNotQuoted
 Recommended.JsonInput.DoubleFieldNanNotQuoted
 Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
+Recommended.JsonInput.DurationHas3FractionalDigits.Validator
+Recommended.JsonInput.DurationHas6FractionalDigits.Validator
+Recommended.JsonInput.DurationHas9FractionalDigits.Validator
+Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator
+Recommended.JsonInput.FieldMaskInvalidCharacter
+Recommended.JsonInput.FieldNameDuplicate
+Recommended.JsonInput.FieldNameDuplicateDifferentCasing1
+Recommended.JsonInput.FieldNameDuplicateDifferentCasing2
+Recommended.JsonInput.FieldNameNotQuoted
+Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
+Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
+Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
 Recommended.JsonInput.FloatFieldInfinityNotQuoted
 Recommended.JsonInput.FloatFieldNanNotQuoted
 Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
+Recommended.JsonInput.Int32MapFieldKeyNotQuoted
+Recommended.JsonInput.Int64FieldBeString.Validator
+Recommended.JsonInput.Int64MapFieldKeyNotQuoted
+Recommended.JsonInput.JsonWithComments
+Recommended.JsonInput.MapFieldKeyIsNull
+Recommended.JsonInput.MapFieldValueIsNull
+Recommended.JsonInput.MissingCommaMultiline
+Recommended.JsonInput.MissingCommaOneLine
+Recommended.JsonInput.MultilineNoSpaces.JsonOutput
+Recommended.JsonInput.MultilineNoSpaces.ProtobufOutput
+Recommended.JsonInput.MultilineWithSpaces.JsonOutput
+Recommended.JsonInput.MultilineWithSpaces.ProtobufOutput
+Recommended.JsonInput.OneLineNoSpaces.JsonOutput
+Recommended.JsonInput.OneLineNoSpaces.ProtobufOutput
+Recommended.JsonInput.OneLineWithSpaces.JsonOutput
+Recommended.JsonInput.OneLineWithSpaces.ProtobufOutput
+Recommended.JsonInput.OneofZeroBool.JsonOutput
+Recommended.JsonInput.OneofZeroBool.ProtobufOutput
+Recommended.JsonInput.OneofZeroBytes.JsonOutput
+Recommended.JsonInput.OneofZeroBytes.ProtobufOutput
+Recommended.JsonInput.OneofZeroDouble.JsonOutput
+Recommended.JsonInput.OneofZeroDouble.ProtobufOutput
+Recommended.JsonInput.OneofZeroEnum.JsonOutput
+Recommended.JsonInput.OneofZeroEnum.ProtobufOutput
+Recommended.JsonInput.OneofZeroFloat.JsonOutput
+Recommended.JsonInput.OneofZeroFloat.ProtobufOutput
+Recommended.JsonInput.OneofZeroMessage.JsonOutput
+Recommended.JsonInput.OneofZeroMessage.ProtobufOutput
+Recommended.JsonInput.OneofZeroString.JsonOutput
+Recommended.JsonInput.OneofZeroString.ProtobufOutput
+Recommended.JsonInput.OneofZeroUint32.JsonOutput
+Recommended.JsonInput.OneofZeroUint32.ProtobufOutput
+Recommended.JsonInput.OneofZeroUint64.JsonOutput
+Recommended.JsonInput.OneofZeroUint64.ProtobufOutput
+Recommended.JsonInput.RepeatedFieldMessageElementIsNull
+Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull
+Recommended.JsonInput.RepeatedFieldTrailingComma
+Recommended.JsonInput.RepeatedFieldTrailingCommaWithNewlines
+Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpace
+Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace
+Recommended.JsonInput.StringEndsWithEscapeChar
+Recommended.JsonInput.StringFieldInvalidEscape
+Recommended.JsonInput.StringFieldSingleQuoteBoth
+Recommended.JsonInput.StringFieldSingleQuoteKey
+Recommended.JsonInput.StringFieldSingleQuoteValue
+Recommended.JsonInput.StringFieldSurrogateInWrongOrder
+Recommended.JsonInput.StringFieldUnpairedHighSurrogate
+Recommended.JsonInput.StringFieldUnpairedLowSurrogate
+Recommended.JsonInput.StringFieldUnterminatedEscape
+Recommended.JsonInput.StringFieldUppercaseEscapeLetter
+Recommended.JsonInput.TimestampHas3FractionalDigits.Validator
+Recommended.JsonInput.TimestampHas6FractionalDigits.Validator
+Recommended.JsonInput.TimestampHas9FractionalDigits.Validator
+Recommended.JsonInput.TimestampHasZeroFractionalDigit.Validator
+Recommended.JsonInput.TimestampZeroNormalized.Validator
+Recommended.JsonInput.TrailingCommaInAnObject
+Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines
+Recommended.JsonInput.TrailingCommaInAnObjectWithSpace
+Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
+Recommended.JsonInput.Uint32MapFieldKeyNotQuoted
+Recommended.JsonInput.Uint64FieldBeString.Validator
+Recommended.JsonInput.Uint64MapFieldKeyNotQuoted
+Recommended.ProtobufInput.OneofZeroBool.JsonOutput
+Recommended.ProtobufInput.OneofZeroBool.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroBytes.JsonOutput
+Recommended.ProtobufInput.OneofZeroBytes.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroDouble.JsonOutput
+Recommended.ProtobufInput.OneofZeroDouble.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroEnum.JsonOutput
+Recommended.ProtobufInput.OneofZeroEnum.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroFloat.JsonOutput
+Recommended.ProtobufInput.OneofZeroFloat.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroMessage.JsonOutput
+Recommended.ProtobufInput.OneofZeroMessage.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroString.JsonOutput
+Recommended.ProtobufInput.OneofZeroString.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroUint32.JsonOutput
+Recommended.ProtobufInput.OneofZeroUint32.ProtobufOutput
+Recommended.ProtobufInput.OneofZeroUint64.JsonOutput
+Recommended.ProtobufInput.OneofZeroUint64.ProtobufOutput
+Required.DurationProtoInputTooLarge.JsonOutput
+Required.DurationProtoInputTooSmall.JsonOutput
+Required.JsonInput.AllFieldAcceptNull.JsonOutput
+Required.JsonInput.AllFieldAcceptNull.ProtobufOutput
+Required.JsonInput.Any.JsonOutput
+Required.JsonInput.Any.ProtobufOutput
+Required.JsonInput.AnyNested.JsonOutput
+Required.JsonInput.AnyNested.ProtobufOutput
+Required.JsonInput.AnyUnorderedTypeTag.JsonOutput
+Required.JsonInput.AnyUnorderedTypeTag.ProtobufOutput
+Required.JsonInput.AnyWithDuration.JsonOutput
+Required.JsonInput.AnyWithDuration.ProtobufOutput
+Required.JsonInput.AnyWithFieldMask.JsonOutput
+Required.JsonInput.AnyWithFieldMask.ProtobufOutput
+Required.JsonInput.AnyWithInt32ValueWrapper.JsonOutput
+Required.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
+Required.JsonInput.AnyWithStruct.JsonOutput
+Required.JsonInput.AnyWithStruct.ProtobufOutput
+Required.JsonInput.AnyWithTimestamp.JsonOutput
+Required.JsonInput.AnyWithTimestamp.ProtobufOutput
+Required.JsonInput.AnyWithValueForInteger.JsonOutput
+Required.JsonInput.AnyWithValueForInteger.ProtobufOutput
+Required.JsonInput.AnyWithValueForJsonObject.JsonOutput
+Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
+Required.JsonInput.BoolFieldFalse.JsonOutput
+Required.JsonInput.BoolFieldFalse.ProtobufOutput
+Required.JsonInput.BoolFieldTrue.JsonOutput
+Required.JsonInput.BoolFieldTrue.ProtobufOutput
+Required.JsonInput.BoolMapEscapedKey.JsonOutput
+Required.JsonInput.BoolMapEscapedKey.ProtobufOutput
+Required.JsonInput.BoolMapField.JsonOutput
+Required.JsonInput.BoolMapField.ProtobufOutput
+Required.JsonInput.BytesField.JsonOutput
+Required.JsonInput.BytesField.ProtobufOutput
 Required.JsonInput.BytesFieldInvalidBase64Characters
+Required.JsonInput.BytesRepeatedField.JsonOutput
+Required.JsonInput.BytesRepeatedField.ProtobufOutput
+Required.JsonInput.DoubleFieldInfinity.JsonOutput
+Required.JsonInput.DoubleFieldInfinity.ProtobufOutput
+Required.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
+Required.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
+Required.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
+Required.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput
+Required.JsonInput.DoubleFieldMinNegativeValue.JsonOutput
+Required.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput
+Required.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
+Required.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
+Required.JsonInput.DoubleFieldNan.JsonOutput
+Required.JsonInput.DoubleFieldNan.ProtobufOutput
+Required.JsonInput.DoubleFieldNegativeInfinity.JsonOutput
+Required.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput
+Required.JsonInput.DoubleFieldQuotedValue.JsonOutput
+Required.JsonInput.DoubleFieldQuotedValue.ProtobufOutput
+Required.JsonInput.DoubleFieldTooLarge
 Required.JsonInput.DoubleFieldTooSmall
+Required.JsonInput.DurationJsonInputTooLarge
+Required.JsonInput.DurationJsonInputTooSmall
+Required.JsonInput.DurationMaxValue.JsonOutput
+Required.JsonInput.DurationMaxValue.ProtobufOutput
+Required.JsonInput.DurationMinValue.JsonOutput
+Required.JsonInput.DurationMinValue.ProtobufOutput
+Required.JsonInput.DurationMissingS
+Required.JsonInput.DurationRepeatedValue.JsonOutput
+Required.JsonInput.DurationRepeatedValue.ProtobufOutput
+Required.JsonInput.EnumField.JsonOutput
+Required.JsonInput.EnumField.ProtobufOutput
+Required.JsonInput.EnumFieldNotQuoted
+Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput
+Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
+Required.JsonInput.EnumFieldNumericValueZero.JsonOutput
+Required.JsonInput.EnumFieldNumericValueZero.ProtobufOutput
 Required.JsonInput.EnumFieldUnknownValue.Validator
+Required.JsonInput.EnumRepeatedField.JsonOutput
+Required.JsonInput.EnumRepeatedField.ProtobufOutput
+Required.JsonInput.FieldMask.JsonOutput
+Required.JsonInput.FieldMask.ProtobufOutput
+Required.JsonInput.FieldNameEscaped.JsonOutput
+Required.JsonInput.FieldNameEscaped.ProtobufOutput
+Required.JsonInput.FieldNameInLowerCamelCase.Validator
+Required.JsonInput.FieldNameInSnakeCase.JsonOutput
+Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
+Required.JsonInput.FieldNameWithMixedCases.JsonOutput
+Required.JsonInput.FieldNameWithMixedCases.ProtobufOutput
+Required.JsonInput.FieldNameWithMixedCases.Validator
+Required.JsonInput.FieldNameWithNumbers.JsonOutput
+Required.JsonInput.FieldNameWithNumbers.ProtobufOutput
+Required.JsonInput.FieldNameWithNumbers.Validator
+Required.JsonInput.FloatFieldInfinity.JsonOutput
+Required.JsonInput.FloatFieldInfinity.ProtobufOutput
+Required.JsonInput.FloatFieldMaxNegativeValue.JsonOutput
+Required.JsonInput.FloatFieldMaxNegativeValue.ProtobufOutput
+Required.JsonInput.FloatFieldMaxPositiveValue.JsonOutput
+Required.JsonInput.FloatFieldMaxPositiveValue.ProtobufOutput
+Required.JsonInput.FloatFieldMinNegativeValue.JsonOutput
+Required.JsonInput.FloatFieldMinNegativeValue.ProtobufOutput
+Required.JsonInput.FloatFieldMinPositiveValue.JsonOutput
+Required.JsonInput.FloatFieldMinPositiveValue.ProtobufOutput
+Required.JsonInput.FloatFieldNan.JsonOutput
+Required.JsonInput.FloatFieldNan.ProtobufOutput
+Required.JsonInput.FloatFieldNegativeInfinity.JsonOutput
+Required.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput
+Required.JsonInput.FloatFieldQuotedValue.JsonOutput
+Required.JsonInput.FloatFieldQuotedValue.ProtobufOutput
 Required.JsonInput.FloatFieldTooLarge
 Required.JsonInput.FloatFieldTooSmall
+Required.JsonInput.HelloWorld.JsonOutput
+Required.JsonInput.HelloWorld.ProtobufOutput
+Required.JsonInput.Int32FieldExponentialFormat.JsonOutput
+Required.JsonInput.Int32FieldExponentialFormat.ProtobufOutput
+Required.JsonInput.Int32FieldFloatTrailingZero.JsonOutput
+Required.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
+Required.JsonInput.Int32FieldLeadingSpace
+Required.JsonInput.Int32FieldLeadingZero
+Required.JsonInput.Int32FieldMaxFloatValue.JsonOutput
+Required.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
+Required.JsonInput.Int32FieldMaxValue.JsonOutput
+Required.JsonInput.Int32FieldMaxValue.ProtobufOutput
+Required.JsonInput.Int32FieldMinFloatValue.JsonOutput
+Required.JsonInput.Int32FieldMinFloatValue.ProtobufOutput
+Required.JsonInput.Int32FieldMinValue.JsonOutput
+Required.JsonInput.Int32FieldMinValue.ProtobufOutput
+Required.JsonInput.Int32FieldNegativeWithLeadingZero
+Required.JsonInput.Int32FieldNotInteger
+Required.JsonInput.Int32FieldNotNumber
+Required.JsonInput.Int32FieldPlusSign
+Required.JsonInput.Int32FieldStringValue.JsonOutput
+Required.JsonInput.Int32FieldStringValue.ProtobufOutput
+Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput
+Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
+Required.JsonInput.Int32FieldTooLarge
+Required.JsonInput.Int32FieldTooSmall
+Required.JsonInput.Int32FieldTrailingSpace
+Required.JsonInput.Int32MapEscapedKey.JsonOutput
+Required.JsonInput.Int32MapEscapedKey.ProtobufOutput
+Required.JsonInput.Int32MapField.JsonOutput
+Required.JsonInput.Int32MapField.ProtobufOutput
+Required.JsonInput.Int64FieldMaxValue.JsonOutput
+Required.JsonInput.Int64FieldMaxValue.ProtobufOutput
+Required.JsonInput.Int64FieldMaxValueNotQuoted.JsonOutput
+Required.JsonInput.Int64FieldMaxValueNotQuoted.ProtobufOutput
+Required.JsonInput.Int64FieldMinValue.JsonOutput
+Required.JsonInput.Int64FieldMinValue.ProtobufOutput
+Required.JsonInput.Int64FieldMinValueNotQuoted.JsonOutput
+Required.JsonInput.Int64FieldMinValueNotQuoted.ProtobufOutput
+Required.JsonInput.Int64FieldNotInteger
+Required.JsonInput.Int64FieldNotNumber
+Required.JsonInput.Int64FieldTooLarge
+Required.JsonInput.Int64FieldTooSmall
+Required.JsonInput.Int64MapEscapedKey.JsonOutput
+Required.JsonInput.Int64MapEscapedKey.ProtobufOutput
+Required.JsonInput.Int64MapField.JsonOutput
+Required.JsonInput.Int64MapField.ProtobufOutput
+Required.JsonInput.MessageField.JsonOutput
+Required.JsonInput.MessageField.ProtobufOutput
+Required.JsonInput.MessageMapField.JsonOutput
+Required.JsonInput.MessageMapField.ProtobufOutput
+Required.JsonInput.MessageRepeatedField.JsonOutput
+Required.JsonInput.MessageRepeatedField.ProtobufOutput
+Required.JsonInput.OneofFieldDuplicate
+Required.JsonInput.OptionalBoolWrapper.JsonOutput
+Required.JsonInput.OptionalBoolWrapper.ProtobufOutput
+Required.JsonInput.OptionalBytesWrapper.JsonOutput
+Required.JsonInput.OptionalBytesWrapper.ProtobufOutput
+Required.JsonInput.OptionalDoubleWrapper.JsonOutput
+Required.JsonInput.OptionalDoubleWrapper.ProtobufOutput
+Required.JsonInput.OptionalFloatWrapper.JsonOutput
+Required.JsonInput.OptionalFloatWrapper.ProtobufOutput
+Required.JsonInput.OptionalInt32Wrapper.JsonOutput
+Required.JsonInput.OptionalInt32Wrapper.ProtobufOutput
+Required.JsonInput.OptionalInt64Wrapper.JsonOutput
+Required.JsonInput.OptionalInt64Wrapper.ProtobufOutput
+Required.JsonInput.OptionalStringWrapper.JsonOutput
+Required.JsonInput.OptionalStringWrapper.ProtobufOutput
+Required.JsonInput.OptionalUint32Wrapper.JsonOutput
+Required.JsonInput.OptionalUint32Wrapper.ProtobufOutput
+Required.JsonInput.OptionalUint64Wrapper.JsonOutput
+Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput
+Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
+Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
+Required.JsonInput.OriginalProtoFieldName.JsonOutput
+Required.JsonInput.OriginalProtoFieldName.ProtobufOutput
+Required.JsonInput.PrimitiveRepeatedField.JsonOutput
+Required.JsonInput.PrimitiveRepeatedField.ProtobufOutput
+Required.JsonInput.RepeatedBoolWrapper.JsonOutput
+Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput
+Required.JsonInput.RepeatedBytesWrapper.JsonOutput
+Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput
+Required.JsonInput.RepeatedDoubleWrapper.JsonOutput
+Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput
 Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotMessage
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotString
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotBool
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotInt
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotString
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
+Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotMessage
+Required.JsonInput.RepeatedFloatWrapper.JsonOutput
+Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput
+Required.JsonInput.RepeatedInt32Wrapper.JsonOutput
+Required.JsonInput.RepeatedInt32Wrapper.ProtobufOutput
+Required.JsonInput.RepeatedInt64Wrapper.JsonOutput
+Required.JsonInput.RepeatedInt64Wrapper.ProtobufOutput
+Required.JsonInput.RepeatedStringWrapper.JsonOutput
+Required.JsonInput.RepeatedStringWrapper.ProtobufOutput
+Required.JsonInput.RepeatedUint32Wrapper.JsonOutput
+Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput
+Required.JsonInput.RepeatedUint64Wrapper.JsonOutput
+Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput
+Required.JsonInput.StringField.JsonOutput
+Required.JsonInput.StringField.ProtobufOutput
+Required.JsonInput.StringFieldEscape.JsonOutput
+Required.JsonInput.StringFieldEscape.ProtobufOutput
+Required.JsonInput.StringFieldNotAString
+Required.JsonInput.StringFieldSurrogatePair.JsonOutput
+Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput
+Required.JsonInput.StringFieldUnicode.JsonOutput
+Required.JsonInput.StringFieldUnicode.ProtobufOutput
+Required.JsonInput.StringFieldUnicodeEscape.JsonOutput
+Required.JsonInput.StringFieldUnicodeEscape.ProtobufOutput
+Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput
+Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput
+Required.JsonInput.StringRepeatedField.JsonOutput
+Required.JsonInput.StringRepeatedField.ProtobufOutput
+Required.JsonInput.Struct.JsonOutput
+Required.JsonInput.Struct.ProtobufOutput
 Required.JsonInput.TimestampJsonInputLowercaseT
+Required.JsonInput.TimestampJsonInputLowercaseZ
+Required.JsonInput.TimestampJsonInputMissingT
+Required.JsonInput.TimestampJsonInputMissingZ
+Required.JsonInput.TimestampJsonInputTooLarge
+Required.JsonInput.TimestampJsonInputTooSmall
+Required.JsonInput.TimestampMaxValue.JsonOutput
+Required.JsonInput.TimestampMaxValue.ProtobufOutput
+Required.JsonInput.TimestampMinValue.JsonOutput
+Required.JsonInput.TimestampMinValue.ProtobufOutput
+Required.JsonInput.TimestampRepeatedValue.JsonOutput
+Required.JsonInput.TimestampRepeatedValue.ProtobufOutput
+Required.JsonInput.TimestampWithNegativeOffset.JsonOutput
+Required.JsonInput.TimestampWithNegativeOffset.ProtobufOutput
+Required.JsonInput.TimestampWithPositiveOffset.JsonOutput
+Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput
+Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput
+Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
+Required.JsonInput.Uint32FieldMaxValue.JsonOutput
+Required.JsonInput.Uint32FieldMaxValue.ProtobufOutput
+Required.JsonInput.Uint32FieldNotInteger
+Required.JsonInput.Uint32FieldNotNumber
+Required.JsonInput.Uint32FieldTooLarge
+Required.JsonInput.Uint32MapField.JsonOutput
+Required.JsonInput.Uint32MapField.ProtobufOutput
+Required.JsonInput.Uint64FieldMaxValue.JsonOutput
+Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput
+Required.JsonInput.Uint64FieldMaxValueNotQuoted.JsonOutput
+Required.JsonInput.Uint64FieldMaxValueNotQuoted.ProtobufOutput
+Required.JsonInput.Uint64FieldNotInteger
+Required.JsonInput.Uint64FieldNotNumber
+Required.JsonInput.Uint64FieldTooLarge
+Required.JsonInput.Uint64MapField.JsonOutput
+Required.JsonInput.Uint64MapField.ProtobufOutput
+Required.JsonInput.ValueAcceptBool.JsonOutput
+Required.JsonInput.ValueAcceptBool.ProtobufOutput
+Required.JsonInput.ValueAcceptFloat.JsonOutput
+Required.JsonInput.ValueAcceptFloat.ProtobufOutput
+Required.JsonInput.ValueAcceptInteger.JsonOutput
+Required.JsonInput.ValueAcceptInteger.ProtobufOutput
+Required.JsonInput.ValueAcceptList.JsonOutput
+Required.JsonInput.ValueAcceptList.ProtobufOutput
+Required.JsonInput.ValueAcceptNull.JsonOutput
+Required.JsonInput.ValueAcceptNull.ProtobufOutput
+Required.JsonInput.ValueAcceptObject.JsonOutput
+Required.JsonInput.ValueAcceptObject.ProtobufOutput
+Required.JsonInput.ValueAcceptString.JsonOutput
+Required.JsonInput.ValueAcceptString.ProtobufOutput
+Required.JsonInput.WrapperTypesWithNullValue.JsonOutput
+Required.JsonInput.WrapperTypesWithNullValue.ProtobufOutput
+Required.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
+Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
+Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
+Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
+Required.ProtobufInput.IllegalZeroFieldNum_Case_0
+Required.ProtobufInput.IllegalZeroFieldNum_Case_1
+Required.ProtobufInput.IllegalZeroFieldNum_Case_2
+Required.ProtobufInput.IllegalZeroFieldNum_Case_3
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BOOL
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BYTES
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.DOUBLE
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.ENUM
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED32
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED64
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FLOAT
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT32
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT64
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.MESSAGE
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED32
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED64
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT32
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT64
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.STRING
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT32
+Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT64
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BOOL
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BYTES
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.DOUBLE
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.ENUM
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED32
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED64
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FLOAT
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT32
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT64
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED32
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED64
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT32
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT64
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.STRING
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT32
+Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT64
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.BOOL
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.BYTES
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.DOUBLE
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.ENUM
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED32
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED64
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.FLOAT
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT32
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT64
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.MESSAGE
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED32
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED64
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT32
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT64
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.STRING
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT32
+Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT64
+Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.BYTES
 Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
+Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.STRING
+Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.BYTES
 Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
+Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.STRING
+Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.BYTES
+Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.MESSAGE
+Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.STRING
 Required.ProtobufInput.PrematureEofInPackedField.BOOL
 Required.ProtobufInput.PrematureEofInPackedField.DOUBLE
 Required.ProtobufInput.PrematureEofInPackedField.ENUM
@@ -36,3 +476,149 @@
 Required.ProtobufInput.PrematureEofInPackedField.SINT64
 Required.ProtobufInput.PrematureEofInPackedField.UINT32
 Required.ProtobufInput.PrematureEofInPackedField.UINT64
+Required.ProtobufInput.PrematureEofInPackedFieldValue.BOOL
+Required.ProtobufInput.PrematureEofInPackedFieldValue.DOUBLE
+Required.ProtobufInput.PrematureEofInPackedFieldValue.ENUM
+Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED32
+Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED64
+Required.ProtobufInput.PrematureEofInPackedFieldValue.FLOAT
+Required.ProtobufInput.PrematureEofInPackedFieldValue.INT32
+Required.ProtobufInput.PrematureEofInPackedFieldValue.INT64
+Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED32
+Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED64
+Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT32
+Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT64
+Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT32
+Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT64
+Required.ProtobufInput.PrematureEofInSubmessageValue.MESSAGE
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BOOL
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BYTES
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.DOUBLE
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.ENUM
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED32
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED64
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FLOAT
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT32
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT64
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.MESSAGE
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED32
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED64
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT32
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT64
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.STRING
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT32
+Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT64
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BOOL
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BYTES
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.DOUBLE
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.ENUM
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED32
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED64
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FLOAT
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT32
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT64
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED32
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED64
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT32
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT64
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.STRING
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT32
+Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT64
+Required.ProtobufInput.PrematureEofInsideUnknownValue.BOOL
+Required.ProtobufInput.PrematureEofInsideUnknownValue.BYTES
+Required.ProtobufInput.PrematureEofInsideUnknownValue.DOUBLE
+Required.ProtobufInput.PrematureEofInsideUnknownValue.ENUM
+Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED32
+Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED64
+Required.ProtobufInput.PrematureEofInsideUnknownValue.FLOAT
+Required.ProtobufInput.PrematureEofInsideUnknownValue.INT32
+Required.ProtobufInput.PrematureEofInsideUnknownValue.INT64
+Required.ProtobufInput.PrematureEofInsideUnknownValue.MESSAGE
+Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED32
+Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED64
+Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT32
+Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT64
+Required.ProtobufInput.PrematureEofInsideUnknownValue.STRING
+Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT32
+Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT64
+Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.ProtobufOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.JsonOutput
+Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.BOOL.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.BOOL.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.DOUBLE.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.DOUBLE.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.FIXED32.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.FIXED32.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.FIXED64.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.FIXED64.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.FLOAT.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.FLOAT.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.INT32.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.INT32.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.INT64.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.INT64.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.SFIXED32.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.SFIXED32.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.SFIXED64.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.SFIXED64.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.SINT32.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.SINT32.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.SINT64.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.SINT64.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.UINT32.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.UINT32.ProtobufOutput
+Required.ProtobufInput.ValidDataRepeated.UINT64.JsonOutput
+Required.ProtobufInput.ValidDataRepeated.UINT64.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.BOOL.JsonOutput
+Required.ProtobufInput.ValidDataScalar.BOOL.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.DOUBLE.JsonOutput
+Required.ProtobufInput.ValidDataScalar.DOUBLE.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.FIXED32.JsonOutput
+Required.ProtobufInput.ValidDataScalar.FIXED32.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.FIXED64.JsonOutput
+Required.ProtobufInput.ValidDataScalar.FIXED64.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.FLOAT.JsonOutput
+Required.ProtobufInput.ValidDataScalar.FLOAT.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.INT32.JsonOutput
+Required.ProtobufInput.ValidDataScalar.INT32.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.INT64.JsonOutput
+Required.ProtobufInput.ValidDataScalar.INT64.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.SFIXED32.JsonOutput
+Required.ProtobufInput.ValidDataScalar.SFIXED32.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.SFIXED64.JsonOutput
+Required.ProtobufInput.ValidDataScalar.SFIXED64.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.SINT32.JsonOutput
+Required.ProtobufInput.ValidDataScalar.SINT32.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.SINT64.JsonOutput
+Required.ProtobufInput.ValidDataScalar.SINT64.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.UINT32.JsonOutput
+Required.ProtobufInput.ValidDataScalar.UINT32.ProtobufOutput
+Required.ProtobufInput.ValidDataScalar.UINT64.JsonOutput
+Required.ProtobufInput.ValidDataScalar.UINT64.ProtobufOutput
+Required.TimestampProtoInputTooLarge.JsonOutput
+Required.TimestampProtoInputTooSmall.JsonOutput
diff --git a/generate_descriptor_proto.sh b/generate_descriptor_proto.sh
index 809214c..229bec4 100755
--- a/generate_descriptor_proto.sh
+++ b/generate_descriptor_proto.sh
@@ -41,6 +41,11 @@
   google/protobuf/type.proto \
   google/protobuf/wrappers.proto)
 
+declare -a COMPILER_PROTO_FILES=(\
+  google/protobuf/compiler/plugin.proto \
+  google/protobuf/compiler/profile.proto \
+)
+
 CORE_PROTO_IS_CORRECT=0
 PROCESS_ROUND=1
 TMP=$(mktemp -d)
@@ -57,9 +62,9 @@
   fi
 
   ./protoc --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:$TMP ${RUNTIME_PROTO_FILES[@]} && \
-  ./protoc --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:$TMP google/protobuf/compiler/plugin.proto
+  ./protoc --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:$TMP ${COMPILER_PROTO_FILES[@]}
 
-  for PROTO_FILE in ${RUNTIME_PROTO_FILES[@]}; do
+  for PROTO_FILE in ${RUNTIME_PROTO_FILES[@]} ${COMPILER_PROTO_FILES[@]}; do
     BASE_NAME=${PROTO_FILE%.*}
     diff ${BASE_NAME}.pb.h $TMP/${BASE_NAME}.pb.h > /dev/null
     if test $? -ne 0; then
@@ -71,24 +76,14 @@
     fi
   done
 
-  diff google/protobuf/compiler/plugin.pb.h $TMP/google/protobuf/compiler/plugin.pb.h > /dev/null
-  if test $? -ne 0; then
-    CORE_PROTO_IS_CORRECT=0
-  fi
-  diff google/protobuf/compiler/plugin.pb.cc $TMP/google/protobuf/compiler/plugin.pb.cc > /dev/null
-  if test $? -ne 0; then
-    CORE_PROTO_IS_CORRECT=0
-  fi
-
   # Only override the output if the files are different to avoid re-compilation
   # of the protoc.
   if [ $CORE_PROTO_IS_CORRECT -ne 1 ]; then
-    for PROTO_FILE in ${RUNTIME_PROTO_FILES[@]}; do
+    for PROTO_FILE in ${RUNTIME_PROTO_FILES[@]} ${COMPILER_PROTO_FILES[@]}; do
       BASE_NAME=${PROTO_FILE%.*}
       mv $TMP/${BASE_NAME}.pb.h ${BASE_NAME}.pb.h
       mv $TMP/${BASE_NAME}.pb.cc ${BASE_NAME}.pb.cc
     done
-    mv $TMP/google/protobuf/compiler/plugin.pb.* google/protobuf/compiler/
   fi
 
   PROCESS_ROUND=$((PROCESS_ROUND + 1))
diff --git a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java
index 37180da..b5043eb 100644
--- a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java
+++ b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java
@@ -34,7 +34,6 @@
 import com.google.protobuf.Descriptors.FieldDescriptor;
 import com.google.protobuf.Descriptors.OneofDescriptor;
 import com.google.protobuf.Internal.EnumLite;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Arrays;
@@ -328,7 +327,8 @@
       extends AbstractMessageLite.Builder
       implements Message.Builder {
     // The compiler produces an error if this is not declared explicitly.
-    // Method isn't abstract to bypass Java 1.6 compiler issue http://bugs.java.com/view_bug.do?bug_id=6908259
+    // Method isn't abstract to bypass Java 1.6 compiler issue:
+    //     http://bugs.java.com/view_bug.do?bug_id=6908259
     @Override
     public BuilderType clone() {
       throw new UnsupportedOperationException("clone() should be implemented in subclasses.");
diff --git a/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java b/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java
index 4f691df..99787fc 100644
--- a/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java
+++ b/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java
@@ -30,6 +30,8 @@
 
 package com.google.protobuf;
 
+import static com.google.protobuf.Internal.checkNotNull;
+
 import java.io.FilterInputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -351,22 +353,23 @@
      */
     protected static <T> void addAll(final Iterable<T> values,
                                      final Collection<? super T> list) {
-      if (values == null) {
-        throw new NullPointerException();
-      }
+      checkNotNull(values);
       if (values instanceof LazyStringList) {
         // For StringOrByteStringLists, check the underlying elements to avoid
         // forcing conversions of ByteStrings to Strings.
+        // TODO(dweis): Could we just prohibit nulls in all protobuf lists and get rid of this? Is
+        // if even possible to hit this condition as all protobuf methods check for null first,
+        // right?
         checkForNullValues(((LazyStringList) values).getUnderlyingElements());
         list.addAll((Collection<T>) values);
       } else if (values instanceof Collection) {
-        checkForNullValues(values);
+        if (!(values instanceof PrimitiveNonBoxingCollection)) {
+          checkForNullValues(values);
+        }
         list.addAll((Collection<T>) values);
       } else {
         for (final T value : values) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
+          checkNotNull(value);
           list.add(value);
         }
       }
@@ -374,9 +377,7 @@
 
     private static void checkForNullValues(final Iterable<?> values) {
       for (final Object value : values) {
-        if (value == null) {
-          throw new NullPointerException();
-        }
+        checkNotNull(value);
       }
     }
   }
diff --git a/java/core/src/main/java/com/google/protobuf/AbstractParser.java b/java/core/src/main/java/com/google/protobuf/AbstractParser.java
index 7ff73ba..ba570e3 100644
--- a/java/core/src/main/java/com/google/protobuf/AbstractParser.java
+++ b/java/core/src/main/java/com/google/protobuf/AbstractParser.java
@@ -31,9 +31,9 @@
 package com.google.protobuf;
 
 import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream;
-
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.ByteBuffer;
 
 /**
  * A partial implementation of the {@link Parser} interface which implements
@@ -131,6 +131,30 @@
   }
 
   @Override
+  public MessageType parseFrom(ByteBuffer data, ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    MessageType message;
+    try {
+      CodedInputStream input = CodedInputStream.newInstance(data);
+      message = parsePartialFrom(input, extensionRegistry);
+      try {
+        input.checkLastTagWas(0);
+      } catch (InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(message);
+      }
+    } catch (InvalidProtocolBufferException e) {
+      throw e;
+    }
+
+    return checkMessageInitialized(message);
+  }
+
+  @Override
+  public MessageType parseFrom(ByteBuffer data) throws InvalidProtocolBufferException {
+    return parseFrom(data, EMPTY_REGISTRY);
+  }
+
+  @Override
   public MessageType parsePartialFrom(
       byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
       throws InvalidProtocolBufferException {
diff --git a/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java b/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java
index 0d9f87b..fd4c142 100644
--- a/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java
@@ -30,8 +30,9 @@
 
 package com.google.protobuf;
 
-import com.google.protobuf.Internal.BooleanList;
+import static com.google.protobuf.Internal.checkNotNull;
 
+import com.google.protobuf.Internal.BooleanList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.RandomAccess;
@@ -41,9 +42,8 @@
  *
  * @author dweis@google.com (Daniel Weis)
  */
-final class BooleanArrayList
-    extends AbstractProtobufList<Boolean>
-    implements BooleanList, RandomAccess {
+final class BooleanArrayList extends AbstractProtobufList<Boolean>
+    implements BooleanList, RandomAccess, PrimitiveNonBoxingCollection {
 
   private static final BooleanArrayList EMPTY_LIST = new BooleanArrayList();
   static {
@@ -198,9 +198,7 @@
   public boolean addAll(Collection<? extends Boolean> collection) {
     ensureIsMutable();
 
-    if (collection == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(collection);
 
     // We specialize when adding another BooleanArrayList to avoid boxing elements.
     if (!(collection instanceof BooleanArrayList)) {
diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
index 239798e..3dfbcb0 100644
--- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
+++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
@@ -355,8 +355,8 @@
    * <p>Set the maximum message size. In order to prevent malicious messages from exhausting memory
    * or causing integer overflows, {@code CodedInputStream} limits how large a message may be. The
    * default limit is {@code Integer.MAX_INT}. You should set this limit as small as you can without
-   * harming your app's functionality. Note that size limits only apply when reading from an
-   * {@code InputStream}, not when constructed around a raw byte array.
+   * harming your app's functionality. Note that size limits only apply when reading from an {@code
+   * InputStream}, not when constructed around a raw byte array.
    *
    * <p>If you want to read several messages from a single CodedInputStream, you could call {@link
    * #resetSizeCounter()} after each one to avoid hitting the size limit.
diff --git a/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java b/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java
index 3e32c2c..da0e9b1 100644
--- a/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java
+++ b/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java
@@ -184,7 +184,7 @@
    *     maps are sorted on the lexicographical order of the UTF8 encoded keys.
    * </ul>
    */
-  void useDeterministicSerialization() {
+  public void useDeterministicSerialization() {
     serializationDeterministic = true;
   }
 
@@ -1854,7 +1854,7 @@
     }
 
     static boolean isSupported() {
-      return UnsafeUtil.hasUnsafeByteBufferOperations();
+      return UnsafeUtil.hasUnsafeByteBufferOperations() && UnsafeUtil.hasUnsafeCopyMemory();
     }
 
     @Override
diff --git a/java/core/src/main/java/com/google/protobuf/Descriptors.java b/java/core/src/main/java/com/google/protobuf/Descriptors.java
index 38346f1..75b16fe 100644
--- a/java/core/src/main/java/com/google/protobuf/Descriptors.java
+++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java
@@ -30,9 +30,10 @@
 
 package com.google.protobuf;
 
+import static com.google.protobuf.Internal.checkNotNull;
+
 import com.google.protobuf.DescriptorProtos.*;
 import com.google.protobuf.Descriptors.FileDescriptor.Syntax;
-
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -682,9 +683,7 @@
 
     /** Determines if the given field name is reserved. */
     public boolean isReservedName(final String name) {
-      if (name == null) {
-        throw new NullPointerException();
-      }
+      checkNotNull(name);
       for (final String reservedName : proto.getReservedNameList()) {
         if (reservedName.equals(name)) {
           return true;
diff --git a/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java b/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java
index 6177f3c..867b85c 100644
--- a/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java
@@ -30,8 +30,9 @@
 
 package com.google.protobuf;
 
-import com.google.protobuf.Internal.DoubleList;
+import static com.google.protobuf.Internal.checkNotNull;
 
+import com.google.protobuf.Internal.DoubleList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.RandomAccess;
@@ -41,9 +42,8 @@
  *
  * @author dweis@google.com (Daniel Weis)
  */
-final class DoubleArrayList
-    extends AbstractProtobufList<Double>
-    implements DoubleList, RandomAccess {
+final class DoubleArrayList extends AbstractProtobufList<Double>
+    implements DoubleList, RandomAccess, PrimitiveNonBoxingCollection {
 
   private static final DoubleArrayList EMPTY_LIST = new DoubleArrayList();
   static {
@@ -199,9 +199,7 @@
   public boolean addAll(Collection<? extends Double> collection) {
     ensureIsMutable();
 
-    if (collection == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(collection);
 
     // We specialize when adding another DoubleArrayList to avoid boxing elements.
     if (!(collection instanceof DoubleArrayList)) {
diff --git a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
index e6358c3..2631db7 100644
--- a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
+++ b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
@@ -30,11 +30,12 @@
 
 package com.google.protobuf;
 
+import static com.google.protobuf.Internal.checkNotNull;
+
 import com.google.protobuf.Descriptors.Descriptor;
 import com.google.protobuf.Descriptors.EnumValueDescriptor;
 import com.google.protobuf.Descriptors.FieldDescriptor;
 import com.google.protobuf.Descriptors.OneofDescriptor;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Collections;
@@ -631,9 +632,7 @@
     /** Verifies that the value is EnumValueDescriptor and matches Enum Type. */
     private void ensureSingularEnumValueDescriptor(
         FieldDescriptor field, Object value) {
-      if (value == null) {
-        throw new NullPointerException();
-      }
+      checkNotNull(value);
       if (!(value instanceof EnumValueDescriptor)) {
         throw new IllegalArgumentException(
           "DynamicMessage should use EnumValueDescriptor to set Enum Value.");
diff --git a/java/core/src/main/java/com/google/protobuf/FieldSet.java b/java/core/src/main/java/com/google/protobuf/FieldSet.java
index a828f30..8a9239e 100644
--- a/java/core/src/main/java/com/google/protobuf/FieldSet.java
+++ b/java/core/src/main/java/com/google/protobuf/FieldSet.java
@@ -30,8 +30,9 @@
 
 package com.google.protobuf;
 
-import com.google.protobuf.LazyField.LazyIterator;
+import static com.google.protobuf.Internal.checkNotNull;
 
+import com.google.protobuf.LazyField.LazyIterator;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -385,9 +386,7 @@
    */
   private static void verifyType(final WireFormat.FieldType type,
                                  final Object value) {
-    if (value == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(value);
 
     boolean isValid = false;
     switch (type.getJavaType()) {
diff --git a/java/core/src/main/java/com/google/protobuf/FloatArrayList.java b/java/core/src/main/java/com/google/protobuf/FloatArrayList.java
index 90d6154..7664558 100644
--- a/java/core/src/main/java/com/google/protobuf/FloatArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/FloatArrayList.java
@@ -30,8 +30,9 @@
 
 package com.google.protobuf;
 
-import com.google.protobuf.Internal.FloatList;
+import static com.google.protobuf.Internal.checkNotNull;
 
+import com.google.protobuf.Internal.FloatList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.RandomAccess;
@@ -41,9 +42,8 @@
  *
  * @author dweis@google.com (Daniel Weis)
  */
-final class FloatArrayList
-    extends AbstractProtobufList<Float>
-    implements FloatList, RandomAccess {
+final class FloatArrayList extends AbstractProtobufList<Float>
+    implements FloatList, RandomAccess, PrimitiveNonBoxingCollection {
 
   private static final FloatArrayList EMPTY_LIST = new FloatArrayList();
   static {
@@ -198,9 +198,7 @@
   public boolean addAll(Collection<? extends Float> collection) {
     ensureIsMutable();
 
-    if (collection == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(collection);
 
     // We specialize when adding another FloatArrayList to avoid boxing elements.
     if (!(collection instanceof FloatArrayList)) {
diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
index 2d7fd33..cf3486e 100644
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
@@ -34,6 +34,7 @@
 import com.google.protobuf.GeneratedMessageLite.EqualsVisitor.NotEqualsException;
 import com.google.protobuf.Internal.BooleanList;
 import com.google.protobuf.Internal.DoubleList;
+import com.google.protobuf.Internal.EnumLiteMap;
 import com.google.protobuf.Internal.FloatList;
 import com.google.protobuf.Internal.IntList;
 import com.google.protobuf.Internal.LongList;
@@ -45,6 +46,7 @@
 import java.io.Serializable;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
@@ -136,6 +138,7 @@
       return false;
     }
 
+
     try {
       visit(EqualsVisitor.INSTANCE, (MessageType) other);
     } catch (NotEqualsException e) {
@@ -1154,6 +1157,7 @@
     }
   }
 
+
   /**
    * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}.
    *
@@ -1529,6 +1533,20 @@
 
   // Validates last tag.
   protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
+      T defaultInstance, ByteBuffer data, ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    return checkMessageInitialized(
+        parseFrom(defaultInstance, CodedInputStream.newInstance(data), extensionRegistry));
+  }
+
+  // Validates last tag.
+  protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
+      T defaultInstance, ByteBuffer data) throws InvalidProtocolBufferException {
+    return parseFrom(defaultInstance, data, ExtensionRegistryLite.getEmptyRegistry());
+  }
+
+  // Validates last tag.
+  protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
       T defaultInstance, ByteString data)
       throws InvalidProtocolBufferException {
     return checkMessageInitialized(
@@ -1979,13 +1997,13 @@
   /**
    * Implements hashCode by accumulating state.
    */
-  private static class HashCodeVisitor implements Visitor {
+  static class HashCodeVisitor implements Visitor {
 
     // The caller must ensure that the visitor is invoked parameterized with this and this such that
     // other is this. This is required due to how oneof cases are handled. See the class comment
     // on Visitor for more information.
 
-    private int hashCode = 0;
+    int hashCode = 0;
 
     @Override
     public boolean visitBoolean(
diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
index fd051e7..b949cd1 100644
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
@@ -41,7 +41,7 @@
 // class without breaking binary compatibility with old generated code that still subclasses
 // the old GeneratedMessageV3 class. To allow these different GeneratedMessageV3V? classes to
 // interoperate (e.g., a GeneratedMessageV3V3 object has a message extension field whose class
-// type is GeneratedMessageV3V4), these classes still share a common parent class AbstarctMessage
+// type is GeneratedMessageV3V4), these classes still share a common parent class AbstractMessage
 // and are using the same GeneratedMessage.GeneratedExtension class for extension definitions.
 // Since this class becomes GeneratedMessageV3V? in opensource, we have to add an import here
 // to be able to use GeneratedMessage.GeneratedExtension. The GeneratedExtension definition in
diff --git a/java/core/src/main/java/com/google/protobuf/IntArrayList.java b/java/core/src/main/java/com/google/protobuf/IntArrayList.java
index 2f526e3..aff5c21 100644
--- a/java/core/src/main/java/com/google/protobuf/IntArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/IntArrayList.java
@@ -30,8 +30,9 @@
 
 package com.google.protobuf;
 
-import com.google.protobuf.Internal.IntList;
+import static com.google.protobuf.Internal.checkNotNull;
 
+import com.google.protobuf.Internal.IntList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.RandomAccess;
@@ -41,9 +42,8 @@
  *
  * @author dweis@google.com (Daniel Weis)
  */
-final class IntArrayList
-    extends AbstractProtobufList<Integer>
-    implements IntList, RandomAccess {
+final class IntArrayList extends AbstractProtobufList<Integer>
+    implements IntList, RandomAccess, PrimitiveNonBoxingCollection {
 
   private static final IntArrayList EMPTY_LIST = new IntArrayList();
   static {
@@ -198,9 +198,7 @@
   public boolean addAll(Collection<? extends Integer> collection) {
     ensureIsMutable();
 
-    if (collection == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(collection);
 
     // We specialize when adding another IntArrayList to avoid boxing elements.
     if (!(collection instanceof IntArrayList)) {
diff --git a/java/core/src/main/java/com/google/protobuf/Internal.java b/java/core/src/main/java/com/google/protobuf/Internal.java
index c234559..36bdece 100644
--- a/java/core/src/main/java/com/google/protobuf/Internal.java
+++ b/java/core/src/main/java/com/google/protobuf/Internal.java
@@ -62,6 +62,16 @@
   /**
    * Throws an appropriate {@link NullPointerException} if the given objects is {@code null}.
    */
+  static <T> T checkNotNull(T obj) {
+    if (obj == null) {
+      throw new NullPointerException();
+    }
+    return obj;
+  }
+
+  /**
+   * Throws an appropriate {@link NullPointerException} if the given objects is {@code null}.
+   */
   static <T> T checkNotNull(T obj, String message) {
     if (obj == null) {
       throw new NullPointerException(message);
@@ -420,6 +430,11 @@
       CodedInputStream.newInstance(EMPTY_BYTE_ARRAY);
 
 
+  /** Helper method to merge two MessageLite instances. */
+  static Object mergeMessage(Object destination, Object source) {
+    return ((MessageLite) destination).toBuilder().mergeFrom((MessageLite) source).buildPartial();
+  }
+
   /**
    * Provides an immutable view of {@code List<T>} around a {@code List<F>}.
    *
diff --git a/java/core/src/main/java/com/google/protobuf/LazyFieldLite.java b/java/core/src/main/java/com/google/protobuf/LazyFieldLite.java
index 4b0ba0f..49ecfc0 100644
--- a/java/core/src/main/java/com/google/protobuf/LazyFieldLite.java
+++ b/java/core/src/main/java/com/google/protobuf/LazyFieldLite.java
@@ -394,6 +394,7 @@
     }
   }
 
+
   /**
    * Might lazily parse the bytes that were previously passed in. Is thread-safe.
    */
diff --git a/java/core/src/main/java/com/google/protobuf/LongArrayList.java b/java/core/src/main/java/com/google/protobuf/LongArrayList.java
index 5a772e3..fc146e2 100644
--- a/java/core/src/main/java/com/google/protobuf/LongArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/LongArrayList.java
@@ -30,8 +30,9 @@
 
 package com.google.protobuf;
 
-import com.google.protobuf.Internal.LongList;
+import static com.google.protobuf.Internal.checkNotNull;
 
+import com.google.protobuf.Internal.LongList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.RandomAccess;
@@ -41,9 +42,8 @@
  *
  * @author dweis@google.com (Daniel Weis)
  */
-final class LongArrayList
-    extends AbstractProtobufList<Long>
-    implements LongList, RandomAccess {
+final class LongArrayList extends AbstractProtobufList<Long>
+    implements LongList, RandomAccess, PrimitiveNonBoxingCollection {
 
   private static final LongArrayList EMPTY_LIST = new LongArrayList();
   static {
@@ -198,9 +198,7 @@
   public boolean addAll(Collection<? extends Long> collection) {
     ensureIsMutable();
 
-    if (collection == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(collection);
 
     // We specialize when adding another LongArrayList to avoid boxing elements.
     if (!(collection instanceof LongArrayList)) {
diff --git a/java/core/src/main/java/com/google/protobuf/MapEntry.java b/java/core/src/main/java/com/google/protobuf/MapEntry.java
index 7e8e9aa..0849b82 100644
--- a/java/core/src/main/java/com/google/protobuf/MapEntry.java
+++ b/java/core/src/main/java/com/google/protobuf/MapEntry.java
@@ -33,7 +33,6 @@
 import com.google.protobuf.Descriptors.Descriptor;
 import com.google.protobuf.Descriptors.EnumValueDescriptor;
 import com.google.protobuf.Descriptors.FieldDescriptor;
-
 import java.io.IOException;
 import java.util.Collections;
 import java.util.Map;
@@ -171,7 +170,7 @@
 
   @Override
   public Builder<K, V> toBuilder() {
-    return new Builder<K, V>(metadata, key, value);
+    return new Builder<K, V>(metadata, key, value, true, true);
   }
 
   @Override
@@ -247,15 +246,19 @@
     private final Metadata<K, V> metadata;
     private K key;
     private V value;
+    private boolean hasKey;
+    private boolean hasValue;
 
     private Builder(Metadata<K, V> metadata) {
-      this(metadata, metadata.defaultKey, metadata.defaultValue);
+      this(metadata, metadata.defaultKey, metadata.defaultValue, false, false);
     }
 
-    private Builder(Metadata<K, V> metadata, K key, V value) {
+    private Builder(Metadata<K, V> metadata, K key, V value, boolean hasKey, boolean hasValue) {
       this.metadata = metadata;
       this.key = key;
       this.value = value;
+      this.hasKey = hasKey;
+      this.hasValue = hasValue;
     }
 
     public K getKey() {
@@ -268,21 +271,25 @@
 
     public Builder<K, V> setKey(K key) {
       this.key = key;
+      this.hasKey = true;
       return this;
     }
 
     public Builder<K, V> clearKey() {
       this.key = metadata.defaultKey;
+      this.hasKey = false;
       return this;
     }
 
     public Builder<K, V> setValue(V value) {
       this.value = value;
+      this.hasValue = true;
       return this;
     }
 
     public Builder<K, V> clearValue() {
       this.value = metadata.defaultValue;
+      this.hasValue = false;
       return this;
     }
 
@@ -404,7 +411,7 @@
     @Override
     public boolean hasField(FieldDescriptor field) {
       checkFieldDescriptor(field);
-      return true;
+      return field.getNumber() == 1 ? hasKey : hasValue;
     }
 
     @Override
@@ -438,7 +445,7 @@
     @Override
     @SuppressWarnings("unchecked")
     public Builder<K, V> clone() {
-      return new Builder(metadata, key, value);
+      return new Builder(metadata, key, value, hasKey, hasValue);
     }
   }
 
@@ -448,4 +455,9 @@
     }
     return true;
   }
+  
+  /** Returns the metadata only for experimental runtime. */
+  final Metadata<K, V> getMetadata() {
+    return metadata;
+  }
 }
diff --git a/java/core/src/main/java/com/google/protobuf/MapEntryLite.java b/java/core/src/main/java/com/google/protobuf/MapEntryLite.java
index 22aef8f..dcb5dfa 100644
--- a/java/core/src/main/java/com/google/protobuf/MapEntryLite.java
+++ b/java/core/src/main/java/com/google/protobuf/MapEntryLite.java
@@ -223,4 +223,9 @@
     input.popLimit(oldLimit);
     map.put(key, value);
   }
+
+  /** For experimental runtime internal use only. */
+  Metadata<K, V> getMetadata() {
+    return metadata;
+  }
 }
diff --git a/java/core/src/main/java/com/google/protobuf/MapField.java b/java/core/src/main/java/com/google/protobuf/MapField.java
index 805defe..ad8ceb0 100644
--- a/java/core/src/main/java/com/google/protobuf/MapField.java
+++ b/java/core/src/main/java/com/google/protobuf/MapField.java
@@ -30,6 +30,8 @@
 
 package com.google.protobuf;
 
+import static com.google.protobuf.Internal.checkNotNull;
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -329,6 +331,8 @@
     @Override
     public V put(K key, V value) {
       mutabilityOracle.ensureMutable();
+      checkNotNull(key);
+      checkNotNull(value);
       return delegate.put(key, value);
     }
 
@@ -341,6 +345,10 @@
     @Override
     public void putAll(Map<? extends K, ? extends V> m) {
       mutabilityOracle.ensureMutable();
+      for (K key : m.keySet()) {
+        checkNotNull(key);
+        checkNotNull(m.get(key));
+      }
       delegate.putAll(m);
     }
 
diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldLite.java b/java/core/src/main/java/com/google/protobuf/MapFieldLite.java
index 4264027..a8b3dd8 100644
--- a/java/core/src/main/java/com/google/protobuf/MapFieldLite.java
+++ b/java/core/src/main/java/com/google/protobuf/MapFieldLite.java
@@ -30,8 +30,9 @@
 
 package com.google.protobuf;
 
-import com.google.protobuf.Internal.EnumLite;
+import static com.google.protobuf.Internal.checkNotNull;
 
+import com.google.protobuf.Internal.EnumLite;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedHashMap;
@@ -88,6 +89,9 @@
 
   @Override public V put(K key, V value) {
     ensureMutable();
+    checkNotNull(key);
+
+    checkNotNull(value);
     return super.put(key, value);
   }
 
@@ -97,6 +101,7 @@
 
   @Override public void putAll(Map<? extends K, ? extends V> m) {
     ensureMutable();
+    checkForNullKeysAndValues(m);
     super.putAll(m);
   }
 
@@ -105,6 +110,13 @@
     return super.remove(key);
   }
 
+  private static void checkForNullKeysAndValues(Map<?, ?> m) {
+    for (Object key : m.keySet()) {
+      checkNotNull(key);
+      checkNotNull(m.get(key));
+    }
+  }
+
   private static boolean equals(Object a, Object b) {
     if (a instanceof byte[] && b instanceof byte[]) {
       return Arrays.equals((byte[]) a, (byte[]) b);
diff --git a/java/core/src/main/java/com/google/protobuf/Parser.java b/java/core/src/main/java/com/google/protobuf/Parser.java
index cfbcb44..e07c689 100644
--- a/java/core/src/main/java/com/google/protobuf/Parser.java
+++ b/java/core/src/main/java/com/google/protobuf/Parser.java
@@ -31,6 +31,7 @@
 package com.google.protobuf;
 
 import java.io.InputStream;
+import java.nio.ByteBuffer;
 
 /**
  * Abstract interface for parsing Protocol Messages.
@@ -93,6 +94,18 @@
   // Convenience methods.
 
   /**
+   * Parses {@code data} as a message of {@code MessageType}. This is just a small wrapper around
+   * {@link #parseFrom(CodedInputStream)}.
+   */
+  public MessageType parseFrom(ByteBuffer data) throws InvalidProtocolBufferException;
+
+  /**
+   * Parses {@code data} as a message of {@code MessageType}. This is just a small wrapper around
+   * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}.
+   */
+  public MessageType parseFrom(ByteBuffer data, ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException;
+  /**
    * Parses {@code data} as a message of {@code MessageType}.
    * This is just a small wrapper around {@link #parseFrom(CodedInputStream)}.
    */
diff --git a/java/core/src/main/java/com/google/protobuf/PrimitiveNonBoxingCollection.java b/java/core/src/main/java/com/google/protobuf/PrimitiveNonBoxingCollection.java
new file mode 100644
index 0000000..79b5769
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/PrimitiveNonBoxingCollection.java
@@ -0,0 +1,34 @@
+// 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.
+
+package com.google.protobuf;
+
+/** A marker interface indicating that the collection supports primitives and is non-boxing. */
+interface PrimitiveNonBoxingCollection {}
diff --git a/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java
index 77b61b5..30c991d 100644
--- a/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java
+++ b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java
@@ -30,6 +30,8 @@
 
 package com.google.protobuf;
 
+import static com.google.protobuf.Internal.checkNotNull;
+
 import java.util.AbstractList;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -290,9 +292,7 @@
    */
   public RepeatedFieldBuilderV3<MType, BType, IType> setMessage(
       int index, MType message) {
-    if (message == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(message);
     ensureMutableMessageList();
     messages.set(index, message);
     if (builders != null) {
@@ -315,9 +315,7 @@
    */
   public RepeatedFieldBuilderV3<MType, BType, IType> addMessage(
       MType message) {
-    if (message == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(message);
     ensureMutableMessageList();
     messages.add(message);
     if (builders != null) {
@@ -339,9 +337,7 @@
    */
   public RepeatedFieldBuilderV3<MType, BType, IType> addMessage(
       int index, MType message) {
-    if (message == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(message);
     ensureMutableMessageList();
     messages.add(index, message);
     if (builders != null) {
@@ -363,9 +359,7 @@
   public RepeatedFieldBuilderV3<MType, BType, IType> addAllMessages(
       Iterable<? extends MType> values) {
     for (final MType value : values) {
-      if (value == null) {
-        throw new NullPointerException();
-      }
+      checkNotNull(value);
     }
 
     // If we can inspect the size, we can more efficiently add messages.
diff --git a/java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java b/java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java
index fb1f76a..8ab0f26 100644
--- a/java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java
+++ b/java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java
@@ -30,6 +30,8 @@
 
 package com.google.protobuf;
 
+import static com.google.protobuf.Internal.checkNotNull;
+
 /**
  * {@code SingleFieldBuilderV3} implements a structure that a protocol
  * message uses to hold a single field of another protocol message. It supports
@@ -84,10 +86,7 @@
       MType message,
       AbstractMessage.BuilderParent parent,
       boolean isClean) {
-    if (message == null) {
-      throw new NullPointerException();
-    }
-    this.message = message;
+    this.message = checkNotNull(message);
     this.parent = parent;
     this.isClean = isClean;
   }
@@ -169,10 +168,7 @@
    */
   public SingleFieldBuilderV3<MType, BType, IType> setMessage(
       MType message) {
-    if (message == null) {
-      throw new NullPointerException();
-    }
-    this.message = message;
+    this.message = checkNotNull(message);
     if (builder != null) {
       builder.dispose();
       builder = null;
diff --git a/java/core/src/main/java/com/google/protobuf/TextFormat.java b/java/core/src/main/java/com/google/protobuf/TextFormat.java
index 4970824..53dead8 100644
--- a/java/core/src/main/java/com/google/protobuf/TextFormat.java
+++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java
@@ -1442,7 +1442,7 @@
 
     /**
      * Parse a single field from {@code tokenizer} and merge it into
-     * {@code builder}.
+     * {@code target}.
      */
     private void mergeField(final Tokenizer tokenizer,
                             final ExtensionRegistry extensionRegistry,
@@ -1712,6 +1712,8 @@
       }
 
       if (field.isRepeated()) {
+        // TODO(b/29122459): If field.isMapField() and FORBID_SINGULAR_OVERWRITES mode,
+        //     check for duplicate map keys here.
         target.addRepeatedField(field, value);
       } else if ((singularOverwritePolicy
               == SingularOverwritePolicy.FORBID_SINGULAR_OVERWRITES)
diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
index 2bef27e..d938113 100644
--- a/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
+++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
@@ -91,7 +91,7 @@
    * Construct an {@code UnknownFieldSet} around the given map.  The map is
    * expected to be immutable.
    */
-  private UnknownFieldSet(final Map<Integer, Field> fields,
+  UnknownFieldSet(final Map<Integer, Field> fields,
       final Map<Integer, Field> fieldsDescending) {
     this.fields = fields;
   }
@@ -715,7 +715,7 @@
    * @see UnknownFieldSet
    */
   public static final class Field {
-    private Field() {}
+    Field() {}
 
     /** Construct a new {@link Builder}. */
     public static Builder newBuilder() {
diff --git a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
index 5f7bafd..ca80d94 100644
--- a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
+++ b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
@@ -33,19 +33,23 @@
 import java.lang.reflect.Field;
 import java.nio.Buffer;
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
-import sun.misc.Unsafe;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /** Utility class for working with unsafe operations. */
-// TODO(nathanmittler): Add support for Android Memory/MemoryBlock
 final class UnsafeUtil {
+  private static final Logger logger = Logger.getLogger(UnsafeUtil.class.getName());
   private static final sun.misc.Unsafe UNSAFE = getUnsafe();
+  private static final MemoryAccessor MEMORY_ACCESSOR = getMemoryAccessor();
   private static final boolean HAS_UNSAFE_BYTEBUFFER_OPERATIONS =
       supportsUnsafeByteBufferOperations();
   private static final boolean HAS_UNSAFE_ARRAY_OPERATIONS = supportsUnsafeArrayOperations();
+  private static final boolean HAS_UNSAFE_COPY_MEMORY = supportsUnsafeCopyMemory();
   private static final long ARRAY_BASE_OFFSET = byteArrayBaseOffset();
-  private static final long BUFFER_ADDRESS_OFFSET = fieldOffset(field(Buffer.class, "address"));
+  private static final long BUFFER_ADDRESS_OFFSET = fieldOffset(bufferAddressField());
 
   private UnsafeUtil() {}
 
@@ -53,20 +57,16 @@
     return HAS_UNSAFE_ARRAY_OPERATIONS;
   }
 
+  static boolean hasUnsafeCopyMemory() {
+    return HAS_UNSAFE_COPY_MEMORY;
+  }
+
   static boolean hasUnsafeByteBufferOperations() {
     return HAS_UNSAFE_BYTEBUFFER_OPERATIONS;
   }
 
-  static Object allocateInstance(Class<?> clazz) {
-    try {
-      return UNSAFE.allocateInstance(clazz);
-    } catch (InstantiationException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
   static long objectFieldOffset(Field field) {
-    return UNSAFE.objectFieldOffset(field);
+    return MEMORY_ACCESSOR.objectFieldOffset(field);
   }
 
   static long getArrayBaseOffset() {
@@ -74,103 +74,103 @@
   }
 
   static byte getByte(Object target, long offset) {
-    return UNSAFE.getByte(target, offset);
+    return MEMORY_ACCESSOR.getByte(target, offset);
   }
 
   static void putByte(Object target, long offset, byte value) {
-    UNSAFE.putByte(target, offset, value);
+    MEMORY_ACCESSOR.putByte(target, offset, value);
   }
 
   static int getInt(Object target, long offset) {
-    return UNSAFE.getInt(target, offset);
+    return MEMORY_ACCESSOR.getInt(target, offset);
   }
 
   static void putInt(Object target, long offset, int value) {
-    UNSAFE.putInt(target, offset, value);
+    MEMORY_ACCESSOR.putInt(target, offset, value);
   }
 
   static long getLong(Object target, long offset) {
-    return UNSAFE.getLong(target, offset);
+    return MEMORY_ACCESSOR.getLong(target, offset);
   }
 
   static void putLong(Object target, long offset, long value) {
-    UNSAFE.putLong(target, offset, value);
+    MEMORY_ACCESSOR.putLong(target, offset, value);
   }
 
   static boolean getBoolean(Object target, long offset) {
-    return UNSAFE.getBoolean(target, offset);
+    return MEMORY_ACCESSOR.getBoolean(target, offset);
   }
 
   static void putBoolean(Object target, long offset, boolean value) {
-    UNSAFE.putBoolean(target, offset, value);
+    MEMORY_ACCESSOR.putBoolean(target, offset, value);
   }
 
   static float getFloat(Object target, long offset) {
-    return UNSAFE.getFloat(target, offset);
+    return MEMORY_ACCESSOR.getFloat(target, offset);
   }
 
   static void putFloat(Object target, long offset, float value) {
-    UNSAFE.putFloat(target, offset, value);
+    MEMORY_ACCESSOR.putFloat(target, offset, value);
   }
 
   static double getDouble(Object target, long offset) {
-    return UNSAFE.getDouble(target, offset);
+    return MEMORY_ACCESSOR.getDouble(target, offset);
   }
 
   static void putDouble(Object target, long offset, double value) {
-    UNSAFE.putDouble(target, offset, value);
+    MEMORY_ACCESSOR.putDouble(target, offset, value);
   }
 
   static Object getObject(Object target, long offset) {
-    return UNSAFE.getObject(target, offset);
+    return MEMORY_ACCESSOR.getObject(target, offset);
   }
 
   static void putObject(Object target, long offset, Object value) {
-    UNSAFE.putObject(target, offset, value);
+    MEMORY_ACCESSOR.putObject(target, offset, value);
   }
 
   static void copyMemory(
       Object src, long srcOffset, Object target, long targetOffset, long length) {
-    UNSAFE.copyMemory(src, srcOffset, target, targetOffset, length);
+    MEMORY_ACCESSOR.copyMemory(src, srcOffset, target, targetOffset, length);
   }
 
   static byte getByte(long address) {
-    return UNSAFE.getByte(address);
+    return MEMORY_ACCESSOR.getByte(address);
   }
 
   static void putByte(long address, byte value) {
-    UNSAFE.putByte(address, value);
+    MEMORY_ACCESSOR.putByte(address, value);
   }
 
   static int getInt(long address) {
-    return UNSAFE.getInt(address);
+    return MEMORY_ACCESSOR.getInt(address);
   }
 
   static void putInt(long address, int value) {
-    UNSAFE.putInt(address, value);
+    MEMORY_ACCESSOR.putInt(address, value);
   }
 
   static long getLong(long address) {
-    return UNSAFE.getLong(address);
+    return MEMORY_ACCESSOR.getLong(address);
   }
 
   static void putLong(long address, long value) {
-    UNSAFE.putLong(address, value);
+    MEMORY_ACCESSOR.putLong(address, value);
   }
 
   static void copyMemory(long srcAddress, long targetAddress, long length) {
-    UNSAFE.copyMemory(srcAddress, targetAddress, length);
-  }
-
-  static void setMemory(long address, long numBytes, byte value) {
-    UNSAFE.setMemory(address, numBytes, value);
+    MEMORY_ACCESSOR.copyMemory(srcAddress, targetAddress, length);
   }
 
   /**
    * Gets the offset of the {@code address} field of the given direct {@link ByteBuffer}.
    */
   static long addressOffset(ByteBuffer buffer) {
-    return UNSAFE.getLong(buffer, BUFFER_ADDRESS_OFFSET);
+    return MEMORY_ACCESSOR.getLong(buffer, BUFFER_ADDRESS_OFFSET);
+  }
+
+  static Object getStaticObject(Field field) {
+    return MEMORY_ACCESSOR.getStaticObject(field);
   }
 
   /**
@@ -181,7 +181,7 @@
     try {
       unsafe =
           AccessController.doPrivileged(
-              new PrivilegedExceptionAction<Unsafe>() {
+              new PrivilegedExceptionAction<sun.misc.Unsafe>() {
                 @Override
                 public sun.misc.Unsafe run() throws Exception {
                   Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
@@ -204,69 +204,114 @@
     return unsafe;
   }
 
+  /** Get a {@link MemoryAccessor} appropriate for the platform, or null if not supported. */
+  private static MemoryAccessor getMemoryAccessor() {
+    if (UNSAFE == null) {
+      return null;
+    }
+    return new JvmMemoryAccessor(UNSAFE);
+  }
+
   /** Indicates whether or not unsafe array operations are supported on this platform. */
   private static boolean supportsUnsafeArrayOperations() {
-    boolean supported = false;
-    if (UNSAFE != null) {
-      try {
-        Class<?> clazz = UNSAFE.getClass();
-        clazz.getMethod("objectFieldOffset", Field.class);
-        clazz.getMethod("allocateInstance", Class.class);
-        clazz.getMethod("arrayBaseOffset", Class.class);
-        clazz.getMethod("getByte", Object.class, long.class);
-        clazz.getMethod("putByte", Object.class, long.class, byte.class);
-        clazz.getMethod("getBoolean", Object.class, long.class);
-        clazz.getMethod("putBoolean", Object.class, long.class, boolean.class);
-        clazz.getMethod("getInt", Object.class, long.class);
-        clazz.getMethod("putInt", Object.class, long.class, int.class);
-        clazz.getMethod("getLong", Object.class, long.class);
-        clazz.getMethod("putLong", Object.class, long.class, long.class);
-        clazz.getMethod("getFloat", Object.class, long.class);
-        clazz.getMethod("putFloat", Object.class, long.class, float.class);
-        clazz.getMethod("getDouble", Object.class, long.class);
-        clazz.getMethod("putDouble", Object.class, long.class, double.class);
-        clazz.getMethod("getObject", Object.class, long.class);
-        clazz.getMethod("putObject", Object.class, long.class, Object.class);
-        clazz.getMethod(
-            "copyMemory", Object.class, long.class, Object.class, long.class, long.class);
-        supported = true;
-      } catch (Throwable e) {
-        // Do nothing.
-      }
+    if (UNSAFE == null) {
+      return false;
     }
-    return supported;
+    try {
+      Class<?> clazz = UNSAFE.getClass();
+      clazz.getMethod("objectFieldOffset", Field.class);
+      clazz.getMethod("arrayBaseOffset", Class.class);
+      clazz.getMethod("getInt", Object.class, long.class);
+      clazz.getMethod("putInt", Object.class, long.class, int.class);
+      clazz.getMethod("getLong", Object.class, long.class);
+      clazz.getMethod("putLong", Object.class, long.class, long.class);
+      clazz.getMethod("getObject", Object.class, long.class);
+      clazz.getMethod("putObject", Object.class, long.class, Object.class);
+      clazz.getMethod("getByte", Object.class, long.class);
+      clazz.getMethod("putByte", Object.class, long.class, byte.class);
+      clazz.getMethod("getBoolean", Object.class, long.class);
+      clazz.getMethod("putBoolean", Object.class, long.class, boolean.class);
+      clazz.getMethod("getFloat", Object.class, long.class);
+      clazz.getMethod("putFloat", Object.class, long.class, float.class);
+      clazz.getMethod("getDouble", Object.class, long.class);
+      clazz.getMethod("putDouble", Object.class, long.class, double.class);
+
+      return true;
+    } catch (Throwable e) {
+      logger.log(
+          Level.WARNING,
+          "platform method missing - proto runtime falling back to safer methods: " + e);
+    }
+    return false;
+  }
+
+  /**
+   * Indicates whether or not unsafe copyMemory(object, long, object, long, long) operations are
+   * supported on this platform.
+   */
+  private static boolean supportsUnsafeCopyMemory() {
+    if (UNSAFE == null) {
+      return false;
+    }
+    try {
+      Class<?> clazz = UNSAFE.getClass();
+      clazz.getMethod("copyMemory", Object.class, long.class, Object.class, long.class, long.class);
+
+      return true;
+    } catch (Throwable e) {
+      logger.log(
+          Level.WARNING,
+          "copyMemory is missing from platform - proto runtime falling back to safer methods.");
+    }
+    return false;
   }
 
   private static boolean supportsUnsafeByteBufferOperations() {
-    boolean supported = false;
-    if (UNSAFE != null) {
-      try {
-        Class<?> clazz = UNSAFE.getClass();
-        // Methods for getting direct buffer address.
-        clazz.getMethod("objectFieldOffset", Field.class);
-        clazz.getMethod("getLong", Object.class, long.class);
-
-        clazz.getMethod("getByte", long.class);
-        clazz.getMethod("putByte", long.class, byte.class);
-        clazz.getMethod("getInt", long.class);
-        clazz.getMethod("putInt", long.class, int.class);
-        clazz.getMethod("getLong", long.class);
-        clazz.getMethod("putLong", long.class, long.class);
-        clazz.getMethod("setMemory", long.class, long.class, byte.class);
-        clazz.getMethod("copyMemory", long.class, long.class, long.class);
-        supported = true;
-      } catch (Throwable e) {
-        // Do nothing.
-      }
+    if (UNSAFE == null) {
+      return false;
     }
-    return supported;
+    try {
+      Class<?> clazz = UNSAFE.getClass();
+      // Methods for getting direct buffer address.
+      clazz.getMethod("objectFieldOffset", Field.class);
+      clazz.getMethod("getLong", Object.class, long.class);
+
+      clazz.getMethod("getByte", long.class);
+      clazz.getMethod("putByte", long.class, byte.class);
+      clazz.getMethod("getInt", long.class);
+      clazz.getMethod("putInt", long.class, int.class);
+      clazz.getMethod("getLong", long.class);
+      clazz.getMethod("putLong", long.class, long.class);
+      clazz.getMethod("copyMemory", long.class, long.class, long.class);
+      return true;
+    } catch (Throwable e) {
+      logger.log(
+          Level.WARNING,
+          "platform method missing - proto runtime falling back to safer methods: " + e);
+    }
+    return false;
+  }
+
+
+  @SuppressWarnings("unchecked")
+  private static <T> Class<T> getClassForName(String name) {
+    try {
+      return (Class<T>) Class.forName(name);
+    } catch (Throwable e) {
+      return null;
+    }
+  }
+
+  /** Finds the address field within a direct {@link Buffer}. */
+  private static Field bufferAddressField() {
+    return field(Buffer.class, "address");
   }
 
   /**
    * Get the base offset for byte arrays, or {@code -1} if {@code sun.misc.Unsafe} is not available.
    */
   private static int byteArrayBaseOffset() {
-    return HAS_UNSAFE_ARRAY_OPERATIONS ? UNSAFE.arrayBaseOffset(byte[].class) : -1;
+    return HAS_UNSAFE_ARRAY_OPERATIONS ? MEMORY_ACCESSOR.arrayBaseOffset(byte[].class) : -1;
   }
 
   /**
@@ -274,7 +319,7 @@
    * available.
    */
   private static long fieldOffset(Field field) {
-    return field == null || UNSAFE == null ? -1 : UNSAFE.objectFieldOffset(field);
+    return field == null || MEMORY_ACCESSOR == null ? -1 : MEMORY_ACCESSOR.objectFieldOffset(field);
   }
 
   /**
@@ -292,4 +337,174 @@
     }
     return field;
   }
+
+  private abstract static class MemoryAccessor {
+
+    sun.misc.Unsafe unsafe;
+
+    MemoryAccessor(sun.misc.Unsafe unsafe) {
+      this.unsafe = unsafe;
+    }
+
+    public final long objectFieldOffset(Field field) {
+      return unsafe.objectFieldOffset(field);
+    }
+
+    public abstract byte getByte(Object target, long offset);
+
+    public abstract void putByte(Object target, long offset, byte value);
+
+    public final int getInt(Object target, long offset) {
+      return unsafe.getInt(target, offset);
+    }
+
+    public final void putInt(Object target, long offset, int value) {
+      unsafe.putInt(target, offset, value);
+    }
+
+    public final long getLong(Object target, long offset) {
+      return unsafe.getLong(target, offset);
+    }
+
+    public final void putLong(Object target, long offset, long value) {
+      unsafe.putLong(target, offset, value);
+    }
+
+    public abstract boolean getBoolean(Object target, long offset);
+
+    public abstract void putBoolean(Object target, long offset, boolean value);
+
+    public abstract float getFloat(Object target, long offset);
+
+    public abstract void putFloat(Object target, long offset, float value);
+
+    public abstract double getDouble(Object target, long offset);
+
+    public abstract void putDouble(Object target, long offset, double value);
+
+    public final Object getObject(Object target, long offset) {
+      return unsafe.getObject(target, offset);
+    }
+
+    public final void putObject(Object target, long offset, Object value) {
+      unsafe.putObject(target, offset, value);
+    }
+
+    public final int arrayBaseOffset(Class<?> clazz) {
+      return unsafe.arrayBaseOffset(clazz);
+    }
+
+    public abstract byte getByte(long address);
+
+    public abstract void putByte(long address, byte value);
+
+    public abstract int getInt(long address);
+
+    public abstract void putInt(long address, int value);
+
+    public abstract long getLong(long address);
+
+    public abstract void putLong(long address, long value);
+
+    public abstract void copyMemory(long srcAddress, long targetAddress, long length);
+
+    public abstract void copyMemory(
+        Object src, long srcOffset, Object target, long targetOffset, long length);
+
+    public abstract Object getStaticObject(Field field);
+  }
+
+  private static final class JvmMemoryAccessor extends MemoryAccessor {
+
+    JvmMemoryAccessor(sun.misc.Unsafe unsafe) {
+      super(unsafe);
+    }
+
+    @Override
+    public byte getByte(long address) {
+      return unsafe.getByte(address);
+    }
+
+    @Override
+    public void putByte(long address, byte value) {
+      unsafe.putByte(address, value);
+    }
+
+    @Override
+    public int getInt(long address) {
+      return unsafe.getInt(address);
+    }
+
+    @Override
+    public void putInt(long address, int value) {
+      unsafe.putInt(address, value);
+    }
+
+    @Override
+    public long getLong(long address) {
+      return unsafe.getLong(address);
+    }
+
+    @Override
+    public void putLong(long address, long value) {
+      unsafe.putLong(address, value);
+    }
+
+    @Override
+    public byte getByte(Object target, long offset) {
+      return unsafe.getByte(target, offset);
+    }
+
+    @Override
+    public void putByte(Object target, long offset, byte value) {
+      unsafe.putByte(target, offset, value);
+    }
+
+    @Override
+    public boolean getBoolean(Object target, long offset) {
+      return unsafe.getBoolean(target, offset);
+    }
+
+    @Override
+    public void putBoolean(Object target, long offset, boolean value) {
+      unsafe.putBoolean(target, offset, value);
+    }
+
+    @Override
+    public float getFloat(Object target, long offset) {
+      return unsafe.getFloat(target, offset);
+    }
+
+    @Override
+    public void putFloat(Object target, long offset, float value) {
+      unsafe.putFloat(target, offset, value);
+    }
+
+    @Override
+    public double getDouble(Object target, long offset) {
+      return unsafe.getDouble(target, offset);
+    }
+
+    @Override
+    public void putDouble(Object target, long offset, double value) {
+      unsafe.putDouble(target, offset, value);
+    }
+
+    @Override
+    public void copyMemory(
+        Object src, long srcOffset, Object target, long targetOffset, long length) {
+      unsafe.copyMemory(src, srcOffset, target, targetOffset, length);
+    }
+
+    @Override
+    public void copyMemory(long srcAddress, long targetAddress, long length) {
+      unsafe.copyMemory(srcAddress, targetAddress, length);
+    }
+
+    @Override
+    public Object getStaticObject(Field field) {
+      return getObject(unsafe.staticFieldBase(field), unsafe.staticFieldOffset(field));
+    }
+  }
+
 }
diff --git a/java/core/src/main/java/com/google/protobuf/Utf8.java b/java/core/src/main/java/com/google/protobuf/Utf8.java
index 5b80d40..be7b746 100644
--- a/java/core/src/main/java/com/google/protobuf/Utf8.java
+++ b/java/core/src/main/java/com/google/protobuf/Utf8.java
@@ -1332,7 +1332,7 @@
       // the index (relative to the start of the array) is also 8-byte aligned. We do this by
       // ANDing the index with 7 to determine the number of bytes that need to be read before
       // we're 8-byte aligned.
-      final int unaligned = (int) offset & 7;
+      final int unaligned = 8 - ((int) offset & 7);
       for (int j = unaligned; j > 0; j--) {
         if (UnsafeUtil.getByte(bytes, offset++) < 0) {
           return unaligned - j;
diff --git a/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java b/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java
index 5f013f3..f27e8e5 100644
--- a/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java
@@ -32,7 +32,6 @@
 
 import protobuf_unittest.UnittestProto.TestAllExtensions;
 import protobuf_unittest.UnittestProto.TestAllTypes;
-import java.io.IOException;
 import junit.framework.TestCase;
 
 /**
@@ -89,6 +88,7 @@
     assertFalse(message.equals(lazyField.getValue()));
   }
 
+  @SuppressWarnings("EqualsIncompatibleType") // LazyField.equals() is not symmetric
   public void testEqualsObjectEx() throws Exception {
     TestAllExtensions message = TestUtil.getAllExtensionsSet();
     LazyField lazyField = createLazyFieldFromMessage(message);
diff --git a/java/core/src/test/java/com/google/protobuf/LiteTest.java b/java/core/src/test/java/com/google/protobuf/LiteTest.java
index 538432f..98c637a 100644
--- a/java/core/src/test/java/com/google/protobuf/LiteTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LiteTest.java
@@ -52,6 +52,7 @@
 import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Foo;
 import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestOneofEquals;
 import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestRecursiveOneof;
+import java.nio.ByteBuffer;
 import junit.framework.TestCase;
 
 /**
@@ -2174,6 +2175,24 @@
     assertFalse(bar.equals(barPrime));
   }
 
+  public void testEqualsAndHashCodeForTrickySchemaTypes() {
+    Foo foo1 = Foo.newBuilder()
+        .build();
+    Foo foo2 = Foo.newBuilder()
+        .setSint64(1)
+        .build();
+    Foo foo3 = Foo.newBuilder()
+        .putMyMap("key", "value2")
+        .build();
+    Foo foo4 = Foo.newBuilder()
+        .setMyGroup(Foo.MyGroup.newBuilder().setValue(4).build())
+        .build();
+
+    assertEqualsAndHashCodeAreFalse(foo1, foo2);
+    assertEqualsAndHashCodeAreFalse(foo1, foo3);
+    assertEqualsAndHashCodeAreFalse(foo1, foo4);
+  }
+
   public void testOneofEquals() throws Exception {
     TestOneofEquals.Builder builder = TestOneofEquals.newBuilder();
     TestOneofEquals message1 = builder.build();
@@ -2270,4 +2289,93 @@
     // This tests that we don't infinite loop.
     TestRecursiveOneof.getDefaultInstance().hashCode();
   }
+
+  public void testParseFromByteBuffer() throws Exception {
+    TestAllTypesLite message =
+        TestAllTypesLite.newBuilder()
+            .setOptionalInt32(123)
+            .addRepeatedString("hello")
+            .setOptionalNestedMessage(TestAllTypesLite.NestedMessage.newBuilder().setBb(7))
+            .build();
+
+    TestAllTypesLite copy =
+        TestAllTypesLite.parseFrom(message.toByteString().asReadOnlyByteBuffer());
+
+    assertEquals(message, copy);
+  }
+
+  public void testParseFromByteBufferThrows() {
+    try {
+      TestAllTypesLite.parseFrom(ByteBuffer.wrap(new byte[] { 0x5 }));
+      fail();
+    } catch (InvalidProtocolBufferException expected) {
+    }
+
+    TestAllTypesLite message =
+        TestAllTypesLite.newBuilder()
+            .setOptionalInt32(123)
+            .addRepeatedString("hello")
+            .build();
+
+    ByteBuffer buffer = ByteBuffer.wrap(message.toByteArray(), 0, message.getSerializedSize() - 1);
+    try {
+      TestAllTypesLite.parseFrom(buffer);
+      fail();
+    } catch (InvalidProtocolBufferException expected) {
+      assertEquals(
+          TestAllTypesLite.newBuilder()
+              .setOptionalInt32(123)
+              .build(),
+          expected.getUnfinishedMessage());
+    }
+  }
+
+  public void testParseFromByteBuffer_extensions() throws Exception {
+    TestAllExtensionsLite message =
+        TestAllExtensionsLite.newBuilder()
+            .setExtension(UnittestLite.optionalInt32ExtensionLite, 123)
+            .addExtension(UnittestLite.repeatedStringExtensionLite, "hello")
+            .setExtension(
+                UnittestLite.optionalNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ)
+            .setExtension(
+                UnittestLite.optionalNestedMessageExtensionLite,
+                TestAllTypesLite.NestedMessage.newBuilder().setBb(7).build())
+            .build();
+
+    ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
+    UnittestLite.registerAllExtensions(registry);
+
+    TestAllExtensionsLite copy =
+        TestAllExtensionsLite.parseFrom(message.toByteString().asReadOnlyByteBuffer(), registry);
+
+    assertEquals(message, copy);
+  }
+
+  public void testParseFromByteBufferThrows_extensions() {
+    ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
+    UnittestLite.registerAllExtensions(registry);
+    try {
+      TestAllExtensionsLite.parseFrom(ByteBuffer.wrap(new byte[] { 0x5 }), registry);
+      fail();
+    } catch (InvalidProtocolBufferException expected) {
+    }
+
+    TestAllExtensionsLite message =
+        TestAllExtensionsLite.newBuilder()
+            .setExtension(UnittestLite.optionalInt32ExtensionLite, 123)
+            .addExtension(UnittestLite.repeatedStringExtensionLite, "hello")
+            .build();
+
+    ByteBuffer buffer = ByteBuffer.wrap(message.toByteArray(), 0, message.getSerializedSize() - 1);
+    try {
+      TestAllExtensionsLite.parseFrom(buffer, registry);
+      fail();
+    } catch (InvalidProtocolBufferException expected) {
+      assertEquals(
+          TestAllExtensionsLite.newBuilder()
+              .setExtension(UnittestLite.optionalInt32ExtensionLite, 123)
+              .build(),
+          expected.getUnfinishedMessage());
+    }
+  }
 }
diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
index cfe4c45..453d392 100644
--- a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
+++ b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
@@ -759,6 +759,7 @@
     assertEquals(55, message.getInt32ToInt32Field().get(55).intValue());
   }
 
+  // See additional coverage in TextFormatTest.java.
   public void testTextFormat() throws Exception {
     TestMap.Builder builder = TestMap.newBuilder();
     setMapValuesUsingAccessors(builder);
diff --git a/java/core/src/test/java/com/google/protobuf/MapTest.java b/java/core/src/test/java/com/google/protobuf/MapTest.java
index 81e951c..01b371a 100644
--- a/java/core/src/test/java/com/google/protobuf/MapTest.java
+++ b/java/core/src/test/java/com/google/protobuf/MapTest.java
@@ -30,7 +30,7 @@
 
 package com.google.protobuf;
 
-
+import static org.junit.Assert.assertArrayEquals;
 import com.google.protobuf.Descriptors.Descriptor;
 import com.google.protobuf.Descriptors.EnumDescriptor;
 import com.google.protobuf.Descriptors.EnumValueDescriptor;
@@ -870,6 +870,7 @@
     assertEquals(55, message.getInt32ToInt32Field().get(55).intValue());
   }
 
+  // See additional coverage in TextFormatTest.java.
   public void testTextFormat() throws Exception {
     TestMap.Builder builder = TestMap.newBuilder();
     setMapValuesUsingAccessors(builder);
@@ -1492,4 +1493,40 @@
     map.put(key3, value3);
     return map;
   }
+
+  public void testMap_withNulls() {
+    TestMap.Builder builder = TestMap.newBuilder();
+
+    try {
+      builder.putStringToInt32Field(null, 3);
+      fail();
+    } catch (NullPointerException expected) {
+    }
+
+    try {
+      builder.putAllStringToInt32Field(newMap(null, 3, "hi", 4));
+      fail();
+    } catch (NullPointerException expected) {
+    }
+
+    try {
+      builder.putInt32ToMessageField(3, null);
+      fail();
+    } catch (NullPointerException expected) {
+    }
+
+    try {
+      builder.putAllInt32ToMessageField(newMap(4, null, 5, null));
+      fail();
+    } catch (NullPointerException expected) {
+    }
+
+    try {
+      builder.putAllInt32ToMessageField(null);
+      fail();
+    } catch (NullPointerException expected) {
+    }
+
+    assertArrayEquals(new byte[0], builder.build().toByteArray());
+  }
 }
diff --git a/java/core/src/test/java/com/google/protobuf/ParserTest.java b/java/core/src/test/java/com/google/protobuf/ParserTest.java
index 8c2e4c2..4bd3411 100644
--- a/java/core/src/test/java/com/google/protobuf/ParserTest.java
+++ b/java/core/src/test/java/com/google/protobuf/ParserTest.java
@@ -79,6 +79,8 @@
         new ByteArrayInputStream(data), registry));
     assertMessageEquals(message, parser.parseFrom(
         CodedInputStream.newInstance(data), registry));
+    assertMessageEquals(
+        message, parser.parseFrom(message.toByteString().asReadOnlyByteBuffer(), registry));
   }
 
   @SuppressWarnings("unchecked")
@@ -99,6 +101,7 @@
         new ByteArrayInputStream(data)));
     assertMessageEquals(message, parser.parseFrom(
         CodedInputStream.newInstance(data)));
+    assertMessageEquals(message, parser.parseFrom(message.toByteString().asReadOnlyByteBuffer()));
   }
 
   private void assertMessageEquals(
@@ -178,6 +181,9 @@
   public void testParseExtensions() throws Exception {
     assertRoundTripEquals(TestUtil.getAllExtensionsSet(),
                           TestUtil.getExtensionRegistry());
+  }
+
+  public void testParseExtensionsLite() throws Exception {
     assertRoundTripEquals(
         TestUtilLite.getAllLiteExtensionsSet(), TestUtilLite.getExtensionRegistryLite());
   }
@@ -186,6 +192,9 @@
     assertRoundTripEquals(TestUtil.getPackedSet());
     assertRoundTripEquals(TestUtil.getPackedExtensionsSet(),
                           TestUtil.getExtensionRegistry());
+  }
+
+  public void testParsePackedLite() throws Exception {
     assertRoundTripEquals(
         TestUtilLite.getLitePackedExtensionsSet(), TestUtilLite.getExtensionRegistryLite());
   }
@@ -195,15 +204,26 @@
     TestAllTypes normalMessage = TestUtil.getAllSet();
     ByteArrayOutputStream output = new ByteArrayOutputStream();
     normalMessage.writeDelimitedTo(output);
+    normalMessage.writeDelimitedTo(output);
 
+    InputStream input = new ByteArrayInputStream(output.toByteArray());
+    assertMessageEquals(normalMessage, normalMessage.getParserForType().parseDelimitedFrom(input));
+    assertMessageEquals(normalMessage, normalMessage.getParserForType().parseDelimitedFrom(input));
+  }
+
+  public void testParseDelimitedToLite() throws Exception {
     // Write MessageLite with packed extension fields.
     TestPackedExtensionsLite packedMessage = TestUtilLite.getLitePackedExtensionsSet();
+    ByteArrayOutputStream output = new ByteArrayOutputStream();
+    packedMessage.writeDelimitedTo(output);
     packedMessage.writeDelimitedTo(output);
 
     InputStream input = new ByteArrayInputStream(output.toByteArray());
     assertMessageEquals(
-        normalMessage,
-        normalMessage.getParserForType().parseDelimitedFrom(input));
+        packedMessage,
+        packedMessage
+            .getParserForType()
+            .parseDelimitedFrom(input, TestUtilLite.getExtensionRegistryLite()));
     assertMessageEquals(
         packedMessage,
         packedMessage
@@ -314,8 +334,7 @@
 
   public void testParsingMergeLite() throws Exception {
     // Build messages.
-    TestAllTypesLite.Builder builder =
-        TestAllTypesLite.newBuilder();
+    TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder();
     TestAllTypesLite msg1 = builder.setOptionalInt32(1).build();
     builder.clear();
     TestAllTypesLite msg2 = builder.setOptionalInt64(2).build();
diff --git a/java/core/src/test/java/com/google/protobuf/TestUtil.java b/java/core/src/test/java/com/google/protobuf/TestUtil.java
index c1bd21d..e96adf0 100644
--- a/java/core/src/test/java/com/google/protobuf/TestUtil.java
+++ b/java/core/src/test/java/com/google/protobuf/TestUtil.java
@@ -2622,6 +2622,8 @@
         break;
       case FOO_NOT_SET:
         break;
+      default:
+        // TODO(b/18683919): go/enum-switch-lsc
     }
   }
 
diff --git a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
index 6a91b02..249d7c5 100644
--- a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
+++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
@@ -30,9 +30,12 @@
 
 package com.google.protobuf;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import com.google.protobuf.Descriptors.Descriptor;
 import com.google.protobuf.Descriptors.FieldDescriptor;
 import com.google.protobuf.TextFormat.Parser.SingularOverwritePolicy;
+import map_test.MapTestProto.TestMap;
 import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
 import protobuf_unittest.UnittestMset.TestMessageSetExtension2;
 import protobuf_unittest.UnittestProto.OneString;
@@ -940,6 +943,7 @@
   }
 
 
+  // See additional coverage in testOneofOverwriteForbidden and testMapOverwriteForbidden.
   public void testParseNonRepeatedFields() throws Exception {
     assertParseSuccessWithOverwriteForbidden(
         "repeated_int32: 1\n" +
@@ -950,6 +954,7 @@
     assertParseSuccessWithOverwriteForbidden(
         "repeated_nested_message { bb: 1 }\n" +
         "repeated_nested_message { bb: 2 }\n");
+
     assertParseErrorWithOverwriteForbidden(
         "3:17: Non-repeated field " +
         "\"protobuf_unittest.TestAllTypes.optional_int32\" " +
@@ -988,6 +993,7 @@
     assertParseSuccessWithOverwriteForbidden("repeated_int32: [ 1, 2 ]\n");
     assertParseSuccessWithOverwriteForbidden("RepeatedGroup [{ a: 1 },{ a: 2 }]\n");
     assertParseSuccessWithOverwriteForbidden("repeated_nested_message [{ bb: 1 }, { bb: 2 }]\n");
+    // See also testMapShortForm.
   }
 
   public void testParseShortRepeatedFormOfEmptyRepeatedFields() throws Exception {
@@ -995,6 +1001,7 @@
     assertParseSuccessWithOverwriteForbidden("repeated_int32: []\n");
     assertParseSuccessWithOverwriteForbidden("RepeatedGroup []\n");
     assertParseSuccessWithOverwriteForbidden("repeated_nested_message []\n");
+    // See also testMapShortFormEmpty.
   }
 
   public void testParseShortRepeatedFormWithTrailingComma() throws Exception {
@@ -1010,6 +1017,7 @@
     assertParseErrorWithOverwriteForbidden(
         "1:37: Expected \"{\".",
         "repeated_nested_message [{ bb: 1 }, ]\n");
+    // See also testMapShortFormTrailingComma.
   }
 
   public void testParseShortRepeatedFormOfNonRepeatedFields() throws Exception {
@@ -1058,6 +1066,90 @@
   }
 
   // =======================================================================
+  // test map
+
+  public void testMapTextFormat() throws Exception {
+    TestMap message =
+        TestMap.newBuilder()
+            .putInt32ToStringField(10, "apple")
+            .putInt32ToStringField(20, "banana")
+            .putInt32ToStringField(30, "cherry")
+            .build();
+    String text = TextFormat.printToUnicodeString(message);
+    {
+      TestMap.Builder dest = TestMap.newBuilder();
+      TextFormat.merge(text, dest);
+      assertThat(dest.build()).isEqualTo(message);
+    }
+    {
+      TestMap.Builder dest = TestMap.newBuilder();
+      parserWithOverwriteForbidden.merge(text, dest);
+      assertThat(dest.build()).isEqualTo(message);
+    }
+  }
+
+  public void testMapShortForm() throws Exception {
+    String text =
+        "string_to_int32_field [{ key: 'x' value: 10 }, { key: 'y' value: 20 }]\n"
+        + "int32_to_message_field "
+        + "[{ key: 1 value { value: 100 } }, { key: 2 value: { value: 200 } }]\n";
+    TestMap.Builder dest = TestMap.newBuilder();
+    parserWithOverwriteForbidden.merge(text, dest);
+    TestMap message = dest.build();
+    assertThat(message.getStringToInt32Field().size()).isEqualTo(2);
+    assertThat(message.getInt32ToMessageField().size()).isEqualTo(2);
+    assertThat(message.getStringToInt32Field().get("x")).isEqualTo(10);
+    assertThat(message.getInt32ToMessageField().get(2).getValue()).isEqualTo(200);
+  }
+
+  public void testMapShortFormEmpty() throws Exception {
+    String text = "string_to_int32_field []\n"
+        + "int32_to_message_field: []\n";
+    TestMap.Builder dest = TestMap.newBuilder();
+    parserWithOverwriteForbidden.merge(text, dest);
+    TestMap message = dest.build();
+    assertThat(message.getStringToInt32Field().size()).isEqualTo(0);
+    assertThat(message.getInt32ToMessageField().size()).isEqualTo(0);
+  }
+
+  public void testMapShortFormTrailingComma() throws Exception {
+    String text = "string_to_int32_field [{ key: 'x' value: 10 }, ]\n";
+    TestMap.Builder dest = TestMap.newBuilder();
+    try {
+      parserWithOverwriteForbidden.merge(text, dest);
+      fail("Expected parse exception.");
+    } catch (TextFormat.ParseException e) {
+      assertThat(e).hasMessageThat().isEqualTo("1:48: Expected \"{\".");
+    }
+  }
+
+  public void testMapOverwrite() throws Exception {
+    String text =
+        "int32_to_int32_field { key: 1 value: 10 }\n"
+            + "int32_to_int32_field { key: 2 value: 20 }\n"
+            + "int32_to_int32_field { key: 1 value: 30 }\n";
+
+    {
+      // With default parser, last value set for the key holds.
+      TestMap.Builder builder = TestMap.newBuilder();
+      defaultParser.merge(text, builder);
+      TestMap map = builder.build();
+      assertThat(map.getInt32ToInt32Field().size()).isEqualTo(2);
+      assertThat(map.getInt32ToInt32Field().get(1).intValue()).isEqualTo(30);
+    }
+
+    {
+      // With overwrite forbidden, same behavior.
+      // TODO(b/29122459): Expect parse exception here.
+      TestMap.Builder builder = TestMap.newBuilder();
+      defaultParser.merge(text, builder);
+      TestMap map = builder.build();
+      assertThat(map.getInt32ToInt32Field().size()).isEqualTo(2);
+      assertThat(map.getInt32ToInt32Field().get(1).intValue()).isEqualTo(30);
+    }
+  }
+
+  // =======================================================================
   // test location information
 
   public void testParseInfoTreeBuilding() throws Exception {
diff --git a/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto b/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto
index 6eef42c..b18b0d7 100644
--- a/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto
+++ b/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto
@@ -46,6 +46,14 @@
 message Foo {
   optional int32 value = 1;
   repeated Bar bar = 2;
+  map<string, string> my_map = 3;
+  oneof Single {
+    sint64 sint64 = 4;
+    // LINT: ALLOW_GROUPS
+    group MyGroup = 5 {
+      optional int32 value = 1;
+    }
+  }
 
   extensions 100 to max;
 }
diff --git a/java/lite/pom.xml b/java/lite/pom.xml
index d7b1509..c902f81 100644
--- a/java/lite/pom.xml
+++ b/java/lite/pom.xml
@@ -137,6 +137,7 @@
             <include>**/MutabilityOracle.java</include>
             <include>**/NioByteString.java</include>
             <include>**/Parser.java</include>
+            <include>**/PrimitiveNonBoxingCollection.java</include>
             <include>**/ProtobufArrayList.java</include>
             <include>**/ProtocolStringList.java</include>
             <include>**/RopeByteString.java</include>
diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
index 838700f..5e0f5fe 100644
--- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
+++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
@@ -30,6 +30,7 @@
 
 package com.google.protobuf.util;
 
+import com.google.common.base.Preconditions;
 import com.google.common.io.BaseEncoding;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
@@ -102,7 +103,8 @@
    * Creates a {@link Printer} with default configurations.
    */
   public static Printer printer() {
-    return new Printer(TypeRegistry.getEmptyTypeRegistry(), false, false, false);
+    return new Printer(
+        TypeRegistry.getEmptyTypeRegistry(), false, Collections.emptySet(), false, false);
   }
 
   /**
@@ -110,16 +112,27 @@
    */
   public static class Printer {
     private final TypeRegistry registry;
-    private final boolean includingDefaultValueFields;
+    // NOTE: There are 3 states for these *defaultValueFields variables:
+    // 1) Default - alwaysOutput is false & including is empty set. Fields only output if they are
+    //    set to non-default values.
+    // 2) No-args includingDefaultValueFields() called - alwaysOutput is true & including is
+    //    irrelevant (but set to empty set). All fields are output regardless of their values.
+    // 3) includingDefaultValueFields(Set<FieldDescriptor>) called - alwaysOutput is false &
+    //    including is set to the specified set. Fields in that set are always output & fields not
+    //    in that set are only output if set to non-default values.
+    private boolean alwaysOutputDefaultValueFields;
+    private Set<FieldDescriptor> includingDefaultValueFields;
     private final boolean preservingProtoFieldNames;
     private final boolean omittingInsignificantWhitespace;
 
     private Printer(
         TypeRegistry registry,
-        boolean includingDefaultValueFields,
+        boolean alwaysOutputDefaultValueFields,
+        Set<FieldDescriptor> includingDefaultValueFields,
         boolean preservingProtoFieldNames,
         boolean omittingInsignificantWhitespace) {
       this.registry = registry;
+      this.alwaysOutputDefaultValueFields = alwaysOutputDefaultValueFields;
       this.includingDefaultValueFields = includingDefaultValueFields;
       this.preservingProtoFieldNames = preservingProtoFieldNames;
       this.omittingInsignificantWhitespace = omittingInsignificantWhitespace;
@@ -137,6 +150,7 @@
       }
       return new Printer(
           registry,
+          alwaysOutputDefaultValueFields,
           includingDefaultValueFields,
           preservingProtoFieldNames,
           omittingInsignificantWhitespace);
@@ -149,8 +163,41 @@
      * {@link Printer}.
      */
     public Printer includingDefaultValueFields() {
+      checkUnsetIncludingDefaultValueFields();
       return new Printer(
-          registry, true, preservingProtoFieldNames, omittingInsignificantWhitespace);
+          registry,
+          true,
+          Collections.emptySet(),
+          preservingProtoFieldNames,
+          omittingInsignificantWhitespace);
+    }
+
+    /**
+     * Creates a new {@link Printer} that will also print default-valued fields if their
+     * FieldDescriptors are found in the supplied set. Empty repeated fields and map fields will be
+     * printed as well, if they match. The new Printer clones all other configurations from the
+     * current {@link Printer}. Call includingDefaultValueFields() with no args to unconditionally
+     * output all fields.
+     */
+    public Printer includingDefaultValueFields(Set<FieldDescriptor> fieldsToAlwaysOutput) {
+      Preconditions.checkArgument(
+          null != fieldsToAlwaysOutput && !fieldsToAlwaysOutput.isEmpty(),
+          "Non-empty Set must be supplied for includingDefaultValueFields.");
+
+      checkUnsetIncludingDefaultValueFields();
+      return new Printer(
+          registry,
+          false,
+          fieldsToAlwaysOutput,
+          preservingProtoFieldNames,
+          omittingInsignificantWhitespace);
+    }
+
+    private void checkUnsetIncludingDefaultValueFields() {
+      if (alwaysOutputDefaultValueFields || !includingDefaultValueFields.isEmpty()) {
+        throw new IllegalStateException(
+            "JsonFormat includingDefaultValueFields has already been set.");
+      }
     }
 
     /**
@@ -161,15 +208,20 @@
      */
     public Printer preservingProtoFieldNames() {
       return new Printer(
-          registry, includingDefaultValueFields, true, omittingInsignificantWhitespace);
+          registry,
+          alwaysOutputDefaultValueFields,
+          includingDefaultValueFields,
+          true,
+          omittingInsignificantWhitespace);
     }
 
 
     /**
-     * Create a new  {@link Printer}  that will omit all insignificant whitespace
-     * in the JSON output. This new Printer clones all other configurations from the
-     * current Printer. Insignificant whitespace is defined by the JSON spec as whitespace
-     * that appear between JSON structural elements:
+     * Create a new {@link Printer} that will omit all insignificant whitespace in the JSON output.
+     * This new Printer clones all other configurations from the current Printer. Insignificant
+     * whitespace is defined by the JSON spec as whitespace that appear between JSON structural
+     * elements:
+     *
      * <pre>
      * ws = *(
      * %x20 /              ; Space
@@ -177,18 +229,24 @@
      * %x0A /              ; Line feed or New line
      * %x0D )              ; Carriage return
      * </pre>
+     *
      * See <a href="https://tools.ietf.org/html/rfc7159">https://tools.ietf.org/html/rfc7159</a>
      * current {@link Printer}.
      */
     public Printer omittingInsignificantWhitespace() {
-      return new Printer(registry, includingDefaultValueFields, preservingProtoFieldNames, true);
+      return new Printer(
+          registry,
+          alwaysOutputDefaultValueFields,
+          includingDefaultValueFields,
+          preservingProtoFieldNames,
+          true);
     }
 
     /**
      * Converts a protobuf message to JSON format.
      *
-     * @throws InvalidProtocolBufferException if the message contains Any types
-     *         that can't be resolved.
+     * @throws InvalidProtocolBufferException if the message contains Any types that can't be
+     *     resolved.
      * @throws IOException if writing to the output fails.
      */
     public void appendTo(MessageOrBuilder message, Appendable output) throws IOException {
@@ -196,6 +254,7 @@
       // mobile.
       new PrinterImpl(
               registry,
+              alwaysOutputDefaultValueFields,
               includingDefaultValueFields,
               preservingProtoFieldNames,
               output,
@@ -428,19 +487,16 @@
       this.output = output;
     }
 
-    /**
-     * ignored by compact printer
-     */
+    /** ignored by compact printer */
+    @Override
     public void indent() {}
 
-    /**
-     * ignored by compact printer
-     */
+    /** ignored by compact printer */
+    @Override
     public void outdent() {}
 
-    /**
-     * Print text to the output stream.
-     */
+    /** Print text to the output stream. */
+    @Override
     public void print(final CharSequence text) throws IOException {
       output.append(text);
     }
@@ -458,18 +514,17 @@
     }
 
     /**
-     * Indent text by two spaces.  After calling Indent(), two spaces will be
-     * inserted at the beginning of each line of text.  Indent() may be called
-     * multiple times to produce deeper indents.
+     * Indent text by two spaces. After calling Indent(), two spaces will be inserted at the
+     * beginning of each line of text. Indent() may be called multiple times to produce deeper
+     * indents.
      */
+    @Override
     public void indent() {
       indent.append("  ");
     }
 
-    /**
-     * Reduces the current indent level by two spaces, or crashes if the indent
-     * level is zero.
-     */
+    /** Reduces the current indent level by two spaces, or crashes if the indent level is zero. */
+    @Override
     public void outdent() {
       final int length = indent.length();
       if (length < 2) {
@@ -478,9 +533,8 @@
       indent.delete(length - 2, length);
     }
 
-    /**
-     * Print text to the output stream.
-     */
+    /** Print text to the output stream. */
+    @Override
     public void print(final CharSequence text) throws IOException {
       final int size = text.length();
       int pos = 0;
@@ -512,7 +566,8 @@
    */
   private static final class PrinterImpl {
     private final TypeRegistry registry;
-    private final boolean includingDefaultValueFields;
+    private final boolean alwaysOutputDefaultValueFields;
+    private final Set<FieldDescriptor> includingDefaultValueFields;
     private final boolean preservingProtoFieldNames;
     private final TextGenerator generator;
     // We use Gson to help handle string escapes.
@@ -526,11 +581,13 @@
 
     PrinterImpl(
         TypeRegistry registry,
-        boolean includingDefaultValueFields,
+        boolean alwaysOutputDefaultValueFields,
+        Set<FieldDescriptor> includingDefaultValueFields,
         boolean preservingProtoFieldNames,
         Appendable jsonOutput,
         boolean omittingInsignificantWhitespace) {
       this.registry = registry;
+      this.alwaysOutputDefaultValueFields = alwaysOutputDefaultValueFields;
       this.includingDefaultValueFields = includingDefaultValueFields;
       this.preservingProtoFieldNames = preservingProtoFieldNames;
       this.gson = GsonHolder.DEFAULT_GSON;
@@ -781,23 +838,26 @@
         printedField = true;
       }
       Map<FieldDescriptor, Object> fieldsToPrint = null;
-      if (includingDefaultValueFields) {
-        fieldsToPrint = new TreeMap<FieldDescriptor, Object>();
+      if (alwaysOutputDefaultValueFields || !includingDefaultValueFields.isEmpty()) {
+        fieldsToPrint = new TreeMap<FieldDescriptor, Object>(message.getAllFields());
         for (FieldDescriptor field : message.getDescriptorForType().getFields()) {
           if (field.isOptional()) {
             if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE
-                && !message.hasField(field)){
+                && !message.hasField(field)) {
               // Always skip empty optional message fields. If not we will recurse indefinitely if
               // a message has itself as a sub-field.
               continue;
             }
             OneofDescriptor oneof = field.getContainingOneof();
             if (oneof != null && !message.hasField(field)) {
-                // Skip all oneof fields except the one that is actually set
+              // Skip all oneof fields except the one that is actually set
               continue;
             }
           }
-          fieldsToPrint.put(field, message.getField(field));
+          if (!fieldsToPrint.containsKey(field)
+              && (alwaysOutputDefaultValueFields || includingDefaultValueFields.contains(field))) {
+            fieldsToPrint.put(field, message.getField(field));
+          }
         }
       } else {
         fieldsToPrint = message.getAllFields();
@@ -1451,45 +1511,6 @@
       }
     }
 
-    /**
-     * Gets the default value for a field type. Note that we use proto3
-     * language defaults and ignore any default values set through the
-     * proto "default" option.
-     */
-    private Object getDefaultValue(FieldDescriptor field, Message.Builder builder) {
-      switch (field.getType()) {
-        case INT32:
-        case SINT32:
-        case SFIXED32:
-        case UINT32:
-        case FIXED32:
-          return 0;
-        case INT64:
-        case SINT64:
-        case SFIXED64:
-        case UINT64:
-        case FIXED64:
-          return 0L;
-        case FLOAT:
-          return 0.0f;
-        case DOUBLE:
-          return 0.0;
-        case BOOL:
-          return false;
-        case STRING:
-          return "";
-        case BYTES:
-          return ByteString.EMPTY;
-        case ENUM:
-          return field.getEnumType().getValues().get(0);
-        case MESSAGE:
-        case GROUP:
-          return builder.newBuilderForField(field).getDefaultInstanceForType();
-        default:
-          throw new IllegalStateException("Invalid field type: " + field.getType());
-      }
-    }
-
     private void mergeRepeatedField(
         FieldDescriptor field, JsonElement json, Message.Builder builder)
         throws InvalidProtocolBufferException {
diff --git a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java
index 1d631a2..d0bac41 100644
--- a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java
+++ b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java
@@ -297,7 +297,7 @@
    * Convert a Timestamp to the number of microseconds elapsed from the epoch.
    *
    * <p>The result will be rounded down to the nearest microsecond. E.g., if the timestamp
-   * represents "1969-12-31T23:59:59.999999999Z", it will be rounded to -1 millisecond.
+   * represents "1969-12-31T23:59:59.999999999Z", it will be rounded to -1 microsecond.
    */
   public static long toMicros(Timestamp timestamp) {
     checkValid(timestamp);
diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
index de02c11..6943093 100644
--- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
+++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
@@ -34,6 +34,7 @@
 import com.google.protobuf.BoolValue;
 import com.google.protobuf.ByteString;
 import com.google.protobuf.BytesValue;
+import com.google.protobuf.Descriptors.FieldDescriptor;
 import com.google.protobuf.DoubleValue;
 import com.google.protobuf.FloatValue;
 import com.google.protobuf.Int32Value;
@@ -68,9 +69,12 @@
 import java.io.StringReader;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 import junit.framework.TestCase;
 
 public class JsonFormatTest extends TestCase {
@@ -284,8 +288,8 @@
     assertEquals(9012, message.getOptionalSint32());
     assertEquals(3456, message.getOptionalFixed32());
     assertEquals(7890, message.getOptionalSfixed32());
-    assertEquals(1.5f, message.getOptionalFloat());
-    assertEquals(1.25, message.getOptionalDouble());
+    assertEquals(1.5f, message.getOptionalFloat(), 0.0f);
+    assertEquals(1.25, message.getOptionalDouble(), 0.0);
     assertEquals(true, message.getOptionalBool());
   }
 
@@ -1215,6 +1219,115 @@
             + "}",
         JsonFormat.printer().includingDefaultValueFields().print(message));
 
+    Set<FieldDescriptor> fixedFields = new HashSet<FieldDescriptor>();
+    for (FieldDescriptor fieldDesc : TestAllTypes.getDescriptor().getFields()) {
+      if (fieldDesc.getName().contains("_fixed")) {
+        fixedFields.add(fieldDesc);
+      }
+    }
+
+    assertEquals(
+        "{\n"
+            + "  \"optionalFixed32\": 0,\n"
+            + "  \"optionalFixed64\": \"0\",\n"
+            + "  \"repeatedFixed32\": [],\n"
+            + "  \"repeatedFixed64\": []\n"
+            + "}",
+        JsonFormat.printer().includingDefaultValueFields(fixedFields).print(message));
+
+    TestAllTypes messageNonDefaults =
+        message.toBuilder().setOptionalInt64(1234).setOptionalFixed32(3232).build();
+    assertEquals(
+        "{\n"
+            + "  \"optionalInt64\": \"1234\",\n"
+            + "  \"optionalFixed32\": 3232,\n"
+            + "  \"optionalFixed64\": \"0\",\n"
+            + "  \"repeatedFixed32\": [],\n"
+            + "  \"repeatedFixed64\": []\n"
+            + "}",
+        JsonFormat.printer().includingDefaultValueFields(fixedFields).print(messageNonDefaults));
+
+    try {
+      JsonFormat.printer().includingDefaultValueFields().includingDefaultValueFields();
+      fail("IllegalStateException is expected.");
+    } catch (IllegalStateException e) {
+      // Expected.
+      assertTrue(
+          "Exception message should mention includingDefaultValueFields.",
+          e.getMessage().contains("includingDefaultValueFields"));
+    }
+
+    try {
+      JsonFormat.printer().includingDefaultValueFields().includingDefaultValueFields(fixedFields);
+      fail("IllegalStateException is expected.");
+    } catch (IllegalStateException e) {
+      // Expected.
+      assertTrue(
+          "Exception message should mention includingDefaultValueFields.",
+          e.getMessage().contains("includingDefaultValueFields"));
+    }
+
+    try {
+      JsonFormat.printer().includingDefaultValueFields(fixedFields).includingDefaultValueFields();
+      fail("IllegalStateException is expected.");
+    } catch (IllegalStateException e) {
+      // Expected.
+      assertTrue(
+          "Exception message should mention includingDefaultValueFields.",
+          e.getMessage().contains("includingDefaultValueFields"));
+    }
+
+    try {
+      JsonFormat.printer()
+          .includingDefaultValueFields(fixedFields)
+          .includingDefaultValueFields(fixedFields);
+      fail("IllegalStateException is expected.");
+    } catch (IllegalStateException e) {
+      // Expected.
+      assertTrue(
+          "Exception message should mention includingDefaultValueFields.",
+          e.getMessage().contains("includingDefaultValueFields"));
+    }
+
+    Set<FieldDescriptor> intFields = new HashSet<FieldDescriptor>();
+    for (FieldDescriptor fieldDesc : TestAllTypes.getDescriptor().getFields()) {
+      if (fieldDesc.getName().contains("_int")) {
+        intFields.add(fieldDesc);
+      }
+    }
+
+    try {
+      JsonFormat.printer()
+          .includingDefaultValueFields(intFields)
+          .includingDefaultValueFields(fixedFields);
+      fail("IllegalStateException is expected.");
+    } catch (IllegalStateException e) {
+      // Expected.
+      assertTrue(
+          "Exception message should mention includingDefaultValueFields.",
+          e.getMessage().contains("includingDefaultValueFields"));
+    }
+
+    try {
+      JsonFormat.printer().includingDefaultValueFields(null);
+      fail("IllegalArgumentException is expected.");
+    } catch (IllegalArgumentException e) {
+      // Expected.
+      assertTrue(
+          "Exception message should mention includingDefaultValueFields.",
+          e.getMessage().contains("includingDefaultValueFields"));
+    }
+
+    try {
+      JsonFormat.printer().includingDefaultValueFields(Collections.emptySet());
+      fail("IllegalArgumentException is expected.");
+    } catch (IllegalArgumentException e) {
+      // Expected.
+      assertTrue(
+          "Exception message should mention includingDefaultValueFields.",
+          e.getMessage().contains("includingDefaultValueFields"));
+    }
+
     TestMap mapMessage = TestMap.getDefaultInstance();
     assertEquals("{\n}", JsonFormat.printer().print(mapMessage));
     assertEquals(
@@ -1283,16 +1396,17 @@
     assertEquals("{\n}", JsonFormat.printer().includingDefaultValueFields().print(oneofMessage));
 
     oneofMessage = TestOneof.newBuilder().setOneofInt32(42).build();
-    assertEquals("{\n  \"oneofInt32\": 42\n}",
-        JsonFormat.printer().print(oneofMessage));
-    assertEquals("{\n  \"oneofInt32\": 42\n}",
+    assertEquals("{\n  \"oneofInt32\": 42\n}", JsonFormat.printer().print(oneofMessage));
+    assertEquals(
+        "{\n  \"oneofInt32\": 42\n}",
         JsonFormat.printer().includingDefaultValueFields().print(oneofMessage));
 
     TestOneof.Builder oneofBuilder = TestOneof.newBuilder();
     mergeFromJson("{\n" + "  \"oneofNullValue\": null \n" + "}", oneofBuilder);
     oneofMessage = oneofBuilder.build();
     assertEquals("{\n  \"oneofNullValue\": null\n}", JsonFormat.printer().print(oneofMessage));
-    assertEquals("{\n  \"oneofNullValue\": null\n}",
+    assertEquals(
+        "{\n  \"oneofNullValue\": null\n}",
         JsonFormat.printer().includingDefaultValueFields().print(oneofMessage));
   }
 
@@ -1424,11 +1538,12 @@
 
   // Test that we are not leaking out JSON exceptions.
   public void testJsonException() throws Exception {
-    InputStream throwingInputStream = new InputStream() {
-      public int read() throws IOException {
-        throw new IOException("12345");
-      }
-    };
+    InputStream throwingInputStream =
+        new InputStream() {
+          public int read() throws IOException {
+            throw new IOException("12345");
+          }
+        };
     InputStreamReader throwingReader = new InputStreamReader(throwingInputStream);
     // When the underlying reader throws IOException, JsonFormat should forward
     // through this IOException.
diff --git a/js/binary/decoder.js b/js/binary/decoder.js
index 26bf359..ad9cb01 100644
--- a/js/binary/decoder.js
+++ b/js/binary/decoder.js
@@ -71,7 +71,7 @@
    */
   this.nextMethod_ = null;
 
-  /** @private {Array.<number>} */
+  /** @private {?Array<number|boolean|string>} */
   this.elements_ = null;
 
   /** @private {number} */
@@ -100,7 +100,7 @@
     this.decoder_ = opt_decoder;
     this.nextMethod_ = opt_next;
   }
-  this.elements_ = opt_elements ? opt_elements : null;
+  this.elements_ = opt_elements || null;
   this.cursor_ = 0;
   this.nextValue_ = null;
   this.atEnd_ = !this.decoder_ && !this.elements_;
@@ -953,6 +953,7 @@
   var end = cursor + length;
   var codeUnits = [];
 
+  var result = '';
   while (cursor < end) {
     var c = bytes[cursor++];
     if (c < 128) { // Regular 7-bit ASCII.
@@ -973,7 +974,7 @@
       var c2 = bytes[cursor++];
       var c3 = bytes[cursor++];
       var c4 = bytes[cursor++];
-      // Characters written on 4 bytes have 21 bits for a codepoint. 
+      // Characters written on 4 bytes have 21 bits for a codepoint.
       // We can't fit that on 16bit characters, so we use surrogates.
       var codepoint = ((c & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63);
       // Surrogates formula from wikipedia.
@@ -986,10 +987,14 @@
       var high = ((codepoint >> 10) & 1023) + 0xD800;
       codeUnits.push(high, low);
     }
+
+    // Avoid exceeding the maximum stack size when calling {@code apply}.
+    if (codeUnits.length >= 8192) {
+      result += String.fromCharCode.apply(null, codeUnits);
+      codeUnits.length = 0;
+    }
   }
-  // String.fromCharCode.apply is faster than manually appending characters on
-  // Chrome 25+, and generates no additional cons string garbage.
-  var result = String.fromCharCode.apply(null, codeUnits);
+  result += String.fromCharCode.apply(null, codeUnits);
   this.cursor_ = cursor;
   return result;
 };
diff --git a/js/binary/decoder_test.js b/js/binary/decoder_test.js
index cb8aff9..d0139e2 100644
--- a/js/binary/decoder_test.js
+++ b/js/binary/decoder_test.js
@@ -211,6 +211,25 @@
   });
 
   /**
+   * Tests reading and writing large strings
+   */
+  it('testLargeStrings', function() {
+    var encoder = new jspb.BinaryEncoder();
+
+    var len = 150000;
+    var long_string = '';
+    for (var i = 0; i < len; i++) {
+      long_string += 'a';
+    }
+
+    encoder.writeString(long_string);
+
+    var decoder = jspb.BinaryDecoder.alloc(encoder.end());
+
+    assertEquals(long_string, decoder.readString(len));
+  });
+
+  /**
    * Test encoding and decoding utf-8.
    */
    it('testUtf8', function() {
diff --git a/js/binary/encoder.js b/js/binary/encoder.js
index aee33e7..f25935f 100644
--- a/js/binary/encoder.js
+++ b/js/binary/encoder.js
@@ -355,8 +355,8 @@
  */
 jspb.BinaryEncoder.prototype.writeInt64String = function(value) {
   goog.asserts.assert(value == Math.floor(value));
-  goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
-                      (value < jspb.BinaryConstants.TWO_TO_63));
+  goog.asserts.assert((+value >= -jspb.BinaryConstants.TWO_TO_63) &&
+                      (+value < jspb.BinaryConstants.TWO_TO_63));
   jspb.utils.splitHash64(jspb.utils.decimalStringToHash64(value));
   this.writeSplitFixed64(jspb.utils.split64Low, jspb.utils.split64High);
 };
diff --git a/js/binary/reader.js b/js/binary/reader.js
index 8c5a4e8..d5d698f 100644
--- a/js/binary/reader.js
+++ b/js/binary/reader.js
@@ -971,7 +971,7 @@
 
 /**
  * Reads a packed scalar field using the supplied raw reader function.
- * @param {function()} decodeMethod
+ * @param {function(this:jspb.BinaryDecoder)} decodeMethod
  * @return {!Array}
  * @private
  */
diff --git a/js/binary/utils.js b/js/binary/utils.js
index 3ecd08e..7702020 100644
--- a/js/binary/utils.js
+++ b/js/binary/utils.js
@@ -430,7 +430,7 @@
 
 /**
  * Individual digits for number->string conversion.
- * @const {!Array.<number>}
+ * @const {!Array.<string>}
  */
 jspb.utils.DIGITS = [
   '0', '1', '2', '3', '4', '5', '6', '7',
diff --git a/js/binary/writer.js b/js/binary/writer.js
index c3009db..672e94b 100644
--- a/js/binary/writer.js
+++ b/js/binary/writer.js
@@ -596,8 +596,8 @@
  */
 jspb.BinaryWriter.prototype.writeSint64String = function(field, value) {
   if (value == null) return;
-  goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
-                      (value < jspb.BinaryConstants.TWO_TO_63));
+  goog.asserts.assert((+value >= -jspb.BinaryConstants.TWO_TO_63) &&
+                      (+value < jspb.BinaryConstants.TWO_TO_63));
   this.writeZigzagVarint64String_(field, value);
 };
 
diff --git a/js/binary/writer_test.js b/js/binary/writer_test.js
index 83fcdf9..118eecf 100644
--- a/js/binary/writer_test.js
+++ b/js/binary/writer_test.js
@@ -47,7 +47,7 @@
  * @param {function()} func This function should throw an error when run.
  */
 function assertFails(func) {
-  var e = assertThrows(func);
+  assertThrows(func);
 }
 
 
diff --git a/js/map.js b/js/map.js
index 4f562db..d423499 100644
--- a/js/map.js
+++ b/js/map.js
@@ -136,7 +136,7 @@
  *
  * @param {boolean=} includeInstance Whether to include the JSPB instance for
  *    transitional soy proto support: http://goto/soy-param-migration
- * @param {!function((boolean|undefined),!V):!Object=} valueToObject
+ * @param {!function((boolean|undefined),V):!Object=} valueToObject
  *    The static toObject() method, if V is a message type.
  * @return {!Array<!Array<!Object>>}
  */
@@ -146,7 +146,7 @@
   for (var i = 0; i < rawArray.length; i++) {
     var entry = this.map_[rawArray[i][0].toString()];
     this.wrapEntry_(entry);
-    var valueWrapper = /** @type {!V|undefined} */ (entry.valueWrapper);
+    var valueWrapper = /** @type {V|undefined} */ (entry.valueWrapper);
     if (valueWrapper) {
       goog.asserts.assert(valueToObject);
       entries.push([entry.key, valueToObject(includeInstance, valueWrapper)]);
@@ -412,8 +412,8 @@
  * @param {!jspb.BinaryWriter} writer
  * @param {!function(this:jspb.BinaryWriter,number,K)} keyWriterFn
  *     The method on BinaryWriter that writes type K to the stream.
- * @param {!function(this:jspb.BinaryWriter,number,V)|
- *          function(this:jspb.BinaryReader,V,?)} valueWriterFn
+ * @param {!function(this:jspb.BinaryWriter,number,V,?=)|
+ *          function(this:jspb.BinaryWriter,number,V,?)} valueWriterFn
  *     The method on BinaryWriter that writes type V to the stream.  May be
  *     writeMessage, in which case the second callback arg form is used.
  * @param {function(V,!jspb.BinaryWriter)=} opt_valueWriterCallback
@@ -509,7 +509,7 @@
 
 
 /**
- * @param {!K} key The entry's key.
+ * @param {K} key The entry's key.
  * @param {V=} opt_value The entry's value wrapper.
  * @constructor
  * @struct
diff --git a/js/message.js b/js/message.js
index 220a5bd..1f6bf16 100644
--- a/js/message.js
+++ b/js/message.js
@@ -106,8 +106,9 @@
 /**
  * Stores binary-related information for a single extension field.
  * @param {!jspb.ExtensionFieldInfo<T>} fieldInfo
- * @param {!function(number,?)} binaryReaderFn
- * @param {!function(number,?)|function(number,?,?,?,?,?)} binaryWriterFn
+ * @param {function(this:jspb.BinaryReader,number,?)} binaryReaderFn
+ * @param {function(this:jspb.BinaryWriter,number,?)
+ *        |function(this:jspb.BinaryWriter,number,?,?,?,?,?)} binaryWriterFn
  * @param {function(?,?)=} opt_binaryMessageSerializeFn
  * @param {function(?,?)=} opt_binaryMessageDeserializeFn
  * @param {boolean=} opt_isPacked
@@ -141,6 +142,21 @@
 
 /**
  * Base class for all JsPb messages.
+ *
+ * Several common methods (toObject, serializeBinary, in particular) are not
+ * defined on the prototype to encourage code patterns that minimize code bloat
+ * due to otherwise unused code on all protos contained in the project.
+ *
+ * If you want to call these methods on a generic message, either
+ * pass in your instance of method as a parameter:
+ *     someFunction(instanceOfKnownProto,
+ *                  KnownProtoClass.prototype.serializeBinary);
+ * or use a lambda that knows the type:
+ *     someFunction(()=>instanceOfKnownProto.serializeBinary());
+ * or, if you don't care about code size, just suppress the
+ *     WARNING - Property serializeBinary never defined on jspb.Message
+ * and call it the intuitive way.
+ *
  * @constructor
  * @struct
  */
@@ -524,7 +540,7 @@
  * @param {!jspb.Message} proto The proto whose extensions to convert.
  * @param {*} writer The binary-format writer to write to.
  * @param {!Object} extensions The proto class' registered extensions.
- * @param {function(jspb.ExtensionFieldInfo) : *} getExtensionFn The proto
+ * @param {function(this:jspb.Message,!jspb.ExtensionFieldInfo) : *} getExtensionFn The proto
  *     class' getExtension function. Passed for effective dead code removal.
  */
 jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions,
@@ -570,10 +586,13 @@
  * Reads an extension field from the given reader and, if a valid extension,
  * sets the extension value.
  * @param {!jspb.Message} msg A jspb proto.
- * @param {{skipField:function(),getFieldNumber:function():number}} reader
+ * @param {{
+ *   skipField:function(this:jspb.BinaryReader),
+ *   getFieldNumber:function(this:jspb.BinaryReader):number
+ * }} reader
  * @param {!Object} extensions The extensions object.
- * @param {function(jspb.ExtensionFieldInfo)} getExtensionFn
- * @param {function(jspb.ExtensionFieldInfo, ?)} setExtensionFn
+ * @param {function(this:jspb.Message,!jspb.ExtensionFieldInfo)} getExtensionFn
+ * @param {function(this:jspb.Message,!jspb.ExtensionFieldInfo, ?)} setExtensionFn
  */
 jspb.Message.readBinaryExtension = function(msg, reader, extensions,
     getExtensionFn, setExtensionFn) {
diff --git a/js/message_test.js b/js/message_test.js
index 2298742..dc0ae21 100644
--- a/js/message_test.js
+++ b/js/message_test.js
@@ -40,6 +40,7 @@
 goog.require('jspb.Message');
 
 // CommonJS-LoadFromFile: test8_pb proto.jspb.exttest.nested
+goog.require('proto.jspb.exttest.nested.TestNestedExtensionsMessage');
 goog.require('proto.jspb.exttest.nested.TestOuterMessage');
 
 // CommonJS-LoadFromFile: test5_pb proto.jspb.exttest.beta
diff --git a/python/google/protobuf/descriptor_database.py b/python/google/protobuf/descriptor_database.py
index 1333f99..40bcdd7 100644
--- a/python/google/protobuf/descriptor_database.py
+++ b/python/google/protobuf/descriptor_database.py
@@ -54,9 +54,9 @@
     Args:
       file_desc_proto: The FileDescriptorProto to add.
     Raises:
-      DescriptorDatabaseException: if an attempt is made to add a proto
-        with the same name but different definition than an exisiting
-        proto in the database.
+      DescriptorDatabaseConflictingDefinitionError: if an attempt is made to
+        add a proto with the same name but different definition than an
+        exisiting proto in the database.
     """
     proto_name = file_desc_proto.name
     if proto_name not in self._file_desc_protos_by_file:
@@ -65,7 +65,7 @@
       raise DescriptorDatabaseConflictingDefinitionError(
           '%s already added, but with different descriptor.' % proto_name)
 
-    # Add the top-level Message, Enum and Extension descriptors to the index.
+    # Add all the top-level descriptors to the index.
     package = file_desc_proto.package
     for message in file_desc_proto.message_type:
       self._file_desc_protos_by_symbol.update(
@@ -76,6 +76,9 @@
     for extension in file_desc_proto.extension:
       self._file_desc_protos_by_symbol[
           '.'.join((package, extension.name))] = file_desc_proto
+    for service in file_desc_proto.service:
+      self._file_desc_protos_by_symbol[
+          '.'.join((package, service.name))] = file_desc_proto
 
   def FindFileByName(self, name):
     """Finds the file descriptor proto by file name.
diff --git a/python/google/protobuf/descriptor_pool.py b/python/google/protobuf/descriptor_pool.py
index fc3a7f4..7844575 100644
--- a/python/google/protobuf/descriptor_pool.py
+++ b/python/google/protobuf/descriptor_pool.py
@@ -124,6 +124,7 @@
     self._descriptor_db = descriptor_db
     self._descriptors = {}
     self._enum_descriptors = {}
+    self._service_descriptors = {}
     self._file_descriptors = {}
     self._toplevel_extensions = {}
     # We store extensions in two two-level mappings: The first key is the
@@ -174,7 +175,7 @@
   def AddEnumDescriptor(self, enum_desc):
     """Adds an EnumDescriptor to the pool.
 
-    This method also registers the FileDescriptor associated with the message.
+    This method also registers the FileDescriptor associated with the enum.
 
     Args:
       enum_desc: An EnumDescriptor.
@@ -186,6 +187,18 @@
     self._enum_descriptors[enum_desc.full_name] = enum_desc
     self.AddFileDescriptor(enum_desc.file)
 
+  def AddServiceDescriptor(self, service_desc):
+    """Adds a ServiceDescriptor to the pool.
+
+    Args:
+      service_desc: A ServiceDescriptor.
+    """
+
+    if not isinstance(service_desc, descriptor.ServiceDescriptor):
+      raise TypeError('Expected instance of descriptor.ServiceDescriptor.')
+
+    self._service_descriptors[service_desc.full_name] = service_desc
+
   def AddExtensionDescriptor(self, extension):
     """Adds a FieldDescriptor describing an extension to the pool.
 
@@ -252,7 +265,7 @@
       A FileDescriptor for the named file.
 
     Raises:
-      KeyError: if the file can not be found in the pool.
+      KeyError: if the file cannot be found in the pool.
     """
 
     try:
@@ -281,7 +294,7 @@
       A FileDescriptor that contains the specified symbol.
 
     Raises:
-      KeyError: if the file can not be found in the pool.
+      KeyError: if the file cannot be found in the pool.
     """
 
     symbol = _NormalizeFullyQualifiedName(symbol)
@@ -296,15 +309,18 @@
       pass
 
     try:
-      file_proto = self._internal_db.FindFileContainingSymbol(symbol)
-    except KeyError as error:
-      if self._descriptor_db:
-        file_proto = self._descriptor_db.FindFileContainingSymbol(symbol)
-      else:
-        raise error
-    if not file_proto:
+      return self._FindFileContainingSymbolInDb(symbol)
+    except KeyError:
+      pass
+
+    # Try nested extensions inside a message.
+    message_name, _, extension_name = symbol.rpartition('.')
+    try:
+      scope = self.FindMessageTypeByName(message_name)
+      assert scope.extensions_by_name[extension_name]
+      return scope.file
+    except KeyError:
       raise KeyError('Cannot find a file containing %s' % symbol)
-    return self._ConvertFileProtoToFileDescriptor(file_proto)
 
   def FindMessageTypeByName(self, full_name):
     """Loads the named descriptor from the pool.
@@ -314,11 +330,14 @@
 
     Returns:
       The descriptor for the named type.
+
+    Raises:
+      KeyError: if the message cannot be found in the pool.
     """
 
     full_name = _NormalizeFullyQualifiedName(full_name)
     if full_name not in self._descriptors:
-      self.FindFileContainingSymbol(full_name)
+      self._FindFileContainingSymbolInDb(full_name)
     return self._descriptors[full_name]
 
   def FindEnumTypeByName(self, full_name):
@@ -329,11 +348,14 @@
 
     Returns:
       The enum descriptor for the named type.
+
+    Raises:
+      KeyError: if the enum cannot be found in the pool.
     """
 
     full_name = _NormalizeFullyQualifiedName(full_name)
     if full_name not in self._enum_descriptors:
-      self.FindFileContainingSymbol(full_name)
+      self._FindFileContainingSymbolInDb(full_name)
     return self._enum_descriptors[full_name]
 
   def FindFieldByName(self, full_name):
@@ -344,6 +366,9 @@
 
     Returns:
       The field descriptor for the named field.
+
+    Raises:
+      KeyError: if the field cannot be found in the pool.
     """
     full_name = _NormalizeFullyQualifiedName(full_name)
     message_name, _, field_name = full_name.rpartition('.')
@@ -358,6 +383,9 @@
 
     Returns:
       A FieldDescriptor, describing the named extension.
+
+    Raises:
+      KeyError: if the extension cannot be found in the pool.
     """
     full_name = _NormalizeFullyQualifiedName(full_name)
     try:
@@ -374,7 +402,7 @@
       scope = self.FindMessageTypeByName(message_name)
     except KeyError:
       # Some extensions are defined at file scope.
-      scope = self.FindFileContainingSymbol(full_name)
+      scope = self._FindFileContainingSymbolInDb(full_name)
     return scope.extensions_by_name[extension_name]
 
   def FindExtensionByNumber(self, message_descriptor, number):
@@ -390,7 +418,7 @@
     Returns:
       A FieldDescriptor describing the extension.
 
-    Raise:
+    Raises:
       KeyError: when no extension with the given number is known for the
         specified message.
     """
@@ -410,6 +438,46 @@
     """
     return list(self._extensions_by_number[message_descriptor].values())
 
+  def FindServiceByName(self, full_name):
+    """Loads the named service descriptor from the pool.
+
+    Args:
+      full_name: The full name of the service descriptor to load.
+
+    Returns:
+      The service descriptor for the named service.
+
+    Raises:
+      KeyError: if the service cannot be found in the pool.
+    """
+    full_name = _NormalizeFullyQualifiedName(full_name)
+    if full_name not in self._service_descriptors:
+      self._FindFileContainingSymbolInDb(full_name)
+    return self._service_descriptors[full_name]
+
+  def _FindFileContainingSymbolInDb(self, symbol):
+    """Finds the file in descriptor DB containing the specified symbol.
+
+    Args:
+      symbol: The name of the symbol to search for.
+
+    Returns:
+      A FileDescriptor that contains the specified symbol.
+
+    Raises:
+      KeyError: if the file cannot be found in the descriptor database.
+    """
+    try:
+      file_proto = self._internal_db.FindFileContainingSymbol(symbol)
+    except KeyError as error:
+      if self._descriptor_db:
+        file_proto = self._descriptor_db.FindFileContainingSymbol(symbol)
+      else:
+        raise error
+    if not file_proto:
+      raise KeyError('Cannot find a file containing %s' % symbol)
+    return self._ConvertFileProtoToFileDescriptor(file_proto)
+
   def _ConvertFileProtoToFileDescriptor(self, file_proto):
     """Creates a FileDescriptor from a proto or returns a cached copy.
 
@@ -804,6 +872,7 @@
                                         methods=methods,
                                         options=_OptionsOrNone(service_proto),
                                         file=file_desc)
+    self._service_descriptors[service_name] = desc
     return desc
 
   def _MakeMethodDescriptor(self, method_proto, service_name, package, scope,
diff --git a/python/google/protobuf/internal/containers.py b/python/google/protobuf/internal/containers.py
index de13018..68be9e5 100755
--- a/python/google/protobuf/internal/containers.py
+++ b/python/google/protobuf/internal/containers.py
@@ -275,7 +275,7 @@
     new_values = [self._type_checker.CheckValue(elem) for elem in elem_seq_iter]
     if new_values:
       self._values.extend(new_values)
-      self._message_listener.Modified()
+    self._message_listener.Modified()
 
   def MergeFrom(self, other):
     """Appends the contents of another repeated field of the same type to this
diff --git a/python/google/protobuf/internal/descriptor_pool_test.py b/python/google/protobuf/internal/descriptor_pool_test.py
index 1e710dc..2ba1d28 100644
--- a/python/google/protobuf/internal/descriptor_pool_test.py
+++ b/python/google/protobuf/internal/descriptor_pool_test.py
@@ -71,6 +71,13 @@
     self.pool.Add(self.factory_test1_fd)
     self.pool.Add(self.factory_test2_fd)
 
+    self.pool.Add(descriptor_pb2.FileDescriptorProto.FromString(
+        unittest_import_public_pb2.DESCRIPTOR.serialized_pb))
+    self.pool.Add(descriptor_pb2.FileDescriptorProto.FromString(
+        unittest_import_pb2.DESCRIPTOR.serialized_pb))
+    self.pool.Add(descriptor_pb2.FileDescriptorProto.FromString(
+        unittest_pb2.DESCRIPTOR.serialized_pb))
+
   def testFindFileByName(self):
     name1 = 'google/protobuf/internal/factory_test1.proto'
     file_desc1 = self.pool.FindFileByName(name1)
@@ -107,6 +114,20 @@
     self.assertEqual('google.protobuf.python.internal', file_desc2.package)
     self.assertIn('Factory2Message', file_desc2.message_types_by_name)
 
+    # Tests top level extension.
+    file_desc3 = self.pool.FindFileContainingSymbol(
+        'google.protobuf.python.internal.another_field')
+    self.assertIsInstance(file_desc3, descriptor.FileDescriptor)
+    self.assertEqual('google/protobuf/internal/factory_test2.proto',
+                     file_desc3.name)
+
+    # Tests nested extension inside a message.
+    file_desc4 = self.pool.FindFileContainingSymbol(
+        'google.protobuf.python.internal.Factory2Message.one_more_field')
+    self.assertIsInstance(file_desc4, descriptor.FileDescriptor)
+    self.assertEqual('google/protobuf/internal/factory_test2.proto',
+                     file_desc4.name)
+
   def testFindFileContainingSymbolFailure(self):
     with self.assertRaises(KeyError):
       self.pool.FindFileContainingSymbol('Does not exist')
@@ -311,6 +332,10 @@
       self.pool.FindExtensionByName(
           'google.protobuf.python.internal.Factory1Message.list_value')
 
+  def testFindService(self):
+    service = self.pool.FindServiceByName('protobuf_unittest.TestService')
+    self.assertEqual(service.full_name, 'protobuf_unittest.TestService')
+
   def testUserDefinedDB(self):
     db = descriptor_database.DescriptorDatabase()
     self.pool = descriptor_pool.DescriptorPool(db)
@@ -645,6 +670,17 @@
 
   @unittest.skipIf(api_implementation.Type() == 'cpp',
                    'With the cpp implementation, Add() must be called first')
+  def testService(self):
+    pool = descriptor_pool.DescriptorPool()
+    with self.assertRaises(KeyError):
+      pool.FindServiceByName('protobuf_unittest.TestService')
+    pool.AddServiceDescriptor(unittest_pb2._TESTSERVICE)
+    self.assertEqual(
+        'protobuf_unittest.TestService',
+        pool.FindServiceByName('protobuf_unittest.TestService').full_name)
+
+  @unittest.skipIf(api_implementation.Type() == 'cpp',
+                   'With the cpp implementation, Add() must be called first')
   def testFile(self):
     pool = descriptor_pool.DescriptorPool()
     pool.AddFileDescriptor(unittest_pb2.DESCRIPTOR)
diff --git a/python/google/protobuf/internal/encoder.py b/python/google/protobuf/internal/encoder.py
index 48ef2df..80e59ca 100755
--- a/python/google/protobuf/internal/encoder.py
+++ b/python/google/protobuf/internal/encoder.py
@@ -340,7 +340,7 @@
 # Map is special: it needs custom logic to compute its size properly.
 
 
-def MapSizer(field_descriptor):
+def MapSizer(field_descriptor, is_message_map):
   """Returns a sizer for a map field."""
 
   # Can't look at field_descriptor.message_type._concrete_class because it may
@@ -355,9 +355,12 @@
       # It's wasteful to create the messages and throw them away one second
       # later since we'll do the same for the actual encode.  But there's not an
       # obvious way to avoid this within the current design without tons of code
-      # duplication.
+      # duplication. For message map, value.ByteSize() should be called to
+      # update the status.
       entry_msg = message_type._concrete_class(key=key, value=value)
       total += message_sizer(entry_msg)
+      if is_message_map:
+        value.ByteSize()
     return total
 
   return FieldSize
diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py
index 9986c0d..e8b794f 100755
--- a/python/google/protobuf/internal/message_test.py
+++ b/python/google/protobuf/internal/message_test.py
@@ -564,6 +564,11 @@
     self.assertIsInstance(m.repeated_nested_message,
                           collections.MutableSequence)
 
+  def testRepeatedFieldInsideNestedMessage(self, message_module):
+    m = message_module.NestedTestAllTypes()
+    m.payload.repeated_int32.extend([])
+    self.assertTrue(m.HasField('payload'))
+
   def ensureNestedMessageExists(self, msg, attribute):
     """Make sure that a nested message object exists.
 
@@ -1432,6 +1437,18 @@
     self.assertIn(-456, msg2.map_int32_foreign_message)
     self.assertEqual(2, len(msg2.map_int32_foreign_message))
 
+  def testMapByteSize(self):
+    msg = map_unittest_pb2.TestMap()
+    msg.map_int32_int32[1] = 1
+    size = msg.ByteSize()
+    msg.map_int32_int32[1] = 128
+    self.assertEqual(msg.ByteSize(), size + 1)
+
+    msg.map_int32_foreign_message[19].c = 1
+    size = msg.ByteSize()
+    msg.map_int32_foreign_message[19].c = 128
+    self.assertEqual(msg.ByteSize(), size + 1)
+
   def testMergeFrom(self):
     msg = map_unittest_pb2.TestMap()
     msg.map_int32_int32[12] = 34
@@ -1456,7 +1473,15 @@
     self.assertEqual(5, msg2.map_int32_foreign_message[111].c)
     self.assertEqual(10, msg2.map_int32_foreign_message[222].c)
     self.assertFalse(msg2.map_int32_foreign_message[222].HasField('d'))
-    self.assertEqual(15, old_map_value.c)
+    if api_implementation.Type() != 'cpp':
+      # During the call to MergeFrom(), the C++ implementation will have
+      # deallocated the underlying message, but this is very difficult to detect
+      # properly. The line below is likely to cause a segmentation fault.
+      # With the Python implementation, old_map_value is just 'detached' from
+      # the main message. Using it will not crash of course, but since it still
+      # have a reference to the parent message I'm sure we can find interesting
+      # ways to cause inconsistencies.
+      self.assertEqual(15, old_map_value.c)
 
     # Verify that there is only one entry per key, even though the MergeFrom
     # may have internally created multiple entries for a single key in the
diff --git a/python/google/protobuf/internal/python_message.py b/python/google/protobuf/internal/python_message.py
index 4b70103..cb97cb2 100755
--- a/python/google/protobuf/internal/python_message.py
+++ b/python/google/protobuf/internal/python_message.py
@@ -288,7 +288,8 @@
 
   if is_map_entry:
     field_encoder = encoder.MapEncoder(field_descriptor)
-    sizer = encoder.MapSizer(field_descriptor)
+    sizer = encoder.MapSizer(field_descriptor,
+                             _IsMessageMapField(field_descriptor))
   elif _IsMessageSetExtension(field_descriptor):
     field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number)
     sizer = encoder.MessageSetItemSizer(field_descriptor.number)
@@ -891,7 +892,7 @@
 def _InternalUnpackAny(msg):
   """Unpacks Any message and returns the unpacked message.
 
-  This internal method is differnt from public Any Unpack method which takes
+  This internal method is different from public Any Unpack method which takes
   the target message as argument. _InternalUnpackAny method does not have
   target message type and need to find the message type in descriptor pool.
 
diff --git a/python/google/protobuf/internal/python_protobuf.cc b/python/google/protobuf/internal/python_protobuf.cc
new file mode 100644
index 0000000..f90cc43
--- /dev/null
+++ b/python/google/protobuf/internal/python_protobuf.cc
@@ -0,0 +1,63 @@
+// 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.
+
+// Author: qrczak@google.com (Marcin Kowalczyk)
+
+#include <google/protobuf/python/python_protobuf.h>
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+static const Message* GetCProtoInsidePyProtoStub(PyObject* msg) {
+  return NULL;
+}
+static Message* MutableCProtoInsidePyProtoStub(PyObject* msg) {
+  return NULL;
+}
+
+// This is initialized with a default, stub implementation.
+// If python-google.protobuf.cc is loaded, the function pointer is overridden
+// with a full implementation.
+const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg) =
+    GetCProtoInsidePyProtoStub;
+Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg) =
+    MutableCProtoInsidePyProtoStub;
+
+const Message* GetCProtoInsidePyProto(PyObject* msg) {
+  return GetCProtoInsidePyProtoPtr(msg);
+}
+Message* MutableCProtoInsidePyProto(PyObject* msg) {
+  return MutableCProtoInsidePyProtoPtr(msg);
+}
+
+}  // namespace python
+}  // namespace protobuf
+}  // namespace google
diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py
index 0e88101..55b0d72 100755
--- a/python/google/protobuf/internal/reflection_test.py
+++ b/python/google/protobuf/internal/reflection_test.py
@@ -1551,7 +1551,14 @@
     container = copy.deepcopy(proto1.repeated_int32)
     self.assertEqual([2, 3], container)
 
-    # TODO(anuraag): Implement deepcopy for repeated composite / extension dict
+    message1 = proto1.repeated_nested_message.add()
+    message1.bb = 1
+    messages = copy.deepcopy(proto1.repeated_nested_message)
+    self.assertEqual(proto1.repeated_nested_message, messages)
+    message1.bb = 2
+    self.assertNotEqual(proto1.repeated_nested_message, messages)
+
+    # TODO(anuraag): Implement deepcopy for extension dict
 
   def testClear(self):
     proto = unittest_pb2.TestAllTypes()
diff --git a/python/google/protobuf/internal/symbol_database_test.py b/python/google/protobuf/internal/symbol_database_test.py
index 4f5173b..af42681 100644
--- a/python/google/protobuf/internal/symbol_database_test.py
+++ b/python/google/protobuf/internal/symbol_database_test.py
@@ -60,6 +60,7 @@
     db.RegisterMessage(unittest_pb2.TestAllTypes.RepeatedGroup)
     db.RegisterEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR)
     db.RegisterEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR)
+    db.RegisterServiceDescriptor(unittest_pb2._TESTSERVICE)
     return db
 
   def testGetPrototype(self):
@@ -109,7 +110,13 @@
         self._Database().pool.FindMessageTypeByName(
             'protobuf_unittest.TestAllTypes.NestedMessage').full_name)
 
-  def testFindFindContainingSymbol(self):
+  def testFindServiceByName(self):
+    self.assertEqual(
+        'protobuf_unittest.TestService',
+        self._Database().pool.FindServiceByName(
+            'protobuf_unittest.TestService').full_name)
+
+  def testFindFileContainingSymbol(self):
     # Lookup based on either enum or message.
     self.assertEqual(
         'google/protobuf/unittest.proto',
diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py
index 176cbd1..188310b 100755
--- a/python/google/protobuf/internal/text_format_test.py
+++ b/python/google/protobuf/internal/text_format_test.py
@@ -1119,6 +1119,11 @@
     packed_message = unittest_pb2.OneString()
     message.any_value.Unpack(packed_message)
     self.assertEqual('string', packed_message.data)
+    message.Clear()
+    text_format.Parse(text, message, descriptor_pool=descriptor_pool.Default())
+    packed_message = unittest_pb2.OneString()
+    message.any_value.Unpack(packed_message)
+    self.assertEqual('string', packed_message.data)
 
   def testMergeExpandedAnyRepeated(self):
     message = any_test_pb2.TestAny()
@@ -1373,6 +1378,52 @@
     self.assertEqual('# some comment', tokenizer.ConsumeComment())
     self.assertTrue(tokenizer.AtEnd())
 
+  def testConsumeLineComment(self):
+    tokenizer = text_format.Tokenizer('# some comment'.splitlines(),
+                                      skip_comments=False)
+    self.assertFalse(tokenizer.AtEnd())
+    self.assertEqual((False, '# some comment'),
+                     tokenizer.ConsumeCommentOrTrailingComment())
+    self.assertTrue(tokenizer.AtEnd())
+
+  def testConsumeTwoLineComments(self):
+    text = '# some comment\n# another comment'
+    tokenizer = text_format.Tokenizer(text.splitlines(), skip_comments=False)
+    self.assertEqual((False, '# some comment'),
+                     tokenizer.ConsumeCommentOrTrailingComment())
+    self.assertFalse(tokenizer.AtEnd())
+    self.assertEqual((False, '# another comment'),
+                     tokenizer.ConsumeCommentOrTrailingComment())
+    self.assertTrue(tokenizer.AtEnd())
+
+  def testConsumeAndCheckTrailingComment(self):
+    text = 'some_number: 4  # some comment'  # trailing comment on the same line
+    tokenizer = text_format.Tokenizer(text.splitlines(), skip_comments=False)
+    self.assertRaises(text_format.ParseError,
+                      tokenizer.ConsumeCommentOrTrailingComment)
+
+    self.assertEqual('some_number', tokenizer.ConsumeIdentifier())
+    self.assertEqual(tokenizer.token, ':')
+    tokenizer.NextToken()
+    self.assertRaises(text_format.ParseError,
+                      tokenizer.ConsumeCommentOrTrailingComment)
+    self.assertEqual(4, tokenizer.ConsumeInteger())
+    self.assertFalse(tokenizer.AtEnd())
+
+    self.assertEqual((True, '# some comment'),
+                     tokenizer.ConsumeCommentOrTrailingComment())
+    self.assertTrue(tokenizer.AtEnd())
+
+  def testHashinComment(self):
+    text = 'some_number: 4  # some comment # not a new comment'
+    tokenizer = text_format.Tokenizer(text.splitlines(), skip_comments=False)
+    self.assertEqual('some_number', tokenizer.ConsumeIdentifier())
+    self.assertEqual(tokenizer.token, ':')
+    tokenizer.NextToken()
+    self.assertEqual(4, tokenizer.ConsumeInteger())
+    self.assertEqual((True, '# some comment # not a new comment'),
+                     tokenizer.ConsumeCommentOrTrailingComment())
+    self.assertTrue(tokenizer.AtEnd())
 
 if __name__ == '__main__':
   unittest.main()
diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc
index 924ae0b9..f13e1bc 100644
--- a/python/google/protobuf/pyext/descriptor.cc
+++ b/python/google/protobuf/pyext/descriptor.cc
@@ -32,6 +32,7 @@
 
 #include <Python.h>
 #include <frameobject.h>
+#include <google/protobuf/stubs/hash.h>
 #include <string>
 
 #include <google/protobuf/io/coded_stream.h>
@@ -1666,6 +1667,15 @@
       &PyServiceDescriptor_Type, service_descriptor, NULL);
 }
 
+const ServiceDescriptor* PyServiceDescriptor_AsDescriptor(PyObject* obj) {
+  if (!PyObject_TypeCheck(obj, &PyServiceDescriptor_Type)) {
+    PyErr_SetString(PyExc_TypeError, "Not a ServiceDescriptor");
+    return NULL;
+  }
+  return reinterpret_cast<const ServiceDescriptor*>(
+      reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
+}
+
 namespace method_descriptor {
 
 // Unchecked accessor to the C++ pointer.
@@ -1769,6 +1779,15 @@
       &PyMethodDescriptor_Type, method_descriptor, NULL);
 }
 
+const MethodDescriptor* PyMethodDescriptor_AsDescriptor(PyObject* obj) {
+  if (!PyObject_TypeCheck(obj, &PyMethodDescriptor_Type)) {
+    PyErr_SetString(PyExc_TypeError, "Not a MethodDescriptor");
+    return NULL;
+  }
+  return reinterpret_cast<const MethodDescriptor*>(
+      reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor);
+}
+
 // Add a enum values to a type dictionary.
 static bool AddEnumValues(PyTypeObject *type,
                           const EnumDescriptor* enum_descriptor) {
diff --git a/python/google/protobuf/pyext/descriptor.h b/python/google/protobuf/pyext/descriptor.h
index 1ae0e67..f081df8 100644
--- a/python/google/protobuf/pyext/descriptor.h
+++ b/python/google/protobuf/pyext/descriptor.h
@@ -80,6 +80,8 @@
 const FieldDescriptor* PyFieldDescriptor_AsDescriptor(PyObject* obj);
 const EnumDescriptor* PyEnumDescriptor_AsDescriptor(PyObject* obj);
 const FileDescriptor* PyFileDescriptor_AsDescriptor(PyObject* obj);
+const ServiceDescriptor* PyServiceDescriptor_AsDescriptor(PyObject* obj);
+const MethodDescriptor* PyMethodDescriptor_AsDescriptor(PyObject* obj);
 
 // Returns the raw C++ pointer.
 const void* PyDescriptor_AsVoidPtr(PyObject* obj);
diff --git a/python/google/protobuf/pyext/descriptor_pool.cc b/python/google/protobuf/pyext/descriptor_pool.cc
index fa66bf9..16f4d49 100644
--- a/python/google/protobuf/pyext/descriptor_pool.cc
+++ b/python/google/protobuf/pyext/descriptor_pool.cc
@@ -39,6 +39,7 @@
 #include <google/protobuf/pyext/message.h>
 #include <google/protobuf/pyext/message_factory.h>
 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+#include <google/protobuf/stubs/hash.h>
 
 #if PY_MAJOR_VERSION >= 3
   #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
@@ -437,8 +438,23 @@
   Py_RETURN_NONE;
 }
 
-// The code below loads new Descriptors from a serialized FileDescriptorProto.
+PyObject* AddServiceDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
+  const ServiceDescriptor* service_descriptor =
+      PyServiceDescriptor_AsDescriptor(descriptor);
+  if (!service_descriptor) {
+    return NULL;
+  }
+  if (service_descriptor !=
+      self->pool->FindServiceByName(service_descriptor->full_name())) {
+    PyErr_Format(PyExc_ValueError,
+                 "The service descriptor %s does not belong to this pool",
+                 service_descriptor->full_name().c_str());
+    return NULL;
+  }
+  Py_RETURN_NONE;
+}
 
+// The code below loads new Descriptors from a serialized FileDescriptorProto.
 
 // Collects errors that occur during proto file building to allow them to be
 // propagated in the python exception instead of only living in ERROR logs.
@@ -538,6 +554,8 @@
     "No-op. Add() must have been called before." },
   { "AddExtensionDescriptor", (PyCFunction)AddExtensionDescriptor, METH_O,
     "No-op. Add() must have been called before." },
+  { "AddServiceDescriptor", (PyCFunction)AddServiceDescriptor, METH_O,
+    "No-op. Add() must have been called before." },
 
   { "FindFileByName", (PyCFunction)FindFileByName, METH_O,
     "Searches for a file descriptor by its .proto name." },
diff --git a/python/google/protobuf/pyext/descriptor_pool.h b/python/google/protobuf/pyext/descriptor_pool.h
index c4d7d40..53ee53d 100644
--- a/python/google/protobuf/pyext/descriptor_pool.h
+++ b/python/google/protobuf/pyext/descriptor_pool.h
@@ -85,6 +85,7 @@
 
 namespace cdescriptor_pool {
 
+
 // Looks up a message by name.
 // Returns a message Descriptor, or NULL if not found.
 const Descriptor* FindMessageTypeByName(PyDescriptorPool* self,
diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc
index 43a2bc1..9cb4e9a 100644
--- a/python/google/protobuf/pyext/repeated_composite_container.cc
+++ b/python/google/protobuf/pyext/repeated_composite_container.cc
@@ -47,6 +47,7 @@
 #include <google/protobuf/pyext/descriptor_pool.h>
 #include <google/protobuf/pyext/message.h>
 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+#include <google/protobuf/reflection.h>
 
 #if PY_MAJOR_VERSION >= 3
   #define PyInt_Check PyLong_Check
@@ -485,6 +486,32 @@
   return 0;
 }
 
+PyObject* DeepCopy(RepeatedCompositeContainer* self, PyObject* arg) {
+  ScopedPyObjectPtr cloneObj(
+      PyType_GenericAlloc(&RepeatedCompositeContainer_Type, 0));
+  if (cloneObj == NULL) {
+    return NULL;
+  }
+  RepeatedCompositeContainer* clone =
+      reinterpret_cast<RepeatedCompositeContainer*>(cloneObj.get());
+
+  Message* new_message = self->message->New();
+  clone->parent = NULL;
+  clone->parent_field_descriptor = self->parent_field_descriptor;
+  clone->message = new_message;
+  clone->owner.reset(new_message);
+  Py_INCREF(self->child_message_class);
+  clone->child_message_class = self->child_message_class;
+  clone->child_messages = PyList_New(0);
+
+  new_message->GetReflection()
+      ->GetMutableRepeatedFieldRef<Message>(new_message,
+                                            self->parent_field_descriptor)
+      .MergeFrom(self->message->GetReflection()->GetRepeatedFieldRef<Message>(
+          *self->message, self->parent_field_descriptor));
+  return cloneObj.release();
+}
+
 int SetOwner(RepeatedCompositeContainer* self,
              const shared_ptr<Message>& new_owner) {
   GOOGLE_CHECK_ATTACHED(self);
@@ -551,6 +578,8 @@
 };
 
 static PyMethodDef Methods[] = {
+  { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
+    "Makes a deep copy of the class." },
   { "add", (PyCFunction) Add, METH_VARARGS | METH_KEYWORDS,
     "Adds an object to the repeated container." },
   { "extend", (PyCFunction) Extend, METH_O,
diff --git a/python/google/protobuf/pyext/scoped_pyobject_ptr.h b/python/google/protobuf/pyext/scoped_pyobject_ptr.h
index a128cd4..a2afa7f 100644
--- a/python/google/protobuf/pyext/scoped_pyobject_ptr.h
+++ b/python/google/protobuf/pyext/scoped_pyobject_ptr.h
@@ -36,61 +36,70 @@
 #include <google/protobuf/stubs/common.h>
 
 #include <Python.h>
-
 namespace google {
-class ScopedPyObjectPtr {
+namespace protobuf {
+namespace python {
+
+// Owns a python object and decrements the reference count on destruction.
+// This class is not threadsafe.
+template <typename PyObjectStruct>
+class ScopedPythonPtr {
  public:
-  // Constructor.  Defaults to initializing with NULL.
-  // There is no way to create an uninitialized ScopedPyObjectPtr.
-  explicit ScopedPyObjectPtr(PyObject* p = NULL) : ptr_(p) { }
+  // Takes the ownership of the specified object to ScopedPythonPtr.
+  // The reference count of the specified py_object is not incremented.
+  explicit ScopedPythonPtr(PyObjectStruct* py_object = NULL)
+      : ptr_(py_object) {}
 
-  // Destructor.  If there is a PyObject object, delete it.
-  ~ScopedPyObjectPtr() {
-    Py_XDECREF(ptr_);
-  }
+  // If a PyObject is owned, decrement its reference count.
+  ~ScopedPythonPtr() { Py_XDECREF(ptr_); }
 
-  // Reset.  Deletes the current owned object, if any.
-  // Then takes ownership of a new object, if given.
+  // Deletes the current owned object, if any.
+  // Then takes ownership of a new object without incrementing the reference
+  // count.
   // This function must be called with a reference that you own.
   //   this->reset(this->get()) is wrong!
   //   this->reset(this->release()) is OK.
-  PyObject* reset(PyObject* p = NULL) {
+  PyObjectStruct* reset(PyObjectStruct* p = NULL) {
     Py_XDECREF(ptr_);
     ptr_ = p;
     return ptr_;
   }
 
-  // Releases ownership of the object.
+  // Releases ownership of the object without decrementing the reference count.
   // The caller now owns the returned reference.
-  PyObject* release() {
+  PyObjectStruct* release() {
     PyObject* p = ptr_;
     ptr_ = NULL;
     return p;
   }
 
-  PyObject* operator->() const  {
+  PyObjectStruct* operator->() const {
     assert(ptr_ != NULL);
     return ptr_;
   }
 
-  PyObject* get() const { return ptr_; }
+  PyObjectStruct* get() const { return ptr_; }
 
-  Py_ssize_t refcnt() const { return Py_REFCNT(ptr_); }
+  PyObject* as_pyobject() const { return reinterpret_cast<PyObject*>(ptr_); }
 
+  // Increments the reference count fo the current object.
+  // Should not be called when no object is held.
   void inc() const { Py_INCREF(ptr_); }
 
-  // Comparison operators.
-  // These return whether a ScopedPyObjectPtr and a raw pointer
-  // refer to the same object, not just to two different but equal
-  // objects.
-  bool operator==(const PyObject* p) const { return ptr_ == p; }
-  bool operator!=(const PyObject* p) const { return ptr_ != p; }
+  // True when a ScopedPyObjectPtr and a raw pointer refer to the same object.
+  // Comparison operators are non reflexive.
+  bool operator==(const PyObjectStruct* p) const { return ptr_ == p; }
+  bool operator!=(const PyObjectStruct* p) const { return ptr_ != p; }
 
  private:
-  PyObject* ptr_;
+  PyObjectStruct* ptr_;
 
-  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ScopedPyObjectPtr);
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ScopedPythonPtr);
 };
 
+typedef ScopedPythonPtr<PyObject> ScopedPyObjectPtr;
+
+}  // namespace python
+}  // namespace protobuf
 }  // namespace google
 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_SCOPED_PYOBJECT_PTR_H__
diff --git a/python/google/protobuf/pyext/python_protobuf.h b/python/google/protobuf/python_protobuf.h
similarity index 100%
rename from python/google/protobuf/pyext/python_protobuf.h
rename to python/google/protobuf/python_protobuf.h
diff --git a/python/google/protobuf/reflection.py b/python/google/protobuf/reflection.py
index 05bafd6..f4ce8ca 100755
--- a/python/google/protobuf/reflection.py
+++ b/python/google/protobuf/reflection.py
@@ -107,7 +107,7 @@
     The Message class object described by the descriptor.
   """
   if descriptor in MESSAGE_CLASS_CACHE:
-      return MESSAGE_CLASS_CACHE[descriptor]
+    return MESSAGE_CLASS_CACHE[descriptor]
 
   attributes = {}
   for name, nested_type in descriptor.nested_types_by_name.items():
@@ -115,7 +115,7 @@
 
   attributes[GeneratedProtocolMessageType._DESCRIPTOR_KEY] = descriptor
 
-  result = GeneratedProtocolMessageType(str(descriptor.name), (message.Message,),
-                                      attributes)
+  result = GeneratedProtocolMessageType(
+      str(descriptor.name), (message.Message,), attributes)
   MESSAGE_CLASS_CACHE[descriptor] = result
   return result
diff --git a/python/google/protobuf/symbol_database.py b/python/google/protobuf/symbol_database.py
index ecbef21..07341ef 100644
--- a/python/google/protobuf/symbol_database.py
+++ b/python/google/protobuf/symbol_database.py
@@ -94,6 +94,17 @@
     self.pool.AddEnumDescriptor(enum_descriptor)
     return enum_descriptor
 
+  def RegisterServiceDescriptor(self, service_descriptor):
+    """Registers the given service descriptor in the local database.
+
+    Args:
+      service_descriptor: a descriptor.ServiceDescriptor.
+
+    Returns:
+      The provided descriptor.
+    """
+    self.pool.AddServiceDescriptor(service_descriptor)
+
   def RegisterFileDescriptor(self, file_descriptor):
     """Registers the given file descriptor in the local database.
 
diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py
index 90f6ce4..c216e09 100755
--- a/python/google/protobuf/text_format.py
+++ b/python/google/protobuf/text_format.py
@@ -422,7 +422,8 @@
 def Parse(text,
           message,
           allow_unknown_extension=False,
-          allow_field_number=False):
+          allow_field_number=False,
+          descriptor_pool=None):
   """Parses a text representation of a protocol message into a message.
 
   Args:
@@ -431,6 +432,7 @@
     allow_unknown_extension: if True, skip over missing extensions and keep
       parsing
     allow_field_number: if True, both field number and field name are allowed.
+    descriptor_pool: A DescriptorPool used to resolve Any types.
 
   Returns:
     The same message passed as argument.
@@ -440,8 +442,11 @@
   """
   if not isinstance(text, str):
     text = text.decode('utf-8')
-  return ParseLines(
-      text.split('\n'), message, allow_unknown_extension, allow_field_number)
+  return ParseLines(text.split('\n'),
+                    message,
+                    allow_unknown_extension,
+                    allow_field_number,
+                    descriptor_pool=descriptor_pool)
 
 
 def Merge(text,
@@ -479,7 +484,8 @@
 def ParseLines(lines,
                message,
                allow_unknown_extension=False,
-               allow_field_number=False):
+               allow_field_number=False,
+               descriptor_pool=None):
   """Parses a text representation of a protocol message into a message.
 
   Args:
@@ -496,7 +502,9 @@
   Raises:
     ParseError: On text parsing problems.
   """
-  parser = _Parser(allow_unknown_extension, allow_field_number)
+  parser = _Parser(allow_unknown_extension,
+                   allow_field_number,
+                   descriptor_pool=descriptor_pool)
   return parser.ParseLines(lines, message)
 
 
@@ -513,6 +521,7 @@
     allow_unknown_extension: if True, skip over missing extensions and keep
       parsing
     allow_field_number: if True, both field number and field name are allowed.
+    descriptor_pool: A DescriptorPool used to resolve Any types.
 
   Returns:
     The same message passed as argument.
@@ -1023,6 +1032,22 @@
     self.NextToken()
     return result
 
+  def ConsumeCommentOrTrailingComment(self):
+    """Consumes a comment, returns a 2-tuple (trailing bool, comment str)."""
+
+    # Tokenizer initializes _previous_line and _previous_column to 0. As the
+    # tokenizer starts, it looks like there is a previous token on the line.
+    just_started = self._line == 0 and self._column == 0
+
+    before_parsing = self._previous_line
+    comment = self.ConsumeComment()
+
+    # A trailing comment is a comment on the same line than the previous token.
+    trailing = (self._previous_line == before_parsing
+                and not just_started)
+
+    return trailing, comment
+
   def TryConsumeIdentifier(self):
     try:
       self.ConsumeIdentifier()
diff --git a/src/Makefile.am b/src/Makefile.am
index bcd8157..34abfca 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -37,18 +37,19 @@
 # If you are adding new files here, also remember to change the build files for
 # all other languages, //protoc-artifacts/build-zip.sh and run
 # //update_file_list.sh for bazel.
-nobase_dist_proto_DATA = google/protobuf/descriptor.proto     \
-                         google/protobuf/any.proto            \
-                         google/protobuf/api.proto            \
-                         google/protobuf/duration.proto       \
-                         google/protobuf/empty.proto          \
-                         google/protobuf/field_mask.proto     \
-                         google/protobuf/source_context.proto \
-                         google/protobuf/struct.proto         \
-                         google/protobuf/timestamp.proto      \
-                         google/protobuf/type.proto           \
-                         google/protobuf/wrappers.proto       \
-                         google/protobuf/compiler/plugin.proto
+nobase_dist_proto_DATA = google/protobuf/descriptor.proto      \
+                         google/protobuf/any.proto             \
+                         google/protobuf/api.proto             \
+                         google/protobuf/duration.proto        \
+                         google/protobuf/empty.proto           \
+                         google/protobuf/field_mask.proto      \
+                         google/protobuf/source_context.proto  \
+                         google/protobuf/struct.proto          \
+                         google/protobuf/timestamp.proto       \
+                         google/protobuf/type.proto            \
+                         google/protobuf/wrappers.proto        \
+                         google/protobuf/compiler/plugin.proto \
+                         google/protobuf/compiler/profile.proto
 
 # Not sure why these don't get cleaned automatically.
 clean-local:
@@ -155,6 +156,7 @@
   google/protobuf/compiler/parser.h                              \
   google/protobuf/compiler/plugin.h                              \
   google/protobuf/compiler/plugin.pb.h                           \
+  google/protobuf/compiler/profile.pb.h                          \
   google/protobuf/compiler/cpp/cpp_generator.h                   \
   google/protobuf/compiler/csharp/csharp_generator.h             \
   google/protobuf/compiler/csharp/csharp_names.h                 \
@@ -324,6 +326,7 @@
   google/protobuf/compiler/command_line_interface.cc           \
   google/protobuf/compiler/plugin.cc                           \
   google/protobuf/compiler/plugin.pb.cc                        \
+  google/protobuf/compiler/profile.pb.cc                       \
   google/protobuf/compiler/subprocess.cc                       \
   google/protobuf/compiler/subprocess.h                        \
   google/protobuf/compiler/zip_writer.cc                       \
@@ -535,6 +538,9 @@
   google/protobuf/unittest_import.proto                           \
   google/protobuf/unittest_import_public_lite.proto               \
   google/protobuf/unittest_import_public.proto                    \
+  google/protobuf/unittest_lazy_dependencies.proto                \
+  google/protobuf/unittest_lazy_dependencies_custom_option.proto  \
+  google/protobuf/unittest_lazy_dependencies_enum.proto           \
   google/protobuf/unittest_lite_imports_nonlite.proto             \
   google/protobuf/unittest_lite.proto                             \
   google/protobuf/unittest_mset.proto                             \
@@ -639,6 +645,12 @@
   google/protobuf/unittest_import.pb.h                            \
   google/protobuf/unittest_import_public.pb.cc                    \
   google/protobuf/unittest_import_public.pb.h                     \
+  google/protobuf/unittest_lazy_dependencies.pb.cc                \
+  google/protobuf/unittest_lazy_dependencies.pb.h                 \
+  google/protobuf/unittest_lazy_dependencies_custom_option.pb.cc  \
+  google/protobuf/unittest_lazy_dependencies_custom_option.pb.h   \
+  google/protobuf/unittest_lazy_dependencies_enum.pb.cc           \
+  google/protobuf/unittest_lazy_dependencies_enum.pb.h            \
   google/protobuf/unittest_lite_imports_nonlite.pb.cc             \
   google/protobuf/unittest_lite_imports_nonlite.pb.h              \
   google/protobuf/unittest_mset.pb.cc                             \
@@ -847,7 +859,12 @@
 # depend on gtest because our internal version of gtest depend on proto
 # full runtime and we want to make sure this test builds without full
 # runtime.
-protobuf_lite_test_LDADD = $(PTHREAD_LIBS) libprotobuf-lite.la
+protobuf_lite_test_LDADD = $(PTHREAD_LIBS) libprotobuf-lite.la \
+                           ../gmock/gtest/lib/libgtest.la      \
+                           ../gmock/lib/libgmock.la            \
+                           ../gmock/lib/libgmock_main.la
+protobuf_lite_test_CPPFLAGS= -I$(srcdir)/../gmock/include \
+                             -I$(srcdir)/../gmock/gtest/include
 protobuf_lite_test_CXXFLAGS = $(NO_OPT_CXXFLAGS)
 protobuf_lite_test_SOURCES =                                           \
   google/protobuf/lite_unittest.cc                                     \
diff --git a/src/google/protobuf/any.h b/src/google/protobuf/any.h
index 04e5416..c2c27ec 100644
--- a/src/google/protobuf/any.h
+++ b/src/google/protobuf/any.h
@@ -63,7 +63,7 @@
 
   // Unpacks the payload into the given message. Returns false if the message's
   // type doesn't match the type specified in the type URL (i.e., the full
-  // name after the last "/" of the type URL doesn't match the message's actaul
+  // name after the last "/" of the type URL doesn't match the message's actual
   // full name) or parsing the payload has failed.
   bool UnpackTo(Message* message) const;
 
@@ -90,8 +90,8 @@
 
 // Get the proto type name from Any::type_url value. For example, passing
 // "type.googleapis.com/rpc.QueryOrigin" will return "rpc.QueryOrigin" in
-// *full_type_name. Returns false if type_url does not start with
-// "type.googleapis.com" or "type.googleprod.com".
+// *full_type_name. Returns false if the type_url does not have a "/"
+// in the type url separating the full type name.
 bool ParseAnyTypeUrl(const string& type_url, string* full_type_name);
 
 // See if message is of type google.protobuf.Any, if so, return the descriptors
diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc
index 94c9539..6c80aaa 100644
--- a/src/google/protobuf/any.pb.cc
+++ b/src/google/protobuf/any.pb.cc
@@ -31,11 +31,26 @@
 
 }  // namespace
 
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+    const TableStruct::entries[] = {
+  {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+    const TableStruct::aux[] = {
+  ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+    TableStruct::schema[] = {
+  { NULL, NULL, 0, -1, -1, false },
+};
+
 const ::google::protobuf::uint32 TableStruct::offsets[] = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, type_url_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, value_),
 };
@@ -186,7 +201,7 @@
 }
 const ::google::protobuf::Descriptor* Any::descriptor() {
   protobuf_google_2fprotobuf_2fany_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fany_2eproto::file_level_metadata[0].descriptor;
+  return protobuf_google_2fprotobuf_2fany_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const Any& Any::default_instance() {
@@ -270,6 +285,9 @@
 void Any::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Any)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string type_url = 1;
   if (this->type_url().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -291,8 +309,10 @@
 
 ::google::protobuf::uint8* Any::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Any)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string type_url = 1;
   if (this->type_url().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -359,6 +379,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Any)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.type_url().size() > 0) {
 
     type_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_url_);
@@ -399,7 +422,7 @@
 
 ::google::protobuf::Metadata Any::GetMetadata() const {
   protobuf_google_2fprotobuf_2fany_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fany_2eproto::file_level_metadata[0];
+  return protobuf_google_2fprotobuf_2fany_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -427,6 +450,7 @@
 }
 #endif
 void Any::set_type_url(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Any.type_url)
@@ -479,6 +503,7 @@
 }
 #endif
 void Any::set_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Any.value)
diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h
index 1a61d5a..e5051c7 100644
--- a/src/google/protobuf/any.pb.h
+++ b/src/google/protobuf/any.pb.h
@@ -22,6 +22,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/message.h>
@@ -44,6 +45,9 @@
 namespace protobuf_google_2fprotobuf_2fany_2eproto {
 // Internal implementation detail -- do not call these.
 struct LIBPROTOBUF_EXPORT TableStruct {
+  static const ::google::protobuf::internal::ParseTableField entries[];
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+  static const ::google::protobuf::internal::ParseTable schema[];
   static const ::google::protobuf::uint32 offsets[];
   static void InitDefaultsImpl();
   static void Shutdown();
@@ -73,6 +77,8 @@
     return reinterpret_cast<const Any*>(
                &_Any_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    0;
 
   // implements Any -----------------------------------------------
 
@@ -105,11 +111,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -167,7 +168,7 @@
   ::google::protobuf::internal::ArenaStringPtr value_;
   mutable int _cached_size_;
   ::google::protobuf::internal::AnyMetadata _any_metadata_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fany_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fany_2eproto::TableStruct;
 };
 // ===================================================================
 
@@ -199,6 +200,7 @@
 }
 #endif
 inline void Any::set_type_url(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Any.type_url)
@@ -251,6 +253,7 @@
 }
 #endif
 inline void Any::set_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Any.value)
diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc
index 6518e51..94c6685 100644
--- a/src/google/protobuf/api.pb.cc
+++ b/src/google/protobuf/api.pb.cc
@@ -35,11 +35,28 @@
 
 }  // namespace
 
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+    const TableStruct::entries[] = {
+  {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+    const TableStruct::aux[] = {
+  ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+    TableStruct::schema[] = {
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+};
+
 const ::google::protobuf::uint32 TableStruct::offsets[] = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, methods_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, options_),
@@ -51,6 +68,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, request_type_url_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, request_streaming_),
@@ -62,14 +80,15 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, root_),
 };
 
 static const ::google::protobuf::internal::MigrationSchema schemas[] = {
   { 0, -1, sizeof(Api)},
-  { 11, -1, sizeof(Method)},
-  { 22, -1, sizeof(Mixin)},
+  { 12, -1, sizeof(Method)},
+  { 24, -1, sizeof(Mixin)},
 };
 
 static ::google::protobuf::Message const * const file_default_instances[] = {
@@ -246,7 +265,7 @@
 }
 const ::google::protobuf::Descriptor* Api::descriptor() {
   protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[0].descriptor;
+  return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const Api& Api::default_instance() {
@@ -306,13 +325,11 @@
       case 2: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(18u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_methods()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -320,13 +337,11 @@
       case 3: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(26u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_options()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -362,13 +377,11 @@
       case 6: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(50u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_mixins()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -411,6 +424,9 @@
 void Api::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Api)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -466,8 +482,10 @@
 
 ::google::protobuf::uint8* Api::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Api)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -483,14 +501,14 @@
   for (unsigned int i = 0, n = this->methods_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        2, this->methods(i), false, target);
+        2, this->methods(i), deterministic, target);
   }
 
   // repeated .google.protobuf.Option options = 3;
   for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        3, this->options(i), false, target);
+        3, this->options(i), deterministic, target);
   }
 
   // string version = 4;
@@ -508,14 +526,14 @@
   if (this->has_source_context()) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        5, *this->source_context_, false, target);
+        5, *this->source_context_, deterministic, target);
   }
 
   // repeated .google.protobuf.Mixin mixins = 6;
   for (unsigned int i = 0, n = this->mixins_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        6, this->mixins(i), false, target);
+        6, this->mixins(i), deterministic, target);
   }
 
   // .google.protobuf.Syntax syntax = 7;
@@ -618,6 +636,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Api)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   methods_.MergeFrom(from.methods_);
   options_.MergeFrom(from.options_);
   mixins_.MergeFrom(from.mixins_);
@@ -660,9 +681,9 @@
   InternalSwap(other);
 }
 void Api::InternalSwap(Api* other) {
-  methods_.UnsafeArenaSwap(&other->methods_);
-  options_.UnsafeArenaSwap(&other->options_);
-  mixins_.UnsafeArenaSwap(&other->mixins_);
+  methods_.InternalSwap(&other->methods_);
+  options_.InternalSwap(&other->options_);
+  mixins_.InternalSwap(&other->mixins_);
   name_.Swap(&other->name_);
   version_.Swap(&other->version_);
   std::swap(source_context_, other->source_context_);
@@ -672,7 +693,7 @@
 
 ::google::protobuf::Metadata Api::GetMetadata() const {
   protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[0];
+  return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -700,6 +721,7 @@
 }
 #endif
 void Api::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Api.name)
@@ -812,6 +834,7 @@
 }
 #endif
 void Api::set_version(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Api.version)
@@ -998,7 +1021,7 @@
 }
 const ::google::protobuf::Descriptor* Method::descriptor() {
   protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[1].descriptor;
+  return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const Method& Method::default_instance() {
@@ -1114,13 +1137,11 @@
       case 6: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(50u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_options()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -1163,6 +1184,9 @@
 void Method::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Method)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -1220,8 +1244,10 @@
 
 ::google::protobuf::uint8* Method::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Method)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -1269,7 +1295,7 @@
   for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        6, this->options(i), false, target);
+        6, this->options(i), deterministic, target);
   }
 
   // .google.protobuf.Syntax syntax = 7;
@@ -1360,6 +1386,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Method)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   options_.MergeFrom(from.options_);
   if (from.name().size() > 0) {
 
@@ -1407,7 +1436,7 @@
   InternalSwap(other);
 }
 void Method::InternalSwap(Method* other) {
-  options_.UnsafeArenaSwap(&other->options_);
+  options_.InternalSwap(&other->options_);
   name_.Swap(&other->name_);
   request_type_url_.Swap(&other->request_type_url_);
   response_type_url_.Swap(&other->response_type_url_);
@@ -1419,7 +1448,7 @@
 
 ::google::protobuf::Metadata Method::GetMetadata() const {
   protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[1];
+  return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1447,6 +1476,7 @@
 }
 #endif
 void Method::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.name)
@@ -1499,6 +1529,7 @@
 }
 #endif
 void Method::set_request_type_url(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   request_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.request_type_url)
@@ -1565,6 +1596,7 @@
 }
 #endif
 void Method::set_response_type_url(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   response_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.response_type_url)
@@ -1709,7 +1741,7 @@
 }
 const ::google::protobuf::Descriptor* Mixin::descriptor() {
   protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[2].descriptor;
+  return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const Mixin& Mixin::default_instance() {
@@ -1797,6 +1829,9 @@
 void Mixin::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Mixin)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -1822,8 +1857,10 @@
 
 ::google::protobuf::uint8* Mixin::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Mixin)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -1894,6 +1931,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Mixin)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.name().size() > 0) {
 
     name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
@@ -1934,7 +1974,7 @@
 
 ::google::protobuf::Metadata Mixin::GetMetadata() const {
   protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[2];
+  return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1962,6 +2002,7 @@
 }
 #endif
 void Mixin::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name)
@@ -2014,6 +2055,7 @@
 }
 #endif
 void Mixin::set_root(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root)
diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h
index 2eb571e..5ddd78e 100644
--- a/src/google/protobuf/api.pb.h
+++ b/src/google/protobuf/api.pb.h
@@ -22,6 +22,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/message.h>
@@ -69,6 +70,9 @@
 namespace protobuf_google_2fprotobuf_2fapi_2eproto {
 // Internal implementation detail -- do not call these.
 struct LIBPROTOBUF_EXPORT TableStruct {
+  static const ::google::protobuf::internal::ParseTableField entries[];
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+  static const ::google::protobuf::internal::ParseTable schema[];
   static const ::google::protobuf::uint32 offsets[];
   static void InitDefaultsImpl();
   static void Shutdown();
@@ -98,6 +102,8 @@
     return reinterpret_cast<const Api*>(
                &_Api_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    0;
 
   void Swap(Api* other);
 
@@ -120,11 +126,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -237,7 +238,7 @@
   ::google::protobuf::SourceContext* source_context_;
   int syntax_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
 
@@ -260,6 +261,8 @@
     return reinterpret_cast<const Method*>(
                &_Method_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    1;
 
   void Swap(Method* other);
 
@@ -282,11 +285,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -392,7 +390,7 @@
   bool response_streaming_;
   int syntax_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
 
@@ -415,6 +413,8 @@
     return reinterpret_cast<const Mixin*>(
                &_Mixin_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    2;
 
   void Swap(Mixin* other);
 
@@ -437,11 +437,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -498,7 +493,7 @@
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::internal::ArenaStringPtr root_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct;
 };
 // ===================================================================
 
@@ -530,6 +525,7 @@
 }
 #endif
 inline void Api::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Api.name)
@@ -642,6 +638,7 @@
 }
 #endif
 inline void Api::set_version(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Api.version)
@@ -781,6 +778,7 @@
 }
 #endif
 inline void Method::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.name)
@@ -833,6 +831,7 @@
 }
 #endif
 inline void Method::set_request_type_url(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   request_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.request_type_url)
@@ -899,6 +898,7 @@
 }
 #endif
 inline void Method::set_response_type_url(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   response_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.response_type_url)
@@ -1013,6 +1013,7 @@
 }
 #endif
 inline void Mixin::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name)
@@ -1065,6 +1066,7 @@
 }
 #endif
 inline void Mixin::set_root(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root)
diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h
index 05e05eb..b6a375a 100644
--- a/src/google/protobuf/arena.h
+++ b/src/google/protobuf/arena.h
@@ -303,6 +303,17 @@
   // (unless the destructor is trivial). Hence, from T's point of view, it is as
   // if the object were allocated on the heap (except that the underlying memory
   // is obtained from the arena).
+#if LANG_CXX11
+  template <typename T, typename... Args> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
+  static T* Create(::google::protobuf::Arena* arena, Args&&... args) {
+    if (arena == NULL) {
+      return new T(std::forward<Args>(args)...);
+    } else {
+      return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
+                                      std::forward<Args>(args)...);
+    }
+  }
+#endif
   template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   static T* Create(::google::protobuf::Arena* arena) {
     if (arena == NULL) {
@@ -322,17 +333,6 @@
                                       arg);
     }
   }
-#if LANG_CXX11
-  template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
-  static T* Create(::google::protobuf::Arena* arena, Arg&& arg) {
-    if (arena == NULL) {
-      return new T(std::move(arg));
-    } else {
-      return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
-                                      std::move(arg));
-    }
-  }
-#endif
 
   // Version of the above with two constructor arguments for the created object.
   template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
@@ -655,6 +655,17 @@
         AllocateAligned(RTTI_TYPE_ID(T), sizeof(T) * num_elements));
   }
 
+#if LANG_CXX11
+  template <typename T, typename... Args> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
+  T* CreateInternal(bool skip_explicit_ownership, Args&&... args) {
+    T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T)))
+        T(std::forward<Args>(args)...);
+    if (!skip_explicit_ownership) {
+      AddListNode(t, &internal::arena_destruct_object<T>);
+    }
+    return t;
+  }
+#endif
   template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   T* CreateInternal(bool skip_explicit_ownership) {
     T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T();
@@ -673,18 +684,6 @@
     return t;
   }
 
-#if LANG_CXX11
-  template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
-  T* CreateInternal(bool skip_explicit_ownership, Arg&& arg) {
-    T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(
-        std::move(arg));
-    if (!skip_explicit_ownership) {
-      AddListNode(t, &internal::arena_destruct_object<T>);
-    }
-    return t;
-  }
-#endif
-
   template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   T* CreateInternal(
       bool skip_explicit_ownership, const Arg1& arg1, const Arg2& arg2) {
@@ -796,22 +795,20 @@
 
   template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   T* CreateMessageInternal(typename T::InternalArenaConstructable_*) {
-    return CreateInternal<T, Arena*>(SkipDeleteList<T>(static_cast<T*>(0)),
-                                     this);
+    return CreateInternal<T>(SkipDeleteList<T>(static_cast<T*>(0)), this);
   }
 
   template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   T* CreateMessageInternal(typename T::InternalArenaConstructable_*,
                            const Arg& arg) {
-    return CreateInternal<T, Arena*>(SkipDeleteList<T>(static_cast<T*>(0)),
-                                     this, arg);
+    return CreateInternal<T>(SkipDeleteList<T>(static_cast<T*>(0)), this, arg);
   }
 
   template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   T* CreateMessageInternal(typename T::InternalArenaConstructable_*,
                            const Arg1& arg1, const Arg2& arg2) {
-    return CreateInternal<T, Arena*>(SkipDeleteList<T>(static_cast<T*>(0)),
-                                     this, arg1, arg2);
+    return CreateInternal<T>(SkipDeleteList<T>(static_cast<T*>(0)), this, arg1,
+                             arg2);
   }
 
   // CreateInArenaStorage is used to implement map field. Without it,
diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc
index 4f9571d..6172cad 100644
--- a/src/google/protobuf/arena_unittest.cc
+++ b/src/google/protobuf/arena_unittest.cc
@@ -180,6 +180,35 @@
   EXPECT_EQ(2, notifier.GetCount());
 }
 
+TEST(ArenaTest, CreateAndConstCopy) {
+  Arena arena;
+  const string s("foo");
+  const string* s_copy = Arena::Create<string>(&arena, s);
+  EXPECT_TRUE(s_copy != NULL);
+  EXPECT_EQ("foo", s);
+  EXPECT_EQ("foo", *s_copy);
+}
+
+TEST(ArenaTest, CreateAndNonConstCopy) {
+  Arena arena;
+  string s("foo");
+  const string* s_copy = Arena::Create<string>(&arena, s);
+  EXPECT_TRUE(s_copy != NULL);
+  EXPECT_EQ("foo", s);
+  EXPECT_EQ("foo", *s_copy);
+}
+
+#if LANG_CXX11
+TEST(ArenaTest, CreateAndMove) {
+  Arena arena;
+  string s("foo");
+  const string* s_move = Arena::Create<string>(&arena, std::move(s));
+  EXPECT_TRUE(s_move != NULL);
+  EXPECT_TRUE(s.empty());  // NOLINT
+  EXPECT_EQ("foo", *s_move);
+}
+#endif
+
 TEST(ArenaTest, CreateWithFourConstructorArguments) {
   Arena arena;
   const string three("3");
@@ -214,6 +243,29 @@
   ASSERT_EQ("8", new_object->eight_);
 }
 
+#if LANG_CXX11
+class PleaseMoveMe {
+ public:
+  explicit PleaseMoveMe(const string& value) : value_(value) {}
+  PleaseMoveMe(PleaseMoveMe&&) = default;
+  PleaseMoveMe(const PleaseMoveMe&) = delete;
+
+  const string& value() const { return value_; }
+
+ private:
+  string value_;
+};
+
+TEST(ArenaTest, CreateWithMoveArguments) {
+  Arena arena;
+  PleaseMoveMe one("1");
+  const PleaseMoveMe* new_object =
+      Arena::Create<PleaseMoveMe>(&arena, std::move(one));
+  EXPECT_TRUE(new_object);
+  ASSERT_EQ("1", new_object->value());
+}
+#endif
+
 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
diff --git a/src/google/protobuf/arenastring.cc b/src/google/protobuf/arenastring.cc
index f10732c..7f33a0c 100644
--- a/src/google/protobuf/arenastring.cc
+++ b/src/google/protobuf/arenastring.cc
@@ -38,16 +38,6 @@
 namespace internal {
 
 
-void ArenaStringPtr::AssignWithDefault(const ::std::string* default_value,
-                                       ArenaStringPtr value) {
-  const ::std::string* me = *UnsafeRawStringPointer();
-  const ::std::string* other = *value.UnsafeRawStringPointer();
-  // If the pointers are the same then do nothing.
-  if (me != other) {
-    SetNoArena(default_value, value.GetNoArena());
-  }
-}
-
 }  // namespace internal
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h
index a7efb75..63fd00e 100755
--- a/src/google/protobuf/arenastring.h
+++ b/src/google/protobuf/arenastring.h
@@ -310,5 +310,21 @@
 
 
 
+namespace protobuf {
+namespace internal {
+
+inline void ArenaStringPtr::AssignWithDefault(const ::std::string* default_value,
+                                       ArenaStringPtr value) {
+  const ::std::string* me = *UnsafeRawStringPointer();
+  const ::std::string* other = *value.UnsafeRawStringPointer();
+  // If the pointers are the same then do nothing.
+  if (me != other) {
+    SetNoArena(default_value, value.GetNoArena());
+  }
+}
+
+}  // namespace internal
+}  // namespace protobuf
+
 }  // namespace google
 #endif  // GOOGLE_PROTOBUF_ARENASTRING_H__
diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h
index e2b2a66..b917d37 100644
--- a/src/google/protobuf/compiler/code_generator.h
+++ b/src/google/protobuf/compiler/code_generator.h
@@ -162,7 +162,7 @@
 //   "foo=bar,baz,qux=corge"
 // parses to the pairs:
 //   ("foo", "bar"), ("baz", ""), ("qux", "corge")
-extern void LIBPROTOC_EXPORT ParseGeneratorParameter(const string&,
+extern void ParseGeneratorParameter(const string&,
             std::vector<std::pair<string, string> >*);
 
 }  // namespace compiler
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index f516477..30a79c5 100644
--- a/src/google/protobuf/compiler/command_line_interface.cc
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -816,11 +816,11 @@
         if (direct_dependencies_.find(parsed_file->dependency(i)->name()) ==
             direct_dependencies_.end()) {
           indirect_imports = true;
-          cerr << parsed_file->name() << ": "
-               << StringReplace(direct_dependencies_violation_msg_, "%s",
-                                parsed_file->dependency(i)->name(),
-                                true /* replace_all */)
-               << std::endl;
+          std::cerr << parsed_file->name() << ": "
+                    << StringReplace(direct_dependencies_violation_msg_, "%s",
+                                     parsed_file->dependency(i)->name(),
+                                     true /* replace_all */)
+                    << std::endl;
         }
       }
       if (indirect_imports) {
@@ -1038,7 +1038,7 @@
 
   // Make sure each plugin option has a matching plugin output.
   bool foundUnknownPluginOption = false;
-  for (map<string, string>::const_iterator i = plugin_parameters_.begin();
+  for (std::map<string, string>::const_iterator i = plugin_parameters_.begin();
        i != plugin_parameters_.end(); ++i) {
     if (plugins_.find(i->first) != plugins_.end()) {
       continue;
@@ -1221,7 +1221,8 @@
       if (access(disk_path.c_str(), F_OK) < 0) {
         // Try the original path; it may have just happed to have a '=' in it.
         if (access(parts[i].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;
         } else {
           virtual_path = "";
           disk_path = parts[i];
@@ -1391,6 +1392,7 @@
     }
     mode_ = MODE_PRINT;
     print_mode_ = PRINT_FREE_FIELDS;
+  } else if (name == "--profile_path") {
   } else {
     // Some other flag.  Look it up in the generators list.
     const GeneratorInfo* generator_info =
@@ -1790,31 +1792,34 @@
 }
 
 bool CommandLineInterface::WriteDescriptorSet(
-    const std::vector<const FileDescriptor*> parsed_files) {
+    const std::vector<const FileDescriptor*>& parsed_files) {
   FileDescriptorSet file_set;
 
-  if (imports_in_descriptor_set_) {
-    std::set<const FileDescriptor*> already_seen;
+  std::set<const FileDescriptor*> already_seen;
+  if (!imports_in_descriptor_set_) {
+    // Since we don't want to output transitive dependencies, but we do want
+    // things to be in dependency order, add all dependencies that aren't in
+    // parsed_files to already_seen.  This will short circuit the recursion
+    // in GetTransitiveDependencies.
+    std::set<const FileDescriptor*> to_output;
+    to_output.insert(parsed_files.begin(), parsed_files.end());
     for (int i = 0; i < parsed_files.size(); i++) {
-      GetTransitiveDependencies(parsed_files[i],
-                                true,  // Include json_name
-                                source_info_in_descriptor_set_,
-                                &already_seen, file_set.mutable_file());
-    }
-  } else {
-    std::set<const FileDescriptor*> already_seen;
-    for (int i = 0; i < parsed_files.size(); i++) {
-      if (!already_seen.insert(parsed_files[i]).second) {
-        continue;
-      }
-      FileDescriptorProto* file_proto = file_set.add_file();
-      parsed_files[i]->CopyTo(file_proto);
-      parsed_files[i]->CopyJsonNameTo(file_proto);
-      if (source_info_in_descriptor_set_) {
-        parsed_files[i]->CopySourceCodeInfoTo(file_proto);
+      const FileDescriptor* file = parsed_files[i];
+      for (int i = 0; i < file->dependency_count(); i++) {
+        const FileDescriptor* dependency = file->dependency(i);
+        // if the dependency isn't in parsed files, mark it as already seen
+        if (to_output.find(dependency) == to_output.end()) {
+          already_seen.insert(dependency);
+        }
       }
     }
   }
+  for (int i = 0; i < parsed_files.size(); i++) {
+    GetTransitiveDependencies(parsed_files[i],
+                              true,  // Include json_name
+                              source_info_in_descriptor_set_,
+                              &already_seen, file_set.mutable_file());
+  }
 
   int fd;
   do {
diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h
index 8f8c268..997c174 100644
--- a/src/google/protobuf/compiler/command_line_interface.h
+++ b/src/google/protobuf/compiler/command_line_interface.h
@@ -258,7 +258,7 @@
 
   // Implements the --descriptor_set_out option.
   bool WriteDescriptorSet(
-      const std::vector<const FileDescriptor*> parsed_files);
+      const std::vector<const FileDescriptor*>& parsed_files);
 
   // Implements the --dependency_out option
   bool GenerateDependencyManifestFile(
@@ -391,6 +391,11 @@
   // dependency file will be written. Otherwise, empty.
   string dependency_out_name_;
 
+  // Path to a file that contains serialized AccessInfo which provides
+  // relative hotness of fields per message. This helps protoc to generate
+  // better code.
+  string profile_path_;
+
   // True if --include_imports was given, meaning that we should
   // write all transitive dependencies to the DescriptorSet.  Otherwise, only
   // the .proto files listed on the command-line are added.
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index eab14f6..366e623 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -32,9 +32,9 @@
 //  Based on original Protocol Buffers design by
 //  Sanjay Ghemawat, Jeff Dean, and others.
 
-#include <sys/types.h>
-#include <sys/stat.h>
 #include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 #ifdef _MSC_VER
 #include <io.h>
 #else
@@ -46,25 +46,25 @@
 #endif
 #include <vector>
 
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/io/zero_copy_stream.h>
-#include <google/protobuf/compiler/command_line_interface.h>
-#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/testing/file.h>
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/compiler/mock_code_generator.h>
 #include <google/protobuf/compiler/subprocess.h>
-#include <google/protobuf/io/printer.h>
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/compiler/command_line_interface.h>
 #include <google/protobuf/unittest.pb.h>
-#include <google/protobuf/testing/file.h>
-#include <google/protobuf/stubs/stringprintf.h>
-#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
 #include <google/protobuf/stubs/substitute.h>
 
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
 
+#include <google/protobuf/stubs/strutil.h>
 
 namespace google {
 namespace protobuf {
@@ -101,7 +101,7 @@
   // command is automatically split on spaces, and the string "$tmpdir"
   // is replaced with TestTempDir().
   void Run(const string& command);
-  void RunWithArgs(vector<string> args);
+  void RunWithArgs(std::vector<string> args);
 
   // -----------------------------------------------------------------
   // Methods to set up the test (called before Run()).
@@ -301,7 +301,7 @@
   RunWithArgs(Split(command, " ", true));
 }
 
-void CommandLineInterfaceTest::RunWithArgs(vector<string> args) {
+void CommandLineInterfaceTest::RunWithArgs(std::vector<string> args) {
   if (!disallow_plugins_) {
     cli_.AllowPlugins("prefix-");
 #ifndef GOOGLE_THIRD_PARTY_PROTOBUF
@@ -1044,7 +1044,7 @@
                  "syntax = \"proto2\";\n"
                  "message Bar { optional string text = 1; }");
 
-  vector<string> commands;
+  std::vector<string> commands;
   commands.push_back("protocol_compiler");
   commands.push_back("--test_out=$tmpdir");
   commands.push_back("--proto_path=$tmpdir");
@@ -1127,15 +1127,17 @@
   ReadDescriptorSet("descriptor_set", &descriptor_set);
   if (HasFatalFailure()) return;
   EXPECT_EQ(3, descriptor_set.file_size());
-  EXPECT_EQ("bar.proto", descriptor_set.file(0).name());
-  EXPECT_EQ("foo.proto", descriptor_set.file(1).name());
+  // foo should come first since the output is in dependency order.
+  // since bar and baz are unordered, they should be in command line order.
+  EXPECT_EQ("foo.proto", descriptor_set.file(0).name());
+  EXPECT_EQ("bar.proto", descriptor_set.file(1).name());
   EXPECT_EQ("baz.proto", descriptor_set.file(2).name());
   // Descriptor set should not have source code info.
   EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
   // Descriptor set should have json_name.
-  EXPECT_EQ("Bar", descriptor_set.file(0).message_type(0).name());
-  EXPECT_EQ("foo", descriptor_set.file(0).message_type(0).field(0).name());
-  EXPECT_TRUE(descriptor_set.file(0).message_type(0).field(0).has_json_name());
+  EXPECT_EQ("Bar", descriptor_set.file(1).message_type(0).name());
+  EXPECT_EQ("foo", descriptor_set.file(1).message_type(0).field(0).name());
+  EXPECT_TRUE(descriptor_set.file(1).message_type(0).field(0).has_json_name());
 }
 
 TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithSourceInfo) {
diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
index bf4e583..fce58c0 100644
--- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
@@ -46,12 +46,11 @@
 
 #include <google/protobuf/compiler/cpp/cpp_generator.h>
 #include <google/protobuf/compiler/importer.h>
-#include <google/protobuf/descriptor.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/stubs/map_util.h>
 #include <google/protobuf/stubs/stl_util.h>
-#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/stubs/substitute.h>
 
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/testing/file.h>
@@ -126,9 +125,12 @@
     importer.Import("google/protobuf/descriptor.proto");
   const FileDescriptor* plugin_proto_file =
     importer.Import("google/protobuf/compiler/plugin.proto");
+  const FileDescriptor* profile_proto_file =
+    importer.Import("google/protobuf/compiler/profile.proto");
   EXPECT_EQ("", error_collector.text_);
   ASSERT_TRUE(proto_file != NULL);
   ASSERT_TRUE(plugin_proto_file != NULL);
+  ASSERT_TRUE(profile_proto_file != NULL);
 
   CppGenerator generator;
   MockGeneratorContext context;
@@ -139,6 +141,8 @@
   parameter = "dllexport_decl=LIBPROTOC_EXPORT";
   ASSERT_TRUE(generator.Generate(plugin_proto_file, parameter,
                                  &context, &error));
+  ASSERT_TRUE(generator.Generate(profile_proto_file, parameter,
+                                 &context, &error));
 
   context.ExpectFileMatches("google/protobuf/descriptor.pb.h",
                             "google/protobuf/descriptor.pb.h");
@@ -148,6 +152,10 @@
                             "google/protobuf/compiler/plugin.pb.h");
   context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc",
                             "google/protobuf/compiler/plugin.pb.cc");
+  context.ExpectFileMatches("google/protobuf/compiler/profile.pb.h",
+                            "google/protobuf/compiler/profile.pb.h");
+  context.ExpectFileMatches("google/protobuf/compiler/profile.pb.cc",
+                            "google/protobuf/compiler/profile.pb.cc");
 }
 
 }  // namespace
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
index e4b17a9..c15be94 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -318,7 +318,7 @@
 
 void RepeatedEnumFieldGenerator::
 GenerateSwappingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.UnsafeArenaSwap(&other->$name$_);\n");
+  printer->Print(variables_, "$name$_.InternalSwap(&other->$name$_);\n");
 }
 
 void RepeatedEnumFieldGenerator::
@@ -461,20 +461,14 @@
       "    target);\n"
       "  target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray("
       "    _$name$_cached_byte_size_, target);\n"
-      "}\n");
-  }
-  printer->Print(variables_,
-      "for (int i = 0, n = this->$name$_size(); i < n; i++) {\n");
-  if (descriptor_->is_packed()) {
-    printer->Print(variables_,
       "  target = ::google::protobuf::internal::WireFormatLite::WriteEnumNoTagToArray(\n"
-      "    this->$name$(i), target);\n");
+      "    this->$name$_, target);\n"
+      "}\n");
   } else {
     printer->Print(variables_,
-      "  target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n"
-      "    $number$, this->$name$(i), target);\n");
+      "target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n"
+      "  $number$, this->$name$_, target);\n");
   }
-  printer->Print("}\n");
 }
 
 void RepeatedEnumFieldGenerator::
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index f2e013c..83e68c1 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -39,6 +39,7 @@
 #include <google/protobuf/stubs/shared_ptr.h>
 #endif
 #include <set>
+#include <vector>
 
 #include <google/protobuf/compiler/cpp/cpp_enum.h>
 #include <google/protobuf/compiler/cpp/cpp_service.h>
@@ -67,7 +68,7 @@
   return false;
 }
 
-void CollectMacroNames(const Descriptor* message, vector<string>* names) {
+void CollectMacroNames(const Descriptor* message, std::vector<string>* names) {
   for (int i = 0; i < message->field_count(); ++i) {
     const FieldDescriptor* field = message->field(i);
     if (IsMacroName(field->name())) {
@@ -79,7 +80,13 @@
   }
 }
 
-void CollectMacroNames(const FileDescriptor* file, vector<string>* names) {
+void CollectMacroNames(const FileDescriptor* file, std::vector<string>* names) {
+  // Only do this for protobuf's own types. There are some google3 protos using
+  // macros as field names and the generated code compiles after the macro
+  // expansion. Undefing these macros actually breaks such code.
+  if (file->name() != "google/protobuf/compiler/plugin.proto") {
+    return;
+  }
   for (int i = 0; i < file->message_type_count(); ++i) {
     CollectMacroNames(file->message_type(i), names);
   }
@@ -93,18 +100,19 @@
 FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
     : file_(file),
       options_(options),
+      scc_analyzer_(options),
       message_generators_owner_(
-          new google::protobuf::scoped_ptr<MessageGenerator>[ file->message_type_count() ]),
+          new google::protobuf::scoped_ptr<MessageGenerator>[file->message_type_count()]),
       enum_generators_owner_(
-          new google::protobuf::scoped_ptr<EnumGenerator>[ file->enum_type_count() ]),
+          new google::protobuf::scoped_ptr<EnumGenerator>[file->enum_type_count()]),
       service_generators_owner_(
-          new google::protobuf::scoped_ptr<ServiceGenerator>[ file->service_count() ]),
+          new google::protobuf::scoped_ptr<ServiceGenerator>[file->service_count()]),
       extension_generators_owner_(
-          new google::protobuf::scoped_ptr<ExtensionGenerator>[ file->extension_count() ]) {
+          new google::protobuf::scoped_ptr<ExtensionGenerator>[file->extension_count()]) {
 
   for (int i = 0; i < file->message_type_count(); i++) {
     message_generators_owner_[i].reset(
-        new MessageGenerator(file->message_type(i), options));
+        new MessageGenerator(file->message_type(i), options, &scc_analyzer_));
     message_generators_owner_[i]->Flatten(&message_generators_);
   }
 
@@ -137,7 +145,7 @@
 FileGenerator::~FileGenerator() {}
 
 void FileGenerator::GenerateMacroUndefs(io::Printer* printer) {
-  vector<string> names_to_undef;
+  std::vector<string> names_to_undef;
   CollectMacroNames(file_, &names_to_undef);
   for (int i = 0; i < names_to_undef.size(); ++i) {
     printer->Print(
@@ -241,6 +249,7 @@
   } else {
     GenerateLibraryIncludes(printer);
   }
+
   GenerateDependencyIncludes(printer);
   GenerateMetadataPragma(printer, info_path);
 
@@ -327,11 +336,17 @@
   GenerateNamespaceOpeners(printer);
 
   for (int i = 0; i < message_generators_.size(); i++) {
-    if (IsMapEntryMessage(message_generators_[i]->descriptor_)) continue;
+    string parent;
+    if (IsMapEntryMessage(message_generators_[i]->descriptor_)) {
+      parent = ClassName(message_generators_[i]->descriptor_->containing_type(),
+                         false) +
+               "::";
+    }
     printer->Print(
         "class $classname$DefaultTypeInternal : "
-        "public ::google::protobuf::internal::ExplicitlyConstructed<$classname$> {\n",
-        "classname", message_generators_[i]->classname_);
+        "public ::google::protobuf::internal::ExplicitlyConstructed<$parent$$classname$> "
+        "{\n",
+        "parent", parent, "classname", message_generators_[i]->classname_);
     printer->Indent();
     message_generators_[i]->GenerateExtraDefaultFields(printer);
     printer->Outdent();
@@ -340,9 +355,6 @@
         "classname", message_generators_[i]->classname_);
   }
 
-  for (int i = 0; i < message_generators_.size(); i++) {
-    message_generators_[i]->index_in_metadata_ = i;
-  }
   for (int i = 0; i < enum_generators_.size(); i++) {
     enum_generators_[i]->index_in_metadata_ = i;
   }
@@ -530,6 +542,70 @@
   // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors()
   // and we only use AddDescriptors() to allocate default instances.
 
+  // TODO(ckennelly): Gate this with the same options flag to enable
+  // table-driven parsing.
+
+  printer->Print("PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField\n"
+                 "    const TableStruct::entries[] = {\n");
+  printer->Indent();
+
+  std::vector<size_t> entries;
+  size_t count = 0;
+  for (int i = 0; i < message_generators_.size(); i++) {
+    size_t value = message_generators_[i]->GenerateParseOffsets(printer);
+    entries.push_back(value);
+    count += value;
+  }
+
+  // We need these arrays to exist, and MSVC does not like empty arrays.
+  if (count == 0) {
+    printer->Print("{0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},\n");
+  }
+
+  printer->Outdent();
+  printer->Print(
+      "};\n"
+      "\n"
+      "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField\n"
+      "    const TableStruct::aux[] = {\n");
+  printer->Indent();
+
+  std::vector<size_t> aux_entries;
+  count = 0;
+  for (int i = 0; i < message_generators_.size(); i++) {
+    size_t value = message_generators_[i]->GenerateParseAuxTable(printer);
+    aux_entries.push_back(value);
+    count += value;
+  }
+
+  if (count == 0) {
+    printer->Print("::google::protobuf::internal::AuxillaryParseTableField(),\n");
+  }
+
+  printer->Outdent();
+  printer->Print(
+      "};\n"
+      "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const\n"
+      "    TableStruct::schema[] = {\n");
+  printer->Indent();
+
+  size_t offset = 0;
+  size_t aux_offset = 0;
+  for (int i = 0; i < message_generators_.size(); i++) {
+    message_generators_[i]->GenerateParseTable(printer, offset, aux_offset);
+    offset += entries[i];
+    aux_offset += aux_entries[i];
+  }
+
+  if (message_generators_.empty()) {
+    printer->Print("{ NULL, NULL, 0, -1, -1, false },\n");
+  }
+
+  printer->Outdent();
+  printer->Print(
+      "};\n"
+      "\n");
+
   if (HasDescriptorMethods(file_, options_)) {
     if (!message_generators_.empty()) {
       printer->Print("const ::google::protobuf::uint32 TableStruct::offsets[] = {\n");
@@ -560,8 +636,6 @@
       printer->Indent();
       for (int i = 0; i < message_generators_.size(); i++) {
         const Descriptor* descriptor = message_generators_[i]->descriptor_;
-        if (IsMapEntryMessage(descriptor)) continue;
-
         printer->Print(
             "reinterpret_cast<const "
             "::google::protobuf::Message*>(&_$classname$_default_instance_),\n",
@@ -600,7 +674,31 @@
         "  AssignDescriptors(\n"
         "      \"$filename$\", schemas, file_default_instances, "
         "TableStruct::offsets, factory,\n"
-        "      $metadata$, $enum_descriptors$, $service_descriptors$);\n"
+        "      $metadata$, $enum_descriptors$, $service_descriptors$);\n",
+        "filename", file_->name(), "metadata",
+        !message_generators_.empty() ? "file_level_metadata" : "NULL",
+        "enum_descriptors",
+        !enum_generators_.empty() ? "file_level_enum_descriptors" : "NULL",
+        "service_descriptors",
+        HasGenericServices(file_, options_) && file_->service_count() > 0
+            ? "file_level_service_descriptors"
+            : "NULL",
+        "factory", message_factory);
+    // TODO(gerbens) have the compiler include the schemas for map types
+    // so that this can go away, and we can potentially use table driven
+    // serialization for map types as well.
+    for (int i = 0; i < message_generators_.size(); i++) {
+      if (!IsMapEntryMessage(message_generators_[i]->descriptor_)) continue;
+      printer->Print(
+          "file_level_metadata[$index$].reflection = "
+          "$parent$::$classname$::CreateReflection(file_level_metadata[$index$]"
+          ".descriptor, _$classname$_default_instance_.get_mutable());\n",
+          "index", SimpleItoa(i), "parent",
+          ClassName(message_generators_[i]->descriptor_->containing_type(),
+                    false),
+          "classname", ClassName(message_generators_[i]->descriptor_, false));
+    }
+    printer->Print(
         "}\n"
         "\n"
         "void protobuf_AssignDescriptorsOnce() {\n"
@@ -634,12 +732,6 @@
         "size", SimpleItoa(message_generators_.size()));
     }
 
-    // Map types are treated special
-    // TODO(gerbens) find a way to treat maps more like normal messages.
-    for (int i = 0; i < message_generators_.size(); i++) {
-      message_generators_[i]->GenerateTypeRegistrations(printer);
-    }
-
     printer->Outdent();
     printer->Print(
       "}\n"
@@ -902,8 +994,16 @@
       "#include <google/protobuf/io/coded_stream.h>\n"
       "#include <google/protobuf/arena.h>\n"
       "#include <google/protobuf/arenastring.h>\n"
-      "#include <google/protobuf/generated_message_util.h>\n"
+      "#include <google/protobuf/generated_message_table_driven.h>\n"
+      "#include <google/protobuf/generated_message_util.h>\n");
+
+  if (HasDescriptorMethods(file_, options_)) {
+    printer->Print(
       "#include <google/protobuf/metadata.h>\n");
+  } else {
+    printer->Print(
+      "#include <google/protobuf/metadata_lite.h>\n");
+  }
 
   if (!message_generators_.empty()) {
     if (HasDescriptorMethods(file_, options_)) {
@@ -921,7 +1021,8 @@
     "  // IWYU pragma: export\n");
   if (HasMapFields(file_)) {
     printer->Print(
-        "#include <google/protobuf/map.h>\n");
+        "#include <google/protobuf/map.h>"
+        "  // IWYU pragma: export\n");
     if (HasDescriptorMethods(file_, options_)) {
       printer->Print(
           "#include <google/protobuf/map_field_inl.h>\n");
@@ -1001,6 +1102,9 @@
       "namespace $file_namespace$ {\n"
       "// Internal implementation detail -- do not call these.\n"
       "struct $dllexport_decl$TableStruct {\n"
+      "  static const ::google::protobuf::internal::ParseTableField entries[];\n"
+      "  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];\n"
+      "  static const ::google::protobuf::internal::ParseTable schema[];\n"
       "  static const ::google::protobuf::uint32 offsets[];\n"
       // The following function(s) need to be able to access private members of
       // the messages defined in the file. So we make them static members.
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h
index e3fbb96..e10fe2f 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.h
+++ b/src/google/protobuf/compiler/cpp/cpp_file.h
@@ -43,6 +43,7 @@
 #include <vector>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/compiler/cpp/cpp_field.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
 #include <google/protobuf/compiler/cpp/cpp_options.h>
 
 namespace google {
@@ -145,6 +146,8 @@
   const FileDescriptor* file_;
   const Options options_;
 
+  SCCAnalyzer scc_analyzer_;
+
   // Contains the post-order walk of all the messages (and child messages) in
   // this file. If you need a pre-order walk just reverse iterate.
   std::vector<MessageGenerator*> message_generators_;
diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc
index 648ab28..cee3122 100644
--- a/src/google/protobuf/compiler/cpp/cpp_generator.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc
@@ -98,6 +98,8 @@
       file_options.annotation_guard_name = options[i].second;
     } else if (options[i].first == "lite") {
       file_options.enforce_lite = true;
+    } else if (options[i].first == "table_driven_parsing") {
+      file_options.table_driven_parsing = true;
     } else {
       *error = "Unknown generator option: " + options[i].first;
       return false;
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index 3c4dddc..9cddba5 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -654,6 +654,109 @@
                         "VerifyUtf8Cord", "VerifyUTF8CordNamedField", printer);
 }
 
+bool HasWeakFields(const Descriptor* descriptor) {
+  return false;
+}
+
+bool HasWeakFields(const FileDescriptor* file) {
+  return false;
+}
+
+SCCAnalyzer::NodeData SCCAnalyzer::DFS(const Descriptor* descriptor) {
+  // Must not have visited already.
+  GOOGLE_DCHECK_EQ(cache_.count(descriptor), 0);
+
+  // Mark visited by inserting in map.
+  NodeData& result = cache_[descriptor];
+  // Initialize data structures.
+  result.index = result.lowlink = index_++;
+  stack_.push_back(descriptor);
+
+  // Recurse the fields / nodes in graph
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    const Descriptor* child = descriptor->field(i)->message_type();
+    if (child) {
+      if (cache_.count(child) == 0) {
+        // unexplored node
+        NodeData child_data = DFS(child);
+        result.lowlink = std::min(result.lowlink, child_data.lowlink);
+      } else {
+        NodeData child_data = cache_[child];
+        if (child_data.scc == NULL) {
+          // Still in the stack_ so we found a back edge
+          result.lowlink = std::min(result.lowlink, child_data.index);
+        }
+      }
+    }
+  }
+  if (result.index == result.lowlink) {
+    // This is the root of a strongly connected component
+    SCC* scc = CreateSCC();
+    while (true) {
+      const Descriptor* scc_desc = stack_.back();
+      scc->descriptors.push_back(scc_desc);
+      // Remove from stack
+      stack_.pop_back();
+      cache_[scc_desc].scc = scc;
+
+      if (scc_desc == descriptor) break;
+    }
+  }
+  return result;
+}
+
+MessageAnalysis SCCAnalyzer::GetSCCAnalysis(const SCC* scc) {
+  if (analysis_cache_.count(scc)) return analysis_cache_[scc];
+  MessageAnalysis result = MessageAnalysis();
+  for (int i = 0; i < scc->descriptors.size(); i++) {
+    const Descriptor* descriptor = scc->descriptors[i];
+    if (descriptor->extension_range_count() > 0) {
+      result.contains_extension = true;
+    }
+    for (int i = 0; i < descriptor->field_count(); i++) {
+      const FieldDescriptor* field = descriptor->field(i);
+      if (field->is_required()) {
+        result.contains_required = true;
+      }
+      switch (field->type()) {
+        case FieldDescriptor::TYPE_STRING:
+        case FieldDescriptor::TYPE_BYTES: {
+          if (field->options().ctype() == FieldOptions::CORD) {
+            result.contains_cord = true;
+          }
+          break;
+        }
+        case FieldDescriptor::TYPE_GROUP:
+        case FieldDescriptor::TYPE_MESSAGE: {
+          const SCC* child = GetSCC(field->message_type());
+          if (child != scc) {
+            MessageAnalysis analysis = GetSCCAnalysis(child);
+            result.contains_cord |= analysis.contains_cord;
+            result.contains_extension |= analysis.contains_extension;
+            if (!ShouldIgnoreRequiredFieldCheck(field, options_)) {
+              result.contains_required |= analysis.contains_required;
+            }
+          } else {
+            // This field points back into the same SCC hence the messages
+            // in the SCC are recursive. Note if SCC contains more than two
+            // nodes it has to be recursive, however this test also works for
+            // a single node that is recursive.
+            result.is_recursive = true;
+          }
+          break;
+        }
+        default:
+          break;
+      }
+    }
+  }
+  // We deliberately only insert the result here. After we contracted the SCC
+  // in the graph, the graph should be a DAG. Hence we shouldn't need to mark
+  // nodes visited as we can never return to them. By inserting them here
+  // we will go in an infinite loop if the SCC is not correct.
+  return analysis_cache_[scc] = result;
+}
+
 }  // 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 0f297ec..a744a86 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.h
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -277,6 +277,73 @@
       : file->options().optimize_for();
 }
 
+bool HasWeakFields(const Descriptor* desc);
+bool HasWeakFields(const FileDescriptor* desc);
+
+// Returns true if the "required" restriction check should be ignored for the
+// given field.
+inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field,
+                                                  const Options& options) {
+  return false;
+}
+
+struct SCC {
+  std::vector<const Descriptor*> descriptors;
+};
+
+struct MessageAnalysis {
+  bool is_recursive;
+  bool contains_cord;
+  bool contains_extension;
+  bool contains_required;
+};
+
+// This class is used in FileGenerator, to ensure linear instead of
+// quadratic performance, if we do this per message we would get O(V*(V+E)).
+// Logically this is just only used in message.cc, but in the header for
+// FileGenerator to help share it.
+class LIBPROTOC_EXPORT SCCAnalyzer {
+ public:
+  explicit SCCAnalyzer(const Options& options) : options_(options), index_(0) {}
+  ~SCCAnalyzer() {
+    for (int i = 0; i < garbage_bin_.size(); i++) delete garbage_bin_[i];
+  }
+
+  const SCC* GetSCC(const Descriptor* descriptor) {
+    if (cache_.count(descriptor)) return cache_[descriptor].scc;
+    return DFS(descriptor).scc;
+  }
+
+  MessageAnalysis GetSCCAnalysis(const SCC* scc);
+
+  bool HasRequiredFields(const Descriptor* descriptor) {
+    MessageAnalysis result = GetSCCAnalysis(GetSCC(descriptor));
+    return result.contains_required || result.contains_extension;
+  }
+
+ private:
+  struct NodeData {
+    const SCC* scc;  // if null it means its still on the stack
+    int index;
+    int lowlink;
+  };
+
+  Options options_;
+  std::map<const Descriptor*, NodeData> cache_;
+  std::map<const SCC*, MessageAnalysis> analysis_cache_;
+  std::vector<const Descriptor*> stack_;
+  int index_;
+  std::vector<SCC*> garbage_bin_;
+
+  SCC* CreateSCC() {
+    garbage_bin_.push_back(new SCC());
+    return garbage_bin_.back();
+  }
+
+  // Tarjan's Strongly Connected Components algo
+  NodeData DFS(const Descriptor* descriptor);
+};
+
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
index b4eaf48..52a3b8b 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
@@ -32,6 +32,7 @@
 #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 {
@@ -113,18 +114,49 @@
 
 void MapFieldGenerator::
 GeneratePrivateMembers(io::Printer* printer) const {
+  if (HasDescriptorMethods(descriptor_->file(), options_)) {
+    printer->Print(
+        variables_,
+        "public:\n"
+        "class $map_classname$ : public "
+        "::google::protobuf::internal::MapEntry<$map_classname$, \n"
+        "    $key_cpp$, $val_cpp$,\n"
+        "    $key_wire_type$,\n"
+        "    $val_wire_type$,\n"
+        "    $default_enum_value$ > {\n"
+        "public:\n"
+        "  typedef ::google::protobuf::internal::MapEntry<$map_classname$, \n"
+        "    $key_cpp$, $val_cpp$,\n"
+        "    $key_wire_type$,\n"
+        "    $val_wire_type$,\n"
+        "    $default_enum_value$ > SuperType;\n"
+        "  $map_classname$();\n"
+        "  $map_classname$(::google::protobuf::Arena* arena);\n"
+        "  void MergeFrom(const ::google::protobuf::Message& other) PROTOBUF_FINAL;\n"
+        "  void MergeFrom(const $map_classname$& other);\n"
+        "  static const Message* internal_default_instance() { return "
+        "reinterpret_cast<const "
+        "Message*>(&_$map_classname$_default_instance_); }\n"
+        "  ::google::protobuf::Metadata GetMetadata() const;\n"
+        "};\n");
+  } else {
+    printer->Print(variables_,
+                   "public:\n"
+                   "typedef ::google::protobuf::internal::MapEntryLite<\n"
+                   "    $key_cpp$, $val_cpp$,\n"
+                   "    $key_wire_type$,\n"
+                   "    $val_wire_type$,\n"
+                   "    $default_enum_value$ >\n"
+                   "    $map_classname$;\n");
+  }
   printer->Print(variables_,
-      "typedef ::google::protobuf::internal::MapEntryLite<\n"
-      "    $key_cpp$, $val_cpp$,\n"
-      "    $key_wire_type$,\n"
-      "    $val_wire_type$,\n"
-      "    $default_enum_value$ >\n"
-      "    $map_classname$;\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");
+                 "::google::protobuf::internal::MapField$lite$<\n"
+                 "    $map_classname$,\n"
+                 "    $key_cpp$, $val_cpp$,\n"
+                 "    $key_wire_type$,\n"
+                 "    $val_wire_type$,\n"
+                 "    $default_enum_value$ > $name$_;\n"
+                 "private:\n");
 }
 
 void MapFieldGenerator::
@@ -172,17 +204,6 @@
 }
 
 void MapFieldGenerator::
-GenerateConstructorCode(io::Printer* printer) const {
-  if (HasDescriptorMethods(descriptor_->file(), options_)) {
-    printer->Print(variables_,
-                   "$name$_.SetAssignDescriptorCallback(\n"
-                   "    $file_namespace$::protobuf_AssignDescriptorsOnce);\n"
-                   "$name$_.SetEntryDescriptor(\n"
-                   "    &$type$_descriptor);\n");
-  }
-}
-
-void MapFieldGenerator::
 GenerateCopyConstructorCode(io::Printer* printer) const {
   GenerateConstructorCode(printer);
   GenerateMergingCode(printer);
@@ -199,13 +220,15 @@
   string value;
   if (IsProto3Field(descriptor_) ||
       value_field->type() != FieldDescriptor::TYPE_ENUM) {
-    printer->Print(variables_,
+    printer->Print(
+        variables_,
         "$map_classname$::Parser< ::google::protobuf::internal::MapField$lite$<\n"
-                   "    $key_cpp$, $val_cpp$,\n"
-                   "    $key_wire_type$,\n"
-                   "    $val_wire_type$,\n"
-                   "    $default_enum_value$ >,\n"
-                   "  ::google::protobuf::Map< $key_cpp$, $val_cpp$ > >"
+        "    $map_classname$,\n"
+        "    $key_cpp$, $val_cpp$,\n"
+        "    $key_wire_type$,\n"
+        "    $val_wire_type$,\n"
+        "    $default_enum_value$ >,\n"
+        "  ::google::protobuf::Map< $key_cpp$, $val_cpp$ > >"
         " parser(&$name$_);\n"
         "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n"
         "    input, &parser));\n");
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.h b/src/google/protobuf/compiler/cpp/cpp_map_field.h
index 816687b..02e6649 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.h
@@ -54,7 +54,7 @@
   void GenerateClearingCode(io::Printer* printer) const;
   void GenerateMergingCode(io::Printer* printer) const;
   void GenerateSwappingCode(io::Printer* printer) const;
-  void GenerateConstructorCode(io::Printer* printer) const;
+  void GenerateConstructorCode(io::Printer* printer) const {}
   void GenerateCopyConstructorCode(io::Printer* printer) const;
   void GenerateMergeFromCodedStream(io::Printer* printer) const;
   void GenerateSerializeWithCachedSizes(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 1373ffc..d9524f6 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -32,6 +32,8 @@
 //  Based on original Protocol Buffers design by
 //  Sanjay Ghemawat, Jeff Dean, and others.
 
+#include <google/protobuf/compiler/cpp/cpp_message.h>
+
 #include <algorithm>
 #include <google/protobuf/stubs/hash.h>
 #include <map>
@@ -41,16 +43,18 @@
 #endif
 #include <utility>
 #include <vector>
-#include <google/protobuf/compiler/cpp/cpp_message.h>
-#include <google/protobuf/compiler/cpp/cpp_field.h>
+
 #include <google/protobuf/compiler/cpp/cpp_enum.h>
 #include <google/protobuf/compiler/cpp/cpp_extension.h>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
-#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/wire_format.h>
+#include <google/protobuf/io/printer.h>
 #include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/generated_message_table_driven.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
 
 
 namespace google {
@@ -103,54 +107,6 @@
   }
 };
 
-// Returns true if the "required" restriction check should be ignored for the
-// given field.
-inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field,
-                                                  const Options& options) {
-  return false;
-}
-
-// Returns true if the message type has any required fields.  If it doesn't,
-// we can optimize out calls to its IsInitialized() method.
-//
-// already_seen is used to avoid checking the same type multiple times
-// (and also to protect against recursion).
-static bool HasRequiredFields(const Descriptor* type, const Options& options,
-                              hash_set<const Descriptor*>* already_seen) {
-  if (already_seen->count(type) > 0) {
-    // Since the first occurrence of a required field causes the whole
-    // function to return true, we can assume that if the type is already
-    // in the cache it didn't have any required fields.
-    return false;
-  }
-  already_seen->insert(type);
-
-  // If the type has extensions, an extension with message type could contain
-  // required fields, so we have to be conservative and assume such an
-  // extension exists.
-  if (type->extension_range_count() > 0) return true;
-
-  for (int i = 0; i < type->field_count(); i++) {
-    const FieldDescriptor* field = type->field(i);
-    if (field->is_required()) {
-      return true;
-    }
-    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
-        !ShouldIgnoreRequiredFieldCheck(field, options)) {
-      if (HasRequiredFields(field->message_type(), options, already_seen)) {
-        return true;
-      }
-    }
-  }
-
-  return false;
-}
-
-static bool HasRequiredFields(const Descriptor* type, const Options& options) {
-  hash_set<const Descriptor*> already_seen;
-  return HasRequiredFields(type, options, &already_seen);
-}
-
 // This returns an estimate of the compiler's alignment for the field.  This
 // can't guarantee to be correct because the generated code could be compiled on
 // different systems with different alignment rules.  The estimates below assume
@@ -288,10 +244,13 @@
 // order, fields of similiar family (see below) are together and within each
 // family, alignment padding is minimized.
 //
-// We try to do this while keeping each field as close as possible to its
-// declaration order (from the .proto file) so that we don't reduce cache
-// locality much for function that access each field in order.  This is also the
-// only (weak) signal we have for author intent concerning field layout.
+// We try to do this while keeping each field as close as possible to its field
+// number order so that we don't reduce cache locality much for function that
+// access each field in order.  Originally, OptimizePadding used declaration
+// order for its decisions, but generated code minus the serializer/parsers uses
+// the output of OptimizePadding as well (stored in
+// MessageGenerator::optimized_order_).  Since the serializers use field number
+// order, we use that as a tie-breaker.
 //
 // TODO(ckennelly):  If/when we have profiles available for the compiler, use
 // those rather than respect declaration order.
@@ -346,10 +305,11 @@
       f = ZERO_INITIALIZABLE;
     }
 
+    const int j = field->number();
     switch (EstimateAlignmentSize(field)) {
-      case 1: aligned_to_1[f].push_back(FieldGroup(i, field)); break;
-      case 4: aligned_to_4[f].push_back(FieldGroup(i, field)); break;
-      case 8: aligned_to_8[f].push_back(FieldGroup(i, field)); break;
+      case 1: aligned_to_1[f].push_back(FieldGroup(j, field)); break;
+      case 4: aligned_to_4[f].push_back(FieldGroup(j, field)); break;
+      case 8: aligned_to_8[f].push_back(FieldGroup(j, field)); break;
       default:
         GOOGLE_LOG(FATAL) << "Unknown alignment size.";
     }
@@ -366,7 +326,7 @@
       }
       aligned_to_4[f].push_back(field_group);
     }
-    // Sort by preferred location to keep fields as close to their declaration
+    // Sort by preferred location to keep fields as close to their field number
     // order as possible.  Using stable_sort ensures that the output is
     // consistent across runs.
     std::stable_sort(aligned_to_4[f].begin(), aligned_to_4[f].end());
@@ -406,9 +366,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
@@ -495,30 +452,99 @@
 }
 
 
+bool TableDrivenEnabled(const Descriptor* descriptor, const Options& options) {
+  if (!options.table_driven_parsing) {
+    return false;
+  }
+
+  // Consider table-driven parsing.  We only do this if:
+  // - There are no extensions
+  if (descriptor->extension_range_count() != 0) {
+    return false;
+  }
+
+  // - We are not using UnknownFieldSet (part of the non-lite library).
+  if (UseUnknownFieldSet(descriptor->file(), options)) {
+    return false;
+  }
+
+  // - We have has_bits for fields.  This avoids a check on every field we set
+  //   when are present (the common case).
+  if (!HasFieldPresence(descriptor->file())) {
+    return false;
+  }
+
+  const double table_sparseness = 0.5;
+  int max_field_number = 0;
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    const FieldDescriptor* field = descriptor->field(i);
+    if (max_field_number < field->number()) {
+      max_field_number = field->number();
+    }
+
+    // - There are no map fields.
+    if (field->is_map()) {
+      return false;
+    }
+
+    // - There are no oneof fields.
+    if (field->containing_oneof()) {
+      return false;
+    }
+
+    // - There are no weak fields.
+    if (field->options().weak()) {
+      return false;
+    }
+  }
+
+  // - There range of field numbers is "small"
+  if (max_field_number >= (2 << 14)) {
+    return false;
+  }
+
+  // - Field numbers are relatively dense within the actual number of fields
+  if (max_field_number * table_sparseness >= descriptor->field_count()) {
+    return false;
+  }
+
+  // - This is not a MapEntryMessage.
+  if (IsMapEntryMessage(descriptor)) {
+    return false;
+  }
+
+  return true;
+}
+
 }  // anonymous namespace
 
 // ===================================================================
 
 MessageGenerator::MessageGenerator(const Descriptor* descriptor,
-                                   const Options& options)
+                                   const Options& options,
+                                   SCCAnalyzer* scc_analyzer)
     : descriptor_(descriptor),
       classname_(ClassName(descriptor, false)),
       options_(options),
       field_generators_(descriptor, options),
       max_has_bit_index_(0),
       nested_generators_(new google::protobuf::scoped_ptr<
-          MessageGenerator>[descriptor->nested_type_count()]),
+                         MessageGenerator>[descriptor->nested_type_count()]),
       enum_generators_(
           new google::protobuf::scoped_ptr<EnumGenerator>[descriptor->enum_type_count()]),
       extension_generators_(new google::protobuf::scoped_ptr<
-          ExtensionGenerator>[descriptor->extension_count()]),
-      use_dependent_base_(false) {
-
+                            ExtensionGenerator>[descriptor->extension_count()]),
+      use_dependent_base_(false),
+      num_weak_fields_(0),
+      scc_analyzer_(scc_analyzer) {
   // Compute optimized field order to be used for layout and initialization
   // purposes.
   for (int i = 0; i < descriptor_->field_count(); i++) {
-    if (!descriptor_->field(i)->containing_oneof()) {
-      optimized_order_.push_back(descriptor_->field(i));
+    const FieldDescriptor* field = descriptor_->field(i);
+    if (field->options().weak()) {
+      num_weak_fields_++;
+    } else if (!field->containing_oneof()) {
+      optimized_order_.push_back(field);
     }
   }
   OptimizePadding(&optimized_order_, options_);
@@ -538,8 +564,8 @@
   }
 
   for (int i = 0; i < descriptor->nested_type_count(); i++) {
-    nested_generators_[i].reset(
-      new MessageGenerator(descriptor->nested_type(i), options));
+    nested_generators_[i].reset(new MessageGenerator(descriptor->nested_type(i),
+                                                     options, scc_analyzer));
   }
 
   for (int i = 0; i < descriptor->enum_type_count(); i++) {
@@ -565,6 +591,8 @@
     // Always make oneofs dependent.
     use_dependent_base_ = true;
   }
+
+  table_driven_ = TableDrivenEnabled(descriptor_, options_);
 }
 
 MessageGenerator::~MessageGenerator() {}
@@ -586,6 +614,7 @@
   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
     nested_generators_[i]->Flatten(list);
   }
+  index_in_file_messages_ = list->size();
   list->push_back(this);
 }
 
@@ -602,7 +631,6 @@
 
 void MessageGenerator::FillMessageForwardDeclarations(
     std::map<string, const Descriptor*>* class_names) {
-  if (IsMapEntryMessage(descriptor_)) return;
   (*class_names)[classname_] = descriptor_;
 }
 
@@ -644,7 +672,7 @@
       ordered_fields.begin(), optimized_order_.begin(), optimized_order_.end());
   for (int i = 0; i < descriptor_->field_count(); i++) {
     const FieldDescriptor* field = descriptor_->field(i);
-    if (field->containing_oneof() == NULL) {
+    if (field->containing_oneof() == NULL && !field->options().weak()) {
       continue;
     }
     ordered_fields.push_back(field);
@@ -777,6 +805,15 @@
 GenerateSingularFieldHasBits(const FieldDescriptor* field,
                              std::map<string, string> vars,
                              io::Printer* printer) {
+  if (field->options().weak()) {
+    printer->Print(
+        vars,
+        "$inline$"
+        "bool $classname$::has_$name$() const {\n"
+        "  return _weak_field_map_.Has($number$);\n"
+        "}\n");
+    return;
+  }
   if (HasFieldPresence(descriptor_->file())) {
     // N.B.: without field presence, we do not use has-bits or generate
     // has_$name$() methods.
@@ -896,7 +933,7 @@
     field_generators_.get(field)
         .GenerateClearingCode(printer);
     if (HasFieldPresence(descriptor_->file())) {
-      if (!field->is_repeated()) {
+      if (!field->is_repeated() && !field->options().weak()) {
         printer->Print(vars,
                        "$this_message$clear_has_$name$();\n");
       }
@@ -1049,6 +1086,29 @@
     "}\n"
     "\n");
 
+  // Generate move constructor and move assignment operator for types other than
+  // Any.
+  #ifdef PROTO_EXPERIMENTAL_ENABLE_MOVE
+  if (!IsAnyMessage(descriptor_)) {
+    printer->Print(vars,
+      "#if LANG_CXX11\n"
+      "$classname$($classname$&& from)\n"
+      "  : $classname$() {\n"
+      "  *this = ::std::move(from);\n"
+      "}\n"
+      "\n"
+      "inline $classname$& operator=($classname$&& from) {\n"
+      "  if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {\n"
+      "    InternalSwap(&from);\n"
+      "  } else {\n"
+      "    CopyFrom(from);\n"
+      "  }\n"
+      "  return *this;\n"
+      "}\n"
+      "#endif\n");
+  }
+  #endif
+
   if (PreserveUnknownFields(descriptor_)) {
     string type = UseUnknownFieldSet(descriptor_->file(), options_)
                       ? "::google::protobuf::UnknownFieldSet"
@@ -1119,12 +1179,15 @@
   }
 
   // TODO(gerbens) make this private, while still granting other protos access.
+  vars["message_index"] = SimpleItoa(index_in_file_messages_);
   printer->Print(
       vars,
       "static inline const $classname$* internal_default_instance() {\n"
       "  return reinterpret_cast<const $classname$*>(\n"
       "             &_$classname$_default_instance_);\n"
       "}\n"
+      "static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =\n"
+      "  $message_index$;\n"
       "\n");
 
 
@@ -1199,14 +1262,8 @@
     }
     if (HasFastArraySerialization(descriptor_->file(), options_)) {
       printer->Print(
-          "::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(\n"
-          "    bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;\n"
-          "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)\n"
-          "    const PROTOBUF_FINAL {\n"
-          "  return InternalSerializeWithCachedSizesToArray(\n"
-          "      ::google::protobuf::io::CodedOutputStream::"
-          "IsDefaultSerializationDeterministic(), output);\n"
-          "}\n");
+        "::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(\n"
+        "    bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;\n");
     }
   }
 
@@ -1312,7 +1369,8 @@
 
 
   for (int i = 0; i < descriptor_->field_count(); i++) {
-    if (!descriptor_->field(i)->is_repeated()) {
+    if (!descriptor_->field(i)->is_repeated() &&
+        !descriptor_->field(i)->options().weak()) {
       // set_has_***() generated in all proto1/2 code and in oneofs (only) for
       // messages without true field presence.
       if (HasFieldPresence(descriptor_->file()) ||
@@ -1451,6 +1509,10 @@
       "\n");
   }
 
+  if (num_weak_fields_) {
+    printer->Print(
+        "::google::protobuf::internal::WeakFieldMap _weak_field_map_;\n");
+  }
   // Generate _any_metadata_ for the Any type.
   if (IsAnyMessage(descriptor_)) {
     printer->Print(vars,
@@ -1459,6 +1521,7 @@
 
   // The TableStruct struct needs access to the private parts, in order to
   // construct the offsets of all members.
+  //
   // Some InitDefault and Shutdown are defined as static member functions of
   // TableStruct such that they are also allowed to access private members.
   printer->Print(
@@ -1511,8 +1574,9 @@
 
 void MessageGenerator::
 GenerateExtraDefaultFields(io::Printer* printer) {
-  // Generate oneof default instance for reflection usage.
-  if (descriptor_->oneof_decl_count() > 0) {
+  // Generate oneof default instance and weak field instances for reflection
+  // usage.
+  if (descriptor_->oneof_decl_count() > 0 || num_weak_fields_ > 0) {
     printer->Print("public:\n");
     for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
       for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
@@ -1525,9 +1589,71 @@
         field_generators_.get(field).GeneratePrivateMembers(printer);
       }
     }
+    for (int i = 0; i < descriptor_->field_count(); i++) {
+      const FieldDescriptor* field = descriptor_->field(i);
+      if (field->options().weak()) {
+        printer->Print(
+            "  const ::google::protobuf::Message* $name$_;\n", "name", FieldName(field));
+      }
+    }
   }
 }
 
+bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset,
+                                          size_t aux_offset) {
+  if (!table_driven_) {
+    printer->Print("{ NULL, NULL, 0, -1, -1, false },\n");
+    return false;
+  }
+
+  std::map<string, string> vars;
+
+  vars["classname"] = classname_;
+  vars["offset"] = SimpleItoa(offset);
+  vars["aux_offset"] = SimpleItoa(aux_offset);
+
+  int max_field_number = 0;
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+    if (max_field_number < field->number()) {
+      max_field_number = field->number();
+    }
+  }
+
+  vars["max_field_number"] = SimpleItoa(max_field_number);
+
+  printer->Print("{\n");
+  printer->Indent();
+
+  printer->Print(vars,
+      "TableStruct::entries + $offset$,\n"
+      "TableStruct::aux + $aux_offset$,\n"
+      "$max_field_number$,\n");
+
+  if (!HasFieldPresence(descriptor_->file())) {
+    // If we don't have field presence, then _has_bits_ does not exist.
+    printer->Print(vars, "-1,\n");
+  } else {
+    printer->Print(vars,
+      "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n"
+      "  $classname$, _has_bits_),\n");
+  }
+
+  printer->Print(vars,
+    "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n"
+    "  $classname$, _internal_metadata_),\n");
+
+  if (UseUnknownFieldSet(descriptor_->file(), options_)) {
+    printer->Print(vars, "true,\n");
+  } else {
+    printer->Print(vars, "false,\n");
+  }
+
+  printer->Outdent();
+  printer->Print("},\n");
+  return true;
+}
+
 void MessageGenerator::GenerateSchema(io::Printer* printer, int offset,
                                       int has_offset) {
   if (IsMapEntryMessage(descriptor_)) return;
@@ -1545,46 +1671,7 @@
 }
 
 void MessageGenerator::
-GenerateTypeRegistrations(io::Printer* printer) {
-  // Register this message type with the message factory.
-  if (IsMapEntryMessage(descriptor_)) {
-    std::map<string, string> vars;
-    CollectMapInfo(descriptor_, &vars);
-    vars["classname"] = classname_;
-    vars["file_namespace"] = FileLevelNamespace(descriptor_->file()->name());
-
-    const FieldDescriptor* val = descriptor_->FindFieldByName("value");
-    if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO2 &&
-        val->type() == FieldDescriptor::TYPE_ENUM) {
-      const EnumValueDescriptor* default_value = val->default_value_enum();
-      vars["default_enum_value"] = Int32ToString(default_value->number());
-    } else {
-      vars["default_enum_value"] = "0";
-    }
-
-    vars["index_in_metadata"] = SimpleItoa(index_in_metadata_);
-
-    printer->Print(
-        vars,
-        "const ::google::protobuf::Descriptor* $classname$_descriptor = "
-        "$file_namespace$::file_level_metadata[$index_in_metadata$].descriptor;"
-        "\n"
-        "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
-        "      $classname$_descriptor,\n"
-        "      ::google::protobuf::internal::MapEntry<\n"
-        "          $key$,\n"
-        "          $val$,\n"
-        "          $key_wire_type$,\n"
-        "          $val_wire_type$,\n"
-        "          $default_enum_value$>::CreateDefaultInstance(\n"
-        "              $classname$_descriptor));\n");
-  }
-}
-
-void MessageGenerator::
 GenerateDefaultInstanceAllocator(io::Printer* printer) {
-  if (IsMapEntryMessage(descriptor_)) return;
-
   // Construct the default instances of all fields, as they will be used
   // when creating the default instance of the entire message.
   for (int i = 0; i < descriptor_->field_count(); i++) {
@@ -1601,7 +1688,15 @@
 
 void MessageGenerator::
 GenerateDefaultInstanceInitializer(io::Printer* printer) {
-  if (IsMapEntryMessage(descriptor_)) return;
+  if (IsMapEntryMessage(descriptor_)) {
+    printer->Print(
+        "_$classname$_default_instance_.get_mutable()->set_default_instance(_$"
+        "classname$_default_instance_.get_mutable());\n"
+        "_$classname$_default_instance_.get_mutable()->InitAsDefaultInstance();"
+        "\n",
+        "classname", classname_);
+    return;
+  }
 
   // The default instance needs all of its embedded message pointers
   // cross-linked to other default instances.  We can't do this initialization
@@ -1617,7 +1712,7 @@
         (field->containing_oneof() == NULL ||
          HasDescriptorMethods(descriptor_->file(), options_))) {
       string name;
-      if (field->containing_oneof()) {
+      if (field->containing_oneof() || field->options().weak()) {
         name = "_" + classname_ + "_default_instance_.";
       } else {
         name = "_" + classname_ + "_default_instance_.get_mutable()->";
@@ -1645,7 +1740,7 @@
 
   if (HasDescriptorMethods(descriptor_->file(), options_)) {
     printer->Print("delete file_level_metadata[$index$].reflection;\n", "index",
-                   SimpleItoa(index_in_metadata_));
+                   SimpleItoa(index_in_file_messages_));
   }
 
   // Handle default instances of fields.
@@ -1657,7 +1752,31 @@
 
 void MessageGenerator::
 GenerateClassMethods(io::Printer* printer) {
-  if (IsMapEntryMessage(descriptor_)) return;
+  if (IsMapEntryMessage(descriptor_)) {
+    if (HasDescriptorMethods(descriptor_->file(), options_)) {
+      printer->Print(
+          "$parent$::$classname$::$classname$() {}\n"
+          "$parent$::$classname$::$classname$(::google::protobuf::Arena* arena) : "
+          "SuperType(arena) {}\n"
+          "::google::protobuf::Metadata $parent$::$classname$::GetMetadata() const {\n"
+          "  $file_namespace$::protobuf_AssignDescriptorsOnce();\n"
+          "  return $file_namespace$::file_level_metadata[$index$];\n"
+          "}\n"
+          "void $parent$::$classname$::MergeFrom(\n"
+          "    const ::google::protobuf::Message& other) {\n"
+          "  ::google::protobuf::Message::MergeFrom(other);\n"
+          "}\n"
+          "void $parent$::$classname$::MergeFrom(const $classname$& other) {\n"
+          "  MergeFromInternal(other);\n"
+          "}\n"
+          "\n",
+          "file_namespace", FileLevelNamespace(descriptor_->file()->name()),
+          "parent", ClassName(descriptor_->containing_type(), false),
+          "classname", classname_, "index",
+          SimpleItoa(index_in_file_messages_));
+    }
+    return;
+  }
 
   if (IsAnyMessage(descriptor_)) {
     printer->Print(
@@ -1739,11 +1858,12 @@
     printer->Print(
         "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
         "  $file_namespace$::protobuf_AssignDescriptorsOnce();\n"
-        "  return $file_namespace$::file_level_metadata[$index$];\n"
+        "  return "
+        "$file_namespace$::file_level_metadata[kIndexInFileMessages];\n"
         "}\n"
         "\n",
-        "classname", classname_, "index", SimpleItoa(index_in_metadata_),
-        "file_namespace", FileLevelNamespace(descriptor_->file()->name()));
+        "classname", classname_, "file_namespace",
+        FileLevelNamespace(descriptor_->file()->name()));
   } else {
     printer->Print(
       "::std::string $classname$::GetTypeName() const {\n"
@@ -1756,6 +1876,185 @@
 
 }
 
+size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) {
+  if (!table_driven_) {
+    return 0;
+  }
+
+  // Field "0" is special:  We use it in our switch statement of processing
+  // types to handle the successful end tag case.
+  printer->Print("{0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},\n");
+  int last_field_number = 1;
+
+  std::vector<const FieldDescriptor*> ordered_fields =
+      SortFieldsByNumber(descriptor_);
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = ordered_fields[i];
+    GOOGLE_CHECK_GE(field->number(), last_field_number);
+
+    for (; last_field_number < field->number(); last_field_number++) {
+      printer->Print(
+          "{ 0, 0, ::google::protobuf::internal::kInvalidMask,\n"
+          "  ::google::protobuf::internal::kInvalidMask, 0, 0 },\n");
+    }
+    last_field_number++;
+
+    unsigned char normal_wiretype, packed_wiretype, processing_type;
+    normal_wiretype = WireFormat::WireTypeForFieldType(field->type());
+
+    if (field->is_packable()) {
+      packed_wiretype = WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
+    } else {
+      packed_wiretype = internal::kNotPackedMask;
+    }
+
+    processing_type = static_cast<unsigned>(field->type());
+    if (field->type() == FieldDescriptor::TYPE_STRING) {
+      switch (EffectiveStringCType(field)) {
+        case FieldOptions::STRING:
+        default:
+          break;
+      }
+    } else if (field->type() == FieldDescriptor::TYPE_BYTES) {
+      switch (EffectiveStringCType(field)) {
+        case FieldOptions::STRING:
+        default:
+          break;
+      }
+    }
+
+    processing_type |= static_cast<unsigned>(
+        field->is_repeated() ?  internal::kRepeatedMask : 0);
+    const unsigned char tag_size =
+      WireFormat::TagSize(field->number(), field->type());
+
+    std::map<string, string> vars;
+    vars["classname"] = classname_;
+    vars["name"] = FieldName(field);
+    vars["has"] = SimpleItoa(has_bit_indices_[field->index()]);
+    vars["nwtype"] = SimpleItoa(normal_wiretype);
+    vars["pwtype"] = SimpleItoa(packed_wiretype);
+    vars["ptype"] = SimpleItoa(processing_type);
+    vars["tag_size"] = SimpleItoa(tag_size);
+
+    printer->Print(vars,
+      "{\n"
+      "  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n"
+      "    $classname$, $name$_),\n"
+      "  static_cast< ::google::protobuf::uint32>($has$),\n"
+      "  $nwtype$, $pwtype$, $ptype$, $tag_size$\n"
+      "},\n");
+  }
+
+  return last_field_number;
+}
+
+size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) {
+  if (!table_driven_) {
+    return 0;
+  }
+
+  std::vector<const FieldDescriptor*> ordered_fields =
+      SortFieldsByNumber(descriptor_);
+
+  printer->Print("::google::protobuf::internal::AuxillaryParseTableField(),\n");
+  int last_field_number = 1;
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = ordered_fields[i];
+
+    GOOGLE_CHECK_GE(field->number(), last_field_number);
+    for (; last_field_number < field->number(); last_field_number++) {
+      printer->Print("::google::protobuf::internal::AuxillaryParseTableField(),\n");
+    }
+
+    std::map<string, string> vars;
+    SetCommonFieldVariables(field, &vars, options_);
+
+    switch (field->cpp_type()) {
+      case FieldDescriptor::CPPTYPE_ENUM:
+        vars["type"] = ClassName(field->enum_type(), true);
+        printer->Print(
+            vars,
+            "{::google::protobuf::internal::AuxillaryParseTableField::enum_aux{"
+            "$type$_IsValid, \"$type$\" }},\n");
+        last_field_number++;
+        break;
+      case FieldDescriptor::CPPTYPE_MESSAGE: {
+        std::vector<string> package_parts;
+
+        const Descriptor* outer = field->message_type();
+        while (outer->containing_type() != NULL) {
+          outer = outer->containing_type();
+        }
+
+        package_parts = Split(
+            outer->full_name(), ".", true);
+        // outer->full_name() contains the class itself.  Remove it as it is
+        // used in the name of the default instance variable.
+        GOOGLE_DCHECK_NE(package_parts.size(), 0);
+        package_parts.back().clear();
+
+        vars["classname"] = ClassName(field->message_type(), false);
+        vars["ns"] = Join(package_parts, "::");
+        vars["type"] = FieldMessageTypeName(field);
+        vars["file_namespace"] = FileLevelNamespace(outer->file()->name());
+
+        printer->Print(vars,
+            "{::google::protobuf::internal::AuxillaryParseTableField::message_aux{\n"
+            "  &::$ns$_$classname$_default_instance_,\n");
+
+        bool dont_emit_table =
+            !TableDrivenEnabled(field->message_type(), options_);
+
+        if (dont_emit_table) {
+          printer->Print("  NULL,\n");
+        } else {
+          printer->Print(vars,
+              "  ::$ns$$file_namespace$::TableStruct::schema +\n"
+              "    ::$ns$$classname$::kIndexInFileMessages,\n");
+        }
+
+        printer->Print("}},\n");
+        last_field_number++;
+        break;
+      }
+      case FieldDescriptor::CPPTYPE_STRING:
+        switch (EffectiveStringCType(field)) {
+          case FieldOptions::STRING:
+            vars["default"] =
+                field->default_value_string().empty()
+                  ? "&::google::protobuf::internal::fixed_address_empty_string"
+                  : "&" + classname_ + "::_default_" + FieldName(field) + "_";
+            break;
+          case FieldOptions::CORD:
+          case FieldOptions::STRING_PIECE:
+            vars["default"] =
+                "\"" + CEscape(field->default_value_string()) + "\"";
+            break;
+        }
+        vars["full_name"] = field->full_name();
+        vars["strict"] =
+          field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3
+          ? "true" : "false";
+        vars["type"] = field->full_name();
+        printer->Print(vars,
+            "{::google::protobuf::internal::AuxillaryParseTableField::string_aux{\n"
+            "  $default$,\n"
+            "  \"$full_name$\",\n"
+            "  $strict$,\n"
+            "  \"$type$\"\n"
+            "}},\n");
+        last_field_number++;
+        break;
+      default:
+        break;
+    }
+  }
+
+  return last_field_number;
+}
+
 std::pair<size_t, size_t> MessageGenerator::GenerateOffsets(
     io::Printer* printer) {
   if (IsMapEntryMessage(descriptor_)) return std::make_pair(0, 0);
@@ -1765,7 +2064,8 @@
   if (HasFieldPresence(descriptor_->file())) {
     printer->Print(
         variables,
-        "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_),\n");
+        "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
+        "_has_bits_),\n");
   } else {
     printer->Print("~0u,  // no _has_bits_\n");
   }
@@ -1775,34 +2075,41 @@
   if (descriptor_->extension_range_count() > 0) {
     printer->Print(
         variables,
-        "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _extensions_),\n");
+        "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
+        "_extensions_),\n");
   } else {
     printer->Print("~0u,  // no _extensions_\n");
   }
   if (descriptor_->oneof_decl_count() > 0) {
     printer->Print(variables,
-                   "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
-                   "_oneof_case_[0]),\n");
+                   "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
+                   "$classname$, _oneof_case_[0]),\n");
   } else {
     printer->Print("~0u,  // no _oneof_case_\n");
   }
-
-  const int kNumGenericOffsets = 4;  // the number of fixed offsets above
+  if (num_weak_fields_ > 0) {
+    printer->Print(variables,
+                   "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$,"
+                   " _weak_field_map_),\n");
+  } else {
+    printer->Print("~0u,  // no _weak_field_map_\n");
+  }
+  const int kNumGenericOffsets = 5;  // the number of fixed offsets above
   const size_t offsets = kNumGenericOffsets +
                          descriptor_->field_count() +
                          descriptor_->oneof_decl_count();
   size_t entries = offsets;
   for (int i = 0; i < descriptor_->field_count(); i++) {
     const FieldDescriptor* field = descriptor_->field(i);
-    if (field->containing_oneof()) {
+    if (field->containing_oneof() || field->options().weak()) {
       printer->Print(
-          "PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET("
+          "GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET("
           "(&_$classname$_default_instance_), $name$_),\n",
           "classname", classname_, "name", FieldName(field));
     } else {
       printer->Print(
           "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
-                                                 "$name$_),\n",
+                                                         "$name$_),\n",
           "classname", classname_,
           "name", FieldName(field));
     }
@@ -1844,19 +2151,6 @@
     need_to_clear_cached_size = false;
   }
 
-  // TODO(gerbens) Clean this hack, and why do i need a reference to a pointer??
-  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
-    if (HasDescriptorMethods(descriptor_->file(), options_) &&
-        IsMapEntryMessage(descriptor_->nested_type(i))) {
-      printer->Print(
-          "const ::google::protobuf::Descriptor*& $type$_descriptor = "
-          "$file_namespace$::file_level_metadata[$index$].descriptor;\n",
-          "type", ClassName(descriptor_->nested_type(i), false), "index",
-          SimpleItoa(nested_generators_[i]->index_in_metadata_),
-          "file_namespace", FileLevelNamespace(descriptor_->file()->name()));
-    }
-  }
-
   std::vector<bool> processed(optimized_order_.size(), false);
   GenerateConstructorBody(printer, processed, false);
 
@@ -1906,6 +2200,9 @@
         "oneof_name", descriptor_->oneof_decl(i)->name());
   }
 
+  if (num_weak_fields_) {
+    printer->Print("_weak_field_map_.ClearAll();\n");
+  }
   printer->Outdent();
   printer->Print(
     "}\n"
@@ -1956,6 +2253,12 @@
       }
     }
   }
+  if (num_weak_fields_) {
+    // _this is the object being destructed (we are inside a static method
+    // here).
+    printer->Print("_this->_weak_field_map_.ClearAll();\n");
+    need_registration = true;
+  }
 
   printer->Outdent();
   printer->Print(
@@ -2077,12 +2380,18 @@
   if (IsAnyMessage(descriptor_)) {
     initializer_with_arena += ",\n  _any_metadata_(&type_url_, &value_)";
   }
+  if (num_weak_fields_ > 0) {
+    initializer_with_arena += ", _weak_field_map_(arena)";
+  }
 
   string initializer_null;
   initializer_null = ", _internal_metadata_(NULL)";
   if (IsAnyMessage(descriptor_)) {
     initializer_null += ", _any_metadata_(&type_url_, &value_)";
   }
+  if (num_weak_fields_ > 0) {
+    initializer_null += ", _weak_field_map_(NULL)";
+  }
 
   printer->Print(
       "$classname$::$classname$()\n"
@@ -2165,6 +2474,9 @@
   if (IsAnyMessage(descriptor_)) {
     printer->Print(",\n_any_metadata_(&type_url_, &value_)");
   }
+  if (num_weak_fields_ > 0) {
+    printer->Print(",\n_weak_field_map_(from._weak_field_map_)");
+  }
 
   printer->Outdent();
   printer->Outdent();
@@ -2177,19 +2489,6 @@
     printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
   }
 
-  // TODO(gerbens) Clean this hack, and why do i need a reference to a pointer??
-  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
-    if (HasDescriptorMethods(descriptor_->file(), options_) &&
-        IsMapEntryMessage(descriptor_->nested_type(i))) {
-      printer->Print(
-          "const ::google::protobuf::Descriptor*& $type$_descriptor = "
-          "$file_namespace$::file_level_metadata[$index$].descriptor;\n",
-          "type", ClassName(descriptor_->nested_type(i), false), "index",
-          SimpleItoa(nested_generators_[i]->index_in_metadata_),
-          "file_namespace", FileLevelNamespace(descriptor_->file()->name()));
-    }
-  }
-
   GenerateConstructorBody(printer, processed, true);
 
   // Copy oneof fields. Oneof field requires oneof case check.
@@ -2268,11 +2567,13 @@
     printer->Print(
         "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
         "  $file_namespace$::protobuf_AssignDescriptorsOnce();\n"
-        "  return $file_namespace$::file_level_metadata[$index$].descriptor;\n"
+        "  return "
+        "$file_namespace$::file_level_metadata[kIndexInFileMessages]."
+        "descriptor;\n"
         "}\n"
         "\n",
-        "index", SimpleItoa(index_in_metadata_), "classname", classname_,
-        "file_namespace", FileLevelNamespace(descriptor_->file()->name()));
+        "classname", classname_, "file_namespace",
+        FileLevelNamespace(descriptor_->file()->name()));
   }
 
   printer->Print(
@@ -2504,6 +2805,10 @@
         "oneof_name", descriptor_->oneof_decl(i)->name());
   }
 
+  if (num_weak_fields_) {
+    printer->Print("_weak_field_map_.ClearAll();\n");
+  }
+
   if (HasFieldPresence(descriptor_->file())) {
     // Step 5: Everything else.
     printer->Print("_has_bits_.Clear();\n");
@@ -2647,6 +2952,10 @@
     if (descriptor_->extension_range_count() > 0) {
       printer->Print("_extensions_.Swap(&other->_extensions_);\n");
     }
+    if (num_weak_fields_) {
+      printer->Print(
+          "_weak_field_map_.UnsafeArenaSwap(&other->_weak_field_map_);\n");
+    }
   } else {
     printer->Print("GetReflection()->Swap(this, other);");
   }
@@ -2714,7 +3023,14 @@
   }
 
   printer->Print(
-    "_internal_metadata_.MergeFrom(from._internal_metadata_);\n");
+    "_internal_metadata_.MergeFrom(from._internal_metadata_);\n"
+    "::google::protobuf::uint32 cached_has_bits = 0;\n"
+    "(void) cached_has_bits;\n\n");
+
+  // cached_has_bit_index maintains that:
+  //   cached_has_bits = from._has_bits_[cached_has_bit_index]
+  // for cached_has_bit_index >= 0
+  int cached_has_bit_index = -1;
 
   int last_i = -1;
   for (int i = 0; i < optimized_order_.size(); ) {
@@ -2734,7 +3050,7 @@
       generator.GenerateMergingCode(printer);
     }
 
-    // Merge Optional and Required fields (after a _has_bit check).
+    // Merge Optional and Required fields (after a _has_bit_ check).
     int last_chunk = -1;
     int last_chunk_start = -1;
     int last_chunk_end = -1;
@@ -2779,23 +3095,43 @@
         GOOGLE_DCHECK_LE(2, count);
         GOOGLE_DCHECK_GE(8, count);
 
+        if (cached_has_bit_index != last_chunk / 4) {
+          int new_index = last_chunk / 4;
+          printer->Print("cached_has_bits = from._has_bits_[$new_index$];\n",
+                         "new_index", SimpleItoa(new_index));
+          cached_has_bit_index = new_index;
+        }
+
         printer->Print(
-          "if (from._has_bits_[$index$ / 32] & $mask$u) {\n",
-          "index", SimpleItoa(last_chunk * 8),
+          "if (cached_has_bits & $mask$u) {\n",
           "mask", SimpleItoa(last_chunk_mask));
         printer->Indent();
       }
 
       // Go back and emit clears for each of the fields we processed.
+      bool deferred_has_bit_changes = false;
       for (int j = last_chunk_start; j <= last_chunk_end; j++) {
         const FieldDescriptor* field = optimized_order_[j];
         const FieldGenerator& generator = field_generators_.get(field);
 
         bool have_enclosing_if = false;
         if (HasFieldPresence(descriptor_->file())) {
-          printer->Print(
-            "if (from.has_$name$()) {\n",
-            "name", FieldName(field));
+          // Attempt to use the state of cached_has_bits, if possible.
+          int has_bit_index = has_bit_indices_[field->index()];
+          if (!field->options().weak() &&
+              cached_has_bit_index == has_bit_index / 32) {
+            const string mask = StrCat(
+                strings::Hex(1u << (has_bit_index % 32),
+                strings::ZERO_PAD_8));
+
+            printer->Print(
+                "if (cached_has_bits & 0x$mask$u) {\n", "mask", mask);
+          } else {
+            printer->Print(
+              "if (from.has_$name$()) {\n",
+              "name", FieldName(field));
+          }
+
           printer->Indent();
           have_enclosing_if = true;
         } else {
@@ -2805,7 +3141,17 @@
               printer, "from.", field);
         }
 
-        generator.GenerateMergingCode(printer);
+        if (have_outer_if && IsPOD(field)) {
+          // GenerateCopyConstructorCode for enum and primitive scalar fields
+          // does not do _has_bits_ modifications.  We defer _has_bits_
+          // manipulation until the end of the outer if.
+          //
+          // This can reduce the number of loads/stores by up to 7 per 8 fields.
+          deferred_has_bit_changes = true;
+          generator.GenerateCopyConstructorCode(printer);
+        } else {
+          generator.GenerateMergingCode(printer);
+        }
 
         if (have_enclosing_if) {
           printer->Outdent();
@@ -2814,6 +3160,14 @@
       }
 
       if (have_outer_if) {
+        if (deferred_has_bit_changes) {
+          // Flush the has bits for the primitives we deferred.
+          GOOGLE_CHECK_LE(0, cached_has_bit_index);
+          printer->Print(
+              "_has_bits_[$index$] |= cached_has_bits;\n",
+              "index", SimpleItoa(cached_has_bit_index));
+        }
+
         printer->Outdent();
         printer->Print("}\n");
       }
@@ -2849,6 +3203,9 @@
     printer->Print(
         "}\n");
   }
+  if (num_weak_fields_) {
+    printer->Print("_weak_field_map_.MergeFrom(from._weak_field_map_);\n");
+  }
 
   printer->Outdent();
   printer->Print("}\n");
@@ -2913,13 +3270,36 @@
     return;
   }
 
+  std::vector<const FieldDescriptor*> ordered_fields =
+      SortFieldsByNumber(descriptor_);
+
   printer->Print(
     "bool $classname$::MergePartialFromCodedStream(\n"
-    "    ::google::protobuf::io::CodedInputStream* input) {\n"
-    "#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure\n"
-    "  ::google::protobuf::uint32 tag;\n",
+    "    ::google::protobuf::io::CodedInputStream* input) {\n",
     "classname", classname_);
 
+  if (table_driven_) {
+    printer->Indent();
+
+    printer->Print(
+        "return ::google::protobuf::internal::MergePartialFromCodedStream(\n"
+        "    this,\n"
+        "    $file_namespace$::TableStruct::schema[\n"
+        "      $classname$::kIndexInFileMessages],\n"
+        "    input);\n",
+        "classname", classname_,
+        "file_namespace", FileLevelNamespace(descriptor_->file()->name()));
+
+    printer->Outdent();
+
+    printer->Print("}\n");
+    return;
+  }
+
+  printer->Print(
+    "#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure\n"
+    "  ::google::protobuf::uint32 tag;\n");
+
   if (PreserveUnknownFields(descriptor_) &&
       !UseUnknownFieldSet(descriptor_->file(), options_)) {
     // Use LazyStringOutputString to avoid initializing unknown fields string
@@ -2928,7 +3308,8 @@
     printer->Print(
       "  ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(\n"
       "      ::google::protobuf::NewPermanentCallback(&_internal_metadata_,\n"
-      "          &::google::protobuf::internal::InternalMetadataWithArenaLite::mutable_unknown_fields));\n"
+      "          &::google::protobuf::internal::InternalMetadataWithArenaLite::\n"
+      "              mutable_unknown_fields));\n"
       "  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n"
       "      &unknown_fields_string, false);\n",
       "classname", classname_);
@@ -2942,8 +3323,6 @@
   printer->Print("for (;;) {\n");
   printer->Indent();
 
-  std::vector<const FieldDescriptor*> ordered_fields =
-      SortFieldsByNumber(descriptor_);
   uint32 maxtag = descriptor_->field_count() == 0 ? 0 :
       WireFormat::MakeTag(ordered_fields[descriptor_->field_count() - 1]);
   const int kCutoff0 = 127;               // fits in 1-byte varint
@@ -3004,20 +3383,8 @@
 
     printer->Indent();
 
-    // Find repeated messages and groups now, to simplify what follows.
-    hash_set<int> fields_with_parse_loop;
     for (int i = 0; i < ordered_fields.size(); i++) {
       const FieldDescriptor* field = ordered_fields[i];
-      if (field->is_repeated() &&
-          (field->type() == FieldDescriptor::TYPE_MESSAGE ||
-           field->type() == FieldDescriptor::TYPE_GROUP)) {
-        fields_with_parse_loop.insert(i);
-      }
-    }
-
-    for (int i = 0; i < ordered_fields.size(); i++) {
-      const FieldDescriptor* field = ordered_fields[i];
-      const bool loops = fields_with_parse_loop.count(i) > 0;
 
       PrintFieldComment(printer, field);
 
@@ -3030,11 +3397,7 @@
       // Emit code to parse the common, expected case.
       printer->Print("if (static_cast< ::google::protobuf::uint8>(tag) ==\n"
                      "    static_cast< ::google::protobuf::uint8>($commontag$u)) {\n",
-                     "commontag", SimpleItoa(WireFormat::MakeTag(field)));
-
-      if (loops) {
-        printer->Print("  DO_(input->IncrementRecursionDepth());\n");
-      }
+          "commontag", SimpleItoa(WireFormat::MakeTag(field)));
 
       printer->Indent();
       if (field->is_packed()) {
@@ -3074,12 +3437,6 @@
         "  goto handle_unusual;\n"
         "}\n");
 
-      // For repeated messages/groups, we need to decrement recursion depth.
-      if (loops) {
-        printer->Print(
-            "input->UnsafeDecrementRecursionDepth();\n");
-      }
-
       printer->Print(
         "break;\n");
 
@@ -3194,7 +3551,7 @@
     bool to_array) {
   GOOGLE_CHECK(!fields.empty());
   if (fields.size() == 1) {
-    GenerateSerializeOneField(printer, fields[0], to_array);
+    GenerateSerializeOneField(printer, fields[0], to_array, -1);
     return;
   }
   // We have multiple mutually exclusive choices.  Emit a switch statement.
@@ -3227,14 +3584,31 @@
 }
 
 void MessageGenerator::GenerateSerializeOneField(
-    io::Printer* printer, const FieldDescriptor* field, bool to_array) {
-  PrintFieldComment(printer, field);
+    io::Printer* printer, const FieldDescriptor* field, bool to_array,
+    int cached_has_bits_index) {
+  if (!field->options().weak()) {
+    // For weakfields, PrintFieldComment is called during iteration.
+    PrintFieldComment(printer, field);
+  }
 
   bool have_enclosing_if = false;
-  if (!field->is_repeated() && HasFieldPresence(descriptor_->file())) {
-    printer->Print(
-      "if (has_$name$()) {\n",
-      "name", FieldName(field));
+  if (field->options().weak()) {
+  } else if (!field->is_repeated() && HasFieldPresence(descriptor_->file())) {
+    // Attempt to use the state of cached_has_bits, if possible.
+    int has_bit_index = has_bit_indices_[field->index()];
+    if (cached_has_bits_index == has_bit_index / 32) {
+      const string mask = StrCat(
+          strings::Hex(1u << (has_bit_index % 32),
+          strings::ZERO_PAD_8));
+
+      printer->Print(
+          "if (cached_has_bits & 0x$mask$u) {\n", "mask", mask);
+    } else {
+      printer->Print(
+        "if (has_$name$()) {\n",
+        "name", FieldName(field));
+    }
+
     printer->Indent();
     have_enclosing_if = true;
   } else if (!HasFieldPresence(descriptor_->file())) {
@@ -3341,7 +3715,6 @@
     "classname", classname_);
   printer->Indent();
 
-  printer->Print("(void)deterministic;  // Unused\n");
   printer->Print(
     "// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n",
     "full_name", descriptor_->full_name());
@@ -3372,7 +3745,8 @@
         : mg_(mg),
           printer_(printer),
           to_array_(to_array),
-          eager_(!HasFieldPresence(mg->descriptor_->file())) {}
+          eager_(!HasFieldPresence(mg->descriptor_->file())),
+          cached_has_bit_index_(-1) {}
 
     ~LazySerializerEmitter() { Flush(); }
 
@@ -3383,7 +3757,27 @@
         Flush();
       }
       if (field->containing_oneof() == NULL) {
-        mg_->GenerateSerializeOneField(printer_, field, to_array_);
+        // TODO(ckennelly): Defer non-oneof fields similarly to oneof fields.
+
+        if (!field->options().weak() && !field->is_repeated() && !eager_) {
+          // We speculatively load the entire _has_bits_[index] contents, even
+          // if it is for only one field.  Deferring non-oneof emitting would
+          // allow us to determine whether this is going to be useful.
+          int has_bit_index = mg_->has_bit_indices_[field->index()];
+          if (cached_has_bit_index_ != has_bit_index / 32) {
+            // Reload.
+            int new_index = has_bit_index / 32;
+
+            printer_->Print(
+                "cached_has_bits = _has_bits_[$new_index$];\n",
+                "new_index", SimpleItoa(new_index));
+
+            cached_has_bit_index_ = new_index;
+          }
+        }
+
+        mg_->GenerateSerializeOneField(
+            printer_, field, to_array_, cached_has_bit_index_);
       } else {
         v_.push_back(field);
       }
@@ -3409,6 +3803,11 @@
     const bool to_array_;
     const bool eager_;
     std::vector<const FieldDescriptor*> v_;
+
+    // cached_has_bit_index_ maintains that:
+    //   cached_has_bits = from._has_bits_[cached_has_bit_index_]
+    // for cached_has_bit_index_ >= 0
+    int cached_has_bit_index_;
   };
 
   std::vector<const FieldDescriptor*> ordered_fields =
@@ -3420,29 +3819,51 @@
   }
   std::sort(sorted_extensions.begin(), sorted_extensions.end(),
             ExtensionRangeSorter());
+  if (num_weak_fields_) {
+    printer->Print(
+        "::google::protobuf::internal::WeakFieldMap::FieldWriter field_writer("
+        "_weak_field_map_);\n");
+  }
+
+  printer->Print(
+      "::google::protobuf::uint32 cached_has_bits = 0;\n"
+      "(void) cached_has_bits;\n\n");
 
   // Merge the fields and the extension ranges, both sorted by field number.
   {
     LazySerializerEmitter e(this, printer, to_array);
+    const FieldDescriptor* last_weak_field = NULL;
     int i, j;
     for (i = 0, j = 0;
          i < ordered_fields.size() || j < sorted_extensions.size();) {
-      if (i == descriptor_->field_count()) {
-        e.Flush();
-        GenerateSerializeOneExtensionRange(printer,
-                                           sorted_extensions[j++],
-                                           to_array);
-      } else if (j == sorted_extensions.size()) {
-        e.Emit(ordered_fields[i++]);
-      } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) {
-        e.Emit(ordered_fields[i++]);
-      } else {
+      if ((j == sorted_extensions.size()) ||
+          (i < descriptor_->field_count() &&
+           ordered_fields[i]->number() < sorted_extensions[j]->start)) {
+        const FieldDescriptor* field = ordered_fields[i++];
+        if (field->options().weak()) {
+          last_weak_field = field;
+          PrintFieldComment(printer, field);
+        } else {
+          if (last_weak_field != NULL) {
+            e.Emit(last_weak_field);
+            last_weak_field = NULL;
+          }
+          e.Emit(field);
+        }
+      } else  {
+        if (last_weak_field != NULL) {
+          e.Emit(last_weak_field);
+          last_weak_field = NULL;
+        }
         e.Flush();
         GenerateSerializeOneExtensionRange(printer,
                                            sorted_extensions[j++],
                                            to_array);
       }
     }
+    if (last_weak_field != NULL) {
+      e.Emit(last_weak_field);
+    }
   }
 
   if (PreserveUnknownFields(descriptor_)) {
@@ -3783,6 +4204,11 @@
         "}\n");
   }
 
+  if (num_weak_fields_) {
+    // TagSize + MessageSize
+    printer->Print("total_size += _weak_field_map_.ByteSizeLong();\n");
+  }
+
   // We update _cached_size_ even though this is a const method.  In theory,
   // this is not thread-compatible, because concurrent writes have undefined
   // results.  In practice, since any concurrent writes will be writing the
@@ -3840,26 +4266,28 @@
     // TODO(ckennelly): Push this down into a generator?
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
         !ShouldIgnoreRequiredFieldCheck(field, options_) &&
-        HasRequiredFields(field->message_type(), options_)) {
+        scc_analyzer_->HasRequiredFields(field->message_type())) {
       if (field->is_repeated()) {
         printer->Print(
           "if (!::google::protobuf::internal::AllAreInitialized(this->$name$()))"
           " return false;\n",
           "name", FieldName(field));
+      } else if (field->options().weak()) {
+        continue;
       } else {
-        GOOGLE_CHECK(field->options().weak() || !field->containing_oneof());
-        // For weak fields, use the data member (::google::protobuf::Message*) instead
-        // of the getter to avoid a link dependency on the weak message type
-        // which is only forward declared.
+        GOOGLE_CHECK(!field->containing_oneof());
         printer->Print(
             "if (has_$name$()) {\n"
             "  if (!this->$name$_->IsInitialized()) return false;\n"
             "}\n",
-          "name", FieldName(field));
+            "name", FieldName(field));
       }
     }
   }
-
+  if (num_weak_fields_) {
+    // For Weak fields.
+    printer->Print("if (!_weak_field_map_.IsInitialized()) return false;\n");
+  }
   // Go through the oneof fields, emitting a switch if any might have required
   // fields.
   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
@@ -3871,7 +4299,7 @@
 
       if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
           !ShouldIgnoreRequiredFieldCheck(field, options_) &&
-          HasRequiredFields(field->message_type(), options_)) {
+          scc_analyzer_->HasRequiredFields(field->message_type())) {
         has_required_fields = true;
         break;
       }
@@ -3894,17 +4322,10 @@
 
       if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
           !ShouldIgnoreRequiredFieldCheck(field, options_) &&
-          HasRequiredFields(field->message_type(), options_)) {
+          scc_analyzer_->HasRequiredFields(field->message_type())) {
         GOOGLE_CHECK(!(field->options().weak() || !field->containing_oneof()));
         if (field->options().weak()) {
-          // For weak fields, use the data member (::google::protobuf::Message*) instead
-          // of the getter to avoid a link dependency on the weak message type
-          // which is only forward declared.
-          printer->Print(
-              "if (has_$name$()) {\n"
-              "  if (!this->$name$_->IsInitialized()) return false;\n"
-              "}\n",
-            "name", FieldName(field));
+          // Just skip.
         } else {
           printer->Print(
             "if (has_$name$()) {\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h
index 1a804a1..23aaeeb 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message.h
@@ -42,6 +42,7 @@
 #include <set>
 #include <string>
 #include <google/protobuf/compiler/cpp/cpp_field.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
 #include <google/protobuf/compiler/cpp/cpp_options.h>
 
 namespace google {
@@ -61,7 +62,8 @@
 class MessageGenerator {
  public:
   // See generator.cc for the meaning of dllexport_decl.
-  MessageGenerator(const Descriptor* descriptor, const Options& options);
+  MessageGenerator(const Descriptor* descriptor, const Options& options,
+                   SCCAnalyzer* scc_analyzer);
   ~MessageGenerator();
 
   // Appends the pre-order walk of the nested generators to list.
@@ -94,10 +96,6 @@
   // Generate extra fields
   void GenerateExtraDefaultFields(io::Printer* printer);
 
-  // Generate code that calls MessageFactory::InternalRegisterGeneratedMessage()
-  // for all types.
-  void GenerateTypeRegistrations(io::Printer* printer);
-
   // Generates code that allocates the message's default instance.
   void GenerateDefaultInstanceAllocator(io::Printer* printer);
 
@@ -121,6 +119,15 @@
   void GenerateDependentFieldAccessorDefinitions(io::Printer* printer);
   void GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline);
 
+  // Generate the table-driven parsing array.  Returns the number of entries
+  // generated.
+  size_t GenerateParseOffsets(io::Printer* printer);
+  size_t GenerateParseAuxTable(io::Printer* printer);
+  // Generates a ParseTable entry.  Returns whether the proto uses table-driven
+  // parsing.
+  bool GenerateParseTable(io::Printer* printer, size_t offset,
+                          size_t aux_offset);
+
   // Generate the field offsets array.  Returns the a pair of the total numer
   // of entries generated and the index of the first has_bit entry.
   std::pair<size_t, size_t> GenerateOffsets(io::Printer* printer);
@@ -155,9 +162,14 @@
   void GenerateIsInitialized(io::Printer* printer);
 
   // Helpers for GenerateSerializeWithCachedSizes().
+  //
+  // cached_has_bit_index maintains that:
+  //   cached_has_bits = _has_bits_[cached_has_bit_index]
+  // for cached_has_bit_index >= 0
   void GenerateSerializeOneField(io::Printer* printer,
                                  const FieldDescriptor* field,
-                                 bool unbounded);
+                                 bool unbounded,
+                                 int cached_has_bits_index);
   // Generate a switch statement to serialize 2+ fields from the same oneof.
   // Or, if fields.size() == 1, just call GenerateSerializeOneField().
   void GenerateSerializeOneofFields(
@@ -197,7 +209,7 @@
   // optimized_order_ is the order we layout the message's fields in the class.
   // This is reused to initialize the fields in-order for cache efficiency.
   //
-  // optimized_order_ excludes oneof fields.
+  // optimized_order_ excludes oneof fields and weak fields.
   std::vector<const FieldDescriptor *> optimized_order_;
   std::vector<int> has_bit_indices_;
   int max_has_bit_index_;
@@ -206,8 +218,13 @@
   google::protobuf::scoped_array<google::protobuf::scoped_ptr<ExtensionGenerator> > extension_generators_;
   int num_required_fields_;
   bool use_dependent_base_;
+  int num_weak_fields_;
+  // table_driven_ indicates the generated message uses table-driven parsing.
+  bool table_driven_;
 
-  int index_in_metadata_;
+  int index_in_file_messages_;
+
+  SCCAnalyzer* scc_analyzer_;
 
   friend class FileGenerator;
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
index c3d1745..fc3c456 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -35,6 +35,7 @@
 #include <google/protobuf/compiler/cpp/cpp_message_field.h>
 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
 #include <google/protobuf/io/printer.h>
+
 #include <google/protobuf/stubs/strutil.h>
 
 namespace google {
@@ -583,7 +584,7 @@
   printer->Print(variables_,
     "target = ::google::protobuf::internal::WireFormatLite::\n"
     "  InternalWrite$declared_type$NoVirtualToArray(\n"
-    "    $number$, *$non_null_ptr_to_name$, false, target);\n");
+    "    $number$, *$non_null_ptr_to_name$, deterministic, target);\n");
 }
 
 void MessageFieldGenerator::
@@ -670,15 +671,6 @@
   InternalGenerateInlineAccessorDefinitions(variables, printer);
 }
 
-void MessageOneofFieldGenerator::
-GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
-  std::map<string, string> variables(variables_);
-  variables["field_member"] =
-      variables["oneof_prefix"] + variables["name"] + "_";
-
-  //printer->Print(variables,
-}
-
 void MessageOneofFieldGenerator::InternalGenerateInlineAccessorDefinitions(
     const std::map<string, string>& variables, io::Printer* printer) const {
   printer->Print(variables,
@@ -1066,7 +1058,7 @@
 
 void RepeatedMessageFieldGenerator::
 GenerateSwappingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.UnsafeArenaSwap(&other->$name$_);\n");
+  printer->Print(variables_, "$name$_.InternalSwap(&other->$name$_);\n");
 }
 
 void RepeatedMessageFieldGenerator::
@@ -1079,12 +1071,12 @@
   if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
     printer->Print(variables_,
       "DO_(::google::protobuf::internal::WireFormatLite::"
-      "ReadMessageNoVirtualNoRecursionDepth(\n"
+      "ReadMessageNoVirtual(\n"
       "      input, add_$name$()));\n");
   } else {
     printer->Print(variables_,
       "DO_(::google::protobuf::internal::WireFormatLite::"
-      "ReadGroupNoVirtualNoRecursionDepth(\n"
+      "ReadGroupNoVirtual(\n"
       "      $number$, input, add_$name$()));\n");
   }
 }
@@ -1104,7 +1096,7 @@
     "for (unsigned int i = 0, n = this->$name$_size(); i < n; i++) {\n"
     "  target = ::google::protobuf::internal::WireFormatLite::\n"
     "    InternalWrite$declared_type$NoVirtualToArray(\n"
-    "      $number$, this->$name$(i), false, target);\n"
+    "      $number$, this->$name$(i), deterministic, target);\n"
     "}\n");
 }
 
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/google/protobuf/compiler/cpp/cpp_message_field.h
index 9ca9115..cd9737f 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.h
@@ -95,7 +95,7 @@
   void GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const;
   void GenerateInlineAccessorDefinitions(io::Printer* printer,
                                          bool is_inline) const;
-  void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const { }
   void GenerateClearingCode(io::Printer* printer) const;
 
   // MessageFieldGenerator, from which we inherit, overrides this so we need to
diff --git a/src/google/protobuf/compiler/cpp/cpp_options.h b/src/google/protobuf/compiler/cpp/cpp_options.h
index ee44fb0..bdaa12a 100644
--- a/src/google/protobuf/compiler/cpp/cpp_options.h
+++ b/src/google/protobuf/compiler/cpp/cpp_options.h
@@ -46,16 +46,18 @@
   Options()
       : safe_boundary_check(false),
         proto_h(false),
-        allow_import_public(true),
+        transitive_pb_h(true),
         annotate_headers(false),
-        enforce_lite(false) {}
+        enforce_lite(false),
+        table_driven_parsing(false) {}
 
   string dllexport_decl;
   bool safe_boundary_check;
   bool proto_h;
-  bool allow_import_public;
+  bool transitive_pb_h;
   bool annotate_headers;
   bool enforce_lite;
+  bool table_driven_parsing;
   string annotation_pragma_name;
   string annotation_guard_name;
 };
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
index 4a0a23f..020c194 100644
--- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -342,7 +342,7 @@
 
 void RepeatedPrimitiveFieldGenerator::
 GenerateSwappingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.UnsafeArenaSwap(&other->$name$_);\n");
+  printer->Print(variables_, "$name$_.InternalSwap(&other->$name$_);\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::
@@ -385,6 +385,9 @@
       "  output->WriteVarint32(_$name$_cached_byte_size_);\n");
 
     if (FixedSize(descriptor_->type()) > 0) {
+      // TODO(ckennelly): Use RepeatedField<T>::unsafe_data() via
+      // WireFormatLite to access the contents of this->$name$_ to save a branch
+      // here.
       printer->Print(variables_,
         "  ::google::protobuf::internal::WireFormatLite::Write$declared_type$Array(\n"
         "    this->$name$().data(), this->$name$_size(), output);\n");
@@ -420,20 +423,14 @@
       "    target);\n"
       "  target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(\n"
       "    _$name$_cached_byte_size_, target);\n"
-      "}\n");
-  }
-  printer->Print(variables_,
-      "for (int i = 0, n = this->$name$_size(); i < n; i++) {\n");
-  if (descriptor_->is_packed()) {
-    printer->Print(variables_,
       "  target = ::google::protobuf::internal::WireFormatLite::\n"
-      "    Write$declared_type$NoTagToArray(this->$name$(i), target);\n");
+      "    Write$declared_type$NoTagToArray(this->$name$_, target);\n"
+      "}\n");
   } else {
     printer->Print(variables_,
-      "  target = ::google::protobuf::internal::WireFormatLite::\n"
-      "    Write$declared_type$ToArray($number$, this->$name$(i), target);\n");
+      "target = ::google::protobuf::internal::WireFormatLite::\n"
+      "  Write$declared_type$ToArray($number$, this->$name$_, target);\n");
   }
-  printer->Print("}\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index 664a277..7a849e2 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -36,6 +36,7 @@
 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/descriptor.pb.h>
+
 #include <google/protobuf/stubs/strutil.h>
 
 namespace google {
@@ -61,6 +62,7 @@
                 ".get()";
   (*variables)["pointer_type"] =
       descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
+  (*variables)["null_check"] = "GOOGLE_DCHECK(value != NULL);\n";
   // NOTE: Escaped here to unblock proto1->proto2 migration.
   // TODO(liujisi): Extend this to apply for other conflicting methods.
   (*variables)["release_name"] =
@@ -190,6 +192,7 @@
         "  // @@protoc_insertion_point(field_set:$full_name$)\n"
         "}\n"
         "$inline$void $classname$::set_$name$(const char* value) {\n"
+        "  $null_check$"
         "  $set_hasbit$\n"
         "  $name$_.Set($default_variable$, $string_piece$(value),\n"
         "              GetArenaNoVirtual());\n"
@@ -267,6 +270,7 @@
         "}\n"
         "#endif\n"
         "$inline$void $classname$::set_$name$(const char* value) {\n"
+        "  $null_check$"
         "  $set_hasbit$\n"
         "  $name$_.SetNoArena($default_variable$, $string_piece$(value));\n"
         "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
@@ -548,6 +552,7 @@
         "  // @@protoc_insertion_point(field_set:$full_name$)\n"
         "}\n"
         "$inline$void $classname$::set_$name$(const char* value) {\n"
+        "  $null_check$"
         "  if (!has_$name$()) {\n"
         "    clear_$oneof_name$();\n"
         "    set_has_$name$();\n"
@@ -664,6 +669,7 @@
         "}\n"
         "#endif\n"
         "$inline$void $classname$::set_$name$(const char* value) {\n"
+        "  $null_check$"
         "  if (!has_$name$()) {\n"
         "    clear_$oneof_name$();\n"
         "    set_has_$name$();\n"
@@ -882,6 +888,7 @@
     "}\n"
     "#endif\n"
     "$inline$void $classname$::set_$name$(int index, const char* value) {\n"
+    "  $null_check$"
     "  $name$_.Mutable(index)->assign(value);\n"
     "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
     "}\n"
@@ -902,11 +909,12 @@
     "}\n"
     "#if LANG_CXX11\n"
     "$inline$void $classname$::add_$name$(::std::string&& value) {\n"
-    "  $name$_.Add()->assign(std::move(value));\n"
+    "  $name$_.Add(std::move(value));\n"
     "  // @@protoc_insertion_point(field_add:$full_name$)\n"
     "}\n"
     "#endif\n"
     "$inline$void $classname$::add_$name$(const char* value) {\n"
+    "  $null_check$"
     "  $name$_.Add()->assign(value);\n"
     "  // @@protoc_insertion_point(field_add_char:$full_name$)\n"
     "}\n"
@@ -939,7 +947,7 @@
 
 void RepeatedStringFieldGenerator::
 GenerateSwappingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.UnsafeArenaSwap(&other->$name$_);\n");
+  printer->Print(variables_, "$name$_.InternalSwap(&other->$name$_);\n");
 }
 
 void RepeatedStringFieldGenerator::
@@ -969,7 +977,7 @@
 void RepeatedStringFieldGenerator::
 GenerateSerializeWithCachedSizes(io::Printer* printer) const {
   printer->Print(variables_,
-    "for (int i = 0, n = this->$name$_size(); i < n; i++) {\n");
+        "for (int i = 0, n = this->$name$_size(); i < n; i++) {\n");
   printer->Indent();
   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
index 6d68ec3..e56964c 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -76,7 +76,6 @@
 #include <google/protobuf/stubs/callback.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
@@ -2162,6 +2161,61 @@
 
 }
 
+TEST(HelpersTest, TestSCC) {
+  protobuf_unittest::TestMutualRecursionA a;
+  SCCAnalyzer scc_analyzer((Options()));
+  const SCC* scc = scc_analyzer.GetSCC(a.GetDescriptor());
+  std::vector<string> names;
+  for (int i = 0; i < scc->descriptors.size(); i++) {
+    names.push_back(scc->descriptors[i]->full_name());
+  }
+  ASSERT_EQ(names.size(), 4);
+  std::sort(names.begin(), names.end());
+  EXPECT_EQ(names[0], "protobuf_unittest.TestMutualRecursionA");
+  EXPECT_EQ(names[1], "protobuf_unittest.TestMutualRecursionA.SubGroup");
+  EXPECT_EQ(names[2], "protobuf_unittest.TestMutualRecursionA.SubMessage");
+  EXPECT_EQ(names[3], "protobuf_unittest.TestMutualRecursionB");
+
+  MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc);
+  EXPECT_EQ(result.is_recursive, true);
+  EXPECT_EQ(result.contains_required, false);
+  EXPECT_EQ(result.contains_cord, true);  // TestAllTypes
+  EXPECT_EQ(result.contains_extension, false);  // TestAllTypes
+}
+
+TEST(HelpersTest, TestSCCAnalysis) {
+  {
+    protobuf_unittest::TestRecursiveMessage msg;
+    SCCAnalyzer scc_analyzer((Options()));
+    const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor());
+    MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc);
+    EXPECT_EQ(result.is_recursive, true);
+    EXPECT_EQ(result.contains_required, false);
+    EXPECT_EQ(result.contains_cord, false);
+    EXPECT_EQ(result.contains_extension, false);
+  }
+  {
+    protobuf_unittest::TestAllExtensions msg;
+    SCCAnalyzer scc_analyzer((Options()));
+    const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor());
+    MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc);
+    EXPECT_EQ(result.is_recursive, false);
+    EXPECT_EQ(result.contains_required, false);
+    EXPECT_EQ(result.contains_cord, false);
+    EXPECT_EQ(result.contains_extension, true);
+  }
+  {
+    protobuf_unittest::TestRequired msg;
+    SCCAnalyzer scc_analyzer((Options()));
+    const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor());
+    MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc);
+    EXPECT_EQ(result.is_recursive, false);
+    EXPECT_EQ(result.contains_required, true);
+    EXPECT_EQ(result.contains_cord, false);
+    EXPECT_EQ(result.contains_extension, false);
+  }
+}
+
 }  // namespace cpp_unittest
 }  // namespace cpp
 }  // namespace compiler
diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc
index 462748b..844edc1 100644
--- a/src/google/protobuf/compiler/importer.cc
+++ b/src/google/protobuf/compiler/importer.cc
@@ -222,6 +222,7 @@
   pool_.ClearUnusedImportTrackFiles();
 }
 
+
 // ===================================================================
 
 SourceTree::~SourceTree() {}
diff --git a/src/google/protobuf/compiler/importer.h b/src/google/protobuf/compiler/importer.h
index 759636e..a4ffcf8 100644
--- a/src/google/protobuf/compiler/importer.h
+++ b/src/google/protobuf/compiler/importer.h
@@ -175,6 +175,7 @@
   void AddUnusedImportTrackFile(const string& file_name);
   void ClearUnusedImportTrackFiles();
 
+
  private:
   SourceTreeDescriptorDatabase database_;
   DescriptorPool pool_;
diff --git a/src/google/protobuf/compiler/importer_unittest.cc b/src/google/protobuf/compiler/importer_unittest.cc
index 00285bc..a96ac85 100644
--- a/src/google/protobuf/compiler/importer_unittest.cc
+++ b/src/google/protobuf/compiler/importer_unittest.cc
@@ -47,11 +47,11 @@
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <google/protobuf/descriptor.h>
-#include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
 #include <google/protobuf/stubs/map_util.h>
+#include <google/protobuf/stubs/strutil.h>
 
 namespace google {
 namespace protobuf {
diff --git a/src/google/protobuf/compiler/java/java_enum_field_lite.cc b/src/google/protobuf/compiler/java/java_enum_field_lite.cc
index 50eed5d..1eefdcf 100644
--- a/src/google/protobuf/compiler/java/java_enum_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc
@@ -314,6 +314,7 @@
   // noop for enums
 }
 
+
 void ImmutableEnumFieldLiteGenerator::
 GenerateSerializationCode(io::Printer* printer) const {
   printer->Print(variables_,
@@ -423,6 +424,7 @@
     "}\n");
 }
 
+
 void ImmutableEnumOneofFieldLiteGenerator::
 GenerateBuilderMembers(io::Printer* printer) const {
   if (SupportFieldPresence(descriptor_->file())) {
@@ -707,6 +709,7 @@
   }
 }
 
+
 void RepeatedImmutableEnumFieldLiteGenerator::
 GenerateBuilderMembers(io::Printer* printer) const {
   WriteFieldDocComment(printer, descriptor_);
diff --git a/src/google/protobuf/compiler/java/java_enum_lite.cc b/src/google/protobuf/compiler/java/java_enum_lite.cc
index 9681592..38b054e 100644
--- a/src/google/protobuf/compiler/java/java_enum_lite.cc
+++ b/src/google/protobuf/compiler/java/java_enum_lite.cc
@@ -49,17 +49,6 @@
 namespace compiler {
 namespace java {
 
-namespace {
-bool EnumHasCustomOptions(const EnumDescriptor* descriptor) {
-  if (descriptor->options().unknown_fields().field_count() > 0) return true;
-  for (int i = 0; i < descriptor->value_count(); ++i) {
-    const EnumValueDescriptor* value = descriptor->value(i);
-    if (value->options().unknown_fields().field_count() > 0) return true;
-  }
-  return false;
-}
-}  // namespace
-
 EnumLiteGenerator::EnumLiteGenerator(const EnumDescriptor* descriptor,
                                      bool immutable_api, Context* context)
     : descriptor_(descriptor),
@@ -139,22 +128,30 @@
   // -----------------------------------------------------------------
 
   printer->Print(
-    "\n"
-    "public final int getNumber() {\n"
-    "  return value;\n"
-    "}\n"
-    "\n"
-    "/**\n"
-    " * @deprecated Use {@link #forNumber(int)} instead.\n"
-    " */\n"
-    "@java.lang.Deprecated\n"
-    "public static $classname$ valueOf(int value) {\n"
-    "  return forNumber(value);\n"
-    "}\n"
-    "\n"
-    "public static $classname$ forNumber(int value) {\n"
-    "  switch (value) {\n",
-    "classname", descriptor_->name());
+      "\n"
+      "public final int getNumber() {\n");
+  if (SupportUnknownEnumValue(descriptor_->file())) {
+    printer->Print(
+        "  if (this == UNRECOGNIZED) {\n"
+        "    throw new java.lang.IllegalArgumentException(\n"
+        "        \"Can't get the number of an unknown enum value.\");\n"
+        "  }\n");
+  }
+  printer->Print(
+      "  return value;\n"
+      "}\n"
+      "\n"
+      "/**\n"
+      " * @deprecated Use {@link #forNumber(int)} instead.\n"
+      " */\n"
+      "@java.lang.Deprecated\n"
+      "public static $classname$ valueOf(int value) {\n"
+      "  return forNumber(value);\n"
+      "}\n"
+      "\n"
+      "public static $classname$ forNumber(int value) {\n"
+      "  switch (value) {\n",
+      "classname", descriptor_->name());
   printer->Indent();
   printer->Indent();
 
diff --git a/src/google/protobuf/compiler/java/java_field.h b/src/google/protobuf/compiler/java/java_field.h
index 434e610..cc1d83d 100644
--- a/src/google/protobuf/compiler/java/java_field.h
+++ b/src/google/protobuf/compiler/java/java_field.h
@@ -119,6 +119,7 @@
   virtual void GenerateEqualsCode(io::Printer* printer) const = 0;
   virtual void GenerateHashCode(io::Printer* printer) const = 0;
 
+
   virtual string GetBoxedType() const = 0;
 
  private:
diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc
index 86719f7..0fda166 100644
--- a/src/google/protobuf/compiler/java/java_file.cc
+++ b/src/google/protobuf/compiler/java/java_file.cc
@@ -154,12 +154,6 @@
   }
 }
 
-// Compare two field descriptors, returning true if the first should come
-// before the second.
-bool CompareFieldsByName(const FieldDescriptor *a, const FieldDescriptor *b) {
-  return a->full_name() < b->full_name();
-}
-
 // Our static initialization methods can become very, very large.
 // So large that if we aren't careful we end up blowing the JVM's
 // 64K bytes of bytecode/method. Fortunately, since these static
diff --git a/src/google/protobuf/compiler/java/java_generator.cc b/src/google/protobuf/compiler/java/java_generator.cc
index 2c02d99..0214121 100644
--- a/src/google/protobuf/compiler/java/java_generator.cc
+++ b/src/google/protobuf/compiler/java/java_generator.cc
@@ -47,6 +47,7 @@
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/zero_copy_stream.h>
 #include <google/protobuf/descriptor.pb.h>
+
 #include <google/protobuf/stubs/strutil.h>
 
 namespace google {
diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc
index efb5fd4..8469740 100644
--- a/src/google/protobuf/compiler/java/java_helpers.cc
+++ b/src/google/protobuf/compiler/java/java_helpers.cc
@@ -43,6 +43,7 @@
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/stubs/hash.h>  // for hash<T *>
 
 namespace google {
 namespace protobuf {
@@ -245,6 +246,7 @@
   return name_resolver.GetClassName(descriptor, true);
 }
 
+
 string ExtraMessageInterfaces(const Descriptor* descriptor) {
   string interfaces = "// @@protoc_insertion_point(message_implements:"
       + descriptor->full_name() + ")";
diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc
index 49070ba..51bb11f 100644
--- a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc
@@ -232,6 +232,7 @@
     "}\n");
 }
 
+
 // ===================================================================
 
 ImmutableLazyMessageOneofFieldLiteGenerator::
@@ -415,6 +416,7 @@
     "}\n");
 }
 
+
 // ===================================================================
 
 RepeatedImmutableLazyMessageFieldLiteGenerator::
@@ -716,6 +718,7 @@
     "}\n");
 }
 
+
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h
index 47ebeb4..65b84fb 100644
--- a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h
@@ -68,6 +68,7 @@
   void GenerateSerializationCode(io::Printer* printer) const;
   void GenerateSerializedSizeCode(io::Printer* printer) const;
 
+
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageFieldLiteGenerator);
 };
@@ -87,6 +88,7 @@
   void GenerateSerializationCode(io::Printer* printer) const;
   void GenerateSerializedSizeCode(io::Printer* printer) const;
 
+
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageOneofFieldLiteGenerator);
 };
@@ -106,6 +108,7 @@
   void GenerateSerializationCode(io::Printer* printer) const;
   void GenerateSerializedSizeCode(io::Printer* printer) const;
 
+
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableLazyMessageFieldLiteGenerator);
 };
diff --git a/src/google/protobuf/compiler/java/java_map_field_lite.cc b/src/google/protobuf/compiler/java/java_map_field_lite.cc
index 523052c..36fa2b7 100644
--- a/src/google/protobuf/compiler/java/java_map_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_map_field_lite.cc
@@ -484,6 +484,7 @@
   }
 }
 
+
 void ImmutableMapFieldLiteGenerator::
 GenerateBuilderMembers(io::Printer* printer) const {
   printer->Print(
diff --git a/src/google/protobuf/compiler/java/java_map_field_lite.h b/src/google/protobuf/compiler/java/java_map_field_lite.h
index 63dedbc..94aa481 100644
--- a/src/google/protobuf/compiler/java/java_map_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_map_field_lite.h
@@ -62,6 +62,7 @@
   void GenerateEqualsCode(io::Printer* printer) const;
   void GenerateHashCode(io::Printer* printer) const;
 
+
   string GetBoxedType() const;
 
  private:
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index 3b8d7ab..6e3b4a7 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -686,6 +686,17 @@
   //   for code size.
   printer->Print(
     "public static $classname$ parseFrom(\n"
+    "    java.nio.ByteBuffer data)\n"
+    "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
+    "  return PARSER.parseFrom(data);\n"
+    "}\n"
+    "public static $classname$ parseFrom(\n"
+    "    java.nio.ByteBuffer data,\n"
+    "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+    "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
+    "  return PARSER.parseFrom(data, extensionRegistry);\n"
+    "}\n"
+    "public static $classname$ parseFrom(\n"
     "    com.google.protobuf.ByteString data)\n"
     "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
     "  return PARSER.parseFrom(data);\n"
diff --git a/src/google/protobuf/compiler/java/java_message_builder_lite.cc b/src/google/protobuf/compiler/java/java_message_builder_lite.cc
index 7e404ba..1ad58c0 100644
--- a/src/google/protobuf/compiler/java/java_message_builder_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_builder_lite.cc
@@ -67,13 +67,6 @@
   return SupportFieldPresence(descriptor->file()) ||
       HasRepeatedFields(descriptor);
 }
-
-string MapValueImmutableClassdName(const Descriptor* descriptor,
-                                   ClassNameResolver* name_resolver) {
-  const FieldDescriptor* value_field = descriptor->FindFieldByName("value");
-  GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type());
-  return name_resolver->GetImmutableClassName(value_field->message_type());
-}
 }  // namespace
 
 MessageBuilderLiteGenerator::MessageBuilderLiteGenerator(
diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.cc b/src/google/protobuf/compiler/java/java_message_field_lite.cc
index 0957676..c71e910 100644
--- a/src/google/protobuf/compiler/java/java_message_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_field_lite.cc
@@ -451,6 +451,7 @@
     "}\n");
 }
 
+
 void ImmutableMessageOneofFieldLiteGenerator::
 GenerateBuilderMembers(io::Printer* printer) const {
   // The comments above the methods below are based on a hypothetical
@@ -856,6 +857,7 @@
     "get$capitalized_name$FieldBuilder();\n");
 }
 
+
 void RepeatedImmutableMessageFieldLiteGenerator::
 GenerateInitializationCode(io::Printer* printer) const {
   printer->Print(variables_, "$name$_ = emptyProtobufList();\n");
diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.h b/src/google/protobuf/compiler/java/java_message_field_lite.h
index dbb263d..7c814c6 100644
--- a/src/google/protobuf/compiler/java/java_message_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_message_field_lite.h
@@ -106,6 +106,7 @@
   void GenerateSerializationCode(io::Printer* printer) const;
   void GenerateSerializedSizeCode(io::Printer* printer) const;
 
+
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageOneofFieldLiteGenerator);
 };
@@ -135,6 +136,7 @@
   void GenerateEqualsCode(io::Printer* printer) const;
   void GenerateHashCode(io::Printer* printer) const;
 
+
   string GetBoxedType() const;
 
  protected:
diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc
index e84321b..5007ece 100644
--- a/src/google/protobuf/compiler/java/java_message_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_lite.cc
@@ -398,6 +398,7 @@
 
   printer->Print(
     "}\n"
+    "// fall through\n"
     "case GET_DEFAULT_INSTANCE: {\n"
     "  return DEFAULT_INSTANCE;\n"
     "}\n"
@@ -589,6 +590,19 @@
   //   for code size.
   printer->Print(
     "public static $classname$ parseFrom(\n"
+    "    java.nio.ByteBuffer data)\n"
+    "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
+    "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+    "      DEFAULT_INSTANCE, data);\n"
+    "}\n"
+    "public static $classname$ parseFrom(\n"
+    "    java.nio.ByteBuffer data,\n"
+    "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+    "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
+    "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+    "      DEFAULT_INSTANCE, data, extensionRegistry);\n"
+    "}\n"
+    "public static $classname$ parseFrom(\n"
     "    com.google.protobuf.ByteString data)\n"
     "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
     "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
@@ -1057,21 +1071,6 @@
 
 // ===================================================================
 
-namespace {
-bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) {
-  if (field->is_repeated()) {
-    return false;
-  }
-  if (SupportFieldPresence(field->file())) {
-    return true;
-  }
-  return GetJavaType(field) == JAVATYPE_MESSAGE &&
-      field->containing_oneof() == NULL;
-}
-}  // namespace
-
-// ===================================================================
-
 void ImmutableMessageLiteGenerator::
 GenerateExtensionRegistrationCode(io::Printer* printer) {
   for (int i = 0; i < descriptor_->extension_count(); i++) {
diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
index b04bf1c..0e8e492 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
@@ -297,6 +297,7 @@
   // noop for primitives
 }
 
+
 void ImmutablePrimitiveFieldLiteGenerator::
 GenerateInitializationCode(io::Printer* printer) const {
   if (IsByteStringWithCustomDefaultValue(descriptor_)) {
@@ -747,6 +748,7 @@
   // noop for primitives
 }
 
+
 void RepeatedImmutablePrimitiveFieldLiteGenerator::
 GenerateInitializationCode(io::Printer* printer) const {
   printer->Print(variables_, "$name$_ = $empty_list$;\n");
diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.h b/src/google/protobuf/compiler/java/java_primitive_field_lite.h
index dc59f0c..93416f0 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.h
@@ -80,6 +80,7 @@
   void GenerateEqualsCode(io::Printer* printer) const;
   void GenerateHashCode(io::Printer* printer) const;
 
+
   string GetBoxedType() const;
 
  protected:
@@ -110,6 +111,7 @@
   void GenerateSerializationCode(io::Printer* printer) const;
   void GenerateSerializedSizeCode(io::Printer* printer) const;
 
+
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveOneofFieldLiteGenerator);
 };
@@ -142,6 +144,7 @@
   void GenerateEqualsCode(io::Printer* printer) const;
   void GenerateHashCode(io::Printer* printer) const;
 
+
   string GetBoxedType() const;
 
  private:
diff --git a/src/google/protobuf/compiler/java/java_string_field_lite.cc b/src/google/protobuf/compiler/java/java_string_field_lite.cc
index 138e59b..7e3ad1d 100644
--- a/src/google/protobuf/compiler/java/java_string_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_string_field_lite.cc
@@ -295,6 +295,7 @@
   // noop for strings
 }
 
+
 void ImmutableStringFieldLiteGenerator::
 GenerateInitializationCode(io::Printer* printer) const {
   printer->Print(variables_, "$name$_ = $default$;\n");
@@ -467,6 +468,7 @@
     "}\n");
 }
 
+
 void ImmutableStringOneofFieldLiteGenerator::
 GenerateBuilderMembers(io::Printer* printer) const {
   if (SupportFieldPresence(descriptor_->file())) {
@@ -763,6 +765,7 @@
   // noop for strings
 }
 
+
 void RepeatedImmutableStringFieldLiteGenerator::
 GenerateInitializationCode(io::Printer* printer) const {
   printer->Print(variables_, "$name$_ = $empty_list$;\n");
diff --git a/src/google/protobuf/compiler/java/java_string_field_lite.h b/src/google/protobuf/compiler/java/java_string_field_lite.h
index 80496c8..b7fb640 100644
--- a/src/google/protobuf/compiler/java/java_string_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_string_field_lite.h
@@ -78,6 +78,7 @@
   void GenerateEqualsCode(io::Printer* printer) const;
   void GenerateHashCode(io::Printer* printer) const;
 
+
   string GetBoxedType() const;
 
  protected:
@@ -108,6 +109,7 @@
   void GenerateSerializationCode(io::Printer* printer) const;
   void GenerateSerializedSizeCode(io::Printer* printer) const;
 
+
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringOneofFieldLiteGenerator);
 };
 
@@ -136,6 +138,7 @@
   void GenerateEqualsCode(io::Printer* printer) const;
   void GenerateHashCode(io::Printer* printer) const;
 
+
   string GetBoxedType() const;
 
  private:
diff --git a/src/google/protobuf/compiler/js/embed.cc b/src/google/protobuf/compiler/js/embed.cc
index 57d3823..a725b62 100644
--- a/src/google/protobuf/compiler/js/embed.cc
+++ b/src/google/protobuf/compiler/js/embed.cc
@@ -98,7 +98,7 @@
 
 int main(int argc, char *argv[]) {
   std::cout << "#include "
-               "<google/protobuf/compiler/js/well_known_types_embed.h>\n";
+               "\"google/protobuf/compiler/js/well_known_types_embed.h\"\n";
   std::cout << "struct FileToc well_known_types_js[] = {\n";
 
   for (int i = 1; i < argc; i++) {
diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc
index 727ed09..7c63e58 100755
--- a/src/google/protobuf/compiler/js/js_generator.cc
+++ b/src/google/protobuf/compiler/js/js_generator.cc
@@ -198,8 +198,8 @@
 
 // Returns the fully normalized JavaScript path for the given
 // file descriptor's package.
-string GetPath(const GeneratorOptions& options,
-               const FileDescriptor* file) {
+string GetFilePath(const GeneratorOptions& options,
+                   const FileDescriptor* file) {
   if (!options.namespace_prefix.empty()) {
     return options.namespace_prefix;
   } else if (!file->package().empty()) {
@@ -231,51 +231,32 @@
 string GetPrefix(const GeneratorOptions& options,
                  const FileDescriptor* file_descriptor,
                  const Descriptor* containing_type) {
-  string prefix =
-      GetPath(options, file_descriptor) + GetNestedMessageName(containing_type);
+  string prefix = GetFilePath(options, file_descriptor) +
+                  GetNestedMessageName(containing_type);
   if (!prefix.empty()) {
     prefix += ".";
   }
   return prefix;
 }
 
-
 // Returns the fully normalized JavaScript path for the given
 // message descriptor.
-string GetPath(const GeneratorOptions& options,
-               const Descriptor* descriptor) {
+string GetMessagePath(const GeneratorOptions& options,
+                      const Descriptor* descriptor) {
   return GetPrefix(
       options, descriptor->file(),
       descriptor->containing_type()) + descriptor->name();
 }
 
-
-// Returns the fully normalized JavaScript path for the given
-// field's containing message descriptor.
-string GetPath(const GeneratorOptions& options,
-               const FieldDescriptor* descriptor) {
-  return GetPath(options, descriptor->containing_type());
-}
-
 // Returns the fully normalized JavaScript path for the given
 // enumeration descriptor.
-string GetPath(const GeneratorOptions& options,
-               const EnumDescriptor* enum_descriptor) {
+string GetEnumPath(const GeneratorOptions& options,
+                   const EnumDescriptor* enum_descriptor) {
   return GetPrefix(
       options, enum_descriptor->file(),
       enum_descriptor->containing_type()) + enum_descriptor->name();
 }
 
-
-// Returns the fully normalized JavaScript path for the given
-// enumeration value descriptor.
-string GetPath(const GeneratorOptions& options,
-               const EnumValueDescriptor* value_descriptor) {
-  return GetPath(
-      options,
-      value_descriptor->type()) + "." + value_descriptor->name();
-}
-
 string MaybeCrossFileRef(const GeneratorOptions& options,
                          const FileDescriptor* from_file,
                          const Descriptor* to_message) {
@@ -288,7 +269,7 @@
            to_message->name();
   } else {
     // Within a single file we use a full name.
-    return GetPath(options, to_message);
+    return GetMessagePath(options, to_message);
   }
 }
 
@@ -413,7 +394,7 @@
 // that top-level extensions should go in.
 string GetExtensionFileName(const GeneratorOptions& options,
                             const FileDescriptor* file) {
-  return options.output_dir + "/" + ToFileName(GetPath(options, file)) +
+  return options.output_dir + "/" + ToFileName(GetFilePath(options, file)) +
          options.GetFileNameExtension();
 }
 
@@ -550,14 +531,6 @@
   return name;
 }
 
-string JSMapGetterName(const GeneratorOptions& options,
-                       const FieldDescriptor* field) {
-  return JSIdent(options, field,
-                 /* is_upper_camel = */ true,
-                 /* is_map = */ true,
-                 /* drop_list = */ false);
-}
-
 
 
 string JSOneofName(const OneofDescriptor* oneof) {
@@ -872,11 +845,11 @@
     case FieldDescriptor::TYPE_BYTES:
       return "bytes";
     case FieldDescriptor::TYPE_GROUP:
-      return GetPath(options, field->message_type());
+      return GetMessagePath(options, field->message_type());
     case FieldDescriptor::TYPE_ENUM:
-      return GetPath(options, field->enum_type());
+      return GetEnumPath(options, field->enum_type());
     case FieldDescriptor::TYPE_MESSAGE:
-      return GetPath(options, field->message_type());
+      return GetMessagePath(options, field->message_type());
     default:
       return "";
   }
@@ -925,9 +898,9 @@
     case FieldDescriptor::CPPTYPE_STRING:
       return JSStringTypeName(options, field, bytes_mode);
     case FieldDescriptor::CPPTYPE_ENUM:
-      return GetPath(options, field->enum_type());
+      return GetEnumPath(options, field->enum_type());
     case FieldDescriptor::CPPTYPE_MESSAGE:
-      return GetPath(options, field->message_type());
+      return GetMessagePath(options, field->message_type());
     default:
       return "";
   }
@@ -1111,7 +1084,7 @@
 string RepeatedFieldsArrayName(const GeneratorOptions& options,
                                const Descriptor* desc) {
   return HasRepeatedFields(options, desc)
-             ? (GetPath(options, desc) + kRepeatedFieldArrayName)
+             ? (GetMessagePath(options, desc) + kRepeatedFieldArrayName)
              : "null";
 }
 
@@ -1128,8 +1101,9 @@
 
 string OneofFieldsArrayName(const GeneratorOptions& options,
                             const Descriptor* desc) {
-  return HasOneofFields(desc) ?
-      (GetPath(options, desc) + kOneofGroupArrayName) : "null";
+  return HasOneofFields(desc)
+             ? (GetMessagePath(options, desc) + kOneofGroupArrayName)
+             : "null";
 }
 
 string RepeatedFieldNumberList(const GeneratorOptions& options,
@@ -1571,7 +1545,7 @@
     return;
   }
 
-  string name = GetPath(options, desc);
+  string name = GetMessagePath(options, desc);
   provided->insert(name);
 
   for (int i = 0; i < desc->enum_type_count(); i++) {
@@ -1588,7 +1562,7 @@
                                     io::Printer* printer,
                                     const EnumDescriptor* enumdesc,
                                     std::set<string>* provided) const {
-  string name = GetPath(options, enumdesc);
+  string name = GetEnumPath(options, enumdesc);
   provided->insert(name);
 }
 
@@ -1604,9 +1578,8 @@
       continue;
     }
 
-    string name =
-        GetPath(options, field->file()) + "." +
-        JSObjectFieldName(options, field);
+    string name = GetFilePath(options, field->file()) + "." +
+                  JSObjectFieldName(options, field);
     provided->insert(name);
   }
 }
@@ -1684,7 +1657,7 @@
       }
       if (extension->containing_type()->full_name() !=
         "google.protobuf.bridge.MessageSet") {
-        required.insert(GetPath(options, extension->containing_type()));
+        required.insert(GetMessagePath(options, extension->containing_type()));
       }
       FindRequiresForField(options, extension, &required, &forwards);
       have_extensions = true;
@@ -1805,13 +1778,13 @@
         // dependencies, as per original codegen.
         !(field->is_extension() && field->extension_scope() == NULL)) {
       if (options.add_require_for_enums) {
-        required->insert(GetPath(options, field->enum_type()));
+        required->insert(GetEnumPath(options, field->enum_type()));
       } else {
-        forwards->insert(GetPath(options, field->enum_type()));
+        forwards->insert(GetEnumPath(options, field->enum_type()));
       }
     } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
       if (!IgnoreMessage(options, field->message_type())) {
-        required->insert(GetPath(options, field->message_type()));
+        required->insert(GetMessagePath(options, field->message_type()));
       }
     }
 }
@@ -1821,7 +1794,7 @@
                                          std::set<string>* required,
                                          std::set<string>* forwards) const {
     if (field->containing_type()->full_name() != "google.protobuf.bridge.MessageSet") {
-      required->insert(GetPath(options, field->containing_type()));
+      required->insert(GetMessagePath(options, field->containing_type()));
     }
     FindRequiresForField(options, field, required, forwards);
 }
@@ -1868,7 +1841,7 @@
   }
 
   // Recurse on nested types. These must come *before* the extension-field
-  // info generation in GenerateClassRegistration so that extensions that 
+  // info generation in GenerateClassRegistration so that extensions that
   // reference nested types proceed the definitions of the nested types.
   for (int i = 0; i < desc->enum_type_count(); i++) {
     GenerateEnum(options, printer, desc->enum_type(i));
@@ -1890,7 +1863,6 @@
       }
     }
   }
-
 }
 
 void Generator::GenerateClassConstructor(const GeneratorOptions& options,
@@ -1912,7 +1884,7 @@
       " * @constructor\n"
       " */\n"
       "$classname$ = function(opt_data) {\n",
-      "classname", GetPath(options, desc));
+      "classname", GetMessagePath(options, desc));
   string message_id = GetMessageId(desc);
   printer->Print(
       "  jspb.Message.initialize(this, opt_data, $messageId$, $pivot$, "
@@ -1929,7 +1901,7 @@
       "if (goog.DEBUG && !COMPILED) {\n"
       "  $classname$.displayName = '$classname$';\n"
       "}\n",
-      "classname", GetPath(options, desc));
+      "classname", GetMessagePath(options, desc));
 }
 
 void Generator::GenerateClassFieldInfo(const GeneratorOptions& options,
@@ -1944,7 +1916,7 @@
         " */\n"
         "$classname$$rptfieldarray$ = $rptfields$;\n"
         "\n",
-        "classname", GetPath(options, desc),
+        "classname", GetMessagePath(options, desc),
         "rptfieldarray", kRepeatedFieldArrayName,
         "rptfields", RepeatedFieldNumberList(options, desc));
   }
@@ -1965,7 +1937,7 @@
         " */\n"
         "$classname$$oneofgrouparray$ = $oneofgroups$;\n"
         "\n",
-        "classname", GetPath(options, desc),
+        "classname", GetMessagePath(options, desc),
         "oneofgrouparray", kOneofGroupArrayName,
         "oneofgroups", OneofGroupList(desc));
 
@@ -1985,7 +1957,7 @@
       "\n"
       "\n"
       "$class$.prototype.messageXid = xid('$class$');\n",
-      "class", GetPath(options, desc));
+      "class", GetMessagePath(options, desc));
 }
 
 void Generator::GenerateOneofCaseDefinition(
@@ -1998,7 +1970,7 @@
       " */\n"
       "$classname$.$oneof$Case = {\n"
       "  $upcase$_NOT_SET: 0",
-      "classname", GetPath(options, oneof->containing_type()),
+      "classname", GetMessagePath(options, oneof->containing_type()),
       "oneof", JSOneofName(oneof),
       "upcase", ToEnumCase(oneof->name()));
 
@@ -2026,7 +1998,7 @@
       "computeOneofCase(this, $class$.oneofGroups_[$oneofindex$]));\n"
       "};\n"
       "\n",
-      "class", GetPath(options, oneof->containing_type()),
+      "class", GetMessagePath(options, oneof->containing_type()),
       "oneof", JSOneofName(oneof),
       "oneofindex", JSOneofIndex(oneof));
 }
@@ -2068,7 +2040,7 @@
       " */\n"
       "$classname$.toObject = function(includeInstance, msg) {\n"
       "  var f, obj = {",
-      "classname", GetPath(options, desc));
+      "classname", GetMessagePath(options, desc));
 
   bool first = true;
   for (int i = 0; i < desc->field_count(); i++) {
@@ -2100,7 +2072,7 @@
         "      $extObject$, $class$.prototype.getExtension,\n"
         "      includeInstance);\n",
         "extObject", JSExtensionsObjectName(options, desc->file(), desc),
-        "class", GetPath(options, desc));
+        "class", GetMessagePath(options, desc));
   }
 
   printer->Print(
@@ -2112,7 +2084,7 @@
       "}\n"
       "\n"
       "\n",
-      "classname", GetPath(options, desc));
+      "classname", GetMessagePath(options, desc));
 }
 
 void Generator::GenerateFieldValueExpression(io::Printer* printer,
@@ -2173,7 +2145,7 @@
     string value_to_object;
     if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
       value_to_object =
-          GetPath(options, value_field->message_type()) + ".toObject";
+          GetMessagePath(options, value_field->message_type()) + ".toObject";
     } else {
       value_to_object = "undefined";
     }
@@ -2235,7 +2207,7 @@
       " */\n"
       "$classname$.fromObject = function(obj) {\n"
       "  var f, msg = new $classname$();\n",
-      "classname", GetPath(options, desc));
+      "classname", GetMessagePath(options, desc));
 
   for (int i = 0; i < desc->field_count(); i++) {
     const FieldDescriptor* field = desc->field(i);
@@ -2263,7 +2235,7 @@
           "$fieldclass$.fromObject));\n",
           "name", JSObjectFieldName(options, field),
           "index", JSFieldIndex(field),
-          "fieldclass", GetPath(options, value_field->message_type()));
+          "fieldclass", GetMessagePath(options, value_field->message_type()));
     } else {
       // `msg` is a newly-constructed message object that has not yet built any
       // map containers wrapping underlying arrays, so we can simply directly
@@ -2354,7 +2326,7 @@
       "fielddef", FieldDefinition(options, field),
       "comment", FieldComments(field, bytes_mode),
       "type", type,
-      "class", GetPath(options, field->containing_type()),
+      "class", GetMessagePath(options, field->containing_type()),
       "name", JSGetterName(options, field, bytes_mode),
       "list", field->is_repeated() ? "List" : "",
       "suffix", JSByteGetterSuffix(bytes_mode),
@@ -2395,7 +2367,7 @@
     printer->Print(
         "$class$.prototype.get$name$ = function(opt_noLazyCreate) {\n"
         "  return /** @type {!jspb.Map<$keytype$,$valuetype$>} */ (\n",
-        "class", GetPath(options, field->containing_type()),
+        "class", GetMessagePath(options, field->containing_type()),
         "name", JSGetterName(options, field),
         "keytype", key_type,
         "valuetype", value_type);
@@ -2404,9 +2376,10 @@
         "index", JSFieldIndex(field));
 
     if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
-      printer->Print(",\n"
+      printer->Print(
+          ",\n"
           "      $messageType$",
-            "messageType", GetPath(options, value_field->message_type()));
+          "messageType", GetMessagePath(options, value_field->message_type()));
     } else {
       printer->Print(",\n"
           "      null");
@@ -2443,7 +2416,7 @@
         "};\n"
         "\n"
         "\n",
-        "class", GetPath(options, field->containing_type()),
+        "class", GetMessagePath(options, field->containing_type()),
         "name", JSGetterName(options, field),
         "type", JSFieldTypeAnnotation(options, field,
                                       /* is_setter_argument = */ false,
@@ -2464,7 +2437,7 @@
                               /* force_present = */ false,
                               /* singular_if_not_packed = */ false),
         "returndoc", JSReturnDoc(options, field),
-        "class", GetPath(options, field->containing_type()),
+        "class", GetMessagePath(options, field->containing_type()),
         "name", JSGetterName(options, field),
         "oneoftag", (field->containing_oneof() ? "Oneof" : ""),
         "repeatedtag", (field->is_repeated() ? "Repeated" : ""));
@@ -2520,7 +2493,7 @@
 
     printer->Print(
         "$class$.prototype.get$name$ = function() {\n",
-        "class", GetPath(options, field->containing_type()),
+        "class", GetMessagePath(options, field->containing_type()),
         "name", JSGetterName(options, field));
 
     if (untyped) {
@@ -2585,7 +2558,7 @@
     printer->Print(
         "$class$.prototype.set$name$ = function(value) {\n"
         "  jspb.Message.set$oneoftag$Field(this, $index$",
-        "class", GetPath(options, field->containing_type()),
+        "class", GetMessagePath(options, field->containing_type()),
         "name", JSGetterName(options, field),
         "oneoftag", (field->containing_oneof() ? "Oneof" : ""),
         "index", JSFieldIndex(field));
@@ -2626,7 +2599,7 @@
         "};\n"
         "\n"
         "\n",
-        "class", GetPath(options, field->containing_type()),
+        "class", GetMessagePath(options, field->containing_type()),
         "name", JSGetterName(options, field),
         "returnvalue", JSReturnClause(field));
   } else if (field->is_repeated() ||
@@ -2639,7 +2612,7 @@
         "};\n"
         "\n"
         "\n",
-        "class", GetPath(options, field->containing_type()),
+        "class", GetMessagePath(options, field->containing_type()),
         "name", JSGetterName(options, field),
         "clearedvalue", (field->is_repeated() ? "[]" : "undefined"),
         "returnvalue", JSReturnClause(field));
@@ -2650,7 +2623,7 @@
         "$class$.prototype.clear$name$ = function() {\n"
         "  jspb.Message.set$maybeoneof$Field(this, "
         "$index$$maybeoneofgroup$, ",
-        "class", GetPath(options, field->containing_type()),
+        "class", GetMessagePath(options, field->containing_type()),
         "name", JSGetterName(options, field),
         "maybeoneof", (field->containing_oneof() ? "Oneof" : ""),
         "maybeoneofgroup", (field->containing_oneof() ?
@@ -2676,7 +2649,7 @@
         "};\n"
         "\n"
         "\n",
-        "class", GetPath(options, field->containing_type()),
+        "class", GetMessagePath(options, field->containing_type()),
         "name", JSGetterName(options, field),
         "index", JSFieldIndex(field));
   }
@@ -2692,8 +2665,8 @@
       " */\n"
       "$class$.prototype.add$name$ = function(value, opt_index) {\n"
       "  jspb.Message.addToRepeatedField(this, $index$",
-      "class", GetPath(options, field->containing_type()), "name",
-      JSGetterName(options, field, BYTES_DEFAULT,
+      "class", GetMessagePath(options, field->containing_type()),
+      "name", JSGetterName(options, field, BYTES_DEFAULT,
                    /* drop_list = */ true),
       "optionaltype", JSTypeName(options, field, BYTES_DEFAULT), "index",
       JSFieldIndex(field));
@@ -2719,9 +2692,9 @@
       " */\n"
       "$class$.prototype.add$name$ = function(opt_value, opt_index) {\n"
       "  return jspb.Message.addTo$repeatedtag$WrapperField(",
-      "optionaltype", JSTypeName(options, field, BYTES_DEFAULT), "class",
-      GetPath(options, field->containing_type()), "name",
-      JSGetterName(options, field, BYTES_DEFAULT,
+      "optionaltype", JSTypeName(options, field, BYTES_DEFAULT),
+      "class", GetMessagePath(options, field->containing_type()),
+      "name", JSGetterName(options, field, BYTES_DEFAULT,
                    /* drop_list = */ true),
       "repeatedtag", (field->is_repeated() ? "Repeated" : ""));
 
@@ -2732,7 +2705,7 @@
       "\n",
       "index", JSFieldIndex(field), "oneofgroup",
       (field->containing_oneof() ? (", " + JSOneofArray(options, field)) : ""),
-      "ctor", GetPath(options, field->message_type()));
+      "ctor", GetMessagePath(options, field->message_type()));
 }
 
 void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options,
@@ -2758,7 +2731,7 @@
         " */\n"
         "$class$.extensions = {};\n"
         "\n",
-        "class", GetPath(options, desc));
+        "class", GetMessagePath(options, desc));
 
     printer->Print(
         "\n"
@@ -2779,7 +2752,7 @@
         " */\n"
         "$class$.extensionsBinary = {};\n"
         "\n",
-        "class", GetPath(options, desc));
+        "class", GetMessagePath(options, desc));
   }
 }
 
@@ -2817,7 +2790,7 @@
       "    }\n"
       "    var field = reader.getFieldNumber();\n"
       "    switch (field) {\n",
-      "class", GetPath(options, desc));
+      "class", GetMessagePath(options, desc));
 
   for (int i = 0; i < desc->field_count(); i++) {
     if (!IgnoreField(desc->field(i))) {
@@ -2834,7 +2807,7 @@
         "        $class$.prototype.setExtension);\n"
         "      break;\n",
         "extobj", JSExtensionsObjectName(options, desc->file(), desc),
-        "class", GetPath(options, desc));
+        "class", GetMessagePath(options, desc));
   } else {
     printer->Print(
         "      reader.skipField();\n"
@@ -2873,7 +2846,7 @@
 
     if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
       printer->Print(", $messageType$.deserializeBinaryFromReader",
-          "messageType", GetPath(options, value_field->message_type()));
+          "messageType", GetMessagePath(options, value_field->message_type()));
     }
 
     printer->Print(");\n");
@@ -2941,7 +2914,7 @@
       "$class$.serializeBinaryToWriter = function(message, "
       "writer) {\n"
       "  var f = undefined;\n",
-      "class", GetPath(options, desc));
+      "class", GetMessagePath(options, desc));
 
   for (int i = 0; i < desc->field_count(); i++) {
     if (!IgnoreField(desc->field(i))) {
@@ -2954,7 +2927,7 @@
         "  jspb.Message.serializeBinaryExtensions(message, writer,\n"
         "    $extobj$Binary, $class$.prototype.getExtension);\n",
         "extobj", JSExtensionsObjectName(options, desc->file(), desc),
-        "class", GetPath(options, desc));
+        "class", GetMessagePath(options, desc));
   }
 
   printer->Print(
@@ -3049,7 +3022,7 @@
 
     if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
       printer->Print(", $messageType$.serializeBinaryToWriter",
-          "messageType", GetPath(options, value_field->message_type()));
+          "messageType", GetMessagePath(options, value_field->message_type()));
     }
 
     printer->Print(");\n");
@@ -3088,7 +3061,7 @@
       " * @enum {number}\n"
       " */\n"
       "$name$ = {\n",
-      "name", GetPath(options, enumdesc));
+      "name", GetEnumPath(options, enumdesc));
 
   for (int i = 0; i < enumdesc->value_count(); i++) {
     const EnumValueDescriptor* value = enumdesc->value(i);
@@ -3108,9 +3081,9 @@
                                   io::Printer* printer,
                                   const FieldDescriptor* field) const {
   string extension_scope =
-      (field->extension_scope() ?
-       GetPath(options, field->extension_scope()) :
-       GetPath(options, field->file()));
+      (field->extension_scope()
+           ? GetMessagePath(options, field->extension_scope())
+           : GetFilePath(options, field->file()));
 
   printer->Print(
       "\n"
@@ -3347,7 +3320,7 @@
         IgnoreField(file->extension(i))) {
       continue;
     }
-    provided.insert(GetPath(options, file) + "." +
+    provided.insert(GetFilePath(options, file) + "." +
                     JSObjectFieldName(options, file->extension(i)));
     extensions.insert(file->extension(i));
   }
@@ -3371,7 +3344,7 @@
 
   if (options.import_style == GeneratorOptions::kImportCommonJs) {
     printer->Print("goog.object.extend(exports, $package$);\n",
-                   "package", GetPath(options, file));
+                   "package", GetFilePath(options, file));
   }
 
   // Emit well-known type methods.
diff --git a/src/google/protobuf/compiler/js/well_known_types/timestamp.js b/src/google/protobuf/compiler/js/well_known_types/timestamp.js
index 77c07bb..b7e43f1 100644
--- a/src/google/protobuf/compiler/js/well_known_types/timestamp.js
+++ b/src/google/protobuf/compiler/js/well_known_types/timestamp.js
@@ -48,7 +48,6 @@
  * @param {!Date} value The value to set.
  */
 proto.google.protobuf.Timestamp.prototype.fromDate = function(value) {
-  var millis = value.getTime();
   this.setSeconds(Math.floor(value.getTime() / 1000));
   this.setNanos(value.getMilliseconds() * 1000000);
 };
diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc
index a4b522c..0ddb99e 100644
--- a/src/google/protobuf/compiler/mock_code_generator.cc
+++ b/src/google/protobuf/compiler/mock_code_generator.cc
@@ -40,27 +40,21 @@
 #endif
 #include <vector>
 
+#include <google/protobuf/stubs/strutil.h>
+
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/testing/file.h>
+#include <google/protobuf/compiler/plugin.pb.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/zero_copy_stream.h>
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/descriptor.h>
-#include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/substitute.h>
 #include <gtest/gtest.h>
 
-#ifdef major
-#undef major
-#endif
-#ifdef minor
-#undef minor
-#endif
-#include <google/protobuf/compiler/plugin.pb.h>
-
 namespace google {
 namespace protobuf {
 namespace compiler {
diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc
index 20140f8..d5e3132 100644
--- a/src/google/protobuf/compiler/parser_unittest.cc
+++ b/src/google/protobuf/compiler/parser_unittest.cc
@@ -42,14 +42,13 @@
 
 #include <google/protobuf/compiler/parser.h>
 
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/unittest_custom_options.pb.h>
 #include <google/protobuf/io/tokenizer.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/wire_format.h>
 #include <google/protobuf/text_format.h>
-#include <google/protobuf/unittest.pb.h>
-#include <google/protobuf/unittest_custom_options.pb.h>
-#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/wire_format.h>
 #include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/stubs/map_util.h>
 
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index d044fbb..f7dc1b7 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -38,11 +38,29 @@
 
 }  // namespace
 
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+    const TableStruct::entries[] = {
+  {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+    const TableStruct::aux[] = {
+  ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+    TableStruct::schema[] = {
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+};
+
 const ::google::protobuf::uint32 TableStruct::offsets[] = {
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, _has_bits_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, major_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, minor_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, patch_),
@@ -55,6 +73,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, file_to_generate_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, parameter_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, proto_file_),
@@ -67,6 +86,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, insertion_point_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, content_),
@@ -77,6 +97,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, error_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, file_),
   0,
@@ -84,10 +105,10 @@
 };
 
 static const ::google::protobuf::internal::MigrationSchema schemas[] = {
-  { 0, 8, sizeof(Version)},
-  { 12, 20, sizeof(CodeGeneratorRequest)},
-  { 24, 31, sizeof(CodeGeneratorResponse_File)},
-  { 34, 40, sizeof(CodeGeneratorResponse)},
+  { 0, 9, sizeof(Version)},
+  { 13, 22, sizeof(CodeGeneratorRequest)},
+  { 26, 34, sizeof(CodeGeneratorResponse_File)},
+  { 37, 44, sizeof(CodeGeneratorResponse)},
 };
 
 static ::google::protobuf::Message const * const file_default_instances[] = {
@@ -246,7 +267,7 @@
 }
 const ::google::protobuf::Descriptor* Version::descriptor() {
   protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[0].descriptor;
+  return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const Version& Version::default_instance() {
@@ -369,23 +390,27 @@
 void Version::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.Version)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional int32 major = 1;
-  if (has_major()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->major(), output);
   }
 
   // optional int32 minor = 2;
-  if (has_minor()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->minor(), output);
   }
 
   // optional int32 patch = 3;
-  if (has_patch()) {
+  if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->patch(), output);
   }
 
   // optional string suffix = 4;
-  if (has_suffix()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->suffix().data(), this->suffix().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -403,25 +428,28 @@
 
 ::google::protobuf::uint8* Version::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.Version)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional int32 major = 1;
-  if (has_major()) {
+  if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->major(), target);
   }
 
   // optional int32 minor = 2;
-  if (has_minor()) {
+  if (cached_has_bits & 0x00000004u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->minor(), target);
   }
 
   // optional int32 patch = 3;
-  if (has_patch()) {
+  if (cached_has_bits & 0x00000008u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->patch(), target);
   }
 
   // optional string suffix = 4;
-  if (has_suffix()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->suffix().data(), this->suffix().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -504,20 +532,25 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.Version)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
-  if (from._has_bits_[0 / 32] & 15u) {
-    if (from.has_suffix()) {
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 15u) {
+    if (cached_has_bits & 0x00000001u) {
       set_has_suffix();
       suffix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.suffix_);
     }
-    if (from.has_major()) {
-      set_major(from.major());
+    if (cached_has_bits & 0x00000002u) {
+      major_ = from.major_;
     }
-    if (from.has_minor()) {
-      set_minor(from.minor());
+    if (cached_has_bits & 0x00000004u) {
+      minor_ = from.minor_;
     }
-    if (from.has_patch()) {
-      set_patch(from.patch());
+    if (cached_has_bits & 0x00000008u) {
+      patch_ = from.patch_;
     }
+    _has_bits_[0] |= cached_has_bits;
   }
 }
 
@@ -555,7 +588,7 @@
 
 ::google::protobuf::Metadata Version::GetMetadata() const {
   protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[0];
+  return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -665,6 +698,7 @@
 }
 #endif
 void Version::set_suffix(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_suffix();
   suffix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.Version.suffix)
@@ -759,7 +793,7 @@
 }
 const ::google::protobuf::Descriptor* CodeGeneratorRequest::descriptor() {
   protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[1].descriptor;
+  return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const CodeGeneratorRequest& CodeGeneratorRequest::default_instance() {
@@ -852,13 +886,11 @@
       case 15: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(122u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_proto_file()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -887,6 +919,9 @@
 void CodeGeneratorRequest::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.CodeGeneratorRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated string file_to_generate = 1;
   for (int i = 0, n = this->file_to_generate_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -897,8 +932,9 @@
       1, this->file_to_generate(i), output);
   }
 
+  cached_has_bits = _has_bits_[0];
   // optional string parameter = 2;
-  if (has_parameter()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->parameter().data(), this->parameter().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -908,7 +944,7 @@
   }
 
   // optional .google.protobuf.compiler.Version compiler_version = 3;
-  if (has_compiler_version()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
       3, *this->compiler_version_, output);
   }
@@ -928,8 +964,10 @@
 
 ::google::protobuf::uint8* CodeGeneratorRequest::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated string file_to_generate = 1;
   for (int i = 0, n = this->file_to_generate_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -940,8 +978,9 @@
       WriteStringToArray(1, this->file_to_generate(i), target);
   }
 
+  cached_has_bits = _has_bits_[0];
   // optional string parameter = 2;
-  if (has_parameter()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->parameter().data(), this->parameter().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -952,17 +991,17 @@
   }
 
   // optional .google.protobuf.compiler.Version compiler_version = 3;
-  if (has_compiler_version()) {
+  if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        3, *this->compiler_version_, false, target);
+        3, *this->compiler_version_, deterministic, target);
   }
 
   // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
   for (unsigned int i = 0, n = this->proto_file_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        15, this->proto_file(i), false, target);
+        15, this->proto_file(i), deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -1043,14 +1082,18 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   file_to_generate_.MergeFrom(from.file_to_generate_);
   proto_file_.MergeFrom(from.proto_file_);
-  if (from._has_bits_[0 / 32] & 3u) {
-    if (from.has_parameter()) {
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 3u) {
+    if (cached_has_bits & 0x00000001u) {
       set_has_parameter();
       parameter_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.parameter_);
     }
-    if (from.has_compiler_version()) {
+    if (cached_has_bits & 0x00000002u) {
       mutable_compiler_version()->::google::protobuf::compiler::Version::MergeFrom(from.compiler_version());
     }
   }
@@ -1080,8 +1123,8 @@
   InternalSwap(other);
 }
 void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) {
-  file_to_generate_.UnsafeArenaSwap(&other->file_to_generate_);
-  proto_file_.UnsafeArenaSwap(&other->proto_file_);
+  file_to_generate_.InternalSwap(&other->file_to_generate_);
+  proto_file_.InternalSwap(&other->proto_file_);
   parameter_.Swap(&other->parameter_);
   std::swap(compiler_version_, other->compiler_version_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
@@ -1091,7 +1134,7 @@
 
 ::google::protobuf::Metadata CodeGeneratorRequest::GetMetadata() const {
   protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[1];
+  return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1123,6 +1166,7 @@
 }
 #endif
 void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   file_to_generate_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
 }
@@ -1141,11 +1185,12 @@
 }
 #if LANG_CXX11
 void CodeGeneratorRequest::add_file_to_generate(::std::string&& value) {
-  file_to_generate_.Add()->assign(std::move(value));
+  file_to_generate_.Add(std::move(value));
   // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
 }
 #endif
 void CodeGeneratorRequest::add_file_to_generate(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   file_to_generate_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
 }
@@ -1196,6 +1241,7 @@
 }
 #endif
 void CodeGeneratorRequest::set_parameter(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_parameter();
   parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.parameter)
@@ -1365,7 +1411,7 @@
 }
 const ::google::protobuf::Descriptor* CodeGeneratorResponse_File::descriptor() {
   protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[2].descriptor;
+  return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const CodeGeneratorResponse_File& CodeGeneratorResponse_File::default_instance() {
@@ -1484,8 +1530,12 @@
 void CodeGeneratorResponse_File::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.CodeGeneratorResponse.File)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -1495,7 +1545,7 @@
   }
 
   // optional string insertion_point = 2;
-  if (has_insertion_point()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->insertion_point().data(), this->insertion_point().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -1505,7 +1555,7 @@
   }
 
   // optional string content = 15;
-  if (has_content()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->content().data(), this->content().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -1523,10 +1573,13 @@
 
 ::google::protobuf::uint8* CodeGeneratorResponse_File::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse.File)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -1537,7 +1590,7 @@
   }
 
   // optional string insertion_point = 2;
-  if (has_insertion_point()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->insertion_point().data(), this->insertion_point().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -1548,7 +1601,7 @@
   }
 
   // optional string content = 15;
-  if (has_content()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->content().data(), this->content().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -1624,16 +1677,20 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
-  if (from._has_bits_[0 / 32] & 7u) {
-    if (from.has_name()) {
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 7u) {
+    if (cached_has_bits & 0x00000001u) {
       set_has_name();
       name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
     }
-    if (from.has_insertion_point()) {
+    if (cached_has_bits & 0x00000002u) {
       set_has_insertion_point();
       insertion_point_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.insertion_point_);
     }
-    if (from.has_content()) {
+    if (cached_has_bits & 0x00000004u) {
       set_has_content();
       content_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.content_);
     }
@@ -1673,7 +1730,7 @@
 
 ::google::protobuf::Metadata CodeGeneratorResponse_File::GetMetadata() const {
   protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[2];
+  return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1711,6 +1768,7 @@
 }
 #endif
 void CodeGeneratorResponse_File::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.name)
@@ -1773,6 +1831,7 @@
 }
 #endif
 void CodeGeneratorResponse_File::set_insertion_point(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -1835,6 +1894,7 @@
 }
 #endif
 void CodeGeneratorResponse_File::set_content(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_content();
   content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.content)
@@ -1917,7 +1977,7 @@
 }
 const ::google::protobuf::Descriptor* CodeGeneratorResponse::descriptor() {
   protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[3].descriptor;
+  return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const CodeGeneratorResponse& CodeGeneratorResponse::default_instance() {
@@ -1974,13 +2034,11 @@
       case 15: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(122u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_file()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -2009,8 +2067,12 @@
 void CodeGeneratorResponse::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.CodeGeneratorResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string error = 1;
-  if (has_error()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->error().data(), this->error().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -2034,10 +2096,13 @@
 
 ::google::protobuf::uint8* CodeGeneratorResponse::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string error = 1;
-  if (has_error()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->error().data(), this->error().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -2051,7 +2116,7 @@
   for (unsigned int i = 0, n = this->file_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        15, this->file(i), false, target);
+        15, this->file(i), deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -2115,6 +2180,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   file_.MergeFrom(from.file_);
   if (from.has_error()) {
     set_has_error();
@@ -2145,7 +2213,7 @@
   InternalSwap(other);
 }
 void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) {
-  file_.UnsafeArenaSwap(&other->file_);
+  file_.InternalSwap(&other->file_);
   error_.Swap(&other->error_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
@@ -2154,7 +2222,7 @@
 
 ::google::protobuf::Metadata CodeGeneratorResponse::GetMetadata() const {
   protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[3];
+  return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -2192,6 +2260,7 @@
 }
 #endif
 void CodeGeneratorResponse::set_error(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_error();
   error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.error)
diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h
index ff8b949..c9abc25 100644
--- a/src/google/protobuf/compiler/plugin.pb.h
+++ b/src/google/protobuf/compiler/plugin.pb.h
@@ -22,6 +22,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/message.h>
@@ -137,6 +138,9 @@
 namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto {
 // Internal implementation detail -- do not call these.
 struct LIBPROTOC_EXPORT TableStruct {
+  static const ::google::protobuf::internal::ParseTableField entries[];
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+  static const ::google::protobuf::internal::ParseTable schema[];
   static const ::google::protobuf::uint32 offsets[];
   static void InitDefaultsImpl();
   static void Shutdown();
@@ -174,6 +178,8 @@
     return reinterpret_cast<const Version*>(
                &_Version_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    0;
 
   void Swap(Version* other);
 
@@ -196,11 +202,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -307,6 +308,8 @@
     return reinterpret_cast<const CodeGeneratorRequest*>(
                &_CodeGeneratorRequest_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    1;
 
   void Swap(CodeGeneratorRequest* other);
 
@@ -329,11 +332,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -458,6 +456,8 @@
     return reinterpret_cast<const CodeGeneratorResponse_File*>(
                &_CodeGeneratorResponse_File_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    2;
 
   void Swap(CodeGeneratorResponse_File* other);
 
@@ -480,11 +480,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -597,6 +592,8 @@
     return reinterpret_cast<const CodeGeneratorResponse*>(
                &_CodeGeneratorResponse_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    3;
 
   void Swap(CodeGeneratorResponse* other);
 
@@ -619,11 +616,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -798,6 +790,7 @@
 }
 #endif
 inline void Version::set_suffix(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_suffix();
   suffix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.Version.suffix)
@@ -858,6 +851,7 @@
 }
 #endif
 inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   file_to_generate_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
 }
@@ -876,11 +870,12 @@
 }
 #if LANG_CXX11
 inline void CodeGeneratorRequest::add_file_to_generate(::std::string&& value) {
-  file_to_generate_.Add()->assign(std::move(value));
+  file_to_generate_.Add(std::move(value));
   // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
 }
 #endif
 inline void CodeGeneratorRequest::add_file_to_generate(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   file_to_generate_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
 }
@@ -931,6 +926,7 @@
 }
 #endif
 inline void CodeGeneratorRequest::set_parameter(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_parameter();
   parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.parameter)
@@ -1072,6 +1068,7 @@
 }
 #endif
 inline void CodeGeneratorResponse_File::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.name)
@@ -1134,6 +1131,7 @@
 }
 #endif
 inline void CodeGeneratorResponse_File::set_insertion_point(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -1196,6 +1194,7 @@
 }
 #endif
 inline void CodeGeneratorResponse_File::set_content(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_content();
   content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.content)
@@ -1262,6 +1261,7 @@
 }
 #endif
 inline void CodeGeneratorResponse::set_error(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_error();
   error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.error)
diff --git a/src/google/protobuf/compiler/plugin.proto b/src/google/protobuf/compiler/plugin.proto
index bf91d76..f04dc73 100644
--- a/src/google/protobuf/compiler/plugin.proto
+++ b/src/google/protobuf/compiler/plugin.proto
@@ -84,6 +84,9 @@
   // the entire set into memory at once.  However, as of this writing, this
   // is not similarly optimized on protoc's end -- it will store all fields in
   // memory at once before sending them to the plugin.
+  //
+  // Type names of fields and extensions in the FileDescriptorProto are always
+  // fully qualified.
   repeated FileDescriptorProto proto_file = 15;
 
   // The version number of protocol compiler.
diff --git a/src/google/protobuf/compiler/profile.pb.cc b/src/google/protobuf/compiler/profile.pb.cc
new file mode 100644
index 0000000..c185e4f
--- /dev/null
+++ b/src/google/protobuf/compiler/profile.pb.cc
@@ -0,0 +1,1442 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/compiler/profile.proto
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include <google/protobuf/compiler/profile.pb.h>
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+class FieldAccessInfoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<FieldAccessInfo> {
+} _FieldAccessInfo_default_instance_;
+class MessageAccessInfoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<MessageAccessInfo> {
+} _MessageAccessInfo_default_instance_;
+class AccessInfoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<AccessInfo> {
+} _AccessInfo_default_instance_;
+
+namespace protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto {
+
+
+namespace {
+
+::google::protobuf::Metadata file_level_metadata[3];
+
+}  // namespace
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+    const TableStruct::entries[] = {
+  {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+    const TableStruct::aux[] = {
+  ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+    TableStruct::schema[] = {
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+};
+
+const ::google::protobuf::uint32 TableStruct::offsets[] = {
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, _has_bits_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, name_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, getters_count_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, setters_count_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, configs_count_),
+  0,
+  1,
+  2,
+  3,
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageAccessInfo, _has_bits_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageAccessInfo, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageAccessInfo, name_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageAccessInfo, count_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageAccessInfo, field_),
+  0,
+  1,
+  ~0u,
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AccessInfo, _has_bits_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AccessInfo, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AccessInfo, message_),
+  ~0u,
+};
+
+static const ::google::protobuf::internal::MigrationSchema schemas[] = {
+  { 0, 9, sizeof(FieldAccessInfo)},
+  { 13, 21, sizeof(MessageAccessInfo)},
+  { 24, 30, sizeof(AccessInfo)},
+};
+
+static ::google::protobuf::Message const * const file_default_instances[] = {
+  reinterpret_cast<const ::google::protobuf::Message*>(&_FieldAccessInfo_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&_MessageAccessInfo_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&_AccessInfo_default_instance_),
+};
+
+namespace {
+
+void protobuf_AssignDescriptors() {
+  AddDescriptors();
+  ::google::protobuf::MessageFactory* factory = NULL;
+  AssignDescriptors(
+      "google/protobuf/compiler/profile.proto", schemas, file_default_instances, TableStruct::offsets, factory,
+      file_level_metadata, NULL, NULL);
+}
+
+void protobuf_AssignDescriptorsOnce() {
+  static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+  ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
+void protobuf_RegisterTypes(const ::std::string&) {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 3);
+}
+
+}  // namespace
+
+void TableStruct::Shutdown() {
+  _FieldAccessInfo_default_instance_.Shutdown();
+  delete file_level_metadata[0].reflection;
+  _MessageAccessInfo_default_instance_.Shutdown();
+  delete file_level_metadata[1].reflection;
+  _AccessInfo_default_instance_.Shutdown();
+  delete file_level_metadata[2].reflection;
+}
+
+void TableStruct::InitDefaultsImpl() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  ::google::protobuf::internal::InitProtobufDefaults();
+  _FieldAccessInfo_default_instance_.DefaultConstruct();
+  _MessageAccessInfo_default_instance_.DefaultConstruct();
+  _AccessInfo_default_instance_.DefaultConstruct();
+}
+
+void InitDefaults() {
+  static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+  ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl);
+}
+void AddDescriptorsImpl() {
+  InitDefaults();
+  static const char descriptor[] = {
+      "\n&google/protobuf/compiler/profile.proto"
+      "\022\030google.protobuf.compiler\"d\n\017FieldAcces"
+      "sInfo\022\014\n\004name\030\001 \001(\t\022\025\n\rgetters_count\030\002 \001"
+      "(\004\022\025\n\rsetters_count\030\003 \001(\004\022\025\n\rconfigs_cou"
+      "nt\030\004 \001(\004\"j\n\021MessageAccessInfo\022\014\n\004name\030\001 "
+      "\001(\t\022\r\n\005count\030\002 \001(\004\0228\n\005field\030\003 \003(\0132).goog"
+      "le.protobuf.compiler.FieldAccessInfo\"J\n\n"
+      "AccessInfo\022<\n\007message\030\001 \003(\0132+.google.pro"
+      "tobuf.compiler.MessageAccessInfo"
+  };
+  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+      descriptor, 352);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+    "google/protobuf/compiler/profile.proto", &protobuf_RegisterTypes);
+  ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown);
+}
+
+void AddDescriptors() {
+  static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+  ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
+}
+// Force AddDescriptors() to be called at static initialization time.
+struct StaticDescriptorInitializer {
+  StaticDescriptorInitializer() {
+    AddDescriptors();
+  }
+} static_descriptor_initializer;
+
+}  // namespace protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto
+
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int FieldAccessInfo::kNameFieldNumber;
+const int FieldAccessInfo::kGettersCountFieldNumber;
+const int FieldAccessInfo::kSettersCountFieldNumber;
+const int FieldAccessInfo::kConfigsCountFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+FieldAccessInfo::FieldAccessInfo()
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
+    protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults();
+  }
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.compiler.FieldAccessInfo)
+}
+FieldAccessInfo::FieldAccessInfo(const FieldAccessInfo& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(NULL),
+      _has_bits_(from._has_bits_),
+      _cached_size_(0) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.has_name()) {
+    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+  }
+  ::memcpy(&getters_count_, &from.getters_count_,
+    reinterpret_cast<char*>(&configs_count_) -
+    reinterpret_cast<char*>(&getters_count_) + sizeof(configs_count_));
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.FieldAccessInfo)
+}
+
+void FieldAccessInfo::SharedCtor() {
+  _cached_size_ = 0;
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&getters_count_, 0, reinterpret_cast<char*>(&configs_count_) -
+    reinterpret_cast<char*>(&getters_count_) + sizeof(configs_count_));
+}
+
+FieldAccessInfo::~FieldAccessInfo() {
+  // @@protoc_insertion_point(destructor:google.protobuf.compiler.FieldAccessInfo)
+  SharedDtor();
+}
+
+void FieldAccessInfo::SharedDtor() {
+  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void FieldAccessInfo::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* FieldAccessInfo::descriptor() {
+  protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce();
+  return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
+}
+
+const FieldAccessInfo& FieldAccessInfo::default_instance() {
+  protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults();
+  return *internal_default_instance();
+}
+
+FieldAccessInfo* FieldAccessInfo::New(::google::protobuf::Arena* arena) const {
+  FieldAccessInfo* n = new FieldAccessInfo;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void FieldAccessInfo::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.FieldAccessInfo)
+  if (has_name()) {
+    GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
+    (*name_.UnsafeRawStringPointer())->clear();
+  }
+  if (_has_bits_[0 / 32] & 14u) {
+    ::memset(&getters_count_, 0, reinterpret_cast<char*>(&configs_count_) -
+      reinterpret_cast<char*>(&getters_count_) + sizeof(configs_count_));
+  }
+  _has_bits_.Clear();
+  _internal_metadata_.Clear();
+}
+
+bool FieldAccessInfo::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.compiler.FieldAccessInfo)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string name = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) ==
+            static_cast< ::google::protobuf::uint8>(10u)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->name().data(), this->name().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "google.protobuf.compiler.FieldAccessInfo.name");
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // optional uint64 getters_count = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) ==
+            static_cast< ::google::protobuf::uint8>(16u)) {
+          set_has_getters_count();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
+                 input, &getters_count_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // optional uint64 setters_count = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) ==
+            static_cast< ::google::protobuf::uint8>(24u)) {
+          set_has_setters_count();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
+                 input, &setters_count_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // optional uint64 configs_count = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) ==
+            static_cast< ::google::protobuf::uint8>(32u)) {
+          set_has_configs_count();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
+                 input, &configs_count_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.compiler.FieldAccessInfo)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.compiler.FieldAccessInfo)
+  return false;
+#undef DO_
+}
+
+void FieldAccessInfo::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.FieldAccessInfo)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
+  // optional string name = 1;
+  if (cached_has_bits & 0x00000001u) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.compiler.FieldAccessInfo.name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  // optional uint64 getters_count = 2;
+  if (cached_has_bits & 0x00000002u) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->getters_count(), output);
+  }
+
+  // optional uint64 setters_count = 3;
+  if (cached_has_bits & 0x00000004u) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->setters_count(), output);
+  }
+
+  // optional uint64 configs_count = 4;
+  if (cached_has_bits & 0x00000008u) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->configs_count(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.FieldAccessInfo)
+}
+
+::google::protobuf::uint8* FieldAccessInfo::InternalSerializeWithCachedSizesToArray(
+    bool deterministic, ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.FieldAccessInfo)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
+  // optional string name = 1;
+  if (cached_has_bits & 0x00000001u) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.compiler.FieldAccessInfo.name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  // optional uint64 getters_count = 2;
+  if (cached_has_bits & 0x00000002u) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->getters_count(), target);
+  }
+
+  // optional uint64 setters_count = 3;
+  if (cached_has_bits & 0x00000004u) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->setters_count(), target);
+  }
+
+  // optional uint64 configs_count = 4;
+  if (cached_has_bits & 0x00000008u) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->configs_count(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.FieldAccessInfo)
+  return target;
+}
+
+size_t FieldAccessInfo::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.FieldAccessInfo)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  if (_has_bits_[0 / 32] & 15u) {
+    // optional string name = 1;
+    if (has_name()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->name());
+    }
+
+    // optional uint64 getters_count = 2;
+    if (has_getters_count()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::UInt64Size(
+          this->getters_count());
+    }
+
+    // optional uint64 setters_count = 3;
+    if (has_setters_count()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::UInt64Size(
+          this->setters_count());
+    }
+
+    // optional uint64 configs_count = 4;
+    if (has_configs_count()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::UInt64Size(
+          this->configs_count());
+    }
+
+  }
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = cached_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void FieldAccessInfo::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.FieldAccessInfo)
+  GOOGLE_DCHECK_NE(&from, this);
+  const FieldAccessInfo* source =
+      ::google::protobuf::internal::DynamicCastToGenerated<const FieldAccessInfo>(
+          &from);
+  if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.FieldAccessInfo)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.FieldAccessInfo)
+    MergeFrom(*source);
+  }
+}
+
+void FieldAccessInfo::MergeFrom(const FieldAccessInfo& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.FieldAccessInfo)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 15u) {
+    if (cached_has_bits & 0x00000001u) {
+      set_has_name();
+      name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+    }
+    if (cached_has_bits & 0x00000002u) {
+      getters_count_ = from.getters_count_;
+    }
+    if (cached_has_bits & 0x00000004u) {
+      setters_count_ = from.setters_count_;
+    }
+    if (cached_has_bits & 0x00000008u) {
+      configs_count_ = from.configs_count_;
+    }
+    _has_bits_[0] |= cached_has_bits;
+  }
+}
+
+void FieldAccessInfo::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.FieldAccessInfo)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void FieldAccessInfo::CopyFrom(const FieldAccessInfo& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.FieldAccessInfo)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool FieldAccessInfo::IsInitialized() const {
+  return true;
+}
+
+void FieldAccessInfo::Swap(FieldAccessInfo* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void FieldAccessInfo::InternalSwap(FieldAccessInfo* other) {
+  name_.Swap(&other->name_);
+  std::swap(getters_count_, other->getters_count_);
+  std::swap(setters_count_, other->setters_count_);
+  std::swap(configs_count_, other->configs_count_);
+  std::swap(_has_bits_[0], other->_has_bits_[0]);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata FieldAccessInfo::GetMetadata() const {
+  protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce();
+  return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages];
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// FieldAccessInfo
+
+// optional string name = 1;
+bool FieldAccessInfo::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+void FieldAccessInfo::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+void FieldAccessInfo::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+void FieldAccessInfo::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_name();
+}
+const ::std::string& FieldAccessInfo::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.name)
+  return name_.GetNoArena();
+}
+void FieldAccessInfo::set_name(const ::std::string& value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.name)
+}
+#if LANG_CXX11
+void FieldAccessInfo::set_name(::std::string&& value) {
+  set_has_name();
+  name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.FieldAccessInfo.name)
+}
+#endif
+void FieldAccessInfo::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.FieldAccessInfo.name)
+}
+void FieldAccessInfo::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.FieldAccessInfo.name)
+}
+::std::string* FieldAccessInfo::mutable_name() {
+  set_has_name();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.FieldAccessInfo.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+::std::string* FieldAccessInfo::release_name() {
+  // @@protoc_insertion_point(field_release:google.protobuf.compiler.FieldAccessInfo.name)
+  clear_has_name();
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void FieldAccessInfo::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.FieldAccessInfo.name)
+}
+
+// optional uint64 getters_count = 2;
+bool FieldAccessInfo::has_getters_count() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+void FieldAccessInfo::set_has_getters_count() {
+  _has_bits_[0] |= 0x00000002u;
+}
+void FieldAccessInfo::clear_has_getters_count() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+void FieldAccessInfo::clear_getters_count() {
+  getters_count_ = GOOGLE_ULONGLONG(0);
+  clear_has_getters_count();
+}
+::google::protobuf::uint64 FieldAccessInfo::getters_count() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.getters_count)
+  return getters_count_;
+}
+void FieldAccessInfo::set_getters_count(::google::protobuf::uint64 value) {
+  set_has_getters_count();
+  getters_count_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.getters_count)
+}
+
+// optional uint64 setters_count = 3;
+bool FieldAccessInfo::has_setters_count() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+void FieldAccessInfo::set_has_setters_count() {
+  _has_bits_[0] |= 0x00000004u;
+}
+void FieldAccessInfo::clear_has_setters_count() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+void FieldAccessInfo::clear_setters_count() {
+  setters_count_ = GOOGLE_ULONGLONG(0);
+  clear_has_setters_count();
+}
+::google::protobuf::uint64 FieldAccessInfo::setters_count() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.setters_count)
+  return setters_count_;
+}
+void FieldAccessInfo::set_setters_count(::google::protobuf::uint64 value) {
+  set_has_setters_count();
+  setters_count_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.setters_count)
+}
+
+// optional uint64 configs_count = 4;
+bool FieldAccessInfo::has_configs_count() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+void FieldAccessInfo::set_has_configs_count() {
+  _has_bits_[0] |= 0x00000008u;
+}
+void FieldAccessInfo::clear_has_configs_count() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+void FieldAccessInfo::clear_configs_count() {
+  configs_count_ = GOOGLE_ULONGLONG(0);
+  clear_has_configs_count();
+}
+::google::protobuf::uint64 FieldAccessInfo::configs_count() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.configs_count)
+  return configs_count_;
+}
+void FieldAccessInfo::set_configs_count(::google::protobuf::uint64 value) {
+  set_has_configs_count();
+  configs_count_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.configs_count)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int MessageAccessInfo::kNameFieldNumber;
+const int MessageAccessInfo::kCountFieldNumber;
+const int MessageAccessInfo::kFieldFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+MessageAccessInfo::MessageAccessInfo()
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
+    protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults();
+  }
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.compiler.MessageAccessInfo)
+}
+MessageAccessInfo::MessageAccessInfo(const MessageAccessInfo& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(NULL),
+      _has_bits_(from._has_bits_),
+      _cached_size_(0),
+      field_(from.field_) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.has_name()) {
+    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+  }
+  count_ = from.count_;
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.MessageAccessInfo)
+}
+
+void MessageAccessInfo::SharedCtor() {
+  _cached_size_ = 0;
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  count_ = GOOGLE_ULONGLONG(0);
+}
+
+MessageAccessInfo::~MessageAccessInfo() {
+  // @@protoc_insertion_point(destructor:google.protobuf.compiler.MessageAccessInfo)
+  SharedDtor();
+}
+
+void MessageAccessInfo::SharedDtor() {
+  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void MessageAccessInfo::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* MessageAccessInfo::descriptor() {
+  protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce();
+  return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
+}
+
+const MessageAccessInfo& MessageAccessInfo::default_instance() {
+  protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults();
+  return *internal_default_instance();
+}
+
+MessageAccessInfo* MessageAccessInfo::New(::google::protobuf::Arena* arena) const {
+  MessageAccessInfo* n = new MessageAccessInfo;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void MessageAccessInfo::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.MessageAccessInfo)
+  field_.Clear();
+  if (has_name()) {
+    GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
+    (*name_.UnsafeRawStringPointer())->clear();
+  }
+  count_ = GOOGLE_ULONGLONG(0);
+  _has_bits_.Clear();
+  _internal_metadata_.Clear();
+}
+
+bool MessageAccessInfo::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.compiler.MessageAccessInfo)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string name = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) ==
+            static_cast< ::google::protobuf::uint8>(10u)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->name().data(), this->name().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "google.protobuf.compiler.MessageAccessInfo.name");
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // optional uint64 count = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) ==
+            static_cast< ::google::protobuf::uint8>(16u)) {
+          set_has_count();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
+                 input, &count_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // repeated .google.protobuf.compiler.FieldAccessInfo field = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) ==
+            static_cast< ::google::protobuf::uint8>(26u)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_field()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.compiler.MessageAccessInfo)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.compiler.MessageAccessInfo)
+  return false;
+#undef DO_
+}
+
+void MessageAccessInfo::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.MessageAccessInfo)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
+  // optional string name = 1;
+  if (cached_has_bits & 0x00000001u) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.compiler.MessageAccessInfo.name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  // optional uint64 count = 2;
+  if (cached_has_bits & 0x00000002u) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->count(), output);
+  }
+
+  // repeated .google.protobuf.compiler.FieldAccessInfo field = 3;
+  for (unsigned int i = 0, n = this->field_size(); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, this->field(i), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.MessageAccessInfo)
+}
+
+::google::protobuf::uint8* MessageAccessInfo::InternalSerializeWithCachedSizesToArray(
+    bool deterministic, ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.MessageAccessInfo)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
+  // optional string name = 1;
+  if (cached_has_bits & 0x00000001u) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.compiler.MessageAccessInfo.name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  // optional uint64 count = 2;
+  if (cached_has_bits & 0x00000002u) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->count(), target);
+  }
+
+  // repeated .google.protobuf.compiler.FieldAccessInfo field = 3;
+  for (unsigned int i = 0, n = this->field_size(); i < n; i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageNoVirtualToArray(
+        3, this->field(i), deterministic, target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.MessageAccessInfo)
+  return target;
+}
+
+size_t MessageAccessInfo::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.MessageAccessInfo)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  // repeated .google.protobuf.compiler.FieldAccessInfo field = 3;
+  {
+    unsigned int count = this->field_size();
+    total_size += 1UL * count;
+    for (unsigned int i = 0; i < count; i++) {
+      total_size +=
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          this->field(i));
+    }
+  }
+
+  if (_has_bits_[0 / 32] & 3u) {
+    // optional string name = 1;
+    if (has_name()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->name());
+    }
+
+    // optional uint64 count = 2;
+    if (has_count()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::UInt64Size(
+          this->count());
+    }
+
+  }
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = cached_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void MessageAccessInfo::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.MessageAccessInfo)
+  GOOGLE_DCHECK_NE(&from, this);
+  const MessageAccessInfo* source =
+      ::google::protobuf::internal::DynamicCastToGenerated<const MessageAccessInfo>(
+          &from);
+  if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.MessageAccessInfo)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.MessageAccessInfo)
+    MergeFrom(*source);
+  }
+}
+
+void MessageAccessInfo::MergeFrom(const MessageAccessInfo& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.MessageAccessInfo)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  field_.MergeFrom(from.field_);
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 3u) {
+    if (cached_has_bits & 0x00000001u) {
+      set_has_name();
+      name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+    }
+    if (cached_has_bits & 0x00000002u) {
+      count_ = from.count_;
+    }
+    _has_bits_[0] |= cached_has_bits;
+  }
+}
+
+void MessageAccessInfo::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.MessageAccessInfo)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void MessageAccessInfo::CopyFrom(const MessageAccessInfo& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.MessageAccessInfo)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool MessageAccessInfo::IsInitialized() const {
+  return true;
+}
+
+void MessageAccessInfo::Swap(MessageAccessInfo* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void MessageAccessInfo::InternalSwap(MessageAccessInfo* other) {
+  field_.InternalSwap(&other->field_);
+  name_.Swap(&other->name_);
+  std::swap(count_, other->count_);
+  std::swap(_has_bits_[0], other->_has_bits_[0]);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata MessageAccessInfo::GetMetadata() const {
+  protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce();
+  return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages];
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// MessageAccessInfo
+
+// optional string name = 1;
+bool MessageAccessInfo::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+void MessageAccessInfo::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+void MessageAccessInfo::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+void MessageAccessInfo::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_name();
+}
+const ::std::string& MessageAccessInfo::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.name)
+  return name_.GetNoArena();
+}
+void MessageAccessInfo::set_name(const ::std::string& value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.MessageAccessInfo.name)
+}
+#if LANG_CXX11
+void MessageAccessInfo::set_name(::std::string&& value) {
+  set_has_name();
+  name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.MessageAccessInfo.name)
+}
+#endif
+void MessageAccessInfo::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.MessageAccessInfo.name)
+}
+void MessageAccessInfo::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.MessageAccessInfo.name)
+}
+::std::string* MessageAccessInfo::mutable_name() {
+  set_has_name();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.MessageAccessInfo.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+::std::string* MessageAccessInfo::release_name() {
+  // @@protoc_insertion_point(field_release:google.protobuf.compiler.MessageAccessInfo.name)
+  clear_has_name();
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void MessageAccessInfo::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.MessageAccessInfo.name)
+}
+
+// optional uint64 count = 2;
+bool MessageAccessInfo::has_count() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+void MessageAccessInfo::set_has_count() {
+  _has_bits_[0] |= 0x00000002u;
+}
+void MessageAccessInfo::clear_has_count() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+void MessageAccessInfo::clear_count() {
+  count_ = GOOGLE_ULONGLONG(0);
+  clear_has_count();
+}
+::google::protobuf::uint64 MessageAccessInfo::count() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.count)
+  return count_;
+}
+void MessageAccessInfo::set_count(::google::protobuf::uint64 value) {
+  set_has_count();
+  count_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.MessageAccessInfo.count)
+}
+
+// repeated .google.protobuf.compiler.FieldAccessInfo field = 3;
+int MessageAccessInfo::field_size() const {
+  return field_.size();
+}
+void MessageAccessInfo::clear_field() {
+  field_.Clear();
+}
+const ::google::protobuf::compiler::FieldAccessInfo& MessageAccessInfo::field(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.field)
+  return field_.Get(index);
+}
+::google::protobuf::compiler::FieldAccessInfo* MessageAccessInfo::mutable_field(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.MessageAccessInfo.field)
+  return field_.Mutable(index);
+}
+::google::protobuf::compiler::FieldAccessInfo* MessageAccessInfo::add_field() {
+  // @@protoc_insertion_point(field_add:google.protobuf.compiler.MessageAccessInfo.field)
+  return field_.Add();
+}
+::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >*
+MessageAccessInfo::mutable_field() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.MessageAccessInfo.field)
+  return &field_;
+}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >&
+MessageAccessInfo::field() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.compiler.MessageAccessInfo.field)
+  return field_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int AccessInfo::kMessageFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+AccessInfo::AccessInfo()
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
+    protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults();
+  }
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.compiler.AccessInfo)
+}
+AccessInfo::AccessInfo(const AccessInfo& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(NULL),
+      _has_bits_(from._has_bits_),
+      _cached_size_(0),
+      message_(from.message_) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.AccessInfo)
+}
+
+void AccessInfo::SharedCtor() {
+  _cached_size_ = 0;
+}
+
+AccessInfo::~AccessInfo() {
+  // @@protoc_insertion_point(destructor:google.protobuf.compiler.AccessInfo)
+  SharedDtor();
+}
+
+void AccessInfo::SharedDtor() {
+}
+
+void AccessInfo::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* AccessInfo::descriptor() {
+  protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce();
+  return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
+}
+
+const AccessInfo& AccessInfo::default_instance() {
+  protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults();
+  return *internal_default_instance();
+}
+
+AccessInfo* AccessInfo::New(::google::protobuf::Arena* arena) const {
+  AccessInfo* n = new AccessInfo;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void AccessInfo::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.AccessInfo)
+  message_.Clear();
+  _has_bits_.Clear();
+  _internal_metadata_.Clear();
+}
+
+bool AccessInfo::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.compiler.AccessInfo)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // repeated .google.protobuf.compiler.MessageAccessInfo message = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) ==
+            static_cast< ::google::protobuf::uint8>(10u)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_message()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.compiler.AccessInfo)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.compiler.AccessInfo)
+  return false;
+#undef DO_
+}
+
+void AccessInfo::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.AccessInfo)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // repeated .google.protobuf.compiler.MessageAccessInfo message = 1;
+  for (unsigned int i = 0, n = this->message_size(); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, this->message(i), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.AccessInfo)
+}
+
+::google::protobuf::uint8* AccessInfo::InternalSerializeWithCachedSizesToArray(
+    bool deterministic, ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.AccessInfo)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // repeated .google.protobuf.compiler.MessageAccessInfo message = 1;
+  for (unsigned int i = 0, n = this->message_size(); i < n; i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageNoVirtualToArray(
+        1, this->message(i), deterministic, target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.AccessInfo)
+  return target;
+}
+
+size_t AccessInfo::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.AccessInfo)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  // repeated .google.protobuf.compiler.MessageAccessInfo message = 1;
+  {
+    unsigned int count = this->message_size();
+    total_size += 1UL * count;
+    for (unsigned int i = 0; i < count; i++) {
+      total_size +=
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          this->message(i));
+    }
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = cached_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void AccessInfo::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.AccessInfo)
+  GOOGLE_DCHECK_NE(&from, this);
+  const AccessInfo* source =
+      ::google::protobuf::internal::DynamicCastToGenerated<const AccessInfo>(
+          &from);
+  if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.AccessInfo)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.AccessInfo)
+    MergeFrom(*source);
+  }
+}
+
+void AccessInfo::MergeFrom(const AccessInfo& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.AccessInfo)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  message_.MergeFrom(from.message_);
+}
+
+void AccessInfo::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.AccessInfo)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void AccessInfo::CopyFrom(const AccessInfo& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.AccessInfo)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool AccessInfo::IsInitialized() const {
+  return true;
+}
+
+void AccessInfo::Swap(AccessInfo* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void AccessInfo::InternalSwap(AccessInfo* other) {
+  message_.InternalSwap(&other->message_);
+  std::swap(_has_bits_[0], other->_has_bits_[0]);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata AccessInfo::GetMetadata() const {
+  protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce();
+  return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages];
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// AccessInfo
+
+// repeated .google.protobuf.compiler.MessageAccessInfo message = 1;
+int AccessInfo::message_size() const {
+  return message_.size();
+}
+void AccessInfo::clear_message() {
+  message_.Clear();
+}
+const ::google::protobuf::compiler::MessageAccessInfo& AccessInfo::message(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.AccessInfo.message)
+  return message_.Get(index);
+}
+::google::protobuf::compiler::MessageAccessInfo* AccessInfo::mutable_message(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.AccessInfo.message)
+  return message_.Mutable(index);
+}
+::google::protobuf::compiler::MessageAccessInfo* AccessInfo::add_message() {
+  // @@protoc_insertion_point(field_add:google.protobuf.compiler.AccessInfo.message)
+  return message_.Add();
+}
+::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >*
+AccessInfo::mutable_message() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.AccessInfo.message)
+  return &message_;
+}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >&
+AccessInfo::message() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.compiler.AccessInfo.message)
+  return message_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
diff --git a/src/google/protobuf/compiler/profile.pb.h b/src/google/protobuf/compiler/profile.pb.h
new file mode 100644
index 0000000..c2ce5ef
--- /dev/null
+++ b/src/google/protobuf/compiler/profile.pb.h
@@ -0,0 +1,728 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/compiler/profile.proto
+
+#ifndef PROTOBUF_google_2fprotobuf_2fcompiler_2fprofile_2eproto__INCLUDED
+#define PROTOBUF_google_2fprotobuf_2fcompiler_2fprofile_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 3002000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers.  Please update
+#error your headers.
+#endif
+#if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers.  Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/metadata.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h>  // IWYU pragma: export
+#include <google/protobuf/extension_set.h>  // IWYU pragma: export
+#include <google/protobuf/unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+namespace google {
+namespace protobuf {
+namespace compiler {
+class AccessInfo;
+class AccessInfoDefaultTypeInternal;
+LIBPROTOC_EXPORT extern AccessInfoDefaultTypeInternal _AccessInfo_default_instance_;
+class FieldAccessInfo;
+class FieldAccessInfoDefaultTypeInternal;
+LIBPROTOC_EXPORT extern FieldAccessInfoDefaultTypeInternal _FieldAccessInfo_default_instance_;
+class MessageAccessInfo;
+class MessageAccessInfoDefaultTypeInternal;
+LIBPROTOC_EXPORT extern MessageAccessInfoDefaultTypeInternal _MessageAccessInfo_default_instance_;
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+namespace protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto {
+// Internal implementation detail -- do not call these.
+struct LIBPROTOC_EXPORT TableStruct {
+  static const ::google::protobuf::internal::ParseTableField entries[];
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+  static const ::google::protobuf::internal::ParseTable schema[];
+  static const ::google::protobuf::uint32 offsets[];
+  static void InitDefaultsImpl();
+  static void Shutdown();
+};
+void LIBPROTOC_EXPORT AddDescriptors();
+void LIBPROTOC_EXPORT InitDefaults();
+}  // namespace protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto
+
+// ===================================================================
+
+class LIBPROTOC_EXPORT FieldAccessInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.FieldAccessInfo) */ {
+ public:
+  FieldAccessInfo();
+  virtual ~FieldAccessInfo();
+
+  FieldAccessInfo(const FieldAccessInfo& from);
+
+  inline FieldAccessInfo& operator=(const FieldAccessInfo& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _internal_metadata_.unknown_fields();
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _internal_metadata_.mutable_unknown_fields();
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const FieldAccessInfo& default_instance();
+
+  static inline const FieldAccessInfo* internal_default_instance() {
+    return reinterpret_cast<const FieldAccessInfo*>(
+               &_FieldAccessInfo_default_instance_);
+  }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    0;
+
+  void Swap(FieldAccessInfo* other);
+
+  // implements Message ----------------------------------------------
+
+  inline FieldAccessInfo* New() const PROTOBUF_FINAL { return New(NULL); }
+
+  FieldAccessInfo* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
+  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+  void CopyFrom(const FieldAccessInfo& from);
+  void MergeFrom(const FieldAccessInfo& from);
+  void Clear() PROTOBUF_FINAL;
+  bool IsInitialized() const PROTOBUF_FINAL;
+
+  size_t ByteSizeLong() const PROTOBUF_FINAL;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
+  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const PROTOBUF_FINAL;
+  void InternalSwap(FieldAccessInfo* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return NULL;
+  }
+  inline void* MaybeArenaPtr() const {
+    return NULL;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string name = 1;
+  bool has_name() const;
+  void clear_name();
+  static const int kNameFieldNumber = 1;
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_name(::std::string&& value);
+  #endif
+  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 uint64 getters_count = 2;
+  bool has_getters_count() const;
+  void clear_getters_count();
+  static const int kGettersCountFieldNumber = 2;
+  ::google::protobuf::uint64 getters_count() const;
+  void set_getters_count(::google::protobuf::uint64 value);
+
+  // optional uint64 setters_count = 3;
+  bool has_setters_count() const;
+  void clear_setters_count();
+  static const int kSettersCountFieldNumber = 3;
+  ::google::protobuf::uint64 setters_count() const;
+  void set_setters_count(::google::protobuf::uint64 value);
+
+  // optional uint64 configs_count = 4;
+  bool has_configs_count() const;
+  void clear_configs_count();
+  static const int kConfigsCountFieldNumber = 4;
+  ::google::protobuf::uint64 configs_count() const;
+  void set_configs_count(::google::protobuf::uint64 value);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.FieldAccessInfo)
+ private:
+  void set_has_name();
+  void clear_has_name();
+  void set_has_getters_count();
+  void clear_has_getters_count();
+  void set_has_setters_count();
+  void clear_has_setters_count();
+  void set_has_configs_count();
+  void clear_has_configs_count();
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::HasBits<1> _has_bits_;
+  mutable int _cached_size_;
+  ::google::protobuf::internal::ArenaStringPtr name_;
+  ::google::protobuf::uint64 getters_count_;
+  ::google::protobuf::uint64 setters_count_;
+  ::google::protobuf::uint64 configs_count_;
+  friend struct protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::TableStruct;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOC_EXPORT MessageAccessInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.MessageAccessInfo) */ {
+ public:
+  MessageAccessInfo();
+  virtual ~MessageAccessInfo();
+
+  MessageAccessInfo(const MessageAccessInfo& from);
+
+  inline MessageAccessInfo& operator=(const MessageAccessInfo& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _internal_metadata_.unknown_fields();
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _internal_metadata_.mutable_unknown_fields();
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const MessageAccessInfo& default_instance();
+
+  static inline const MessageAccessInfo* internal_default_instance() {
+    return reinterpret_cast<const MessageAccessInfo*>(
+               &_MessageAccessInfo_default_instance_);
+  }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    1;
+
+  void Swap(MessageAccessInfo* other);
+
+  // implements Message ----------------------------------------------
+
+  inline MessageAccessInfo* New() const PROTOBUF_FINAL { return New(NULL); }
+
+  MessageAccessInfo* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
+  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+  void CopyFrom(const MessageAccessInfo& from);
+  void MergeFrom(const MessageAccessInfo& from);
+  void Clear() PROTOBUF_FINAL;
+  bool IsInitialized() const PROTOBUF_FINAL;
+
+  size_t ByteSizeLong() const PROTOBUF_FINAL;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
+  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const PROTOBUF_FINAL;
+  void InternalSwap(MessageAccessInfo* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return NULL;
+  }
+  inline void* MaybeArenaPtr() const {
+    return NULL;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // repeated .google.protobuf.compiler.FieldAccessInfo field = 3;
+  int field_size() const;
+  void clear_field();
+  static const int kFieldFieldNumber = 3;
+  const ::google::protobuf::compiler::FieldAccessInfo& field(int index) const;
+  ::google::protobuf::compiler::FieldAccessInfo* mutable_field(int index);
+  ::google::protobuf::compiler::FieldAccessInfo* add_field();
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >*
+      mutable_field();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >&
+      field() const;
+
+  // optional string name = 1;
+  bool has_name() const;
+  void clear_name();
+  static const int kNameFieldNumber = 1;
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_name(::std::string&& value);
+  #endif
+  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 uint64 count = 2;
+  bool has_count() const;
+  void clear_count();
+  static const int kCountFieldNumber = 2;
+  ::google::protobuf::uint64 count() const;
+  void set_count(::google::protobuf::uint64 value);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.MessageAccessInfo)
+ private:
+  void set_has_name();
+  void clear_has_name();
+  void set_has_count();
+  void clear_has_count();
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::HasBits<1> _has_bits_;
+  mutable int _cached_size_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo > field_;
+  ::google::protobuf::internal::ArenaStringPtr name_;
+  ::google::protobuf::uint64 count_;
+  friend struct protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::TableStruct;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOC_EXPORT AccessInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.AccessInfo) */ {
+ public:
+  AccessInfo();
+  virtual ~AccessInfo();
+
+  AccessInfo(const AccessInfo& from);
+
+  inline AccessInfo& operator=(const AccessInfo& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _internal_metadata_.unknown_fields();
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _internal_metadata_.mutable_unknown_fields();
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const AccessInfo& default_instance();
+
+  static inline const AccessInfo* internal_default_instance() {
+    return reinterpret_cast<const AccessInfo*>(
+               &_AccessInfo_default_instance_);
+  }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    2;
+
+  void Swap(AccessInfo* other);
+
+  // implements Message ----------------------------------------------
+
+  inline AccessInfo* New() const PROTOBUF_FINAL { return New(NULL); }
+
+  AccessInfo* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
+  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+  void CopyFrom(const AccessInfo& from);
+  void MergeFrom(const AccessInfo& from);
+  void Clear() PROTOBUF_FINAL;
+  bool IsInitialized() const PROTOBUF_FINAL;
+
+  size_t ByteSizeLong() const PROTOBUF_FINAL;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
+  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const PROTOBUF_FINAL;
+  void InternalSwap(AccessInfo* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return NULL;
+  }
+  inline void* MaybeArenaPtr() const {
+    return NULL;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // repeated .google.protobuf.compiler.MessageAccessInfo message = 1;
+  int message_size() const;
+  void clear_message();
+  static const int kMessageFieldNumber = 1;
+  const ::google::protobuf::compiler::MessageAccessInfo& message(int index) const;
+  ::google::protobuf::compiler::MessageAccessInfo* mutable_message(int index);
+  ::google::protobuf::compiler::MessageAccessInfo* add_message();
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >*
+      mutable_message();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >&
+      message() const;
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.AccessInfo)
+ private:
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::HasBits<1> _has_bits_;
+  mutable int _cached_size_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo > message_;
+  friend struct protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::TableStruct;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#if !PROTOBUF_INLINE_NOT_IN_HEADERS
+// FieldAccessInfo
+
+// optional string name = 1;
+inline bool FieldAccessInfo::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FieldAccessInfo::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void FieldAccessInfo::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void FieldAccessInfo::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_name();
+}
+inline const ::std::string& FieldAccessInfo::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.name)
+  return name_.GetNoArena();
+}
+inline void FieldAccessInfo::set_name(const ::std::string& value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.name)
+}
+#if LANG_CXX11
+inline void FieldAccessInfo::set_name(::std::string&& value) {
+  set_has_name();
+  name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.FieldAccessInfo.name)
+}
+#endif
+inline void FieldAccessInfo::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.FieldAccessInfo.name)
+}
+inline void FieldAccessInfo::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.FieldAccessInfo.name)
+}
+inline ::std::string* FieldAccessInfo::mutable_name() {
+  set_has_name();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.FieldAccessInfo.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* FieldAccessInfo::release_name() {
+  // @@protoc_insertion_point(field_release:google.protobuf.compiler.FieldAccessInfo.name)
+  clear_has_name();
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void FieldAccessInfo::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.FieldAccessInfo.name)
+}
+
+// optional uint64 getters_count = 2;
+inline bool FieldAccessInfo::has_getters_count() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FieldAccessInfo::set_has_getters_count() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void FieldAccessInfo::clear_has_getters_count() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void FieldAccessInfo::clear_getters_count() {
+  getters_count_ = GOOGLE_ULONGLONG(0);
+  clear_has_getters_count();
+}
+inline ::google::protobuf::uint64 FieldAccessInfo::getters_count() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.getters_count)
+  return getters_count_;
+}
+inline void FieldAccessInfo::set_getters_count(::google::protobuf::uint64 value) {
+  set_has_getters_count();
+  getters_count_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.getters_count)
+}
+
+// optional uint64 setters_count = 3;
+inline bool FieldAccessInfo::has_setters_count() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void FieldAccessInfo::set_has_setters_count() {
+  _has_bits_[0] |= 0x00000004u;
+}
+inline void FieldAccessInfo::clear_has_setters_count() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+inline void FieldAccessInfo::clear_setters_count() {
+  setters_count_ = GOOGLE_ULONGLONG(0);
+  clear_has_setters_count();
+}
+inline ::google::protobuf::uint64 FieldAccessInfo::setters_count() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.setters_count)
+  return setters_count_;
+}
+inline void FieldAccessInfo::set_setters_count(::google::protobuf::uint64 value) {
+  set_has_setters_count();
+  setters_count_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.setters_count)
+}
+
+// optional uint64 configs_count = 4;
+inline bool FieldAccessInfo::has_configs_count() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void FieldAccessInfo::set_has_configs_count() {
+  _has_bits_[0] |= 0x00000008u;
+}
+inline void FieldAccessInfo::clear_has_configs_count() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+inline void FieldAccessInfo::clear_configs_count() {
+  configs_count_ = GOOGLE_ULONGLONG(0);
+  clear_has_configs_count();
+}
+inline ::google::protobuf::uint64 FieldAccessInfo::configs_count() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.configs_count)
+  return configs_count_;
+}
+inline void FieldAccessInfo::set_configs_count(::google::protobuf::uint64 value) {
+  set_has_configs_count();
+  configs_count_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.configs_count)
+}
+
+// -------------------------------------------------------------------
+
+// MessageAccessInfo
+
+// optional string name = 1;
+inline bool MessageAccessInfo::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void MessageAccessInfo::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void MessageAccessInfo::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void MessageAccessInfo::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_name();
+}
+inline const ::std::string& MessageAccessInfo::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.name)
+  return name_.GetNoArena();
+}
+inline void MessageAccessInfo::set_name(const ::std::string& value) {
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.MessageAccessInfo.name)
+}
+#if LANG_CXX11
+inline void MessageAccessInfo::set_name(::std::string&& value) {
+  set_has_name();
+  name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.MessageAccessInfo.name)
+}
+#endif
+inline void MessageAccessInfo::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
+  set_has_name();
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.MessageAccessInfo.name)
+}
+inline void MessageAccessInfo::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.MessageAccessInfo.name)
+}
+inline ::std::string* MessageAccessInfo::mutable_name() {
+  set_has_name();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.MessageAccessInfo.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* MessageAccessInfo::release_name() {
+  // @@protoc_insertion_point(field_release:google.protobuf.compiler.MessageAccessInfo.name)
+  clear_has_name();
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void MessageAccessInfo::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.MessageAccessInfo.name)
+}
+
+// optional uint64 count = 2;
+inline bool MessageAccessInfo::has_count() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void MessageAccessInfo::set_has_count() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void MessageAccessInfo::clear_has_count() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void MessageAccessInfo::clear_count() {
+  count_ = GOOGLE_ULONGLONG(0);
+  clear_has_count();
+}
+inline ::google::protobuf::uint64 MessageAccessInfo::count() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.count)
+  return count_;
+}
+inline void MessageAccessInfo::set_count(::google::protobuf::uint64 value) {
+  set_has_count();
+  count_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.MessageAccessInfo.count)
+}
+
+// repeated .google.protobuf.compiler.FieldAccessInfo field = 3;
+inline int MessageAccessInfo::field_size() const {
+  return field_.size();
+}
+inline void MessageAccessInfo::clear_field() {
+  field_.Clear();
+}
+inline const ::google::protobuf::compiler::FieldAccessInfo& MessageAccessInfo::field(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.field)
+  return field_.Get(index);
+}
+inline ::google::protobuf::compiler::FieldAccessInfo* MessageAccessInfo::mutable_field(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.MessageAccessInfo.field)
+  return field_.Mutable(index);
+}
+inline ::google::protobuf::compiler::FieldAccessInfo* MessageAccessInfo::add_field() {
+  // @@protoc_insertion_point(field_add:google.protobuf.compiler.MessageAccessInfo.field)
+  return field_.Add();
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >*
+MessageAccessInfo::mutable_field() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.MessageAccessInfo.field)
+  return &field_;
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >&
+MessageAccessInfo::field() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.compiler.MessageAccessInfo.field)
+  return field_;
+}
+
+// -------------------------------------------------------------------
+
+// AccessInfo
+
+// repeated .google.protobuf.compiler.MessageAccessInfo message = 1;
+inline int AccessInfo::message_size() const {
+  return message_.size();
+}
+inline void AccessInfo::clear_message() {
+  message_.Clear();
+}
+inline const ::google::protobuf::compiler::MessageAccessInfo& AccessInfo::message(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.AccessInfo.message)
+  return message_.Get(index);
+}
+inline ::google::protobuf::compiler::MessageAccessInfo* AccessInfo::mutable_message(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.AccessInfo.message)
+  return message_.Mutable(index);
+}
+inline ::google::protobuf::compiler::MessageAccessInfo* AccessInfo::add_message() {
+  // @@protoc_insertion_point(field_add:google.protobuf.compiler.AccessInfo.message)
+  return message_.Add();
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >*
+AccessInfo::mutable_message() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.AccessInfo.message)
+  return &message_;
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >&
+AccessInfo::message() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.compiler.AccessInfo.message)
+  return message_;
+}
+
+#endif  // !PROTOBUF_INLINE_NOT_IN_HEADERS
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+
+#endif  // PROTOBUF_google_2fprotobuf_2fcompiler_2fprofile_2eproto__INCLUDED
diff --git a/src/google/protobuf/compiler/profile.proto b/src/google/protobuf/compiler/profile.proto
new file mode 100644
index 0000000..09ebe09
--- /dev/null
+++ b/src/google/protobuf/compiler/profile.proto
@@ -0,0 +1,68 @@
+// 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.
+
+// Author: seongkim@google.com (Seong Beom Kim)
+//
+// protoc (Protocol Compiler) can generate more efficient code
+// if it knows how a workload accesses fields of a message;
+// e.g. some much more frequently than others.
+//
+// Protos defined here describe the access information per message
+// and per field. Note that one can use any methods to collect
+// the access patterns like CPU profiling, instrumented build, etc.
+
+syntax = "proto2";
+
+package google.protobuf.compiler;
+
+// To convey the access pattern of a field, it classifies
+// the type of the accessor methods into getters, setters and
+// configs. Getters and setters read and write the field
+// respectively and other operations like checking if the field
+// exists are considered as configs.
+message FieldAccessInfo {
+  optional string name = 1;
+  optional uint64 getters_count = 2;
+  optional uint64 setters_count = 3;
+  optional uint64 configs_count = 4;
+}
+
+// "count" correlates with how many samples an access info has
+// for a message. High "count" means more confident optimization
+// based on the info.
+message MessageAccessInfo {
+  optional string name = 1;
+  optional uint64 count = 2;
+  repeated FieldAccessInfo field = 3;
+}
+
+message AccessInfo {
+  repeated MessageAccessInfo message = 1;
+}
diff --git a/src/google/protobuf/compiler/test_plugin.cc b/src/google/protobuf/compiler/test_plugin.cc
index 4830fd7..c676ce8 100644
--- a/src/google/protobuf/compiler/test_plugin.cc
+++ b/src/google/protobuf/compiler/test_plugin.cc
@@ -37,7 +37,6 @@
 #include <stdlib.h>
 #include <google/protobuf/compiler/plugin.h>
 #include <google/protobuf/compiler/mock_code_generator.h>
-#include <google/protobuf/stubs/strutil.h>
 
 int main(int argc, char* argv[]) {
 #ifdef _MSC_VER
diff --git a/src/google/protobuf/compiler/zip_writer.cc b/src/google/protobuf/compiler/zip_writer.cc
index 07d52b1..458cced 100644
--- a/src/google/protobuf/compiler/zip_writer.cc
+++ b/src/google/protobuf/compiler/zip_writer.cc
@@ -28,6 +28,36 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// 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.
+
 // Author: ambrose@google.com (Ambrose Feinstein),
 //         kenton@google.com (Kenton Varda)
 //
diff --git a/src/google/protobuf/compiler/zip_writer.h b/src/google/protobuf/compiler/zip_writer.h
index 737f4d4..03db4d5 100644
--- a/src/google/protobuf/compiler/zip_writer.h
+++ b/src/google/protobuf/compiler/zip_writer.h
@@ -28,6 +28,36 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// 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.
+
 // Author: kenton@google.com (Kenton Varda)
 
 #include <vector>
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index c87327c..6a80792 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -72,6 +72,79 @@
 
 namespace protobuf {
 
+struct Symbol {
+  enum Type {
+    NULL_SYMBOL,
+    MESSAGE,
+    FIELD,
+    ONEOF,
+    ENUM,
+    ENUM_VALUE,
+    SERVICE,
+    METHOD,
+    PACKAGE
+  };
+  Type type;
+  union {
+    const Descriptor* descriptor;
+    const FieldDescriptor* field_descriptor;
+    const OneofDescriptor* oneof_descriptor;
+    const EnumDescriptor* enum_descriptor;
+    const EnumValueDescriptor* enum_value_descriptor;
+    const ServiceDescriptor* service_descriptor;
+    const MethodDescriptor* method_descriptor;
+    const FileDescriptor* package_file_descriptor;
+  };
+
+  inline Symbol() : type(NULL_SYMBOL) { descriptor = NULL; }
+  inline bool IsNull() const { return type == NULL_SYMBOL; }
+  inline bool IsType() const { return type == MESSAGE || type == ENUM; }
+  inline bool IsAggregate() const {
+    return type == MESSAGE || type == PACKAGE || type == ENUM ||
+           type == SERVICE;
+  }
+
+#define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD) \
+  inline explicit Symbol(const TYPE* value) {   \
+    type = TYPE_CONSTANT;                       \
+    this->FIELD = value;                        \
+  }
+
+  CONSTRUCTOR(Descriptor, MESSAGE, descriptor)
+  CONSTRUCTOR(FieldDescriptor, FIELD, field_descriptor)
+  CONSTRUCTOR(OneofDescriptor, ONEOF, oneof_descriptor)
+  CONSTRUCTOR(EnumDescriptor, ENUM, enum_descriptor)
+  CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor)
+  CONSTRUCTOR(ServiceDescriptor, SERVICE, service_descriptor)
+  CONSTRUCTOR(MethodDescriptor, METHOD, method_descriptor)
+  CONSTRUCTOR(FileDescriptor, PACKAGE, package_file_descriptor)
+#undef CONSTRUCTOR
+
+  const FileDescriptor* GetFile() const {
+    switch (type) {
+      case NULL_SYMBOL:
+        return NULL;
+      case MESSAGE:
+        return descriptor->file();
+      case FIELD:
+        return field_descriptor->file();
+      case ONEOF:
+        return oneof_descriptor->containing_type()->file();
+      case ENUM:
+        return enum_descriptor->file();
+      case ENUM_VALUE:
+        return enum_value_descriptor->type()->file();
+      case SERVICE:
+        return service_descriptor->file();
+      case METHOD:
+        return method_descriptor->service()->file();
+      case PACKAGE:
+        return package_file_descriptor;
+    }
+    return NULL;
+  }
+};
+
 const FieldDescriptor::CppType
 FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = {
   static_cast<CppType>(0),  // 0 is reserved for errors
@@ -369,65 +442,6 @@
 };
 
 
-struct Symbol {
-  enum Type {
-    NULL_SYMBOL, MESSAGE, FIELD, ONEOF, ENUM, ENUM_VALUE, SERVICE, METHOD,
-    PACKAGE
-  };
-  Type type;
-  union {
-    const Descriptor* descriptor;
-    const FieldDescriptor* field_descriptor;
-    const OneofDescriptor* oneof_descriptor;
-    const EnumDescriptor* enum_descriptor;
-    const EnumValueDescriptor* enum_value_descriptor;
-    const ServiceDescriptor* service_descriptor;
-    const MethodDescriptor* method_descriptor;
-    const FileDescriptor* package_file_descriptor;
-  };
-
-  inline Symbol() : type(NULL_SYMBOL) { descriptor = NULL; }
-  inline bool IsNull() const { return type == NULL_SYMBOL; }
-  inline bool IsType() const {
-    return type == MESSAGE || type == ENUM;
-  }
-  inline bool IsAggregate() const {
-    return type == MESSAGE || type == PACKAGE
-        || type == ENUM || type == SERVICE;
-  }
-
-#define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD)  \
-  inline explicit Symbol(const TYPE* value) {    \
-    type = TYPE_CONSTANT;                        \
-    this->FIELD = value;                         \
-  }
-
-  CONSTRUCTOR(Descriptor         , MESSAGE   , descriptor             )
-  CONSTRUCTOR(FieldDescriptor    , FIELD     , field_descriptor       )
-  CONSTRUCTOR(OneofDescriptor    , ONEOF     , oneof_descriptor       )
-  CONSTRUCTOR(EnumDescriptor     , ENUM      , enum_descriptor        )
-  CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor  )
-  CONSTRUCTOR(ServiceDescriptor  , SERVICE   , service_descriptor     )
-  CONSTRUCTOR(MethodDescriptor   , METHOD    , method_descriptor      )
-  CONSTRUCTOR(FileDescriptor     , PACKAGE   , package_file_descriptor)
-#undef CONSTRUCTOR
-
-  const FileDescriptor* GetFile() const {
-    switch (type) {
-      case NULL_SYMBOL: return NULL;
-      case MESSAGE    : return descriptor           ->file();
-      case FIELD      : return field_descriptor     ->file();
-      case ONEOF      : return oneof_descriptor     ->containing_type()->file();
-      case ENUM       : return enum_descriptor      ->file();
-      case ENUM_VALUE : return enum_value_descriptor->type()->file();
-      case SERVICE    : return service_descriptor   ->file();
-      case METHOD     : return method_descriptor    ->service()->file();
-      case PACKAGE    : return package_file_descriptor;
-    }
-    return NULL;
-  }
-};
-
 const Symbol kNullSymbol;
 
 typedef hash_map<const char*, Symbol,
@@ -610,6 +624,10 @@
   // The string is initialized to the given value for convenience.
   string* AllocateString(const string& value);
 
+  // Allocate a GoogleOnceDynamic which will be destroyed when the pool is
+  // destroyed.
+  GoogleOnceDynamic* AllocateOnceDynamic();
+
   // Allocate a protocol message object.  Some older versions of GCC have
   // trouble understanding explicit template instantiations in some cases, so
   // in those cases we have to pass a dummy pointer of the right type as the
@@ -622,6 +640,8 @@
  private:
   std::vector<string*> strings_;    // All strings in the pool.
   std::vector<Message*> messages_;  // All messages in the pool.
+  std::vector<GoogleOnceDynamic*>
+      once_dynamics_;  // All GoogleOnceDynamics in the pool.
   std::vector<FileDescriptorTables*>
       file_tables_;                 // All file tables in the pool.
   std::vector<void*> allocations_;  // All other memory allocated in the pool.
@@ -632,19 +652,20 @@
 
   struct CheckPoint {
     explicit CheckPoint(const Tables* tables)
-      : strings_before_checkpoint(tables->strings_.size()),
-        messages_before_checkpoint(tables->messages_.size()),
-        file_tables_before_checkpoint(tables->file_tables_.size()),
-        allocations_before_checkpoint(tables->allocations_.size()),
-        pending_symbols_before_checkpoint(
-            tables->symbols_after_checkpoint_.size()),
-        pending_files_before_checkpoint(
-            tables->files_after_checkpoint_.size()),
-        pending_extensions_before_checkpoint(
-            tables->extensions_after_checkpoint_.size()) {
-    }
+        : strings_before_checkpoint(tables->strings_.size()),
+          messages_before_checkpoint(tables->messages_.size()),
+          once_dynamics_before_checkpoint(tables->once_dynamics_.size()),
+          file_tables_before_checkpoint(tables->file_tables_.size()),
+          allocations_before_checkpoint(tables->allocations_.size()),
+          pending_symbols_before_checkpoint(
+              tables->symbols_after_checkpoint_.size()),
+          pending_files_before_checkpoint(
+              tables->files_after_checkpoint_.size()),
+          pending_extensions_before_checkpoint(
+              tables->extensions_after_checkpoint_.size()) {}
     int strings_before_checkpoint;
     int messages_before_checkpoint;
+    int once_dynamics_before_checkpoint;
     int file_tables_before_checkpoint;
     int allocations_before_checkpoint;
     int pending_symbols_before_checkpoint;
@@ -767,6 +788,7 @@
   }
   STLDeleteElements(&strings_);
   STLDeleteElements(&file_tables_);
+  STLDeleteElements(&once_dynamics_);
 }
 
 FileDescriptorTables::FileDescriptorTables()
@@ -856,6 +878,9 @@
       messages_.begin() + checkpoint.messages_before_checkpoint,
       messages_.end());
   STLDeleteContainerPointers(
+      once_dynamics_.begin() + checkpoint.once_dynamics_before_checkpoint,
+      once_dynamics_.end());
+  STLDeleteContainerPointers(
       file_tables_.begin() + checkpoint.file_tables_before_checkpoint,
       file_tables_.end());
   for (int i = checkpoint.allocations_before_checkpoint;
@@ -866,6 +891,7 @@
 
   strings_.resize(checkpoint.strings_before_checkpoint);
   messages_.resize(checkpoint.messages_before_checkpoint);
+  once_dynamics_.resize(checkpoint.once_dynamics_before_checkpoint);
   file_tables_.resize(checkpoint.file_tables_before_checkpoint);
   allocations_.resize(checkpoint.allocations_before_checkpoint);
   checkpoints_.pop_back();
@@ -1104,6 +1130,12 @@
   return result;
 }
 
+GoogleOnceDynamic* DescriptorPool::Tables::AllocateOnceDynamic() {
+  GoogleOnceDynamic* result = new GoogleOnceDynamic();
+  once_dynamics_.push_back(result);
+  return result;
+}
+
 template<typename Type>
 Type* DescriptorPool::Tables::AllocateMessage(Type* /* dummy */) {
   Type* result = new Type;
@@ -1157,8 +1189,10 @@
     underlay_(NULL),
     tables_(new Tables),
     enforce_dependencies_(true),
+    lazily_build_dependencies_(false),
     allow_unknown_(false),
-    enforce_weak_(false) {}
+    enforce_weak_(false),
+    disallow_enforce_utf8_(false) {}
 
 DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database,
                                ErrorCollector* error_collector)
@@ -1168,8 +1202,10 @@
     underlay_(NULL),
     tables_(new Tables),
     enforce_dependencies_(true),
+    lazily_build_dependencies_(false),
     allow_unknown_(false),
-    enforce_weak_(false) {
+    enforce_weak_(false),
+    disallow_enforce_utf8_(false) {
 }
 
 DescriptorPool::DescriptorPool(const DescriptorPool* underlay)
@@ -1179,8 +1215,10 @@
     underlay_(underlay),
     tables_(new Tables),
     enforce_dependencies_(true),
+    lazily_build_dependencies_(false),
     allow_unknown_(false),
-    enforce_weak_(false) {}
+    enforce_weak_(false),
+    disallow_enforce_utf8_(false) {}
 
 DescriptorPool::~DescriptorPool() {
   if (mutex_ != NULL) delete mutex_;
@@ -1225,6 +1263,7 @@
 static void InitGeneratedPool() {
   generated_database_ = new EncodedDescriptorDatabase;
   generated_pool_ = new DescriptorPool(generated_database_);
+  generated_pool_->InternalSetLazilyBuildDependencies();
 
   internal::OnShutdown(&DeleteGeneratedPool);
 }
@@ -3023,15 +3062,16 @@
   // - Search the pool's underlay if not found in tables_.
   // - Insure that the resulting Symbol is from one of the file's declared
   //   dependencies.
-  Symbol FindSymbol(const string& name);
+  Symbol FindSymbol(const string& name, bool build_it = true);
 
   // Like FindSymbol() but does not require that the symbol is in one of the
   // file's declared dependencies.
-  Symbol FindSymbolNotEnforcingDeps(const string& name);
+  Symbol FindSymbolNotEnforcingDeps(const string& name, bool build_it = true);
 
   // This implements the body of FindSymbolNotEnforcingDeps().
   Symbol FindSymbolNotEnforcingDepsHelper(const DescriptorPool* pool,
-                                          const string& name);
+                                          const string& name,
+                                          bool build_it = true);
 
   // Like FindSymbol(), but looks up the name relative to some other symbol
   // name.  This first searches siblings of relative_to, then siblings of its
@@ -3047,31 +3087,21 @@
   // that LookupSymbol may still return a non-type symbol in LOOKUP_TYPES mode,
   // if it believes that's all it could refer to.  The caller should always
   // check that it receives the type of symbol it was expecting.
-  enum PlaceholderType {
-    PLACEHOLDER_MESSAGE,
-    PLACEHOLDER_ENUM,
-    PLACEHOLDER_EXTENDABLE_MESSAGE
-  };
   enum ResolveMode {
     LOOKUP_ALL, LOOKUP_TYPES
   };
   Symbol LookupSymbol(const string& name, const string& relative_to,
-                      PlaceholderType placeholder_type = PLACEHOLDER_MESSAGE,
-                      ResolveMode resolve_mode = LOOKUP_ALL);
+                      DescriptorPool::PlaceholderType placeholder_type =
+                          DescriptorPool::PLACEHOLDER_MESSAGE,
+                      ResolveMode resolve_mode = LOOKUP_ALL,
+                      bool build_it = true);
 
   // Like LookupSymbol() but will not return a placeholder even if
   // AllowUnknownDependencies() has been used.
   Symbol LookupSymbolNoPlaceholder(const string& name,
                                    const string& relative_to,
-                                   ResolveMode resolve_mode = LOOKUP_ALL);
-
-  // Creates a placeholder type suitable for return from LookupSymbol().  May
-  // return kNullSymbol if the name is not a valid type name.
-  Symbol NewPlaceholder(const string& name, PlaceholderType placeholder_type);
-
-  // Creates a placeholder file.  Never returns NULL.  This is used when an
-  // import is not found and AllowUnknownDependencies() is enabled.
-  FileDescriptor* NewPlaceholderFile(const string& name);
+                                   ResolveMode resolve_mode = LOOKUP_ALL,
+                                   bool build_it = true);
 
   // Calls tables_->AddSymbol() and records an error if it fails.  Returns
   // true if successful or false if failed, though most callers can ignore
@@ -3093,10 +3123,6 @@
   void ValidateSymbolName(const string& name, const string& full_name,
                           const Message& proto);
 
-  // Like ValidateSymbolName(), but the name is allowed to contain periods and
-  // an error is indicated by returning false (not recording the error).
-  bool ValidateQualifiedName(const string& name);
-
   // Used by BUILD_ARRAY macro (below) to avoid having to have the type
   // specified as a macro parameter.
   template <typename Type>
@@ -3495,7 +3521,7 @@
 }
 
 Symbol DescriptorBuilder::FindSymbolNotEnforcingDepsHelper(
-    const DescriptorPool* pool, const string& name) {
+    const DescriptorPool* pool, const string& name, bool build_it) {
   // If we are looking at an underlay, we must lock its mutex_, since we are
   // accessing the underlay's tables_ directly.
   MutexLockMaybe lock((pool == pool_) ? NULL : pool->mutex_);
@@ -3507,12 +3533,14 @@
   }
 
   if (result.IsNull()) {
-    // In theory, we shouldn't need to check fallback_database_ because the
-    // symbol should be in one of its file's direct dependencies, and we have
-    // already loaded those by the time we get here.  But we check anyway so
-    // that we can generate better error message when dependencies are missing
-    // (i.e., "missing dependency" rather than "type is not defined").
-    if (pool->TryFindSymbolInFallbackDatabase(name)) {
+    // With lazily_build_dependencies_, a symbol lookup at cross link time is
+    // not guaranteed to be successful. In most cases, build_it will be false,
+    // which intentionally prevents us from building an import until it's
+    // actually needed. In some cases, like registering an extension, we want
+    // to build the file containing the symbol, and build_it will be set.
+    // Also, build_it will be true when !lazily_build_dependencies_, to provide
+    // better error reporting of missing dependencies.
+    if (build_it && pool->TryFindSymbolInFallbackDatabase(name)) {
       result = pool->tables_->FindSymbol(name);
     }
   }
@@ -3520,17 +3548,18 @@
   return result;
 }
 
-Symbol DescriptorBuilder::FindSymbolNotEnforcingDeps(const string& name) {
-  return FindSymbolNotEnforcingDepsHelper(pool_, name);
+Symbol DescriptorBuilder::FindSymbolNotEnforcingDeps(const string& name,
+                                                     bool build_it) {
+  return FindSymbolNotEnforcingDepsHelper(pool_, name, build_it);
 }
 
-Symbol DescriptorBuilder::FindSymbol(const string& name) {
-  Symbol result = FindSymbolNotEnforcingDeps(name);
+Symbol DescriptorBuilder::FindSymbol(const string& name, bool build_it) {
+  Symbol result = FindSymbolNotEnforcingDeps(name, build_it);
 
   if (result.IsNull()) return result;
 
   if (!pool_->enforce_dependencies_) {
-    // Hack for CompilerUpgrader.
+    // Hack for CompilerUpgrader, and also used for lazily_build_dependencies_
     return result;
   }
 
@@ -3564,14 +3593,16 @@
   return kNullSymbol;
 }
 
-Symbol DescriptorBuilder::LookupSymbolNoPlaceholder(
-    const string& name, const string& relative_to, ResolveMode resolve_mode) {
+Symbol DescriptorBuilder::LookupSymbolNoPlaceholder(const string& name,
+                                                    const string& relative_to,
+                                                    ResolveMode resolve_mode,
+                                                    bool build_it) {
   possible_undeclared_dependency_ = NULL;
   undefine_resolved_name_.clear();
 
-  if (name.size() > 0 && name[0] == '.') {
+  if (!name.empty() && name[0] == '.') {
     // Fully-qualified name.
-    return FindSymbol(name.substr(1));
+    return FindSymbol(name.substr(1), build_it);
   }
 
   // If name is something like "Foo.Bar.baz", and symbols named "Foo" are
@@ -3599,7 +3630,7 @@
     // Chop off the last component of the scope.
     string::size_type dot_pos = scope_to_try.find_last_of('.');
     if (dot_pos == string::npos) {
-      return FindSymbol(name);
+      return FindSymbol(name, build_it);
     } else {
       scope_to_try.erase(dot_pos);
     }
@@ -3608,7 +3639,7 @@
     string::size_type old_size = scope_to_try.size();
     scope_to_try.append(1, '.');
     scope_to_try.append(first_part_of_name);
-    Symbol result = FindSymbol(scope_to_try);
+    Symbol result = FindSymbol(scope_to_try, build_it);
     if (!result.IsNull()) {
       if (first_part_of_name.size() < name.size()) {
         // name is a compound symbol, of which we only found the first part.
@@ -3616,7 +3647,7 @@
         if (result.IsAggregate()) {
           scope_to_try.append(name, first_part_of_name.size(),
                               name.size() - first_part_of_name.size());
-          result = FindSymbol(scope_to_try);
+          result = FindSymbol(scope_to_try, build_it);
           if (result.IsNull()) {
             undefine_resolved_name_ = scope_to_try;
           }
@@ -3640,19 +3671,49 @@
 
 Symbol DescriptorBuilder::LookupSymbol(
     const string& name, const string& relative_to,
-    PlaceholderType placeholder_type, ResolveMode resolve_mode) {
-  Symbol result = LookupSymbolNoPlaceholder(
-      name, relative_to, resolve_mode);
+    DescriptorPool::PlaceholderType placeholder_type, ResolveMode resolve_mode,
+    bool build_it) {
+  Symbol result =
+      LookupSymbolNoPlaceholder(name, relative_to, resolve_mode, build_it);
   if (result.IsNull() && pool_->allow_unknown_) {
     // Not found, but AllowUnknownDependencies() is enabled.  Return a
     // placeholder instead.
-    result = NewPlaceholder(name, placeholder_type);
+    result = pool_->NewPlaceholderWithMutexHeld(name, placeholder_type);
   }
   return result;
 }
 
-Symbol DescriptorBuilder::NewPlaceholder(const string& name,
-                                         PlaceholderType placeholder_type) {
+static bool ValidateQualifiedName(const string& name) {
+  bool last_was_period = false;
+
+  for (int i = 0; i < name.size(); i++) {
+    // I don't trust isalnum() due to locales.  :(
+    if (('a' <= name[i] && name[i] <= 'z') ||
+        ('A' <= name[i] && name[i] <= 'Z') ||
+        ('0' <= name[i] && name[i] <= '9') || (name[i] == '_')) {
+      last_was_period = false;
+    } else if (name[i] == '.') {
+      if (last_was_period) return false;
+      last_was_period = true;
+    } else {
+      return false;
+    }
+  }
+
+  return !name.empty() && !last_was_period;
+}
+
+Symbol DescriptorPool::NewPlaceholder(const string& name,
+                                      PlaceholderType placeholder_type) const {
+  MutexLockMaybe lock(mutex_);
+  return NewPlaceholderWithMutexHeld(name, placeholder_type);
+}
+
+Symbol DescriptorPool::NewPlaceholderWithMutexHeld(
+    const string& name, PlaceholderType placeholder_type) const {
+  if (mutex_) {
+    mutex_->AssertHeld();
+  }
   // Compute names.
   const string* placeholder_full_name;
   const string* placeholder_name;
@@ -3678,7 +3739,7 @@
   }
 
   // Create the placeholders.
-  FileDescriptor* placeholder_file = NewPlaceholderFile(
+  FileDescriptor* placeholder_file = NewPlaceholderFileWithMutexHeld(
       *placeholder_full_name + ".placeholder.proto");
   placeholder_file->package_ = placeholder_package;
 
@@ -3744,19 +3805,28 @@
   }
 }
 
-FileDescriptor* DescriptorBuilder::NewPlaceholderFile(
-    const string& name) {
+FileDescriptor* DescriptorPool::NewPlaceholderFile(const string& name) const {
+  MutexLockMaybe lock(mutex_);
+  return NewPlaceholderFileWithMutexHeld(name);
+}
+
+FileDescriptor* DescriptorPool::NewPlaceholderFileWithMutexHeld(
+    const string& name) const {
+  if (mutex_) {
+    mutex_->AssertHeld();
+  }
   FileDescriptor* placeholder = tables_->Allocate<FileDescriptor>();
   memset(placeholder, 0, sizeof(*placeholder));
 
   placeholder->name_ = tables_->AllocateString(name);
   placeholder->package_ = &internal::GetEmptyString();
-  placeholder->pool_ = pool_;
+  placeholder->pool_ = this;
   placeholder->options_ = &FileOptions::default_instance();
   placeholder->tables_ = &FileDescriptorTables::GetEmptyInstance();
   placeholder->source_code_info_ = &SourceCodeInfo::default_instance();
   placeholder->is_placeholder_ = true;
   placeholder->syntax_ = FileDescriptor::SYNTAX_PROTO2;
+  placeholder->finished_building_ = true;
   // All other fields are zero or NULL.
 
   return placeholder;
@@ -3850,27 +3920,6 @@
   }
 }
 
-bool DescriptorBuilder::ValidateQualifiedName(const string& name) {
-  bool last_was_period = false;
-
-  for (int i = 0; i < name.size(); i++) {
-    // I don't trust isalnum() due to locales.  :(
-    if (('a' <= name[i] && name[i] <= 'z') ||
-        ('A' <= name[i] && name[i] <= 'Z') ||
-        ('0' <= name[i] && name[i] <= '9') ||
-        (name[i] == '_')) {
-      last_was_period = false;
-    } else if (name[i] == '.') {
-      if (last_was_period) return false;
-      last_was_period = true;
-    } else {
-      return false;
-    }
-  }
-
-  return !name.empty() && !last_was_period;
-}
-
 // -------------------------------------------------------------------
 
 // This generic implementation is good for all descriptors except
@@ -4014,20 +4063,22 @@
     }
   }
 
-  // If we have a fallback_database_, attempt to load all dependencies now,
-  // before checkpointing tables_.  This avoids confusion with recursive
-  // checkpoints.
-  if (pool_->fallback_database_ != NULL) {
-    tables_->pending_files_.push_back(proto.name());
-    for (int i = 0; i < proto.dependency_size(); i++) {
-      if (tables_->FindFile(proto.dependency(i)) == NULL &&
-          (pool_->underlay_ == NULL ||
-           pool_->underlay_->FindFileByName(proto.dependency(i)) == NULL)) {
-        // We don't care what this returns since we'll find out below anyway.
-        pool_->TryFindFileInFallbackDatabase(proto.dependency(i));
+  // If we have a fallback_database_, and we aren't doing lazy import building,
+  // attempt to load all dependencies now, before checkpointing tables_.  This
+  // avoids confusion with recursive checkpoints.
+  if (!pool_->lazily_build_dependencies_) {
+    if (pool_->fallback_database_ != NULL) {
+      tables_->pending_files_.push_back(proto.name());
+      for (int i = 0; i < proto.dependency_size(); i++) {
+        if (tables_->FindFile(proto.dependency(i)) == NULL &&
+            (pool_->underlay_ == NULL ||
+             pool_->underlay_->FindFileByName(proto.dependency(i)) == NULL)) {
+          // We don't care what this returns since we'll find out below anyway.
+          pool_->TryFindFileInFallbackDatabase(proto.dependency(i));
+        }
       }
+      tables_->pending_files_.pop_back();
     }
-    tables_->pending_files_.pop_back();
   }
   return BuildFileImpl(proto);
 }
@@ -4041,6 +4092,7 @@
   file_ = result;
 
   result->is_placeholder_ = false;
+  result->finished_building_ = false;
   if (proto.has_source_code_info()) {
     SourceCodeInfo *info = tables_->AllocateMessage<SourceCodeInfo>();
     info->CopyFrom(proto.source_code_info());
@@ -4098,7 +4150,17 @@
   std::set<string> seen_dependencies;
   result->dependency_count_ = proto.dependency_size();
   result->dependencies_ =
-    tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size());
+      tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size());
+  if (pool_->lazily_build_dependencies_) {
+    result->dependencies_once_ = tables_->AllocateOnceDynamic();
+    result->dependencies_names_ =
+        tables_->AllocateArray<const string*>(proto.dependency_size());
+    memset(result->dependencies_names_, 0,
+           sizeof(*result->dependencies_names_) * proto.dependency_size());
+  } else {
+    result->dependencies_once_ = NULL;
+    result->dependencies_names_ = NULL;
+  }
   unused_dependency_.clear();
   std::set<int> weak_deps;
   for (int i = 0; i < proto.weak_dependency_size(); ++i) {
@@ -4125,9 +4187,12 @@
     if (dependency == NULL) {
       if (pool_->allow_unknown_ ||
           (!pool_->enforce_weak_ && weak_deps.find(i) != weak_deps.end())) {
-        dependency = NewPlaceholderFile(proto.dependency(i));
+        dependency =
+            pool_->NewPlaceholderFileWithMutexHeld(proto.dependency(i));
       } else {
-        AddImportError(proto, i);
+        if (!pool_->lazily_build_dependencies_) {
+          AddImportError(proto, i);
+        }
       }
     } else {
       // Add to unused_dependency_ to track unused imported files.
@@ -4141,6 +4206,10 @@
     }
 
     result->dependencies_[i] = dependency;
+    if (pool_->lazily_build_dependencies_ && !dependency) {
+      result->dependencies_names_[i] =
+          tables_->AllocateString(proto.dependency(i));
+    }
   }
 
   // Check public dependencies.
@@ -4153,7 +4222,12 @@
     if (index >= 0 && index < proto.dependency_size()) {
       result->public_dependencies_[public_dependency_count++] = index;
       // Do not track unused imported files for public import.
-      unused_dependency_.erase(result->dependency(index));
+      // Calling dependency(i) builds that file when doing lazy imports,
+      // need to avoid doing this. Unused dependency detection isn't done
+      // when building lazily, anyways.
+      if (!pool_->lazily_build_dependencies_) {
+        unused_dependency_.erase(result->dependency(index));
+      }
     } else {
       AddError(proto.name(), proto,
                DescriptorPool::ErrorCollector::OTHER,
@@ -4164,8 +4238,13 @@
 
   // Build dependency set
   dependencies_.clear();
-  for (int i = 0; i < result->dependency_count(); i++) {
-    RecordPublicDependencies(result->dependency(i));
+  // We don't/can't do proper dependency error checking when
+  // lazily_build_dependencies_, and calling dependency(i) will force
+  // a dependency to be built, which we don't want.
+  if (!pool_->lazily_build_dependencies_) {
+    for (int i = 0; i < result->dependency_count(); i++) {
+      RecordPublicDependencies(result->dependency(i));
+    }
   }
 
   // Check weak dependencies.
@@ -4215,8 +4294,9 @@
     options_to_interpret_.clear();
   }
 
-  // Validate options.
-  if (!had_errors_) {
+  // Validate options. See comments at InternalSetLazilyBuildDependencies about
+  // error checking and lazy import building.
+  if (!had_errors_ && !pool_->lazily_build_dependencies_) {
     ValidateFileOptions(result, proto);
   }
 
@@ -4229,7 +4309,9 @@
   }
 
 
-  if (!unused_dependency_.empty()) {
+  // Again, see comments at InternalSetLazilyBuildDependencies about error
+  // checking.
+  if (!unused_dependency_.empty() && !pool_->lazily_build_dependencies_) {
     LogUnusedDependency(proto, result);
   }
 
@@ -4238,6 +4320,7 @@
     return NULL;
   } else {
     tables_->ClearLastCheckpoint();
+    result->finished_building_ = true;
     return result;
   }
 }
@@ -4447,6 +4530,10 @@
   result->extension_scope_ = NULL;
   result->message_type_ = NULL;
   result->enum_type_ = NULL;
+  result->type_name_ = NULL;
+  result->type_once_ = NULL;
+  result->default_value_enum_ = NULL;
+  result->default_value_enum_name_ = NULL;
 
   result->has_default_value_ = proto.has_default_value();
   if (proto.has_default_value() && result->is_repeated()) {
@@ -4947,8 +5034,8 @@
   ValidateSymbolName(proto.name(), *full_name, proto);
 
   // These will be filled in when cross-linking.
-  result->input_type_ = NULL;
-  result->output_type_ = NULL;
+  result->input_type_.Init();
+  result->output_type_.Init();
 
   // Copy options.
   if (!proto.has_options()) {
@@ -5081,9 +5168,13 @@
     field->options_ = &FieldOptions::default_instance();
   }
 
+  // Add the field to the lowercase-name and camelcase-name tables.
+  file_tables_->AddFieldByStylizedNames(field);
+
   if (proto.has_extendee()) {
-    Symbol extendee = LookupSymbol(proto.extendee(), field->full_name(),
-                                   PLACEHOLDER_EXTENDABLE_MESSAGE);
+    Symbol extendee =
+        LookupSymbol(proto.extendee(), field->full_name(),
+                     DescriptorPool::PLACEHOLDER_EXTENDABLE_MESSAGE);
     if (extendee.IsNull()) {
       AddNotDefinedError(field->full_name(), proto,
                          DescriptorPool::ErrorCollector::EXTENDEE,
@@ -5129,9 +5220,10 @@
                           proto.has_default_value();
 
     Symbol type =
-      LookupSymbol(proto.type_name(), field->full_name(),
-                   expecting_enum ? PLACEHOLDER_ENUM : PLACEHOLDER_MESSAGE,
-                   LOOKUP_TYPES);
+        LookupSymbol(proto.type_name(), field->full_name(),
+                     expecting_enum ? DescriptorPool::PLACEHOLDER_ENUM
+                                    : DescriptorPool::PLACEHOLDER_MESSAGE,
+                     LOOKUP_TYPES, !pool_->lazily_build_dependencies_);
 
     // If the type is a weak type, we change the type to a google.protobuf.Empty field.
     if (type.IsNull() && !pool_->enforce_weak_ && proto.options().weak()) {
@@ -5139,10 +5231,35 @@
     }
 
     if (type.IsNull()) {
-      AddNotDefinedError(field->full_name(), proto,
-                         DescriptorPool::ErrorCollector::TYPE,
-                         proto.type_name());
-      return;
+      if (pool_->lazily_build_dependencies_) {
+        // Save the symbol names for later for lookup, and allocate the once
+        // object needed for the accessors.
+        string name = proto.type_name();
+        if (!pool_->enforce_weak_ && proto.options().weak()) {
+          name = kNonLinkedWeakMessageReplacementName;
+        }
+        field->type_once_ = tables_->AllocateOnceDynamic();
+        field->type_name_ = tables_->AllocateString(name);
+        if (proto.has_default_value()) {
+          field->default_value_enum_name_ =
+              tables_->AllocateString(proto.default_value());
+        }
+        // AddFieldByNumber and AddExtension are done later in this function,
+        // and can/must be done if the field type was not found. The related
+        // error checking is not necessary when in lazily_build_dependencies_
+        // mode, and can't be done without building the type's descriptor,
+        // which we don't want to do.
+        file_tables_->AddFieldByNumber(field);
+        if (field->is_extension()) {
+          tables_->AddExtension(field);
+        }
+        return;
+      } else {
+        AddNotDefinedError(field->full_name(), proto,
+                           DescriptorPool::ErrorCollector::TYPE,
+                           proto.type_name());
+        return;
+      }
     }
 
     if (!proto.has_type()) {
@@ -5238,7 +5355,10 @@
 
   // Add the field to the fields-by-number table.
   // Note:  We have to do this *after* cross-linking because extensions do not
-  //   know their containing type until now.
+  // know their containing type until now. If we're in
+  // lazily_build_dependencies_ mode, we're guaranteed there's no errors, so no
+  // risk to calling containing_type() or other accessors that will build
+  // dependencies.
   if (!file_tables_->AddFieldByNumber(field)) {
     const FieldDescriptor* conflicting_field =
       file_tables_->FindFieldByNumber(field->containing_type(),
@@ -5284,9 +5404,6 @@
       }
     }
   }
-
-  // Add the field to the lowercase-name and camelcase-name tables.
-  file_tables_->AddFieldByStylizedNames(field);
 }
 
 void DescriptorBuilder::CrossLinkEnum(
@@ -5325,30 +5442,44 @@
     method->options_ = &MethodOptions::default_instance();
   }
 
-  Symbol input_type = LookupSymbol(proto.input_type(), method->full_name());
+  Symbol input_type =
+      LookupSymbol(proto.input_type(), method->full_name(),
+                   DescriptorPool::PLACEHOLDER_MESSAGE, LOOKUP_ALL,
+                   !pool_->lazily_build_dependencies_);
   if (input_type.IsNull()) {
-    AddNotDefinedError(method->full_name(), proto,
-                       DescriptorPool::ErrorCollector::INPUT_TYPE,
-                       proto.input_type());
+    if (!pool_->lazily_build_dependencies_) {
+      AddNotDefinedError(method->full_name(), proto,
+                         DescriptorPool::ErrorCollector::INPUT_TYPE,
+                         proto.input_type());
+    } else {
+      method->input_type_.SetLazy(proto.input_type(), file_);
+    }
   } else if (input_type.type != Symbol::MESSAGE) {
     AddError(method->full_name(), proto,
              DescriptorPool::ErrorCollector::INPUT_TYPE,
              "\"" + proto.input_type() + "\" is not a message type.");
   } else {
-    method->input_type_ = input_type.descriptor;
+    method->input_type_.Set(input_type.descriptor);
   }
 
-  Symbol output_type = LookupSymbol(proto.output_type(), method->full_name());
+  Symbol output_type =
+      LookupSymbol(proto.output_type(), method->full_name(),
+                   DescriptorPool::PLACEHOLDER_MESSAGE, LOOKUP_ALL,
+                   !pool_->lazily_build_dependencies_);
   if (output_type.IsNull()) {
-    AddNotDefinedError(method->full_name(), proto,
-                       DescriptorPool::ErrorCollector::OUTPUT_TYPE,
-                       proto.output_type());
+    if (!pool_->lazily_build_dependencies_) {
+      AddNotDefinedError(method->full_name(), proto,
+                         DescriptorPool::ErrorCollector::OUTPUT_TYPE,
+                         proto.output_type());
+    } else {
+      method->output_type_.SetLazy(proto.output_type(), file_);
+    }
   } else if (output_type.type != Symbol::MESSAGE) {
     AddError(method->full_name(), proto,
              DescriptorPool::ErrorCollector::OUTPUT_TYPE,
              "\"" + proto.output_type() + "\" is not a message type.");
   } else {
-    method->output_type_ = output_type.descriptor;
+    method->output_type_.Set(output_type.descriptor);
   }
 }
 
@@ -5539,8 +5670,12 @@
   }
 }
 
+
 void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field,
     const FieldDescriptorProto& proto) {
+  if (pool_->lazily_build_dependencies_ && (!field || !field->message_type())) {
+    return;
+  }
   // Only message type fields may be lazy.
   if (field->options().lazy()) {
     if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
@@ -6553,5 +6688,165 @@
   }
 }
 
+Symbol DescriptorPool::CrossLinkOnDemandHelper(const string& name,
+                                               bool expecting_enum) const {
+  string lookup_name = name;
+  if (!lookup_name.empty() && lookup_name[0] == '.') {
+    lookup_name = lookup_name.substr(1);
+  }
+  Symbol result = tables_->FindByNameHelper(this, lookup_name);
+  return result;
+}
+
+// Handle the lazy import building for a message field whose type wasn't built
+// at cross link time. If that was the case, we saved the name of the type to
+// be looked up when the accessor for the type was called. Set type_,
+// enum_type_, message_type_, and default_value_enum_ appropriately.
+void FieldDescriptor::InternalTypeOnceInit() const {
+  GOOGLE_CHECK(file()->finished_building_ == true);
+  if (type_name_) {
+    Symbol result = file()->pool()->CrossLinkOnDemandHelper(
+        *type_name_, type_ == FieldDescriptor::TYPE_ENUM);
+    if (result.type == Symbol::MESSAGE) {
+      type_ = FieldDescriptor::TYPE_MESSAGE;
+      message_type_ = result.descriptor;
+    } else if (result.type == Symbol::ENUM) {
+      type_ = FieldDescriptor::TYPE_ENUM;
+      enum_type_ = result.enum_descriptor;
+    }
+  }
+  if (enum_type_ && !default_value_enum_) {
+    if (default_value_enum_name_) {
+      // Have to build the full name now instead of at CrossLink time,
+      // because enum_type_ may not be known at the time.
+      string name = enum_type_->full_name();
+      // Enum values reside in the same scope as the enum type.
+      string::size_type last_dot = name.find_last_of('.');
+      if (last_dot != string::npos) {
+        name = name.substr(0, last_dot) + "." + *default_value_enum_name_;
+      } else {
+        name = *default_value_enum_name_;
+      }
+      Symbol result = file()->pool()->CrossLinkOnDemandHelper(name, true);
+      if (result.type == Symbol::ENUM_VALUE) {
+        default_value_enum_ = result.enum_value_descriptor;
+      }
+    }
+    if (!default_value_enum_) {
+      // We use the first defined value as the default
+      // if a default is not explicitly defined.
+      GOOGLE_CHECK(enum_type_->value_count());
+      default_value_enum_ = enum_type_->value(0);
+    }
+  }
+}
+
+void FieldDescriptor::TypeOnceInit(const FieldDescriptor* to_init) {
+  to_init->InternalTypeOnceInit();
+}
+
+// message_type(), enum_type(), default_value_enum(), and type()
+// all share the same GoogleOnceDynamic init path to do lazy
+// import building and cross linking of a field of a message.
+const Descriptor* FieldDescriptor::message_type() const {
+  if (type_once_) {
+    type_once_->Init(&FieldDescriptor::TypeOnceInit, this);
+  }
+  return message_type_;
+}
+
+const EnumDescriptor* FieldDescriptor::enum_type() const {
+  if (type_once_) {
+    type_once_->Init(&FieldDescriptor::TypeOnceInit, this);
+  }
+  return enum_type_;
+}
+
+const EnumValueDescriptor* FieldDescriptor::default_value_enum() const {
+  if (type_once_) {
+    type_once_->Init(&FieldDescriptor::TypeOnceInit, this);
+  }
+  return default_value_enum_;
+}
+
+FieldDescriptor::Type FieldDescriptor::type() const {
+  if (type_once_) {
+    type_once_->Init(&FieldDescriptor::TypeOnceInit, this);
+  }
+  return type_;
+}
+
+void FileDescriptor::InternalDependenciesOnceInit() const {
+  GOOGLE_CHECK(finished_building_ == true);
+  for (int i = 0; i < dependency_count(); i++) {
+    if (dependencies_names_[i]) {
+      dependencies_[i] = pool_->FindFileByName(*dependencies_names_[i]);
+    }
+  }
+}
+
+void FileDescriptor::DependenciesOnceInit(const FileDescriptor* to_init) {
+  to_init->InternalDependenciesOnceInit();
+}
+
+const FileDescriptor* FileDescriptor::dependency(int index) const {
+  if (dependencies_once_) {
+    // Do once init for all indicies, as it's unlikely only a single index would
+    // be called, and saves on GoogleOnceDynamic allocations.
+    dependencies_once_->Init(&FileDescriptor::DependenciesOnceInit, this);
+  }
+  return dependencies_[index];
+}
+
+const Descriptor* MethodDescriptor::input_type() const {
+  return input_type_.Get();
+}
+
+const Descriptor* MethodDescriptor::output_type() const {
+  return output_type_.Get();
+}
+
+
+namespace internal {
+void LazyDescriptor::Set(const Descriptor* descriptor) {
+  GOOGLE_CHECK(!name_);
+  GOOGLE_CHECK(!once_);
+  GOOGLE_CHECK(!file_);
+  descriptor_ = descriptor;
+}
+
+void LazyDescriptor::SetLazy(const string& name, const FileDescriptor* file) {
+  // verify Init() has been called and Set hasn't been called yet.
+  GOOGLE_CHECK(!descriptor_);
+  GOOGLE_CHECK(!file_);
+  GOOGLE_CHECK(!name_);
+  GOOGLE_CHECK(!once_);
+  GOOGLE_CHECK(file && file->pool_);
+  GOOGLE_CHECK(file->pool_->lazily_build_dependencies_);
+  GOOGLE_CHECK(!file->finished_building_);
+  file_ = file;
+  name_ = file->pool_->tables_->AllocateString(name);
+  once_ = file->pool_->tables_->AllocateOnceDynamic();
+}
+
+void LazyDescriptor::Once() {
+  if (once_) {
+    once_->Init(&LazyDescriptor::OnceStatic, this);
+  }
+}
+
+void LazyDescriptor::OnceStatic(LazyDescriptor* lazy) { lazy->OnceInternal(); }
+
+void LazyDescriptor::OnceInternal() {
+  GOOGLE_CHECK(file_->finished_building_);
+  if (!descriptor_ && name_) {
+    Symbol result = file_->pool_->CrossLinkOnDemandHelper(*name_, false);
+    if (!result.IsNull() && result.type == Symbol::MESSAGE) {
+      descriptor_ = result.descriptor;
+    }
+  }
+}
+}  // namespace internal
+
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h
index cc09969..7aea734 100644
--- a/src/google/protobuf/descriptor.h
+++ b/src/google/protobuf/descriptor.h
@@ -63,6 +63,7 @@
 #include <vector>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/mutex.h>
+#include <google/protobuf/stubs/once.h>
 
 // TYPE_BOOL is defined in the MacOS's ConditionalMacros.h.
 #ifdef TYPE_BOOL
@@ -110,6 +111,7 @@
 // Defined in descriptor.cc
 class DescriptorBuilder;
 class FileDescriptorTables;
+struct Symbol;
 
 // Defined in unknown_field_set.h.
 class UnknownField;
@@ -165,6 +167,55 @@
         elide_oneof_body(false) {}
 };
 
+// A class to handle the simplest cases of a lazily linked descriptor
+// for a message type that isn't built at the time of cross linking,
+// which is needed when a pool has lazily_build_dependencies_ set.
+// Must be instantiated as mutable in a descriptor.
+namespace internal {
+class LIBPROTOBUF_EXPORT LazyDescriptor {
+ public:
+  // Init function to be called at init time of a descriptor containing
+  // a LazyDescriptor.
+  void Init() {
+    descriptor_ = NULL;
+    name_ = NULL;
+    once_ = NULL;
+    file_ = NULL;
+  }
+
+  // Sets the value of the descriptor if it is known during the descriptor
+  // building process. Not thread safe, should only be called during the
+  // descriptor build process. Should not be called after SetLazy has been
+  // called.
+  void Set(const Descriptor* descriptor);
+
+  // Sets the information needed to lazily cross link the descriptor at a later
+  // time, SetLazy is not thread safe, should be called only once at descriptor
+  // build time if the symbol wasn't found and building of the file containing
+  // that type is delayed because lazily_build_dependencies_ is set on the pool.
+  // Should not be called after Set() has been called.
+  void SetLazy(const string& name, const FileDescriptor* file);
+
+  // Returns the current value of the descriptor, thread-safe. If SetLazy(...)
+  // has been called, will do a one-time cross link of the type specified,
+  // building the descriptor file that contains the type if necessary.
+  inline const Descriptor* Get() {
+    Once();
+    return descriptor_;
+  }
+
+ private:
+  static void OnceStatic(LazyDescriptor* lazy);
+  void OnceInternal();
+  void Once();
+
+  const Descriptor* descriptor_;
+  const string* name_;
+  GoogleOnceDynamic* once_;
+  const FileDescriptor* file_;
+};
+}  // namespace internal
+
 // Describes a type of protocol message, or a particular group within a
 // message.  To obtain the Descriptor for a given message object, call
 // Message::GetDescriptor().  Generated message classes also have a
@@ -417,6 +468,7 @@
   // Must be constructed using DescriptorPool.
   Descriptor() {}
   friend class DescriptorBuilder;
+  friend class DescriptorPool;
   friend class EnumDescriptor;
   friend class FieldDescriptor;
   friend class OneofDescriptor;
@@ -692,16 +744,21 @@
   const string* json_name_;
   const FileDescriptor* file_;
   int number_;
-  Type type_;
+  GoogleOnceDynamic* type_once_;
+  static void TypeOnceInit(const FieldDescriptor* to_init);
+  void InternalTypeOnceInit() const;
+  mutable Type type_;
   Label label_;
   bool is_extension_;
   int index_in_oneof_;
   const Descriptor* containing_type_;
   const OneofDescriptor* containing_oneof_;
   const Descriptor* extension_scope_;
-  const Descriptor* message_type_;
-  const EnumDescriptor* enum_type_;
+  mutable const Descriptor* message_type_;
+  mutable const EnumDescriptor* enum_type_;
   const FieldOptions* options_;
+  const string* type_name_;
+  const string* default_value_enum_name_;
   // IMPORTANT:  If you add a new field, make sure to search for all instances
   // of Allocate<FieldDescriptor>() and AllocateArray<FieldDescriptor>() in
   // descriptor.cc and update them to initialize the field.
@@ -716,7 +773,7 @@
     double default_value_double_;
     bool   default_value_bool_;
 
-    const EnumValueDescriptor* default_value_enum_;
+    mutable const EnumValueDescriptor* default_value_enum_;
     const string* default_value_string_;
   };
 
@@ -918,6 +975,7 @@
   friend class FieldDescriptor;
   friend class EnumValueDescriptor;
   friend class FileDescriptor;
+  friend class DescriptorPool;
   friend class internal::GeneratedMessageReflection;
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumDescriptor);
 };
@@ -994,6 +1052,7 @@
   EnumValueDescriptor() {}
   friend class DescriptorBuilder;
   friend class EnumDescriptor;
+  friend class DescriptorPool;
   friend class FileDescriptorTables;
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumValueDescriptor);
 };
@@ -1144,8 +1203,8 @@
   const string* name_;
   const string* full_name_;
   const ServiceDescriptor* service_;
-  const Descriptor* input_type_;
-  const Descriptor* output_type_;
+  mutable internal::LazyDescriptor input_type_;
+  mutable internal::LazyDescriptor output_type_;
   const MethodOptions* options_;
   bool client_streaming_;
   bool server_streaming_;
@@ -1302,7 +1361,11 @@
   const string* package_;
   const DescriptorPool* pool_;
   int dependency_count_;
-  const FileDescriptor** dependencies_;
+  mutable const FileDescriptor** dependencies_;
+  const string** dependencies_names_;
+  GoogleOnceDynamic* dependencies_once_;
+  static void DependenciesOnceInit(const FileDescriptor* to_init);
+  void InternalDependenciesOnceInit() const;
   int public_dependency_count_;
   int* public_dependencies_;
   int weak_dependency_count_;
@@ -1321,14 +1384,22 @@
 
   const FileDescriptorTables* tables_;
   const SourceCodeInfo* source_code_info_;
+
+  // Indicates the FileDescriptor is completed building. Used to verify
+  // that type accessor functions that can possibly build a dependent file
+  // aren't called during the process of building the file.
+  bool finished_building_;
+
   // IMPORTANT:  If you add a new field, make sure to search for all instances
   // of Allocate<FileDescriptor>() and AllocateArray<FileDescriptor>() in
   // descriptor.cc and update them to initialize the field.
 
   FileDescriptor() {}
   friend class DescriptorBuilder;
+  friend class DescriptorPool;
   friend class Descriptor;
   friend class FieldDescriptor;
+  friend class internal::LazyDescriptor;
   friend class OneofDescriptor;
   friend class EnumDescriptor;
   friend class EnumValueDescriptor;
@@ -1559,6 +1630,9 @@
   static void InternalAddGeneratedFile(
       const void* encoded_file_descriptor, int size);
 
+  // Disallow [enforce_utf8 = false] in .proto files.
+  void DisallowEnforceUtf8() { disallow_enforce_utf8_ = true; }
+
 
   // For internal use only:  Gets a non-const pointer to the generated pool.
   // This is called at static-initialization time only, so thread-safety is
@@ -1571,6 +1645,21 @@
   // which it did not officially declare as dependencies.
   void InternalDontEnforceDependencies();
 
+  // For internal use only: Enables lazy building of dependencies of a file.
+  // Delay the building of dependencies of a file descriptor until absolutely
+  // necessary, like when message_type() is called on a field that is defined
+  // in that dependency's file. This will cause functional issues if a proto
+  // or one of it's dependencies has errors. Should only be enabled for the
+  // generated_pool_ (because no descriptor build errors are guaranteed by
+  // the compilation generation process), testing, or if a lack of descriptor
+  // build errors can be guaranteed for a pool.
+  void InternalSetLazilyBuildDependencies() {
+    lazily_build_dependencies_ = true;
+    // This needs to be set when lazily building dependencies, as it breaks
+    // dependency checking.
+    InternalDontEnforceDependencies();
+  }
+
   // For internal use only.
   void internal_set_underlay(const DescriptorPool* underlay) {
     underlay_ = underlay;
@@ -1589,10 +1678,13 @@
 
  private:
   friend class Descriptor;
+  friend class internal::LazyDescriptor;
   friend class FieldDescriptor;
   friend class EnumDescriptor;
   friend class ServiceDescriptor;
+  friend class MethodDescriptor;
   friend class FileDescriptor;
+  friend class StreamDescriptor;
   friend class DescriptorBuilder;
   friend class FileDescriptorTables;
 
@@ -1616,6 +1708,28 @@
   const FileDescriptor* BuildFileFromDatabase(
     const FileDescriptorProto& proto) const;
 
+  // Helper for when lazily_build_dependencies_ is set, can look up a symbol
+  // after the file's descriptor is built, and can build the file where that
+  // symbol is defined if necessary. Will create a placeholder if the type
+  // doesn't exist in the fallback database, or the file doesn't build
+  // successfully.
+  Symbol CrossLinkOnDemandHelper(const string& name, bool expecting_enum) const;
+
+  // Create a placeholder FileDescriptor of the specified name
+  FileDescriptor* NewPlaceholderFile(const string& name) const;
+  FileDescriptor* NewPlaceholderFileWithMutexHeld(const string& name) const;
+
+  enum PlaceholderType {
+    PLACEHOLDER_MESSAGE,
+    PLACEHOLDER_ENUM,
+    PLACEHOLDER_EXTENDABLE_MESSAGE
+  };
+  // Create a placeholder Descriptor of the specified name
+  Symbol NewPlaceholder(const string& name,
+                        PlaceholderType placeholder_type) const;
+  Symbol NewPlaceholderWithMutexHeld(const string& name,
+                                     PlaceholderType placeholder_type) const;
+
   // If fallback_database_ is NULL, this is NULL.  Otherwise, this is a mutex
   // which must be locked while accessing tables_.
   Mutex* mutex_;
@@ -1631,9 +1745,11 @@
   google::protobuf::scoped_ptr<Tables> tables_;
 
   bool enforce_dependencies_;
+  bool lazily_build_dependencies_;
   bool allow_unknown_;
   bool enforce_weak_;
   std::set<string> unused_import_track_files_;
+  bool disallow_enforce_utf8_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPool);
 };
@@ -1693,15 +1809,12 @@
 PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, file, const FileDescriptor*)
 PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, number, int)
 PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, is_extension, bool)
-PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, type, FieldDescriptor::Type)
 PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, label, FieldDescriptor::Label)
 PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_type, const Descriptor*)
 PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_oneof,
                          const OneofDescriptor*)
 PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, index_in_oneof, int)
 PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, extension_scope, const Descriptor*)
-PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, message_type, const Descriptor*)
-PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, enum_type, const EnumDescriptor*)
 PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions)
 PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_default_value, bool)
 PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_json_name, bool)
@@ -1712,8 +1825,6 @@
 PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_float , float )
 PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_double, double)
 PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_bool  , bool  )
-PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_enum,
-                         const EnumValueDescriptor*)
 PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, default_value_string)
 
 PROTOBUF_DEFINE_STRING_ACCESSOR(OneofDescriptor, name)
@@ -1749,8 +1860,6 @@
 PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, name)
 PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, full_name)
 PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, service, const ServiceDescriptor*)
-PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, input_type, const Descriptor*)
-PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, output_type, const Descriptor*)
 PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions)
 PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, client_streaming, bool)
 PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, server_streaming, bool)
@@ -1824,7 +1933,7 @@
 // in the parent's array of children.
 inline int FieldDescriptor::index() const {
   if (!is_extension_) {
-    return static_cast<int>(this - containing_type_->fields_);
+    return static_cast<int>(this - containing_type()->fields_);
   } else if (extension_scope_ != NULL) {
     return static_cast<int>(this - extension_scope_->extensions_);
   } else {
@@ -1865,15 +1974,15 @@
 }
 
 inline const char* FieldDescriptor::type_name() const {
-  return kTypeToName[type_];
+  return kTypeToName[type()];
 }
 
 inline FieldDescriptor::CppType FieldDescriptor::cpp_type() const {
-  return kTypeToCppTypeMap[type_];
+  return kTypeToCppTypeMap[type()];
 }
 
 inline const char* FieldDescriptor::cpp_type_name() const {
-  return kCppTypeToName[kTypeToCppTypeMap[type_]];
+  return kCppTypeToName[kTypeToCppTypeMap[type()]];
 }
 
 inline FieldDescriptor::CppType FieldDescriptor::TypeToCppType(Type type) {
@@ -1895,18 +2004,14 @@
           field_type != FieldDescriptor::TYPE_BYTES);
 }
 
-inline const FileDescriptor* FileDescriptor::dependency(int index) const {
-  return dependencies_[index];
-}
-
 inline const FileDescriptor* FileDescriptor::public_dependency(
     int index) const {
-  return dependencies_[public_dependencies_[index]];
+  return dependency(public_dependencies_[index]);
 }
 
 inline const FileDescriptor* FileDescriptor::weak_dependency(
     int index) const {
-  return dependencies_[weak_dependencies_[index]];
+  return dependency(weak_dependencies_[index]);
 }
 
 inline FileDescriptor::Syntax FileDescriptor::syntax() const {
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index 57fbfd8..56c395e 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -80,17 +80,57 @@
 
 }  // namespace
 
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+    const TableStruct::entries[] = {
+  {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+    const TableStruct::aux[] = {
+  ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+    TableStruct::schema[] = {
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+};
+
 const ::google::protobuf::uint32 TableStruct::offsets[] = {
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _has_bits_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, file_),
   ~0u,
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _has_bits_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, package_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, dependency_),
@@ -119,6 +159,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, start_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, end_),
   0,
@@ -127,6 +168,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ReservedRange, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ReservedRange, start_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ReservedRange, end_),
   0,
@@ -135,6 +177,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, field_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_),
@@ -159,6 +202,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, number_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, label_),
@@ -173,8 +217,8 @@
   6,
   8,
   9,
-  1,
   2,
+  1,
   3,
   7,
   4,
@@ -183,6 +227,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, options_),
   0,
@@ -191,6 +236,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, value_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, options_),
@@ -201,6 +247,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, number_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, options_),
@@ -211,6 +258,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, method_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, options_),
@@ -221,6 +269,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, input_type_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, output_type_),
@@ -237,6 +286,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _internal_metadata_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _extensions_),
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   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_),
@@ -275,6 +325,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _internal_metadata_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _extensions_),
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, message_set_wire_format_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, no_standard_descriptor_accessor_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, deprecated_),
@@ -289,6 +340,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _internal_metadata_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _extensions_),
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, ctype_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, packed_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, jstype_),
@@ -297,22 +349,24 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, weak_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, uninterpreted_option_),
   0,
-  2,
   1,
+  5,
+  2,
   3,
   4,
-  5,
   ~0u,
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofOptions, _has_bits_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofOptions, _internal_metadata_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofOptions, _extensions_),
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofOptions, uninterpreted_option_),
   ~0u,
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _has_bits_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _internal_metadata_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _extensions_),
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, allow_alias_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, deprecated_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, uninterpreted_option_),
@@ -323,6 +377,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _internal_metadata_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _extensions_),
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, deprecated_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, uninterpreted_option_),
   0,
@@ -331,6 +386,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _internal_metadata_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _extensions_),
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, deprecated_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, uninterpreted_option_),
   0,
@@ -339,6 +395,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _internal_metadata_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _extensions_),
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, deprecated_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, idempotency_level_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, uninterpreted_option_),
@@ -349,6 +406,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, name_part_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, is_extension_),
   0,
@@ -357,6 +415,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, identifier_value_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, positive_int_value_),
@@ -375,6 +434,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   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_),
@@ -389,12 +449,14 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, location_),
   ~0u,
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _has_bits_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo_Annotation, path_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo_Annotation, source_file_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo_Annotation, begin_),
@@ -407,36 +469,37 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo, annotation_),
   ~0u,
 };
 
 static const ::google::protobuf::internal::MigrationSchema schemas[] = {
-  { 0, 5, sizeof(FileDescriptorSet)},
-  { 6, 22, sizeof(FileDescriptorProto)},
-  { 34, 40, sizeof(DescriptorProto_ExtensionRange)},
-  { 42, 48, sizeof(DescriptorProto_ReservedRange)},
-  { 50, 64, sizeof(DescriptorProto)},
-  { 74, 88, sizeof(FieldDescriptorProto)},
-  { 98, 104, sizeof(OneofDescriptorProto)},
-  { 106, 113, sizeof(EnumDescriptorProto)},
-  { 116, 123, sizeof(EnumValueDescriptorProto)},
-  { 126, 133, sizeof(ServiceDescriptorProto)},
-  { 136, 146, sizeof(MethodDescriptorProto)},
-  { 152, 173, sizeof(FileOptions)},
-  { 190, 199, sizeof(MessageOptions)},
-  { 204, 215, sizeof(FieldOptions)},
-  { 222, 227, sizeof(OneofOptions)},
-  { 228, 235, sizeof(EnumOptions)},
-  { 238, 244, sizeof(EnumValueOptions)},
-  { 246, 252, sizeof(ServiceOptions)},
-  { 254, 261, sizeof(MethodOptions)},
-  { 264, 270, sizeof(UninterpretedOption_NamePart)},
-  { 272, 283, sizeof(UninterpretedOption)},
-  { 290, 299, sizeof(SourceCodeInfo_Location)},
-  { 304, 309, sizeof(SourceCodeInfo)},
-  { 310, 318, sizeof(GeneratedCodeInfo_Annotation)},
-  { 322, 327, sizeof(GeneratedCodeInfo)},
+  { 0, 6, sizeof(FileDescriptorSet)},
+  { 7, 24, sizeof(FileDescriptorProto)},
+  { 36, 43, sizeof(DescriptorProto_ExtensionRange)},
+  { 45, 52, sizeof(DescriptorProto_ReservedRange)},
+  { 54, 69, sizeof(DescriptorProto)},
+  { 79, 94, sizeof(FieldDescriptorProto)},
+  { 104, 111, sizeof(OneofDescriptorProto)},
+  { 113, 121, sizeof(EnumDescriptorProto)},
+  { 124, 132, sizeof(EnumValueDescriptorProto)},
+  { 135, 143, sizeof(ServiceDescriptorProto)},
+  { 146, 157, sizeof(MethodDescriptorProto)},
+  { 163, 185, sizeof(FileOptions)},
+  { 202, 212, sizeof(MessageOptions)},
+  { 217, 229, sizeof(FieldOptions)},
+  { 236, 242, sizeof(OneofOptions)},
+  { 243, 251, sizeof(EnumOptions)},
+  { 254, 261, sizeof(EnumValueOptions)},
+  { 263, 270, sizeof(ServiceOptions)},
+  { 272, 280, sizeof(MethodOptions)},
+  { 283, 290, sizeof(UninterpretedOption_NamePart)},
+  { 292, 304, sizeof(UninterpretedOption)},
+  { 311, 321, sizeof(SourceCodeInfo_Location)},
+  { 326, 332, sizeof(SourceCodeInfo)},
+  { 333, 342, sizeof(GeneratedCodeInfo_Annotation)},
+  { 346, 352, sizeof(GeneratedCodeInfo)},
 };
 
 static ::google::protobuf::Message const * const file_default_instances[] = {
@@ -681,67 +744,67 @@
       "\001(\t\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goo"
       "gle.protobuf.UninterpretedOption\":\n\014Opti"
       "mizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LI"
-      "TE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002J\004\010&\020\'\"\354\001\n\016Messag"
+      "TE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002J\004\010&\020\'\"\362\001\n\016Messag"
       "eOptions\022&\n\027message_set_wire_format\030\001 \001("
       "\010:\005false\022.\n\037no_standard_descriptor_acces"
       "sor\030\002 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005fa"
       "lse\022\021\n\tmap_entry\030\007 \001(\010\022C\n\024uninterpreted_"
       "option\030\347\007 \003(\0132$.google.protobuf.Uninterp"
-      "retedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\010\020\t\"\236\003\n\014FieldOp"
-      "tions\022:\n\005ctype\030\001 \001(\0162#.google.protobuf.F"
-      "ieldOptions.CType:\006STRING\022\016\n\006packed\030\002 \001("
-      "\010\022\?\n\006jstype\030\006 \001(\0162$.google.protobuf.Fiel"
-      "dOptions.JSType:\tJS_NORMAL\022\023\n\004lazy\030\005 \001(\010"
-      ":\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\023\n\004we"
-      "ak\030\n \001(\010:\005false\022C\n\024uninterpreted_option\030"
-      "\347\007 \003(\0132$.google.protobuf.UninterpretedOp"
-      "tion\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014S"
-      "TRING_PIECE\020\002\"5\n\006JSType\022\r\n\tJS_NORMAL\020\000\022\r"
-      "\n\tJS_STRING\020\001\022\r\n\tJS_NUMBER\020\002*\t\010\350\007\020\200\200\200\200\002J"
-      "\004\010\004\020\005\"^\n\014OneofOptions\022C\n\024uninterpreted_o"
+      "retedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\010\020\tJ\004\010\t\020\n\"\236\003\n\014F"
+      "ieldOptions\022:\n\005ctype\030\001 \001(\0162#.google.prot"
+      "obuf.FieldOptions.CType:\006STRING\022\016\n\006packe"
+      "d\030\002 \001(\010\022\?\n\006jstype\030\006 \001(\0162$.google.protobu"
+      "f.FieldOptions.JSType:\tJS_NORMAL\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_o"
       "ption\030\347\007 \003(\0132$.google.protobuf.Uninterpr"
-      "etedOption*\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:\005"
-      "false\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.g"
-      "oogle.protobuf.UninterpretedOption*\t\010\350\007\020"
-      "\200\200\200\200\002\"}\n\020EnumValueOptions\022\031\n\ndeprecated\030"
-      "\001 \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 "
-      "\003(\0132$.google.protobuf.UninterpretedOptio"
-      "n*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndeprec"
-      "ated\030! \001(\010:\005false\022C\n\024uninterpreted_optio"
-      "n\030\347\007 \003(\0132$.google.protobuf.Uninterpreted"
-      "Option*\t\010\350\007\020\200\200\200\200\002\"\255\002\n\rMethodOptions\022\031\n\nd"
-      "eprecated\030! \001(\010:\005false\022_\n\021idempotency_le"
-      "vel\030\" \001(\0162/.google.protobuf.MethodOption"
-      "s.IdempotencyLevel:\023IDEMPOTENCY_UNKNOWN\022"
-      "C\n\024uninterpreted_option\030\347\007 \003(\0132$.google."
-      "protobuf.UninterpretedOption\"P\n\020Idempote"
-      "ncyLevel\022\027\n\023IDEMPOTENCY_UNKNOWN\020\000\022\023\n\017NO_"
-      "SIDE_EFFECTS\020\001\022\016\n\nIDEMPOTENT\020\002*\t\010\350\007\020\200\200\200\200"
-      "\002\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003(\0132"
-      "-.google.protobuf.UninterpretedOption.Na"
-      "mePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022posi"
-      "tive_int_value\030\004 \001(\004\022\032\n\022negative_int_val"
-      "ue\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014string"
-      "_value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323\n"
-      "\010NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_exten"
-      "sion\030\002 \002(\010\"\325\001\n\016SourceCodeInfo\022:\n\010locatio"
-      "n\030\001 \003(\0132(.google.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\021trailing_comments\030\004 \001(\t\022!\n\031leadi"
-      "ng_detached_comments\030\006 \003(\t\"\247\001\n\021Generated"
-      "CodeInfo\022A\n\nannotation\030\001 \003(\0132-.google.pr"
-      "otobuf.GeneratedCodeInfo.Annotation\032O\n\nA"
-      "nnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source_fi"
-      "le\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B\214\001\n"
-      "\023com.google.protobufB\020DescriptorProtosH\001"
-      "Z>github.com/golang/protobuf/protoc-gen-"
-      "go/descriptor;descriptor\242\002\003GPB\252\002\032Google."
-      "Protobuf.Reflection"
+      "etedOption\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020"
+      "\001\022\020\n\014STRING_PIECE\020\002\"5\n\006JSType\022\r\n\tJS_NORM"
+      "AL\020\000\022\r\n\tJS_STRING\020\001\022\r\n\tJS_NUMBER\020\002*\t\010\350\007\020"
+      "\200\200\200\200\002J\004\010\004\020\005\"^\n\014OneofOptions\022C\n\024uninterpr"
+      "eted_option\030\347\007 \003(\0132$.google.protobuf.Uni"
+      "nterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\223\001\n\013EnumOpti"
+      "ons\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.UninterpretedOption"
+      "*\t\010\350\007\020\200\200\200\200\002J\004\010\005\020\006\"}\n\020EnumValueOptions\022\031\n"
+      "\ndeprecated\030\001 \001(\010:\005false\022C\n\024uninterprete"
+      "d_option\030\347\007 \003(\0132$.google.protobuf.Uninte"
+      "rpretedOption*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptio"
+      "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\"\255\002\n\rMethod"
+      "Options\022\031\n\ndeprecated\030! \001(\010:\005false\022_\n\021id"
+      "empotency_level\030\" \001(\0162/.google.protobuf."
+      "MethodOptions.IdempotencyLevel:\023IDEMPOTE"
+      "NCY_UNKNOWN\022C\n\024uninterpreted_option\030\347\007 \003"
+      "(\0132$.google.protobuf.UninterpretedOption"
+      "\"P\n\020IdempotencyLevel\022\027\n\023IDEMPOTENCY_UNKN"
+      "OWN\020\000\022\023\n\017NO_SIDE_EFFECTS\020\001\022\016\n\nIDEMPOTENT"
+      "\020\002*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023UninterpretedOption\022;\n"
+      "\004name\030\002 \003(\0132-.google.protobuf.Uninterpre"
+      "tedOption.NamePart\022\030\n\020identifier_value\030\003"
+      " \001(\t\022\032\n\022positive_int_value\030\004 \001(\004\022\032\n\022nega"
+      "tive_int_value\030\005 \001(\003\022\024\n\014double_value\030\006 \001"
+      "(\001\022\024\n\014string_value\030\007 \001(\014\022\027\n\017aggregate_va"
+      "lue\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\016SourceCodeInf"
+      "o\022:\n\010location\030\001 \003(\0132(.google.protobuf.So"
+      "urceCodeInfo.Location\032\206\001\n\010Location\022\020\n\004pa"
+      "th\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020leadin"
+      "g_comments\030\003 \001(\t\022\031\n\021trailing_comments\030\004 "
+      "\001(\t\022!\n\031leading_detached_comments\030\006 \003(\t\"\247"
+      "\001\n\021GeneratedCodeInfo\022A\n\nannotation\030\001 \003(\013"
+      "2-.google.protobuf.GeneratedCodeInfo.Ann"
+      "otation\032O\n\nAnnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022"
+      "\023\n\013source_file\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003e"
+      "nd\030\004 \001(\005B\214\001\n\023com.google.protobufB\020Descri"
+      "ptorProtosH\001Z>github.com/golang/protobuf"
+      "/protoc-gen-go/descriptor;descriptor\242\002\003G"
+      "PB\252\002\032Google.Protobuf.Reflection"
   };
   ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 5579);
+      descriptor, 5591);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
   ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown);
@@ -972,7 +1035,7 @@
 }
 const ::google::protobuf::Descriptor* FileDescriptorSet::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[0].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const FileDescriptorSet& FileDescriptorSet::default_instance() {
@@ -1009,13 +1072,11 @@
       case 1: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(10u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_file()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -1044,6 +1105,9 @@
 void FileDescriptorSet::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.FileDescriptorSet)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.FileDescriptorProto file = 1;
   for (unsigned int i = 0, n = this->file_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
@@ -1059,13 +1123,15 @@
 
 ::google::protobuf::uint8* FileDescriptorSet::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorSet)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.FileDescriptorProto file = 1;
   for (unsigned int i = 0, n = this->file_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        1, this->file(i), false, target);
+        1, this->file(i), deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -1122,6 +1188,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorSet)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   file_.MergeFrom(from.file_);
 }
 
@@ -1149,7 +1218,7 @@
   InternalSwap(other);
 }
 void FileDescriptorSet::InternalSwap(FileDescriptorSet* other) {
-  file_.UnsafeArenaSwap(&other->file_);
+  file_.InternalSwap(&other->file_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   std::swap(_cached_size_, other->_cached_size_);
@@ -1157,7 +1226,7 @@
 
 ::google::protobuf::Metadata FileDescriptorSet::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[0];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1226,12 +1295,12 @@
       _has_bits_(from._has_bits_),
       _cached_size_(0),
       dependency_(from.dependency_),
-      public_dependency_(from.public_dependency_),
-      weak_dependency_(from.weak_dependency_),
       message_type_(from.message_type_),
       enum_type_(from.enum_type_),
       service_(from.service_),
-      extension_(from.extension_) {
+      extension_(from.extension_),
+      public_dependency_(from.public_dependency_),
+      weak_dependency_(from.weak_dependency_) {
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   if (from.has_name()) {
@@ -1291,7 +1360,7 @@
 }
 const ::google::protobuf::Descriptor* FileDescriptorProto::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[1].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const FileDescriptorProto& FileDescriptorProto::default_instance() {
@@ -1310,12 +1379,12 @@
 void FileDescriptorProto::Clear() {
 // @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorProto)
   dependency_.Clear();
-  public_dependency_.Clear();
-  weak_dependency_.Clear();
   message_type_.Clear();
   enum_type_.Clear();
   service_.Clear();
   extension_.Clear();
+  public_dependency_.Clear();
+  weak_dependency_.Clear();
   if (_has_bits_[0 / 32] & 31u) {
     if (has_name()) {
       GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
@@ -1405,13 +1474,11 @@
       case 4: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(34u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_message_type()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -1419,13 +1486,11 @@
       case 5: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(42u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_enum_type()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -1433,13 +1498,11 @@
       case 6: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(50u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_service()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -1447,13 +1510,11 @@
       case 7: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(58u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_extension()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -1558,8 +1619,12 @@
 void FileDescriptorProto::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.FileDescriptorProto)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -1569,7 +1634,7 @@
   }
 
   // optional string package = 2;
-  if (has_package()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->package().data(), this->package().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -1613,13 +1678,13 @@
   }
 
   // optional .google.protobuf.FileOptions options = 8;
-  if (has_options()) {
+  if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
       8, *this->options_, output);
   }
 
   // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
-  if (has_source_code_info()) {
+  if (cached_has_bits & 0x00000010u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
       9, *this->source_code_info_, output);
   }
@@ -1637,7 +1702,7 @@
   }
 
   // optional string syntax = 12;
-  if (has_syntax()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->syntax().data(), this->syntax().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -1655,10 +1720,13 @@
 
 ::google::protobuf::uint8* FileDescriptorProto::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorProto)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -1669,7 +1737,7 @@
   }
 
   // optional string package = 2;
-  if (has_package()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->package().data(), this->package().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -1693,58 +1761,54 @@
   for (unsigned int i = 0, n = this->message_type_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        4, this->message_type(i), false, target);
+        4, this->message_type(i), deterministic, target);
   }
 
   // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
   for (unsigned int i = 0, n = this->enum_type_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        5, this->enum_type(i), false, target);
+        5, this->enum_type(i), deterministic, target);
   }
 
   // repeated .google.protobuf.ServiceDescriptorProto service = 6;
   for (unsigned int i = 0, n = this->service_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        6, this->service(i), false, target);
+        6, this->service(i), deterministic, target);
   }
 
   // repeated .google.protobuf.FieldDescriptorProto extension = 7;
   for (unsigned int i = 0, n = this->extension_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        7, this->extension(i), false, target);
+        7, this->extension(i), deterministic, target);
   }
 
   // optional .google.protobuf.FileOptions options = 8;
-  if (has_options()) {
+  if (cached_has_bits & 0x00000008u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        8, *this->options_, false, target);
+        8, *this->options_, deterministic, target);
   }
 
   // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
-  if (has_source_code_info()) {
+  if (cached_has_bits & 0x00000010u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        9, *this->source_code_info_, false, target);
+        9, *this->source_code_info_, deterministic, target);
   }
 
   // repeated int32 public_dependency = 10;
-  for (int i = 0, n = this->public_dependency_size(); i < n; i++) {
-    target = ::google::protobuf::internal::WireFormatLite::
-      WriteInt32ToArray(10, this->public_dependency(i), target);
-  }
+  target = ::google::protobuf::internal::WireFormatLite::
+    WriteInt32ToArray(10, this->public_dependency_, target);
 
   // repeated int32 weak_dependency = 11;
-  for (int i = 0, n = this->weak_dependency_size(); i < n; i++) {
-    target = ::google::protobuf::internal::WireFormatLite::
-      WriteInt32ToArray(11, this->weak_dependency(i), target);
-  }
+  target = ::google::protobuf::internal::WireFormatLite::
+    WriteInt32ToArray(11, this->weak_dependency_, target);
 
   // optional string syntax = 12;
-  if (has_syntax()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->syntax().data(), this->syntax().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -1779,24 +1843,6 @@
       this->dependency(i));
   }
 
-  // repeated int32 public_dependency = 10;
-  {
-    size_t data_size = ::google::protobuf::internal::WireFormatLite::
-      Int32Size(this->public_dependency_);
-    total_size += 1 *
-                  ::google::protobuf::internal::FromIntSize(this->public_dependency_size());
-    total_size += data_size;
-  }
-
-  // repeated int32 weak_dependency = 11;
-  {
-    size_t data_size = ::google::protobuf::internal::WireFormatLite::
-      Int32Size(this->weak_dependency_);
-    total_size += 1 *
-                  ::google::protobuf::internal::FromIntSize(this->weak_dependency_size());
-    total_size += data_size;
-  }
-
   // repeated .google.protobuf.DescriptorProto message_type = 4;
   {
     unsigned int count = this->message_type_size();
@@ -1841,6 +1887,24 @@
     }
   }
 
+  // repeated int32 public_dependency = 10;
+  {
+    size_t data_size = ::google::protobuf::internal::WireFormatLite::
+      Int32Size(this->public_dependency_);
+    total_size += 1 *
+                  ::google::protobuf::internal::FromIntSize(this->public_dependency_size());
+    total_size += data_size;
+  }
+
+  // repeated int32 weak_dependency = 11;
+  {
+    size_t data_size = ::google::protobuf::internal::WireFormatLite::
+      Int32Size(this->weak_dependency_);
+    total_size += 1 *
+                  ::google::protobuf::internal::FromIntSize(this->weak_dependency_size());
+    total_size += data_size;
+  }
+
   if (_has_bits_[0 / 32] & 31u) {
     // optional string name = 1;
     if (has_name()) {
@@ -1904,30 +1968,34 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorProto)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   dependency_.MergeFrom(from.dependency_);
-  public_dependency_.MergeFrom(from.public_dependency_);
-  weak_dependency_.MergeFrom(from.weak_dependency_);
   message_type_.MergeFrom(from.message_type_);
   enum_type_.MergeFrom(from.enum_type_);
   service_.MergeFrom(from.service_);
   extension_.MergeFrom(from.extension_);
-  if (from._has_bits_[0 / 32] & 31u) {
-    if (from.has_name()) {
+  public_dependency_.MergeFrom(from.public_dependency_);
+  weak_dependency_.MergeFrom(from.weak_dependency_);
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 31u) {
+    if (cached_has_bits & 0x00000001u) {
       set_has_name();
       name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
     }
-    if (from.has_package()) {
+    if (cached_has_bits & 0x00000002u) {
       set_has_package();
       package_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.package_);
     }
-    if (from.has_syntax()) {
+    if (cached_has_bits & 0x00000004u) {
       set_has_syntax();
       syntax_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.syntax_);
     }
-    if (from.has_options()) {
+    if (cached_has_bits & 0x00000008u) {
       mutable_options()->::google::protobuf::FileOptions::MergeFrom(from.options());
     }
-    if (from.has_source_code_info()) {
+    if (cached_has_bits & 0x00000010u) {
       mutable_source_code_info()->::google::protobuf::SourceCodeInfo::MergeFrom(from.source_code_info());
     }
   }
@@ -1963,13 +2031,13 @@
   InternalSwap(other);
 }
 void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) {
-  dependency_.UnsafeArenaSwap(&other->dependency_);
-  public_dependency_.UnsafeArenaSwap(&other->public_dependency_);
-  weak_dependency_.UnsafeArenaSwap(&other->weak_dependency_);
-  message_type_.UnsafeArenaSwap(&other->message_type_);
-  enum_type_.UnsafeArenaSwap(&other->enum_type_);
-  service_.UnsafeArenaSwap(&other->service_);
-  extension_.UnsafeArenaSwap(&other->extension_);
+  dependency_.InternalSwap(&other->dependency_);
+  message_type_.InternalSwap(&other->message_type_);
+  enum_type_.InternalSwap(&other->enum_type_);
+  service_.InternalSwap(&other->service_);
+  extension_.InternalSwap(&other->extension_);
+  public_dependency_.InternalSwap(&other->public_dependency_);
+  weak_dependency_.InternalSwap(&other->weak_dependency_);
   name_.Swap(&other->name_);
   package_.Swap(&other->package_);
   syntax_.Swap(&other->syntax_);
@@ -1982,7 +2050,7 @@
 
 ::google::protobuf::Metadata FileDescriptorProto::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[1];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -2020,6 +2088,7 @@
 }
 #endif
 void FileDescriptorProto::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.name)
@@ -2082,6 +2151,7 @@
 }
 #endif
 void FileDescriptorProto::set_package(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_package();
   package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.package)
@@ -2138,6 +2208,7 @@
 }
 #endif
 void FileDescriptorProto::set_dependency(int index, const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   dependency_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.dependency)
 }
@@ -2156,11 +2227,12 @@
 }
 #if LANG_CXX11
 void FileDescriptorProto::add_dependency(::std::string&& value) {
-  dependency_.Add()->assign(std::move(value));
+  dependency_.Add(std::move(value));
   // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
 }
 #endif
 void FileDescriptorProto::add_dependency(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   dependency_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.FileDescriptorProto.dependency)
 }
@@ -2481,6 +2553,7 @@
 }
 #endif
 void FileDescriptorProto::set_syntax(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_syntax();
   syntax_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.syntax)
@@ -2561,7 +2634,7 @@
 }
 const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[2].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const DescriptorProto_ExtensionRange& DescriptorProto_ExtensionRange::default_instance() {
@@ -2650,13 +2723,17 @@
 void DescriptorProto_ExtensionRange::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.DescriptorProto.ExtensionRange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional int32 start = 1;
-  if (has_start()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output);
   }
 
   // optional int32 end = 2;
-  if (has_end()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output);
   }
 
@@ -2669,15 +2746,18 @@
 
 ::google::protobuf::uint8* DescriptorProto_ExtensionRange::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ExtensionRange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional int32 start = 1;
-  if (has_start()) {
+  if (cached_has_bits & 0x00000001u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target);
   }
 
   // optional int32 end = 2;
-  if (has_end()) {
+  if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target);
   }
 
@@ -2740,13 +2820,18 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
-  if (from._has_bits_[0 / 32] & 3u) {
-    if (from.has_start()) {
-      set_start(from.start());
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 3u) {
+    if (cached_has_bits & 0x00000001u) {
+      start_ = from.start_;
     }
-    if (from.has_end()) {
-      set_end(from.end());
+    if (cached_has_bits & 0x00000002u) {
+      end_ = from.end_;
     }
+    _has_bits_[0] |= cached_has_bits;
   }
 }
 
@@ -2782,7 +2867,7 @@
 
 ::google::protobuf::Metadata DescriptorProto_ExtensionRange::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[2];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -2886,7 +2971,7 @@
 }
 const ::google::protobuf::Descriptor* DescriptorProto_ReservedRange::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[3].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::default_instance() {
@@ -2975,13 +3060,17 @@
 void DescriptorProto_ReservedRange::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.DescriptorProto.ReservedRange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional int32 start = 1;
-  if (has_start()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output);
   }
 
   // optional int32 end = 2;
-  if (has_end()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output);
   }
 
@@ -2994,15 +3083,18 @@
 
 ::google::protobuf::uint8* DescriptorProto_ReservedRange::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ReservedRange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional int32 start = 1;
-  if (has_start()) {
+  if (cached_has_bits & 0x00000001u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target);
   }
 
   // optional int32 end = 2;
-  if (has_end()) {
+  if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target);
   }
 
@@ -3065,13 +3157,18 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ReservedRange)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
-  if (from._has_bits_[0 / 32] & 3u) {
-    if (from.has_start()) {
-      set_start(from.start());
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 3u) {
+    if (cached_has_bits & 0x00000001u) {
+      start_ = from.start_;
     }
-    if (from.has_end()) {
-      set_end(from.end());
+    if (cached_has_bits & 0x00000002u) {
+      end_ = from.end_;
     }
+    _has_bits_[0] |= cached_has_bits;
   }
 }
 
@@ -3107,7 +3204,7 @@
 
 ::google::protobuf::Metadata DescriptorProto_ReservedRange::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[3];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -3192,10 +3289,10 @@
       _has_bits_(from._has_bits_),
       _cached_size_(0),
       field_(from.field_),
-      extension_(from.extension_),
       nested_type_(from.nested_type_),
       enum_type_(from.enum_type_),
       extension_range_(from.extension_range_),
+      extension_(from.extension_),
       oneof_decl_(from.oneof_decl_),
       reserved_range_(from.reserved_range_),
       reserved_name_(from.reserved_name_) {
@@ -3237,7 +3334,7 @@
 }
 const ::google::protobuf::Descriptor* DescriptorProto::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[4].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const DescriptorProto& DescriptorProto::default_instance() {
@@ -3256,10 +3353,10 @@
 void DescriptorProto::Clear() {
 // @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto)
   field_.Clear();
-  extension_.Clear();
   nested_type_.Clear();
   enum_type_.Clear();
   extension_range_.Clear();
+  extension_.Clear();
   oneof_decl_.Clear();
   reserved_range_.Clear();
   reserved_name_.Clear();
@@ -3307,13 +3404,11 @@
       case 2: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(18u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_field()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -3321,13 +3416,11 @@
       case 3: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(26u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_nested_type()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -3335,13 +3428,11 @@
       case 4: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(34u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_enum_type()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -3349,13 +3440,11 @@
       case 5: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(42u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_extension_range()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -3363,13 +3452,11 @@
       case 6: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(50u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_extension()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -3389,13 +3476,11 @@
       case 8: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(66u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_oneof_decl()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -3403,13 +3488,11 @@
       case 9: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(74u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_reserved_range()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -3455,8 +3538,12 @@
 void DescriptorProto::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.DescriptorProto)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -3496,7 +3583,7 @@
   }
 
   // optional .google.protobuf.MessageOptions options = 7;
-  if (has_options()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
       7, *this->options_, output);
   }
@@ -3532,10 +3619,13 @@
 
 ::google::protobuf::uint8* DescriptorProto::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -3549,56 +3639,56 @@
   for (unsigned int i = 0, n = this->field_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        2, this->field(i), false, target);
+        2, this->field(i), deterministic, target);
   }
 
   // repeated .google.protobuf.DescriptorProto nested_type = 3;
   for (unsigned int i = 0, n = this->nested_type_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        3, this->nested_type(i), false, target);
+        3, this->nested_type(i), deterministic, target);
   }
 
   // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
   for (unsigned int i = 0, n = this->enum_type_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        4, this->enum_type(i), false, target);
+        4, this->enum_type(i), deterministic, target);
   }
 
   // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
   for (unsigned int i = 0, n = this->extension_range_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        5, this->extension_range(i), false, target);
+        5, this->extension_range(i), deterministic, target);
   }
 
   // repeated .google.protobuf.FieldDescriptorProto extension = 6;
   for (unsigned int i = 0, n = this->extension_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        6, this->extension(i), false, target);
+        6, this->extension(i), deterministic, target);
   }
 
   // optional .google.protobuf.MessageOptions options = 7;
-  if (has_options()) {
+  if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        7, *this->options_, false, target);
+        7, *this->options_, deterministic, target);
   }
 
   // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
   for (unsigned int i = 0, n = this->oneof_decl_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        8, this->oneof_decl(i), false, target);
+        8, this->oneof_decl(i), deterministic, target);
   }
 
   // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
   for (unsigned int i = 0, n = this->reserved_range_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        9, this->reserved_range(i), false, target);
+        9, this->reserved_range(i), deterministic, target);
   }
 
   // repeated string reserved_name = 10;
@@ -3639,17 +3729,6 @@
     }
   }
 
-  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
-  {
-    unsigned int count = this->extension_size();
-    total_size += 1UL * count;
-    for (unsigned int i = 0; i < count; i++) {
-      total_size +=
-        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->extension(i));
-    }
-  }
-
   // repeated .google.protobuf.DescriptorProto nested_type = 3;
   {
     unsigned int count = this->nested_type_size();
@@ -3683,6 +3762,17 @@
     }
   }
 
+  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+  {
+    unsigned int count = this->extension_size();
+    total_size += 1UL * count;
+    for (unsigned int i = 0; i < count; i++) {
+      total_size +=
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          this->extension(i));
+    }
+  }
+
   // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
   {
     unsigned int count = this->oneof_decl_size();
@@ -3755,20 +3845,24 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   field_.MergeFrom(from.field_);
-  extension_.MergeFrom(from.extension_);
   nested_type_.MergeFrom(from.nested_type_);
   enum_type_.MergeFrom(from.enum_type_);
   extension_range_.MergeFrom(from.extension_range_);
+  extension_.MergeFrom(from.extension_);
   oneof_decl_.MergeFrom(from.oneof_decl_);
   reserved_range_.MergeFrom(from.reserved_range_);
   reserved_name_.MergeFrom(from.reserved_name_);
-  if (from._has_bits_[0 / 32] & 3u) {
-    if (from.has_name()) {
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 3u) {
+    if (cached_has_bits & 0x00000001u) {
       set_has_name();
       name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
     }
-    if (from.has_options()) {
+    if (cached_has_bits & 0x00000002u) {
       mutable_options()->::google::protobuf::MessageOptions::MergeFrom(from.options());
     }
   }
@@ -3790,9 +3884,9 @@
 
 bool DescriptorProto::IsInitialized() const {
   if (!::google::protobuf::internal::AllAreInitialized(this->field())) return false;
-  if (!::google::protobuf::internal::AllAreInitialized(this->extension())) return false;
   if (!::google::protobuf::internal::AllAreInitialized(this->nested_type())) return false;
   if (!::google::protobuf::internal::AllAreInitialized(this->enum_type())) return false;
+  if (!::google::protobuf::internal::AllAreInitialized(this->extension())) return false;
   if (!::google::protobuf::internal::AllAreInitialized(this->oneof_decl())) return false;
   if (has_options()) {
     if (!this->options_->IsInitialized()) return false;
@@ -3805,14 +3899,14 @@
   InternalSwap(other);
 }
 void DescriptorProto::InternalSwap(DescriptorProto* other) {
-  field_.UnsafeArenaSwap(&other->field_);
-  extension_.UnsafeArenaSwap(&other->extension_);
-  nested_type_.UnsafeArenaSwap(&other->nested_type_);
-  enum_type_.UnsafeArenaSwap(&other->enum_type_);
-  extension_range_.UnsafeArenaSwap(&other->extension_range_);
-  oneof_decl_.UnsafeArenaSwap(&other->oneof_decl_);
-  reserved_range_.UnsafeArenaSwap(&other->reserved_range_);
-  reserved_name_.UnsafeArenaSwap(&other->reserved_name_);
+  field_.InternalSwap(&other->field_);
+  nested_type_.InternalSwap(&other->nested_type_);
+  enum_type_.InternalSwap(&other->enum_type_);
+  extension_range_.InternalSwap(&other->extension_range_);
+  extension_.InternalSwap(&other->extension_);
+  oneof_decl_.InternalSwap(&other->oneof_decl_);
+  reserved_range_.InternalSwap(&other->reserved_range_);
+  reserved_name_.InternalSwap(&other->reserved_name_);
   name_.Swap(&other->name_);
   std::swap(options_, other->options_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
@@ -3822,7 +3916,7 @@
 
 ::google::protobuf::Metadata DescriptorProto::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[4];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -3860,6 +3954,7 @@
 }
 #endif
 void DescriptorProto::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.name)
@@ -4171,6 +4266,7 @@
 }
 #endif
 void DescriptorProto::set_reserved_name(int index, const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   reserved_name_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.reserved_name)
 }
@@ -4189,11 +4285,12 @@
 }
 #if LANG_CXX11
 void DescriptorProto::add_reserved_name(::std::string&& value) {
-  reserved_name_.Add()->assign(std::move(value));
+  reserved_name_.Add(std::move(value));
   // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name)
 }
 #endif
 void DescriptorProto::add_reserved_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   reserved_name_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.DescriptorProto.reserved_name)
 }
@@ -4247,14 +4344,14 @@
   if (from.has_name()) {
     name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
   }
-  type_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  if (from.has_type_name()) {
-    type_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_name_);
-  }
   extendee_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   if (from.has_extendee()) {
     extendee_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.extendee_);
   }
+  type_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.has_type_name()) {
+    type_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_name_);
+  }
   default_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   if (from.has_default_value()) {
     default_value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.default_value_);
@@ -4277,8 +4374,8 @@
 void FieldDescriptorProto::SharedCtor() {
   _cached_size_ = 0;
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  type_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   extendee_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  type_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   default_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   json_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   ::memset(&options_, 0, reinterpret_cast<char*>(&oneof_index_) -
@@ -4294,8 +4391,8 @@
 
 void FieldDescriptorProto::SharedDtor() {
   name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  type_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   extendee_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  type_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   default_value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   json_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   if (this != internal_default_instance()) {
@@ -4310,7 +4407,7 @@
 }
 const ::google::protobuf::Descriptor* FieldDescriptorProto::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[5].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const FieldDescriptorProto& FieldDescriptorProto::default_instance() {
@@ -4333,14 +4430,14 @@
       GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
       (*name_.UnsafeRawStringPointer())->clear();
     }
-    if (has_type_name()) {
-      GOOGLE_DCHECK(!type_name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
-      (*type_name_.UnsafeRawStringPointer())->clear();
-    }
     if (has_extendee()) {
       GOOGLE_DCHECK(!extendee_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
       (*extendee_.UnsafeRawStringPointer())->clear();
     }
+    if (has_type_name()) {
+      GOOGLE_DCHECK(!type_name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
+      (*type_name_.UnsafeRawStringPointer())->clear();
+    }
     if (has_default_value()) {
       GOOGLE_DCHECK(!default_value_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
       (*default_value_.UnsafeRawStringPointer())->clear();
@@ -4559,8 +4656,12 @@
 void FieldDescriptorProto::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.FieldDescriptorProto)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -4570,7 +4671,7 @@
   }
 
   // optional string extendee = 2;
-  if (has_extendee()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->extendee().data(), this->extendee().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -4580,24 +4681,24 @@
   }
 
   // optional int32 number = 3;
-  if (has_number()) {
+  if (cached_has_bits & 0x00000040u) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->number(), output);
   }
 
   // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
-  if (has_label()) {
+  if (cached_has_bits & 0x00000100u) {
     ::google::protobuf::internal::WireFormatLite::WriteEnum(
       4, this->label(), output);
   }
 
   // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
-  if (has_type()) {
+  if (cached_has_bits & 0x00000200u) {
     ::google::protobuf::internal::WireFormatLite::WriteEnum(
       5, this->type(), output);
   }
 
   // optional string type_name = 6;
-  if (has_type_name()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->type_name().data(), this->type_name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -4607,7 +4708,7 @@
   }
 
   // optional string default_value = 7;
-  if (has_default_value()) {
+  if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->default_value().data(), this->default_value().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -4617,18 +4718,18 @@
   }
 
   // optional .google.protobuf.FieldOptions options = 8;
-  if (has_options()) {
+  if (cached_has_bits & 0x00000020u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
       8, *this->options_, output);
   }
 
   // optional int32 oneof_index = 9;
-  if (has_oneof_index()) {
+  if (cached_has_bits & 0x00000080u) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32(9, this->oneof_index(), output);
   }
 
   // optional string json_name = 10;
-  if (has_json_name()) {
+  if (cached_has_bits & 0x00000010u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->json_name().data(), this->json_name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -4646,10 +4747,13 @@
 
 ::google::protobuf::uint8* FieldDescriptorProto::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldDescriptorProto)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -4660,7 +4764,7 @@
   }
 
   // optional string extendee = 2;
-  if (has_extendee()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->extendee().data(), this->extendee().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -4671,24 +4775,24 @@
   }
 
   // optional int32 number = 3;
-  if (has_number()) {
+  if (cached_has_bits & 0x00000040u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->number(), target);
   }
 
   // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
-  if (has_label()) {
+  if (cached_has_bits & 0x00000100u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
       4, this->label(), target);
   }
 
   // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
-  if (has_type()) {
+  if (cached_has_bits & 0x00000200u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
       5, this->type(), target);
   }
 
   // optional string type_name = 6;
-  if (has_type_name()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->type_name().data(), this->type_name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -4699,7 +4803,7 @@
   }
 
   // optional string default_value = 7;
-  if (has_default_value()) {
+  if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->default_value().data(), this->default_value().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -4710,19 +4814,19 @@
   }
 
   // optional .google.protobuf.FieldOptions options = 8;
-  if (has_options()) {
+  if (cached_has_bits & 0x00000020u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        8, *this->options_, false, target);
+        8, *this->options_, deterministic, target);
   }
 
   // optional int32 oneof_index = 9;
-  if (has_oneof_index()) {
+  if (cached_has_bits & 0x00000080u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(9, this->oneof_index(), target);
   }
 
   // optional string json_name = 10;
-  if (has_json_name()) {
+  if (cached_has_bits & 0x00000010u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->json_name().data(), this->json_name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -4757,13 +4861,6 @@
           this->name());
     }
 
-    // optional string type_name = 6;
-    if (has_type_name()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::StringSize(
-          this->type_name());
-    }
-
     // optional string extendee = 2;
     if (has_extendee()) {
       total_size += 1 +
@@ -4771,6 +4868,13 @@
           this->extendee());
     }
 
+    // optional string type_name = 6;
+    if (has_type_name()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->type_name());
+    }
+
     // optional string default_value = 7;
     if (has_default_value()) {
       total_size += 1 +
@@ -4847,44 +4951,50 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldDescriptorProto)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
-  if (from._has_bits_[0 / 32] & 255u) {
-    if (from.has_name()) {
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 255u) {
+    if (cached_has_bits & 0x00000001u) {
       set_has_name();
       name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
     }
-    if (from.has_type_name()) {
-      set_has_type_name();
-      type_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_name_);
-    }
-    if (from.has_extendee()) {
+    if (cached_has_bits & 0x00000002u) {
       set_has_extendee();
       extendee_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.extendee_);
     }
-    if (from.has_default_value()) {
+    if (cached_has_bits & 0x00000004u) {
+      set_has_type_name();
+      type_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_name_);
+    }
+    if (cached_has_bits & 0x00000008u) {
       set_has_default_value();
       default_value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.default_value_);
     }
-    if (from.has_json_name()) {
+    if (cached_has_bits & 0x00000010u) {
       set_has_json_name();
       json_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.json_name_);
     }
-    if (from.has_options()) {
+    if (cached_has_bits & 0x00000020u) {
       mutable_options()->::google::protobuf::FieldOptions::MergeFrom(from.options());
     }
-    if (from.has_number()) {
-      set_number(from.number());
+    if (cached_has_bits & 0x00000040u) {
+      number_ = from.number_;
     }
-    if (from.has_oneof_index()) {
-      set_oneof_index(from.oneof_index());
+    if (cached_has_bits & 0x00000080u) {
+      oneof_index_ = from.oneof_index_;
     }
+    _has_bits_[0] |= cached_has_bits;
   }
-  if (from._has_bits_[8 / 32] & 768u) {
-    if (from.has_label()) {
-      set_label(from.label());
+  if (cached_has_bits & 768u) {
+    if (cached_has_bits & 0x00000100u) {
+      label_ = from.label_;
     }
-    if (from.has_type()) {
-      set_type(from.type());
+    if (cached_has_bits & 0x00000200u) {
+      type_ = from.type_;
     }
+    _has_bits_[0] |= cached_has_bits;
   }
 }
 
@@ -4915,8 +5025,8 @@
 }
 void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) {
   name_.Swap(&other->name_);
-  type_name_.Swap(&other->type_name_);
   extendee_.Swap(&other->extendee_);
+  type_name_.Swap(&other->type_name_);
   default_value_.Swap(&other->default_value_);
   json_name_.Swap(&other->json_name_);
   std::swap(options_, other->options_);
@@ -4931,7 +5041,7 @@
 
 ::google::protobuf::Metadata FieldDescriptorProto::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[5];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -4969,6 +5079,7 @@
 }
 #endif
 void FieldDescriptorProto::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.name)
@@ -5075,13 +5186,13 @@
 
 // optional string type_name = 6;
 bool FieldDescriptorProto::has_type_name() const {
-  return (_has_bits_[0] & 0x00000002u) != 0;
+  return (_has_bits_[0] & 0x00000004u) != 0;
 }
 void FieldDescriptorProto::set_has_type_name() {
-  _has_bits_[0] |= 0x00000002u;
+  _has_bits_[0] |= 0x00000004u;
 }
 void FieldDescriptorProto::clear_has_type_name() {
-  _has_bits_[0] &= ~0x00000002u;
+  _has_bits_[0] &= ~0x00000004u;
 }
 void FieldDescriptorProto::clear_type_name() {
   type_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -5105,6 +5216,7 @@
 }
 #endif
 void FieldDescriptorProto::set_type_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -5137,13 +5249,13 @@
 
 // optional string extendee = 2;
 bool FieldDescriptorProto::has_extendee() const {
-  return (_has_bits_[0] & 0x00000004u) != 0;
+  return (_has_bits_[0] & 0x00000002u) != 0;
 }
 void FieldDescriptorProto::set_has_extendee() {
-  _has_bits_[0] |= 0x00000004u;
+  _has_bits_[0] |= 0x00000002u;
 }
 void FieldDescriptorProto::clear_has_extendee() {
-  _has_bits_[0] &= ~0x00000004u;
+  _has_bits_[0] &= ~0x00000002u;
 }
 void FieldDescriptorProto::clear_extendee() {
   extendee_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -5167,6 +5279,7 @@
 }
 #endif
 void FieldDescriptorProto::set_extendee(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_extendee();
   extendee_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.extendee)
@@ -5229,6 +5342,7 @@
 }
 #endif
 void FieldDescriptorProto::set_default_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -5315,6 +5429,7 @@
 }
 #endif
 void FieldDescriptorProto::set_json_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_json_name();
   json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.json_name)
@@ -5450,7 +5565,7 @@
 }
 const ::google::protobuf::Descriptor* OneofDescriptorProto::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[6].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const OneofDescriptorProto& OneofDescriptorProto::default_instance() {
@@ -5545,8 +5660,12 @@
 void OneofDescriptorProto::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.OneofDescriptorProto)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -5556,7 +5675,7 @@
   }
 
   // optional .google.protobuf.OneofOptions options = 2;
-  if (has_options()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
       2, *this->options_, output);
   }
@@ -5570,10 +5689,13 @@
 
 ::google::protobuf::uint8* OneofDescriptorProto::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofDescriptorProto)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -5584,10 +5706,10 @@
   }
 
   // optional .google.protobuf.OneofOptions options = 2;
-  if (has_options()) {
+  if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        2, *this->options_, false, target);
+        2, *this->options_, deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -5649,12 +5771,16 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofDescriptorProto)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
-  if (from._has_bits_[0 / 32] & 3u) {
-    if (from.has_name()) {
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 3u) {
+    if (cached_has_bits & 0x00000001u) {
       set_has_name();
       name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
     }
-    if (from.has_options()) {
+    if (cached_has_bits & 0x00000002u) {
       mutable_options()->::google::protobuf::OneofOptions::MergeFrom(from.options());
     }
   }
@@ -5695,7 +5821,7 @@
 
 ::google::protobuf::Metadata OneofDescriptorProto::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[6];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -5733,6 +5859,7 @@
 }
 #endif
 void OneofDescriptorProto::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.OneofDescriptorProto.name)
@@ -5870,7 +5997,7 @@
 }
 const ::google::protobuf::Descriptor* EnumDescriptorProto::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[7].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const EnumDescriptorProto& EnumDescriptorProto::default_instance() {
@@ -5933,13 +6060,11 @@
       case 2: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(18u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_value()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -5980,8 +6105,12 @@
 void EnumDescriptorProto::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.EnumDescriptorProto)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -5997,7 +6126,7 @@
   }
 
   // optional .google.protobuf.EnumOptions options = 3;
-  if (has_options()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
       3, *this->options_, output);
   }
@@ -6011,10 +6140,13 @@
 
 ::google::protobuf::uint8* EnumDescriptorProto::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumDescriptorProto)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -6028,14 +6160,14 @@
   for (unsigned int i = 0, n = this->value_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        2, this->value(i), false, target);
+        2, this->value(i), deterministic, target);
   }
 
   // optional .google.protobuf.EnumOptions options = 3;
-  if (has_options()) {
+  if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        3, *this->options_, false, target);
+        3, *this->options_, deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -6108,13 +6240,17 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   value_.MergeFrom(from.value_);
-  if (from._has_bits_[0 / 32] & 3u) {
-    if (from.has_name()) {
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 3u) {
+    if (cached_has_bits & 0x00000001u) {
       set_has_name();
       name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
     }
-    if (from.has_options()) {
+    if (cached_has_bits & 0x00000002u) {
       mutable_options()->::google::protobuf::EnumOptions::MergeFrom(from.options());
     }
   }
@@ -6147,7 +6283,7 @@
   InternalSwap(other);
 }
 void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* other) {
-  value_.UnsafeArenaSwap(&other->value_);
+  value_.InternalSwap(&other->value_);
   name_.Swap(&other->name_);
   std::swap(options_, other->options_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
@@ -6157,7 +6293,7 @@
 
 ::google::protobuf::Metadata EnumDescriptorProto::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[7];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -6195,6 +6331,7 @@
 }
 #endif
 void EnumDescriptorProto::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.EnumDescriptorProto.name)
@@ -6363,7 +6500,7 @@
 }
 const ::google::protobuf::Descriptor* EnumValueDescriptorProto::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[8].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const EnumValueDescriptorProto& EnumValueDescriptorProto::default_instance() {
@@ -6473,8 +6610,12 @@
 void EnumValueDescriptorProto::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.EnumValueDescriptorProto)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -6484,12 +6625,12 @@
   }
 
   // optional int32 number = 2;
-  if (has_number()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->number(), output);
   }
 
   // optional .google.protobuf.EnumValueOptions options = 3;
-  if (has_options()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
       3, *this->options_, output);
   }
@@ -6503,10 +6644,13 @@
 
 ::google::protobuf::uint8* EnumValueDescriptorProto::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueDescriptorProto)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -6517,15 +6661,15 @@
   }
 
   // optional int32 number = 2;
-  if (has_number()) {
+  if (cached_has_bits & 0x00000004u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->number(), target);
   }
 
   // optional .google.protobuf.EnumValueOptions options = 3;
-  if (has_options()) {
+  if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        3, *this->options_, false, target);
+        3, *this->options_, deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -6594,17 +6738,22 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueDescriptorProto)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
-  if (from._has_bits_[0 / 32] & 7u) {
-    if (from.has_name()) {
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 7u) {
+    if (cached_has_bits & 0x00000001u) {
       set_has_name();
       name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
     }
-    if (from.has_options()) {
+    if (cached_has_bits & 0x00000002u) {
       mutable_options()->::google::protobuf::EnumValueOptions::MergeFrom(from.options());
     }
-    if (from.has_number()) {
-      set_number(from.number());
+    if (cached_has_bits & 0x00000004u) {
+      number_ = from.number_;
     }
+    _has_bits_[0] |= cached_has_bits;
   }
 }
 
@@ -6644,7 +6793,7 @@
 
 ::google::protobuf::Metadata EnumValueDescriptorProto::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[8];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -6682,6 +6831,7 @@
 }
 #endif
 void EnumValueDescriptorProto::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValueDescriptorProto.name)
@@ -6843,7 +6993,7 @@
 }
 const ::google::protobuf::Descriptor* ServiceDescriptorProto::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[9].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const ServiceDescriptorProto& ServiceDescriptorProto::default_instance() {
@@ -6906,13 +7056,11 @@
       case 2: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(18u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_method()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -6953,8 +7101,12 @@
 void ServiceDescriptorProto::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.ServiceDescriptorProto)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -6970,7 +7122,7 @@
   }
 
   // optional .google.protobuf.ServiceOptions options = 3;
-  if (has_options()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
       3, *this->options_, output);
   }
@@ -6984,10 +7136,13 @@
 
 ::google::protobuf::uint8* ServiceDescriptorProto::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceDescriptorProto)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -7001,14 +7156,14 @@
   for (unsigned int i = 0, n = this->method_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        2, this->method(i), false, target);
+        2, this->method(i), deterministic, target);
   }
 
   // optional .google.protobuf.ServiceOptions options = 3;
-  if (has_options()) {
+  if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        3, *this->options_, false, target);
+        3, *this->options_, deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -7081,13 +7236,17 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceDescriptorProto)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   method_.MergeFrom(from.method_);
-  if (from._has_bits_[0 / 32] & 3u) {
-    if (from.has_name()) {
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 3u) {
+    if (cached_has_bits & 0x00000001u) {
       set_has_name();
       name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
     }
-    if (from.has_options()) {
+    if (cached_has_bits & 0x00000002u) {
       mutable_options()->::google::protobuf::ServiceOptions::MergeFrom(from.options());
     }
   }
@@ -7120,7 +7279,7 @@
   InternalSwap(other);
 }
 void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* other) {
-  method_.UnsafeArenaSwap(&other->method_);
+  method_.InternalSwap(&other->method_);
   name_.Swap(&other->name_);
   std::swap(options_, other->options_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
@@ -7130,7 +7289,7 @@
 
 ::google::protobuf::Metadata ServiceDescriptorProto::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[9];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -7168,6 +7327,7 @@
 }
 #endif
 void ServiceDescriptorProto::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.ServiceDescriptorProto.name)
@@ -7353,7 +7513,7 @@
 }
 const ::google::protobuf::Descriptor* MethodDescriptorProto::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[10].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const MethodDescriptorProto& MethodDescriptorProto::default_instance() {
@@ -7520,8 +7680,12 @@
 void MethodDescriptorProto::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.MethodDescriptorProto)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -7531,7 +7695,7 @@
   }
 
   // optional string input_type = 2;
-  if (has_input_type()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->input_type().data(), this->input_type().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -7541,7 +7705,7 @@
   }
 
   // optional string output_type = 3;
-  if (has_output_type()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->output_type().data(), this->output_type().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -7551,18 +7715,18 @@
   }
 
   // optional .google.protobuf.MethodOptions options = 4;
-  if (has_options()) {
+  if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
       4, *this->options_, output);
   }
 
   // optional bool client_streaming = 5 [default = false];
-  if (has_client_streaming()) {
+  if (cached_has_bits & 0x00000010u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->client_streaming(), output);
   }
 
   // optional bool server_streaming = 6 [default = false];
-  if (has_server_streaming()) {
+  if (cached_has_bits & 0x00000020u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(6, this->server_streaming(), output);
   }
 
@@ -7575,10 +7739,13 @@
 
 ::google::protobuf::uint8* MethodDescriptorProto::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodDescriptorProto)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string name = 1;
-  if (has_name()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name().data(), this->name().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -7589,7 +7756,7 @@
   }
 
   // optional string input_type = 2;
-  if (has_input_type()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->input_type().data(), this->input_type().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -7600,7 +7767,7 @@
   }
 
   // optional string output_type = 3;
-  if (has_output_type()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->output_type().data(), this->output_type().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -7611,19 +7778,19 @@
   }
 
   // optional .google.protobuf.MethodOptions options = 4;
-  if (has_options()) {
+  if (cached_has_bits & 0x00000008u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        4, *this->options_, false, target);
+        4, *this->options_, deterministic, target);
   }
 
   // optional bool client_streaming = 5 [default = false];
-  if (has_client_streaming()) {
+  if (cached_has_bits & 0x00000010u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->client_streaming(), target);
   }
 
   // optional bool server_streaming = 6 [default = false];
-  if (has_server_streaming()) {
+  if (cached_has_bits & 0x00000020u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(6, this->server_streaming(), target);
   }
 
@@ -7710,28 +7877,33 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodDescriptorProto)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
-  if (from._has_bits_[0 / 32] & 63u) {
-    if (from.has_name()) {
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 63u) {
+    if (cached_has_bits & 0x00000001u) {
       set_has_name();
       name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
     }
-    if (from.has_input_type()) {
+    if (cached_has_bits & 0x00000002u) {
       set_has_input_type();
       input_type_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.input_type_);
     }
-    if (from.has_output_type()) {
+    if (cached_has_bits & 0x00000004u) {
       set_has_output_type();
       output_type_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.output_type_);
     }
-    if (from.has_options()) {
+    if (cached_has_bits & 0x00000008u) {
       mutable_options()->::google::protobuf::MethodOptions::MergeFrom(from.options());
     }
-    if (from.has_client_streaming()) {
-      set_client_streaming(from.client_streaming());
+    if (cached_has_bits & 0x00000010u) {
+      client_streaming_ = from.client_streaming_;
     }
-    if (from.has_server_streaming()) {
-      set_server_streaming(from.server_streaming());
+    if (cached_has_bits & 0x00000020u) {
+      server_streaming_ = from.server_streaming_;
     }
+    _has_bits_[0] |= cached_has_bits;
   }
 }
 
@@ -7774,7 +7946,7 @@
 
 ::google::protobuf::Metadata MethodDescriptorProto::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[10];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -7812,6 +7984,7 @@
 }
 #endif
 void MethodDescriptorProto::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.name)
@@ -7874,6 +8047,7 @@
 }
 #endif
 void MethodDescriptorProto::set_input_type(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -7936,6 +8110,7 @@
 }
 #endif
 void MethodDescriptorProto::set_output_type(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -8169,7 +8344,7 @@
 }
 const ::google::protobuf::Descriptor* FileOptions::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[11].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const FileOptions& FileOptions::default_instance() {
@@ -8486,13 +8661,11 @@
       case 999: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(7994u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_uninterpreted_option()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -8526,8 +8699,12 @@
 void FileOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.FileOptions)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string java_package = 1;
-  if (has_java_package()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->java_package().data(), this->java_package().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -8537,7 +8714,7 @@
   }
 
   // optional string java_outer_classname = 8;
-  if (has_java_outer_classname()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->java_outer_classname().data(), this->java_outer_classname().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -8547,18 +8724,18 @@
   }
 
   // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
-  if (has_optimize_for()) {
+  if (cached_has_bits & 0x00008000u) {
     ::google::protobuf::internal::WireFormatLite::WriteEnum(
       9, this->optimize_for(), output);
   }
 
   // optional bool java_multiple_files = 10 [default = false];
-  if (has_java_multiple_files()) {
+  if (cached_has_bits & 0x00000080u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->java_multiple_files(), output);
   }
 
   // optional string go_package = 11;
-  if (has_go_package()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->go_package().data(), this->go_package().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -8568,42 +8745,42 @@
   }
 
   // optional bool cc_generic_services = 16 [default = false];
-  if (has_cc_generic_services()) {
+  if (cached_has_bits & 0x00000400u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(16, this->cc_generic_services(), output);
   }
 
   // optional bool java_generic_services = 17 [default = false];
-  if (has_java_generic_services()) {
+  if (cached_has_bits & 0x00000800u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(17, this->java_generic_services(), output);
   }
 
   // optional bool py_generic_services = 18 [default = false];
-  if (has_py_generic_services()) {
+  if (cached_has_bits & 0x00001000u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(18, this->py_generic_services(), output);
   }
 
   // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
-  if (has_java_generate_equals_and_hash()) {
+  if (cached_has_bits & 0x00000100u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(20, this->java_generate_equals_and_hash(), output);
   }
 
   // optional bool deprecated = 23 [default = false];
-  if (has_deprecated()) {
+  if (cached_has_bits & 0x00002000u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(23, this->deprecated(), output);
   }
 
   // optional bool java_string_check_utf8 = 27 [default = false];
-  if (has_java_string_check_utf8()) {
+  if (cached_has_bits & 0x00000200u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(27, this->java_string_check_utf8(), output);
   }
 
   // optional bool cc_enable_arenas = 31 [default = false];
-  if (has_cc_enable_arenas()) {
+  if (cached_has_bits & 0x00004000u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(31, this->cc_enable_arenas(), output);
   }
 
   // optional string objc_class_prefix = 36;
-  if (has_objc_class_prefix()) {
+  if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->objc_class_prefix().data(), this->objc_class_prefix().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -8613,7 +8790,7 @@
   }
 
   // optional string csharp_namespace = 37;
-  if (has_csharp_namespace()) {
+  if (cached_has_bits & 0x00000010u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->csharp_namespace().data(), this->csharp_namespace().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -8623,7 +8800,7 @@
   }
 
   // optional string swift_prefix = 39;
-  if (has_swift_prefix()) {
+  if (cached_has_bits & 0x00000020u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->swift_prefix().data(), this->swift_prefix().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -8633,7 +8810,7 @@
   }
 
   // optional string php_class_prefix = 40;
-  if (has_php_class_prefix()) {
+  if (cached_has_bits & 0x00000040u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->php_class_prefix().data(), this->php_class_prefix().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -8661,10 +8838,13 @@
 
 ::google::protobuf::uint8* FileOptions::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileOptions)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional string java_package = 1;
-  if (has_java_package()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->java_package().data(), this->java_package().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -8675,7 +8855,7 @@
   }
 
   // optional string java_outer_classname = 8;
-  if (has_java_outer_classname()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->java_outer_classname().data(), this->java_outer_classname().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -8686,18 +8866,18 @@
   }
 
   // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
-  if (has_optimize_for()) {
+  if (cached_has_bits & 0x00008000u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
       9, this->optimize_for(), target);
   }
 
   // optional bool java_multiple_files = 10 [default = false];
-  if (has_java_multiple_files()) {
+  if (cached_has_bits & 0x00000080u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->java_multiple_files(), target);
   }
 
   // optional string go_package = 11;
-  if (has_go_package()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->go_package().data(), this->go_package().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -8708,42 +8888,42 @@
   }
 
   // optional bool cc_generic_services = 16 [default = false];
-  if (has_cc_generic_services()) {
+  if (cached_has_bits & 0x00000400u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(16, this->cc_generic_services(), target);
   }
 
   // optional bool java_generic_services = 17 [default = false];
-  if (has_java_generic_services()) {
+  if (cached_has_bits & 0x00000800u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(17, this->java_generic_services(), target);
   }
 
   // optional bool py_generic_services = 18 [default = false];
-  if (has_py_generic_services()) {
+  if (cached_has_bits & 0x00001000u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(18, this->py_generic_services(), target);
   }
 
   // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
-  if (has_java_generate_equals_and_hash()) {
+  if (cached_has_bits & 0x00000100u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(20, this->java_generate_equals_and_hash(), target);
   }
 
   // optional bool deprecated = 23 [default = false];
-  if (has_deprecated()) {
+  if (cached_has_bits & 0x00002000u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(23, this->deprecated(), target);
   }
 
   // optional bool java_string_check_utf8 = 27 [default = false];
-  if (has_java_string_check_utf8()) {
+  if (cached_has_bits & 0x00000200u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(27, this->java_string_check_utf8(), target);
   }
 
   // optional bool cc_enable_arenas = 31 [default = false];
-  if (has_cc_enable_arenas()) {
+  if (cached_has_bits & 0x00004000u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(31, this->cc_enable_arenas(), target);
   }
 
   // optional string objc_class_prefix = 36;
-  if (has_objc_class_prefix()) {
+  if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->objc_class_prefix().data(), this->objc_class_prefix().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -8754,7 +8934,7 @@
   }
 
   // optional string csharp_namespace = 37;
-  if (has_csharp_namespace()) {
+  if (cached_has_bits & 0x00000010u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->csharp_namespace().data(), this->csharp_namespace().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -8765,7 +8945,7 @@
   }
 
   // optional string swift_prefix = 39;
-  if (has_swift_prefix()) {
+  if (cached_has_bits & 0x00000020u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->swift_prefix().data(), this->swift_prefix().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -8776,7 +8956,7 @@
   }
 
   // optional string php_class_prefix = 40;
-  if (has_php_class_prefix()) {
+  if (cached_has_bits & 0x00000040u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->php_class_prefix().data(), this->php_class_prefix().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -8790,7 +8970,7 @@
   for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), false, target);
+        999, this->uninterpreted_option(i), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -8953,65 +9133,71 @@
   GOOGLE_DCHECK_NE(&from, this);
   _extensions_.MergeFrom(from._extensions_);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
-  if (from._has_bits_[0 / 32] & 255u) {
-    if (from.has_java_package()) {
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 255u) {
+    if (cached_has_bits & 0x00000001u) {
       set_has_java_package();
       java_package_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.java_package_);
     }
-    if (from.has_java_outer_classname()) {
+    if (cached_has_bits & 0x00000002u) {
       set_has_java_outer_classname();
       java_outer_classname_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.java_outer_classname_);
     }
-    if (from.has_go_package()) {
+    if (cached_has_bits & 0x00000004u) {
       set_has_go_package();
       go_package_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.go_package_);
     }
-    if (from.has_objc_class_prefix()) {
+    if (cached_has_bits & 0x00000008u) {
       set_has_objc_class_prefix();
       objc_class_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.objc_class_prefix_);
     }
-    if (from.has_csharp_namespace()) {
+    if (cached_has_bits & 0x00000010u) {
       set_has_csharp_namespace();
       csharp_namespace_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.csharp_namespace_);
     }
-    if (from.has_swift_prefix()) {
+    if (cached_has_bits & 0x00000020u) {
       set_has_swift_prefix();
       swift_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.swift_prefix_);
     }
-    if (from.has_php_class_prefix()) {
+    if (cached_has_bits & 0x00000040u) {
       set_has_php_class_prefix();
       php_class_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.php_class_prefix_);
     }
-    if (from.has_java_multiple_files()) {
-      set_java_multiple_files(from.java_multiple_files());
+    if (cached_has_bits & 0x00000080u) {
+      java_multiple_files_ = from.java_multiple_files_;
     }
+    _has_bits_[0] |= cached_has_bits;
   }
-  if (from._has_bits_[8 / 32] & 65280u) {
-    if (from.has_java_generate_equals_and_hash()) {
-      set_java_generate_equals_and_hash(from.java_generate_equals_and_hash());
+  if (cached_has_bits & 65280u) {
+    if (cached_has_bits & 0x00000100u) {
+      java_generate_equals_and_hash_ = from.java_generate_equals_and_hash_;
     }
-    if (from.has_java_string_check_utf8()) {
-      set_java_string_check_utf8(from.java_string_check_utf8());
+    if (cached_has_bits & 0x00000200u) {
+      java_string_check_utf8_ = from.java_string_check_utf8_;
     }
-    if (from.has_cc_generic_services()) {
-      set_cc_generic_services(from.cc_generic_services());
+    if (cached_has_bits & 0x00000400u) {
+      cc_generic_services_ = from.cc_generic_services_;
     }
-    if (from.has_java_generic_services()) {
-      set_java_generic_services(from.java_generic_services());
+    if (cached_has_bits & 0x00000800u) {
+      java_generic_services_ = from.java_generic_services_;
     }
-    if (from.has_py_generic_services()) {
-      set_py_generic_services(from.py_generic_services());
+    if (cached_has_bits & 0x00001000u) {
+      py_generic_services_ = from.py_generic_services_;
     }
-    if (from.has_deprecated()) {
-      set_deprecated(from.deprecated());
+    if (cached_has_bits & 0x00002000u) {
+      deprecated_ = from.deprecated_;
     }
-    if (from.has_cc_enable_arenas()) {
-      set_cc_enable_arenas(from.cc_enable_arenas());
+    if (cached_has_bits & 0x00004000u) {
+      cc_enable_arenas_ = from.cc_enable_arenas_;
     }
-    if (from.has_optimize_for()) {
-      set_optimize_for(from.optimize_for());
+    if (cached_has_bits & 0x00008000u) {
+      optimize_for_ = from.optimize_for_;
     }
+    _has_bits_[0] |= cached_has_bits;
   }
 }
 
@@ -9043,7 +9229,7 @@
   InternalSwap(other);
 }
 void FileOptions::InternalSwap(FileOptions* other) {
-  uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_);
+  uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
   java_package_.Swap(&other->java_package_);
   java_outer_classname_.Swap(&other->java_outer_classname_);
   go_package_.Swap(&other->go_package_);
@@ -9068,7 +9254,7 @@
 
 ::google::protobuf::Metadata FileOptions::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[11];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -9106,6 +9292,7 @@
 }
 #endif
 void FileOptions::set_java_package(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -9168,6 +9355,7 @@
 }
 #endif
 void FileOptions::set_java_outer_classname(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -9327,6 +9515,7 @@
 }
 #endif
 void FileOptions::set_go_package(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -9509,6 +9698,7 @@
 }
 #endif
 void FileOptions::set_objc_class_prefix(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -9571,6 +9761,7 @@
 }
 #endif
 void FileOptions::set_csharp_namespace(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_csharp_namespace();
   csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_namespace)
@@ -9633,6 +9824,7 @@
 }
 #endif
 void FileOptions::set_swift_prefix(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_swift_prefix();
   swift_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.swift_prefix)
@@ -9695,6 +9887,7 @@
 }
 #endif
 void FileOptions::set_php_class_prefix(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_php_class_prefix();
   php_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_class_prefix)
@@ -9810,7 +10003,7 @@
 }
 const ::google::protobuf::Descriptor* MessageOptions::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[12].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const MessageOptions& MessageOptions::default_instance() {
@@ -9908,13 +10101,11 @@
       case 999: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(7994u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_uninterpreted_option()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -9948,23 +10139,27 @@
 void MessageOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.MessageOptions)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional bool message_set_wire_format = 1 [default = false];
-  if (has_message_set_wire_format()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->message_set_wire_format(), output);
   }
 
   // optional bool no_standard_descriptor_accessor = 2 [default = false];
-  if (has_no_standard_descriptor_accessor()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->no_standard_descriptor_accessor(), output);
   }
 
   // optional bool deprecated = 3 [default = false];
-  if (has_deprecated()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
   }
 
   // optional bool map_entry = 7;
-  if (has_map_entry()) {
+  if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(7, this->map_entry(), output);
   }
 
@@ -9987,25 +10182,28 @@
 
 ::google::protobuf::uint8* MessageOptions::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MessageOptions)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional bool message_set_wire_format = 1 [default = false];
-  if (has_message_set_wire_format()) {
+  if (cached_has_bits & 0x00000001u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->message_set_wire_format(), target);
   }
 
   // optional bool no_standard_descriptor_accessor = 2 [default = false];
-  if (has_no_standard_descriptor_accessor()) {
+  if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->no_standard_descriptor_accessor(), target);
   }
 
   // optional bool deprecated = 3 [default = false];
-  if (has_deprecated()) {
+  if (cached_has_bits & 0x00000004u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
   }
 
   // optional bool map_entry = 7;
-  if (has_map_entry()) {
+  if (cached_has_bits & 0x00000008u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(7, this->map_entry(), target);
   }
 
@@ -10013,7 +10211,7 @@
   for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), false, target);
+        999, this->uninterpreted_option(i), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -10099,20 +10297,25 @@
   GOOGLE_DCHECK_NE(&from, this);
   _extensions_.MergeFrom(from._extensions_);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
-  if (from._has_bits_[0 / 32] & 15u) {
-    if (from.has_message_set_wire_format()) {
-      set_message_set_wire_format(from.message_set_wire_format());
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 15u) {
+    if (cached_has_bits & 0x00000001u) {
+      message_set_wire_format_ = from.message_set_wire_format_;
     }
-    if (from.has_no_standard_descriptor_accessor()) {
-      set_no_standard_descriptor_accessor(from.no_standard_descriptor_accessor());
+    if (cached_has_bits & 0x00000002u) {
+      no_standard_descriptor_accessor_ = from.no_standard_descriptor_accessor_;
     }
-    if (from.has_deprecated()) {
-      set_deprecated(from.deprecated());
+    if (cached_has_bits & 0x00000004u) {
+      deprecated_ = from.deprecated_;
     }
-    if (from.has_map_entry()) {
-      set_map_entry(from.map_entry());
+    if (cached_has_bits & 0x00000008u) {
+      map_entry_ = from.map_entry_;
     }
+    _has_bits_[0] |= cached_has_bits;
   }
 }
 
@@ -10144,7 +10347,7 @@
   InternalSwap(other);
 }
 void MessageOptions::InternalSwap(MessageOptions* other) {
-  uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_);
+  uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
   std::swap(message_set_wire_format_, other->message_set_wire_format_);
   std::swap(no_standard_descriptor_accessor_, other->no_standard_descriptor_accessor_);
   std::swap(deprecated_, other->deprecated_);
@@ -10157,7 +10360,7 @@
 
 ::google::protobuf::Metadata MessageOptions::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[12];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -10320,15 +10523,15 @@
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   _extensions_.MergeFrom(from._extensions_);
   ::memcpy(&ctype_, &from.ctype_,
-    reinterpret_cast<char*>(&weak_) -
-    reinterpret_cast<char*>(&ctype_) + sizeof(weak_));
+    reinterpret_cast<char*>(&jstype_) -
+    reinterpret_cast<char*>(&ctype_) + sizeof(jstype_));
   // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldOptions)
 }
 
 void FieldOptions::SharedCtor() {
   _cached_size_ = 0;
-  ::memset(&ctype_, 0, reinterpret_cast<char*>(&weak_) -
-    reinterpret_cast<char*>(&ctype_) + sizeof(weak_));
+  ::memset(&ctype_, 0, reinterpret_cast<char*>(&jstype_) -
+    reinterpret_cast<char*>(&ctype_) + sizeof(jstype_));
 }
 
 FieldOptions::~FieldOptions() {
@@ -10346,7 +10549,7 @@
 }
 const ::google::protobuf::Descriptor* FieldOptions::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[13].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const FieldOptions& FieldOptions::default_instance() {
@@ -10367,8 +10570,8 @@
   _extensions_.Clear();
   uninterpreted_option_.Clear();
   if (_has_bits_[0 / 32] & 63u) {
-    ::memset(&ctype_, 0, reinterpret_cast<char*>(&weak_) -
-      reinterpret_cast<char*>(&ctype_) + sizeof(weak_));
+    ::memset(&ctype_, 0, reinterpret_cast<char*>(&jstype_) -
+      reinterpret_cast<char*>(&ctype_) + sizeof(jstype_));
   }
   _has_bits_.Clear();
   _internal_metadata_.Clear();
@@ -10482,13 +10685,11 @@
       case 999: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(7994u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_uninterpreted_option()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -10522,35 +10723,39 @@
 void FieldOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.FieldOptions)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
-  if (has_ctype()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormatLite::WriteEnum(
       1, this->ctype(), output);
   }
 
   // optional bool packed = 2;
-  if (has_packed()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->packed(), output);
   }
 
   // optional bool deprecated = 3 [default = false];
-  if (has_deprecated()) {
+  if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
   }
 
   // optional bool lazy = 5 [default = false];
-  if (has_lazy()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->lazy(), output);
   }
 
   // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
-  if (has_jstype()) {
+  if (cached_has_bits & 0x00000020u) {
     ::google::protobuf::internal::WireFormatLite::WriteEnum(
       6, this->jstype(), output);
   }
 
   // optional bool weak = 10 [default = false];
-  if (has_weak()) {
+  if (cached_has_bits & 0x00000010u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->weak(), output);
   }
 
@@ -10573,37 +10778,40 @@
 
 ::google::protobuf::uint8* FieldOptions::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldOptions)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
-  if (has_ctype()) {
+  if (cached_has_bits & 0x00000001u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
       1, this->ctype(), target);
   }
 
   // optional bool packed = 2;
-  if (has_packed()) {
+  if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->packed(), target);
   }
 
   // optional bool deprecated = 3 [default = false];
-  if (has_deprecated()) {
+  if (cached_has_bits & 0x00000008u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
   }
 
   // optional bool lazy = 5 [default = false];
-  if (has_lazy()) {
+  if (cached_has_bits & 0x00000004u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->lazy(), target);
   }
 
   // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
-  if (has_jstype()) {
+  if (cached_has_bits & 0x00000020u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
       6, this->jstype(), target);
   }
 
   // optional bool weak = 10 [default = false];
-  if (has_weak()) {
+  if (cached_has_bits & 0x00000010u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->weak(), target);
   }
 
@@ -10611,7 +10819,7 @@
   for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), false, target);
+        999, this->uninterpreted_option(i), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -10655,12 +10863,6 @@
         ::google::protobuf::internal::WireFormatLite::EnumSize(this->ctype());
     }
 
-    // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
-    if (has_jstype()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::EnumSize(this->jstype());
-    }
-
     // optional bool packed = 2;
     if (has_packed()) {
       total_size += 1 + 1;
@@ -10681,6 +10883,12 @@
       total_size += 1 + 1;
     }
 
+    // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
+    if (has_jstype()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::EnumSize(this->jstype());
+    }
+
   }
   int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
@@ -10709,26 +10917,31 @@
   GOOGLE_DCHECK_NE(&from, this);
   _extensions_.MergeFrom(from._extensions_);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
-  if (from._has_bits_[0 / 32] & 63u) {
-    if (from.has_ctype()) {
-      set_ctype(from.ctype());
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 63u) {
+    if (cached_has_bits & 0x00000001u) {
+      ctype_ = from.ctype_;
     }
-    if (from.has_jstype()) {
-      set_jstype(from.jstype());
+    if (cached_has_bits & 0x00000002u) {
+      packed_ = from.packed_;
     }
-    if (from.has_packed()) {
-      set_packed(from.packed());
+    if (cached_has_bits & 0x00000004u) {
+      lazy_ = from.lazy_;
     }
-    if (from.has_lazy()) {
-      set_lazy(from.lazy());
+    if (cached_has_bits & 0x00000008u) {
+      deprecated_ = from.deprecated_;
     }
-    if (from.has_deprecated()) {
-      set_deprecated(from.deprecated());
+    if (cached_has_bits & 0x00000010u) {
+      weak_ = from.weak_;
     }
-    if (from.has_weak()) {
-      set_weak(from.weak());
+    if (cached_has_bits & 0x00000020u) {
+      jstype_ = from.jstype_;
     }
+    _has_bits_[0] |= cached_has_bits;
   }
 }
 
@@ -10760,13 +10973,13 @@
   InternalSwap(other);
 }
 void FieldOptions::InternalSwap(FieldOptions* other) {
-  uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_);
+  uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
   std::swap(ctype_, other->ctype_);
-  std::swap(jstype_, other->jstype_);
   std::swap(packed_, other->packed_);
   std::swap(lazy_, other->lazy_);
   std::swap(deprecated_, other->deprecated_);
   std::swap(weak_, other->weak_);
+  std::swap(jstype_, other->jstype_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   std::swap(_cached_size_, other->_cached_size_);
@@ -10775,7 +10988,7 @@
 
 ::google::protobuf::Metadata FieldOptions::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[13];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -10808,13 +11021,13 @@
 
 // optional bool packed = 2;
 bool FieldOptions::has_packed() const {
-  return (_has_bits_[0] & 0x00000004u) != 0;
+  return (_has_bits_[0] & 0x00000002u) != 0;
 }
 void FieldOptions::set_has_packed() {
-  _has_bits_[0] |= 0x00000004u;
+  _has_bits_[0] |= 0x00000002u;
 }
 void FieldOptions::clear_has_packed() {
-  _has_bits_[0] &= ~0x00000004u;
+  _has_bits_[0] &= ~0x00000002u;
 }
 void FieldOptions::clear_packed() {
   packed_ = false;
@@ -10832,13 +11045,13 @@
 
 // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
 bool FieldOptions::has_jstype() const {
-  return (_has_bits_[0] & 0x00000002u) != 0;
+  return (_has_bits_[0] & 0x00000020u) != 0;
 }
 void FieldOptions::set_has_jstype() {
-  _has_bits_[0] |= 0x00000002u;
+  _has_bits_[0] |= 0x00000020u;
 }
 void FieldOptions::clear_has_jstype() {
-  _has_bits_[0] &= ~0x00000002u;
+  _has_bits_[0] &= ~0x00000020u;
 }
 void FieldOptions::clear_jstype() {
   jstype_ = 0;
@@ -10857,13 +11070,13 @@
 
 // optional bool lazy = 5 [default = false];
 bool FieldOptions::has_lazy() const {
-  return (_has_bits_[0] & 0x00000008u) != 0;
+  return (_has_bits_[0] & 0x00000004u) != 0;
 }
 void FieldOptions::set_has_lazy() {
-  _has_bits_[0] |= 0x00000008u;
+  _has_bits_[0] |= 0x00000004u;
 }
 void FieldOptions::clear_has_lazy() {
-  _has_bits_[0] &= ~0x00000008u;
+  _has_bits_[0] &= ~0x00000004u;
 }
 void FieldOptions::clear_lazy() {
   lazy_ = false;
@@ -10881,13 +11094,13 @@
 
 // optional bool deprecated = 3 [default = false];
 bool FieldOptions::has_deprecated() const {
-  return (_has_bits_[0] & 0x00000010u) != 0;
+  return (_has_bits_[0] & 0x00000008u) != 0;
 }
 void FieldOptions::set_has_deprecated() {
-  _has_bits_[0] |= 0x00000010u;
+  _has_bits_[0] |= 0x00000008u;
 }
 void FieldOptions::clear_has_deprecated() {
-  _has_bits_[0] &= ~0x00000010u;
+  _has_bits_[0] &= ~0x00000008u;
 }
 void FieldOptions::clear_deprecated() {
   deprecated_ = false;
@@ -10905,13 +11118,13 @@
 
 // optional bool weak = 10 [default = false];
 bool FieldOptions::has_weak() const {
-  return (_has_bits_[0] & 0x00000020u) != 0;
+  return (_has_bits_[0] & 0x00000010u) != 0;
 }
 void FieldOptions::set_has_weak() {
-  _has_bits_[0] |= 0x00000020u;
+  _has_bits_[0] |= 0x00000010u;
 }
 void FieldOptions::clear_has_weak() {
-  _has_bits_[0] &= ~0x00000020u;
+  _has_bits_[0] &= ~0x00000010u;
 }
 void FieldOptions::clear_weak() {
   weak_ = false;
@@ -11003,7 +11216,7 @@
 }
 const ::google::protobuf::Descriptor* OneofOptions::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[14].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const OneofOptions& OneofOptions::default_instance() {
@@ -11041,13 +11254,11 @@
       case 999: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(7994u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_uninterpreted_option()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -11081,6 +11292,9 @@
 void OneofOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.OneofOptions)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // 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(
@@ -11100,13 +11314,15 @@
 
 ::google::protobuf::uint8* OneofOptions::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofOptions)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // 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::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), false, target);
+        999, this->uninterpreted_option(i), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -11170,6 +11386,9 @@
   GOOGLE_DCHECK_NE(&from, this);
   _extensions_.MergeFrom(from._extensions_);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
 }
 
@@ -11201,7 +11420,7 @@
   InternalSwap(other);
 }
 void OneofOptions::InternalSwap(OneofOptions* other) {
-  uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_);
+  uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   std::swap(_cached_size_, other->_cached_size_);
@@ -11210,7 +11429,7 @@
 
 ::google::protobuf::Metadata OneofOptions::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[14];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -11299,7 +11518,7 @@
 }
 const ::google::protobuf::Descriptor* EnumOptions::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[15].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const EnumOptions& EnumOptions::default_instance() {
@@ -11369,13 +11588,11 @@
       case 999: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(7994u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_uninterpreted_option()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -11409,13 +11626,17 @@
 void EnumOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.EnumOptions)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional bool allow_alias = 2;
-  if (has_allow_alias()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->allow_alias(), output);
   }
 
   // optional bool deprecated = 3 [default = false];
-  if (has_deprecated()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
   }
 
@@ -11438,15 +11659,18 @@
 
 ::google::protobuf::uint8* EnumOptions::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumOptions)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional bool allow_alias = 2;
-  if (has_allow_alias()) {
+  if (cached_has_bits & 0x00000001u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->allow_alias(), target);
   }
 
   // optional bool deprecated = 3 [default = false];
-  if (has_deprecated()) {
+  if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
   }
 
@@ -11454,7 +11678,7 @@
   for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), false, target);
+        999, this->uninterpreted_option(i), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -11530,14 +11754,19 @@
   GOOGLE_DCHECK_NE(&from, this);
   _extensions_.MergeFrom(from._extensions_);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
-  if (from._has_bits_[0 / 32] & 3u) {
-    if (from.has_allow_alias()) {
-      set_allow_alias(from.allow_alias());
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 3u) {
+    if (cached_has_bits & 0x00000001u) {
+      allow_alias_ = from.allow_alias_;
     }
-    if (from.has_deprecated()) {
-      set_deprecated(from.deprecated());
+    if (cached_has_bits & 0x00000002u) {
+      deprecated_ = from.deprecated_;
     }
+    _has_bits_[0] |= cached_has_bits;
   }
 }
 
@@ -11569,7 +11798,7 @@
   InternalSwap(other);
 }
 void EnumOptions::InternalSwap(EnumOptions* other) {
-  uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_);
+  uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
   std::swap(allow_alias_, other->allow_alias_);
   std::swap(deprecated_, other->deprecated_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
@@ -11580,7 +11809,7 @@
 
 ::google::protobuf::Metadata EnumOptions::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[15];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -11713,7 +11942,7 @@
 }
 const ::google::protobuf::Descriptor* EnumValueOptions::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[16].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const EnumValueOptions& EnumValueOptions::default_instance() {
@@ -11766,13 +11995,11 @@
       case 999: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(7994u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_uninterpreted_option()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -11806,8 +12033,12 @@
 void EnumValueOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.EnumValueOptions)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional bool deprecated = 1 [default = false];
-  if (has_deprecated()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->deprecated(), output);
   }
 
@@ -11830,10 +12061,13 @@
 
 ::google::protobuf::uint8* EnumValueOptions::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueOptions)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional bool deprecated = 1 [default = false];
-  if (has_deprecated()) {
+  if (cached_has_bits & 0x00000001u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->deprecated(), target);
   }
 
@@ -11841,7 +12075,7 @@
   for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), false, target);
+        999, this->uninterpreted_option(i), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -11910,6 +12144,9 @@
   GOOGLE_DCHECK_NE(&from, this);
   _extensions_.MergeFrom(from._extensions_);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
   if (from.has_deprecated()) {
     set_deprecated(from.deprecated());
@@ -11944,7 +12181,7 @@
   InternalSwap(other);
 }
 void EnumValueOptions::InternalSwap(EnumValueOptions* other) {
-  uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_);
+  uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
   std::swap(deprecated_, other->deprecated_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
@@ -11954,7 +12191,7 @@
 
 ::google::protobuf::Metadata EnumValueOptions::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[16];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -12063,7 +12300,7 @@
 }
 const ::google::protobuf::Descriptor* ServiceOptions::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[17].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const ServiceOptions& ServiceOptions::default_instance() {
@@ -12116,13 +12353,11 @@
       case 999: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(7994u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_uninterpreted_option()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -12156,8 +12391,12 @@
 void ServiceOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.ServiceOptions)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional bool deprecated = 33 [default = false];
-  if (has_deprecated()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(33, this->deprecated(), output);
   }
 
@@ -12180,10 +12419,13 @@
 
 ::google::protobuf::uint8* ServiceOptions::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceOptions)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional bool deprecated = 33 [default = false];
-  if (has_deprecated()) {
+  if (cached_has_bits & 0x00000001u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(33, this->deprecated(), target);
   }
 
@@ -12191,7 +12433,7 @@
   for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), false, target);
+        999, this->uninterpreted_option(i), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -12260,6 +12502,9 @@
   GOOGLE_DCHECK_NE(&from, this);
   _extensions_.MergeFrom(from._extensions_);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
   if (from.has_deprecated()) {
     set_deprecated(from.deprecated());
@@ -12294,7 +12539,7 @@
   InternalSwap(other);
 }
 void ServiceOptions::InternalSwap(ServiceOptions* other) {
-  uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_);
+  uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
   std::swap(deprecated_, other->deprecated_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
@@ -12304,7 +12549,7 @@
 
 ::google::protobuf::Metadata ServiceOptions::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[17];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -12417,7 +12662,7 @@
 }
 const ::google::protobuf::Descriptor* MethodOptions::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[18].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const MethodOptions& MethodOptions::default_instance() {
@@ -12492,13 +12737,11 @@
       case 999: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(7994u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_uninterpreted_option()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -12532,13 +12775,17 @@
 void MethodOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.MethodOptions)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional bool deprecated = 33 [default = false];
-  if (has_deprecated()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(33, this->deprecated(), output);
   }
 
   // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
-  if (has_idempotency_level()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteEnum(
       34, this->idempotency_level(), output);
   }
@@ -12562,15 +12809,18 @@
 
 ::google::protobuf::uint8* MethodOptions::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodOptions)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // optional bool deprecated = 33 [default = false];
-  if (has_deprecated()) {
+  if (cached_has_bits & 0x00000001u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(33, this->deprecated(), target);
   }
 
   // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
-  if (has_idempotency_level()) {
+  if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
       34, this->idempotency_level(), target);
   }
@@ -12579,7 +12829,7 @@
   for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        999, this->uninterpreted_option(i), false, target);
+        999, this->uninterpreted_option(i), deterministic, target);
   }
 
   // Extension range [1000, 536870912)
@@ -12656,14 +12906,19 @@
   GOOGLE_DCHECK_NE(&from, this);
   _extensions_.MergeFrom(from._extensions_);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
-  if (from._has_bits_[0 / 32] & 3u) {
-    if (from.has_deprecated()) {
-      set_deprecated(from.deprecated());
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 3u) {
+    if (cached_has_bits & 0x00000001u) {
+      deprecated_ = from.deprecated_;
     }
-    if (from.has_idempotency_level()) {
-      set_idempotency_level(from.idempotency_level());
+    if (cached_has_bits & 0x00000002u) {
+      idempotency_level_ = from.idempotency_level_;
     }
+    _has_bits_[0] |= cached_has_bits;
   }
 }
 
@@ -12695,7 +12950,7 @@
   InternalSwap(other);
 }
 void MethodOptions::InternalSwap(MethodOptions* other) {
-  uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_);
+  uninterpreted_option_.InternalSwap(&other->uninterpreted_option_);
   std::swap(deprecated_, other->deprecated_);
   std::swap(idempotency_level_, other->idempotency_level_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
@@ -12706,7 +12961,7 @@
 
 ::google::protobuf::Metadata MethodOptions::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[18];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -12844,7 +13099,7 @@
 }
 const ::google::protobuf::Descriptor* UninterpretedOption_NamePart::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[19].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const UninterpretedOption_NamePart& UninterpretedOption_NamePart::default_instance() {
@@ -12936,8 +13191,12 @@
 void UninterpretedOption_NamePart::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.UninterpretedOption.NamePart)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // required string name_part = 1;
-  if (has_name_part()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name_part().data(), this->name_part().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -12947,7 +13206,7 @@
   }
 
   // required bool is_extension = 2;
-  if (has_is_extension()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->is_extension(), output);
   }
 
@@ -12960,10 +13219,13 @@
 
 ::google::protobuf::uint8* UninterpretedOption_NamePart::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption.NamePart)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
   // required string name_part = 1;
-  if (has_name_part()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->name_part().data(), this->name_part().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -12974,7 +13236,7 @@
   }
 
   // required bool is_extension = 2;
-  if (has_is_extension()) {
+  if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->is_extension(), target);
   }
 
@@ -13051,14 +13313,19 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption.NamePart)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
-  if (from._has_bits_[0 / 32] & 3u) {
-    if (from.has_name_part()) {
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 3u) {
+    if (cached_has_bits & 0x00000001u) {
       set_has_name_part();
       name_part_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_part_);
     }
-    if (from.has_is_extension()) {
-      set_is_extension(from.is_extension());
+    if (cached_has_bits & 0x00000002u) {
+      is_extension_ = from.is_extension_;
     }
+    _has_bits_[0] |= cached_has_bits;
   }
 }
 
@@ -13095,7 +13362,7 @@
 
 ::google::protobuf::Metadata UninterpretedOption_NamePart::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[19];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -13133,6 +13400,7 @@
 }
 #endif
 void UninterpretedOption_NamePart::set_name_part(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -13261,7 +13529,7 @@
 }
 const ::google::protobuf::Descriptor* UninterpretedOption::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[20].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const UninterpretedOption& UninterpretedOption::default_instance() {
@@ -13316,13 +13584,11 @@
       case 2: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(18u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_name()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -13437,14 +13703,18 @@
 void UninterpretedOption::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.UninterpretedOption)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
   for (unsigned int i = 0, n = this->name_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
       2, this->name(i), output);
   }
 
+  cached_has_bits = _has_bits_[0];
   // optional string identifier_value = 3;
-  if (has_identifier_value()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->identifier_value().data(), this->identifier_value().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -13454,28 +13724,28 @@
   }
 
   // optional uint64 positive_int_value = 4;
-  if (has_positive_int_value()) {
+  if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->positive_int_value(), output);
   }
 
   // optional int64 negative_int_value = 5;
-  if (has_negative_int_value()) {
+  if (cached_has_bits & 0x00000010u) {
     ::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->negative_int_value(), output);
   }
 
   // optional double double_value = 6;
-  if (has_double_value()) {
+  if (cached_has_bits & 0x00000020u) {
     ::google::protobuf::internal::WireFormatLite::WriteDouble(6, this->double_value(), output);
   }
 
   // optional bytes string_value = 7;
-  if (has_string_value()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
       7, this->string_value(), output);
   }
 
   // optional string aggregate_value = 8;
-  if (has_aggregate_value()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->aggregate_value().data(), this->aggregate_value().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -13493,17 +13763,20 @@
 
 ::google::protobuf::uint8* UninterpretedOption::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
   for (unsigned int i = 0, n = this->name_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        2, this->name(i), false, target);
+        2, this->name(i), deterministic, target);
   }
 
+  cached_has_bits = _has_bits_[0];
   // optional string identifier_value = 3;
-  if (has_identifier_value()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->identifier_value().data(), this->identifier_value().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -13514,29 +13787,29 @@
   }
 
   // optional uint64 positive_int_value = 4;
-  if (has_positive_int_value()) {
+  if (cached_has_bits & 0x00000008u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->positive_int_value(), target);
   }
 
   // optional int64 negative_int_value = 5;
-  if (has_negative_int_value()) {
+  if (cached_has_bits & 0x00000010u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->negative_int_value(), target);
   }
 
   // optional double double_value = 6;
-  if (has_double_value()) {
+  if (cached_has_bits & 0x00000020u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(6, this->double_value(), target);
   }
 
   // optional bytes string_value = 7;
-  if (has_string_value()) {
+  if (cached_has_bits & 0x00000002u) {
     target =
       ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
         7, this->string_value(), target);
   }
 
   // optional string aggregate_value = 8;
-  if (has_aggregate_value()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->aggregate_value().data(), this->aggregate_value().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -13642,29 +13915,34 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   name_.MergeFrom(from.name_);
-  if (from._has_bits_[0 / 32] & 63u) {
-    if (from.has_identifier_value()) {
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 63u) {
+    if (cached_has_bits & 0x00000001u) {
       set_has_identifier_value();
       identifier_value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.identifier_value_);
     }
-    if (from.has_string_value()) {
+    if (cached_has_bits & 0x00000002u) {
       set_has_string_value();
       string_value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.string_value_);
     }
-    if (from.has_aggregate_value()) {
+    if (cached_has_bits & 0x00000004u) {
       set_has_aggregate_value();
       aggregate_value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.aggregate_value_);
     }
-    if (from.has_positive_int_value()) {
-      set_positive_int_value(from.positive_int_value());
+    if (cached_has_bits & 0x00000008u) {
+      positive_int_value_ = from.positive_int_value_;
     }
-    if (from.has_negative_int_value()) {
-      set_negative_int_value(from.negative_int_value());
+    if (cached_has_bits & 0x00000010u) {
+      negative_int_value_ = from.negative_int_value_;
     }
-    if (from.has_double_value()) {
-      set_double_value(from.double_value());
+    if (cached_has_bits & 0x00000020u) {
+      double_value_ = from.double_value_;
     }
+    _has_bits_[0] |= cached_has_bits;
   }
 }
 
@@ -13692,7 +13970,7 @@
   InternalSwap(other);
 }
 void UninterpretedOption::InternalSwap(UninterpretedOption* other) {
-  name_.UnsafeArenaSwap(&other->name_);
+  name_.InternalSwap(&other->name_);
   identifier_value_.Swap(&other->identifier_value_);
   string_value_.Swap(&other->string_value_);
   aggregate_value_.Swap(&other->aggregate_value_);
@@ -13706,7 +13984,7 @@
 
 ::google::protobuf::Metadata UninterpretedOption::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[20];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -13774,6 +14052,7 @@
 }
 #endif
 void UninterpretedOption::set_identifier_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -13908,6 +14187,7 @@
 }
 #endif
 void UninterpretedOption::set_string_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -13970,6 +14250,7 @@
 }
 #endif
 void UninterpretedOption::set_aggregate_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -14063,7 +14344,7 @@
 }
 const ::google::protobuf::Descriptor* SourceCodeInfo_Location::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[21].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const SourceCodeInfo_Location& SourceCodeInfo_Location::default_instance() {
@@ -14218,6 +14499,9 @@
 void SourceCodeInfo_Location::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.SourceCodeInfo.Location)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated int32 path = 1 [packed = true];
   if (this->path_size() > 0) {
     ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
@@ -14238,8 +14522,9 @@
       this->span(i), output);
   }
 
+  cached_has_bits = _has_bits_[0];
   // optional string leading_comments = 3;
-  if (has_leading_comments()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->leading_comments().data(), this->leading_comments().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -14249,7 +14534,7 @@
   }
 
   // optional string trailing_comments = 4;
-  if (has_trailing_comments()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->trailing_comments().data(), this->trailing_comments().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -14277,8 +14562,10 @@
 
 ::google::protobuf::uint8* SourceCodeInfo_Location::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo.Location)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated int32 path = 1 [packed = true];
   if (this->path_size() > 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
@@ -14287,10 +14574,8 @@
       target);
     target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
       _path_cached_byte_size_, target);
-  }
-  for (int i = 0, n = this->path_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
-      WriteInt32NoTagToArray(this->path(i), target);
+      WriteInt32NoTagToArray(this->path_, target);
   }
 
   // repeated int32 span = 2 [packed = true];
@@ -14301,14 +14586,13 @@
       target);
     target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
       _span_cached_byte_size_, target);
-  }
-  for (int i = 0, n = this->span_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
-      WriteInt32NoTagToArray(this->span(i), target);
+      WriteInt32NoTagToArray(this->span_, target);
   }
 
+  cached_has_bits = _has_bits_[0];
   // optional string leading_comments = 3;
-  if (has_leading_comments()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->leading_comments().data(), this->leading_comments().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -14319,7 +14603,7 @@
   }
 
   // optional string trailing_comments = 4;
-  if (has_trailing_comments()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->trailing_comments().data(), this->trailing_comments().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -14436,15 +14720,19 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo.Location)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   path_.MergeFrom(from.path_);
   span_.MergeFrom(from.span_);
   leading_detached_comments_.MergeFrom(from.leading_detached_comments_);
-  if (from._has_bits_[0 / 32] & 3u) {
-    if (from.has_leading_comments()) {
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 3u) {
+    if (cached_has_bits & 0x00000001u) {
       set_has_leading_comments();
       leading_comments_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.leading_comments_);
     }
-    if (from.has_trailing_comments()) {
+    if (cached_has_bits & 0x00000002u) {
       set_has_trailing_comments();
       trailing_comments_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.trailing_comments_);
     }
@@ -14474,9 +14762,9 @@
   InternalSwap(other);
 }
 void SourceCodeInfo_Location::InternalSwap(SourceCodeInfo_Location* other) {
-  path_.UnsafeArenaSwap(&other->path_);
-  span_.UnsafeArenaSwap(&other->span_);
-  leading_detached_comments_.UnsafeArenaSwap(&other->leading_detached_comments_);
+  path_.InternalSwap(&other->path_);
+  span_.InternalSwap(&other->span_);
+  leading_detached_comments_.InternalSwap(&other->leading_detached_comments_);
   leading_comments_.Swap(&other->leading_comments_);
   trailing_comments_.Swap(&other->trailing_comments_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
@@ -14486,7 +14774,7 @@
 
 ::google::protobuf::Metadata SourceCodeInfo_Location::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[21];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -14584,6 +14872,7 @@
 }
 #endif
 void SourceCodeInfo_Location::set_leading_comments(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -14646,6 +14935,7 @@
 }
 #endif
 void SourceCodeInfo_Location::set_trailing_comments(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -14702,6 +14992,7 @@
 }
 #endif
 void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   leading_detached_comments_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
 }
@@ -14720,11 +15011,12 @@
 }
 #if LANG_CXX11
 void SourceCodeInfo_Location::add_leading_detached_comments(::std::string&& value) {
-  leading_detached_comments_.Add()->assign(std::move(value));
+  leading_detached_comments_.Add(std::move(value));
   // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
 }
 #endif
 void SourceCodeInfo_Location::add_leading_detached_comments(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   leading_detached_comments_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
 }
@@ -14788,7 +15080,7 @@
 }
 const ::google::protobuf::Descriptor* SourceCodeInfo::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[22].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const SourceCodeInfo& SourceCodeInfo::default_instance() {
@@ -14825,13 +15117,11 @@
       case 1: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(10u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_location()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -14860,6 +15150,9 @@
 void SourceCodeInfo::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.SourceCodeInfo)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
   for (unsigned int i = 0, n = this->location_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
@@ -14875,13 +15168,15 @@
 
 ::google::protobuf::uint8* SourceCodeInfo::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
   for (unsigned int i = 0, n = this->location_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        1, this->location(i), false, target);
+        1, this->location(i), deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -14938,6 +15233,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   location_.MergeFrom(from.location_);
 }
 
@@ -14964,7 +15262,7 @@
   InternalSwap(other);
 }
 void SourceCodeInfo::InternalSwap(SourceCodeInfo* other) {
-  location_.UnsafeArenaSwap(&other->location_);
+  location_.InternalSwap(&other->location_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   std::swap(_cached_size_, other->_cached_size_);
@@ -14972,7 +15270,7 @@
 
 ::google::protobuf::Metadata SourceCodeInfo::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[22];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -15067,7 +15365,7 @@
 }
 const ::google::protobuf::Descriptor* GeneratedCodeInfo_Annotation::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[23].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const GeneratedCodeInfo_Annotation& GeneratedCodeInfo_Annotation::default_instance() {
@@ -15195,6 +15493,9 @@
 void GeneratedCodeInfo_Annotation::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.GeneratedCodeInfo.Annotation)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated int32 path = 1 [packed = true];
   if (this->path_size() > 0) {
     ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
@@ -15205,8 +15506,9 @@
       this->path(i), output);
   }
 
+  cached_has_bits = _has_bits_[0];
   // optional string source_file = 2;
-  if (has_source_file()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->source_file().data(), this->source_file().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -15216,12 +15518,12 @@
   }
 
   // optional int32 begin = 3;
-  if (has_begin()) {
+  if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->begin(), output);
   }
 
   // optional int32 end = 4;
-  if (has_end()) {
+  if (cached_has_bits & 0x00000004u) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->end(), output);
   }
 
@@ -15234,8 +15536,10 @@
 
 ::google::protobuf::uint8* GeneratedCodeInfo_Annotation::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.GeneratedCodeInfo.Annotation)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated int32 path = 1 [packed = true];
   if (this->path_size() > 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
@@ -15244,14 +15548,13 @@
       target);
     target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
       _path_cached_byte_size_, target);
-  }
-  for (int i = 0, n = this->path_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
-      WriteInt32NoTagToArray(this->path(i), target);
+      WriteInt32NoTagToArray(this->path_, target);
   }
 
+  cached_has_bits = _has_bits_[0];
   // optional string source_file = 2;
-  if (has_source_file()) {
+  if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
       this->source_file().data(), this->source_file().length(),
       ::google::protobuf::internal::WireFormat::SERIALIZE,
@@ -15262,12 +15565,12 @@
   }
 
   // optional int32 begin = 3;
-  if (has_begin()) {
+  if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->begin(), target);
   }
 
   // optional int32 end = 4;
-  if (has_end()) {
+  if (cached_has_bits & 0x00000004u) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->end(), target);
   }
 
@@ -15352,18 +15655,23 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo.Annotation)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   path_.MergeFrom(from.path_);
-  if (from._has_bits_[0 / 32] & 7u) {
-    if (from.has_source_file()) {
+  cached_has_bits = from._has_bits_[0];
+  if (cached_has_bits & 7u) {
+    if (cached_has_bits & 0x00000001u) {
       set_has_source_file();
       source_file_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.source_file_);
     }
-    if (from.has_begin()) {
-      set_begin(from.begin());
+    if (cached_has_bits & 0x00000002u) {
+      begin_ = from.begin_;
     }
-    if (from.has_end()) {
-      set_end(from.end());
+    if (cached_has_bits & 0x00000004u) {
+      end_ = from.end_;
     }
+    _has_bits_[0] |= cached_has_bits;
   }
 }
 
@@ -15390,7 +15698,7 @@
   InternalSwap(other);
 }
 void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* other) {
-  path_.UnsafeArenaSwap(&other->path_);
+  path_.InternalSwap(&other->path_);
   source_file_.Swap(&other->source_file_);
   std::swap(begin_, other->begin_);
   std::swap(end_, other->end_);
@@ -15401,7 +15709,7 @@
 
 ::google::protobuf::Metadata GeneratedCodeInfo_Annotation::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[23];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -15469,6 +15777,7 @@
 }
 #endif
 void GeneratedCodeInfo_Annotation::set_source_file(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_source_file();
   source_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
@@ -15592,7 +15901,7 @@
 }
 const ::google::protobuf::Descriptor* GeneratedCodeInfo::descriptor() {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[24].descriptor;
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const GeneratedCodeInfo& GeneratedCodeInfo::default_instance() {
@@ -15629,13 +15938,11 @@
       case 1: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(10u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_annotation()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -15664,6 +15971,9 @@
 void GeneratedCodeInfo::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.GeneratedCodeInfo)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
   for (unsigned int i = 0, n = this->annotation_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
@@ -15679,13 +15989,15 @@
 
 ::google::protobuf::uint8* GeneratedCodeInfo::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.GeneratedCodeInfo)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
   for (unsigned int i = 0, n = this->annotation_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        1, this->annotation(i), false, target);
+        1, this->annotation(i), deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -15742,6 +16054,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   annotation_.MergeFrom(from.annotation_);
 }
 
@@ -15768,7 +16083,7 @@
   InternalSwap(other);
 }
 void GeneratedCodeInfo::InternalSwap(GeneratedCodeInfo* other) {
-  annotation_.UnsafeArenaSwap(&other->annotation_);
+  annotation_.InternalSwap(&other->annotation_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   std::swap(_cached_size_, other->_cached_size_);
@@ -15776,7 +16091,7 @@
 
 ::google::protobuf::Metadata GeneratedCodeInfo::GetMetadata() const {
   protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[24];
+  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index 1070896..b8c97a6 100644
--- a/src/google/protobuf/descriptor.pb.h
+++ b/src/google/protobuf/descriptor.pb.h
@@ -22,6 +22,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/message.h>
@@ -116,6 +117,9 @@
 namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto {
 // Internal implementation detail -- do not call these.
 struct LIBPROTOBUF_EXPORT TableStruct {
+  static const ::google::protobuf::internal::ParseTableField entries[];
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+  static const ::google::protobuf::internal::ParseTable schema[];
   static const ::google::protobuf::uint32 offsets[];
   static void InitDefaultsImpl();
   static void Shutdown();
@@ -288,6 +292,8 @@
     return reinterpret_cast<const FileDescriptorSet*>(
                &_FileDescriptorSet_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    0;
 
   void Swap(FileDescriptorSet* other);
 
@@ -310,11 +316,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -386,6 +387,8 @@
     return reinterpret_cast<const FileDescriptorProto*>(
                &_FileDescriptorProto_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    1;
 
   void Swap(FileDescriptorProto* other);
 
@@ -408,11 +411,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -456,30 +454,6 @@
   const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const;
   ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency();
 
-  // repeated int32 public_dependency = 10;
-  int public_dependency_size() const;
-  void clear_public_dependency();
-  static const int kPublicDependencyFieldNumber = 10;
-  ::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;
-  ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
-      mutable_public_dependency();
-
-  // repeated int32 weak_dependency = 11;
-  int weak_dependency_size() const;
-  void clear_weak_dependency();
-  static const int kWeakDependencyFieldNumber = 11;
-  ::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;
-  ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
-      mutable_weak_dependency();
-
   // repeated .google.protobuf.DescriptorProto message_type = 4;
   int message_type_size() const;
   void clear_message_type();
@@ -528,6 +502,30 @@
   const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
       extension() const;
 
+  // repeated int32 public_dependency = 10;
+  int public_dependency_size() const;
+  void clear_public_dependency();
+  static const int kPublicDependencyFieldNumber = 10;
+  ::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;
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+      mutable_public_dependency();
+
+  // repeated int32 weak_dependency = 11;
+  int weak_dependency_size() const;
+  void clear_weak_dependency();
+  static const int kWeakDependencyFieldNumber = 11;
+  ::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;
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+      mutable_weak_dependency();
+
   // optional string name = 1;
   bool has_name() const;
   void clear_name();
@@ -608,12 +606,12 @@
   ::google::protobuf::internal::HasBits<1> _has_bits_;
   mutable int _cached_size_;
   ::google::protobuf::RepeatedPtrField< ::std::string> dependency_;
-  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > public_dependency_;
-  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > weak_dependency_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > message_type_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto > service_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > public_dependency_;
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > weak_dependency_;
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::internal::ArenaStringPtr package_;
   ::google::protobuf::internal::ArenaStringPtr syntax_;
@@ -650,6 +648,8 @@
     return reinterpret_cast<const DescriptorProto_ExtensionRange*>(
                &_DescriptorProto_ExtensionRange_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    2;
 
   void Swap(DescriptorProto_ExtensionRange* other);
 
@@ -672,11 +672,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -755,6 +750,8 @@
     return reinterpret_cast<const DescriptorProto_ReservedRange*>(
                &_DescriptorProto_ReservedRange_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    3;
 
   void Swap(DescriptorProto_ReservedRange* other);
 
@@ -777,11 +774,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -860,6 +852,8 @@
     return reinterpret_cast<const DescriptorProto*>(
                &_DescriptorProto_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    4;
 
   void Swap(DescriptorProto* other);
 
@@ -882,11 +876,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -923,18 +912,6 @@
   const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
       field() const;
 
-  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
-  int extension_size() const;
-  void clear_extension();
-  static const int kExtensionFieldNumber = 6;
-  const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
-  ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
-  ::google::protobuf::FieldDescriptorProto* add_extension();
-  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
-      mutable_extension();
-  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
-      extension() const;
-
   // repeated .google.protobuf.DescriptorProto nested_type = 3;
   int nested_type_size() const;
   void clear_nested_type();
@@ -971,6 +948,18 @@
   const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
       extension_range() const;
 
+  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+  int extension_size() const;
+  void clear_extension();
+  static const int kExtensionFieldNumber = 6;
+  const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
+  ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
+  ::google::protobuf::FieldDescriptorProto* add_extension();
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+      mutable_extension();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+      extension() const;
+
   // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
   int oneof_decl_size() const;
   void clear_oneof_decl();
@@ -1052,10 +1041,10 @@
   ::google::protobuf::internal::HasBits<1> _has_bits_;
   mutable int _cached_size_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > field_;
-  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > nested_type_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange > extension_range_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto > oneof_decl_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange > reserved_range_;
   ::google::protobuf::RepeatedPtrField< ::std::string> reserved_name_;
@@ -1092,6 +1081,8 @@
     return reinterpret_cast<const FieldDescriptorProto*>(
                &_FieldDescriptorProto_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    5;
 
   void Swap(FieldDescriptorProto* other);
 
@@ -1114,11 +1105,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -1241,21 +1227,6 @@
   ::std::string* release_name();
   void set_allocated_name(::std::string* name);
 
-  // optional string type_name = 6;
-  bool has_type_name() const;
-  void clear_type_name();
-  static const int kTypeNameFieldNumber = 6;
-  const ::std::string& type_name() const;
-  void set_type_name(const ::std::string& value);
-  #if LANG_CXX11
-  void set_type_name(::std::string&& value);
-  #endif
-  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;
   bool has_extendee() const;
   void clear_extendee();
@@ -1271,6 +1242,21 @@
   ::std::string* release_extendee();
   void set_allocated_extendee(::std::string* extendee);
 
+  // optional string type_name = 6;
+  bool has_type_name() const;
+  void clear_type_name();
+  static const int kTypeNameFieldNumber = 6;
+  const ::std::string& type_name() const;
+  void set_type_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_type_name(::std::string&& value);
+  #endif
+  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 default_value = 7;
   bool has_default_value() const;
   void clear_default_value();
@@ -1365,8 +1351,8 @@
   ::google::protobuf::internal::HasBits<1> _has_bits_;
   mutable int _cached_size_;
   ::google::protobuf::internal::ArenaStringPtr name_;
-  ::google::protobuf::internal::ArenaStringPtr type_name_;
   ::google::protobuf::internal::ArenaStringPtr extendee_;
+  ::google::protobuf::internal::ArenaStringPtr type_name_;
   ::google::protobuf::internal::ArenaStringPtr default_value_;
   ::google::protobuf::internal::ArenaStringPtr json_name_;
   ::google::protobuf::FieldOptions* options_;
@@ -1405,6 +1391,8 @@
     return reinterpret_cast<const OneofDescriptorProto*>(
                &_OneofDescriptorProto_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    6;
 
   void Swap(OneofDescriptorProto* other);
 
@@ -1427,11 +1415,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -1520,6 +1503,8 @@
     return reinterpret_cast<const EnumDescriptorProto*>(
                &_EnumDescriptorProto_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    7;
 
   void Swap(EnumDescriptorProto* other);
 
@@ -1542,11 +1527,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -1648,6 +1628,8 @@
     return reinterpret_cast<const EnumValueDescriptorProto*>(
                &_EnumValueDescriptorProto_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    8;
 
   void Swap(EnumValueDescriptorProto* other);
 
@@ -1670,11 +1652,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -1773,6 +1750,8 @@
     return reinterpret_cast<const ServiceDescriptorProto*>(
                &_ServiceDescriptorProto_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    9;
 
   void Swap(ServiceDescriptorProto* other);
 
@@ -1795,11 +1774,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -1901,6 +1875,8 @@
     return reinterpret_cast<const MethodDescriptorProto*>(
                &_MethodDescriptorProto_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    10;
 
   void Swap(MethodDescriptorProto* other);
 
@@ -1923,11 +1899,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -2072,6 +2043,8 @@
     return reinterpret_cast<const FileOptions*>(
                &_FileOptions_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    11;
 
   void Swap(FileOptions* other);
 
@@ -2094,11 +2067,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -2417,6 +2385,8 @@
     return reinterpret_cast<const MessageOptions*>(
                &_MessageOptions_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    12;
 
   void Swap(MessageOptions* other);
 
@@ -2439,11 +2409,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -2558,6 +2523,8 @@
     return reinterpret_cast<const FieldOptions*>(
                &_FieldOptions_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    13;
 
   void Swap(FieldOptions* other);
 
@@ -2580,11 +2547,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -2681,13 +2643,6 @@
   ::google::protobuf::FieldOptions_CType ctype() const;
   void set_ctype(::google::protobuf::FieldOptions_CType value);
 
-  // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
-  bool has_jstype() const;
-  void clear_jstype();
-  static const int kJstypeFieldNumber = 6;
-  ::google::protobuf::FieldOptions_JSType jstype() const;
-  void set_jstype(::google::protobuf::FieldOptions_JSType value);
-
   // optional bool packed = 2;
   bool has_packed() const;
   void clear_packed();
@@ -2716,6 +2671,13 @@
   bool weak() const;
   void set_weak(bool value);
 
+  // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
+  bool has_jstype() const;
+  void clear_jstype();
+  static const int kJstypeFieldNumber = 6;
+  ::google::protobuf::FieldOptions_JSType jstype() const;
+  void set_jstype(::google::protobuf::FieldOptions_JSType value);
+
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions)
   // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions)
  private:
@@ -2739,11 +2701,11 @@
   mutable int _cached_size_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
   int ctype_;
-  int jstype_;
   bool packed_;
   bool lazy_;
   bool deprecated_;
   bool weak_;
+  int jstype_;
   friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
@@ -2775,6 +2737,8 @@
     return reinterpret_cast<const OneofOptions*>(
                &_OneofOptions_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    14;
 
   void Swap(OneofOptions* other);
 
@@ -2797,11 +2761,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -2876,6 +2835,8 @@
     return reinterpret_cast<const EnumOptions*>(
                &_EnumOptions_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    15;
 
   void Swap(EnumOptions* other);
 
@@ -2898,11 +2859,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -2997,6 +2953,8 @@
     return reinterpret_cast<const EnumValueOptions*>(
                &_EnumValueOptions_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    16;
 
   void Swap(EnumValueOptions* other);
 
@@ -3019,11 +2977,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -3108,6 +3061,8 @@
     return reinterpret_cast<const ServiceOptions*>(
                &_ServiceOptions_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    17;
 
   void Swap(ServiceOptions* other);
 
@@ -3130,11 +3085,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -3219,6 +3169,8 @@
     return reinterpret_cast<const MethodOptions*>(
                &_MethodOptions_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    18;
 
   void Swap(MethodOptions* other);
 
@@ -3241,11 +3193,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -3368,6 +3315,8 @@
     return reinterpret_cast<const UninterpretedOption_NamePart*>(
                &_UninterpretedOption_NamePart_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    19;
 
   void Swap(UninterpretedOption_NamePart* other);
 
@@ -3390,11 +3339,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -3484,6 +3428,8 @@
     return reinterpret_cast<const UninterpretedOption*>(
                &_UninterpretedOption_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    20;
 
   void Swap(UninterpretedOption* other);
 
@@ -3506,11 +3452,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -3668,6 +3609,8 @@
     return reinterpret_cast<const SourceCodeInfo_Location*>(
                &_SourceCodeInfo_Location_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    21;
 
   void Swap(SourceCodeInfo_Location* other);
 
@@ -3690,11 +3633,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -3840,6 +3778,8 @@
     return reinterpret_cast<const SourceCodeInfo*>(
                &_SourceCodeInfo_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    22;
 
   void Swap(SourceCodeInfo* other);
 
@@ -3862,11 +3802,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -3940,6 +3875,8 @@
     return reinterpret_cast<const GeneratedCodeInfo_Annotation*>(
                &_GeneratedCodeInfo_Annotation_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    23;
 
   void Swap(GeneratedCodeInfo_Annotation* other);
 
@@ -3962,11 +3899,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -4077,6 +4009,8 @@
     return reinterpret_cast<const GeneratedCodeInfo*>(
                &_GeneratedCodeInfo_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    24;
 
   void Swap(GeneratedCodeInfo* other);
 
@@ -4099,11 +4033,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -4222,6 +4151,7 @@
 }
 #endif
 inline void FileDescriptorProto::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.name)
@@ -4284,6 +4214,7 @@
 }
 #endif
 inline void FileDescriptorProto::set_package(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_package();
   package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.package)
@@ -4340,6 +4271,7 @@
 }
 #endif
 inline void FileDescriptorProto::set_dependency(int index, const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   dependency_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.dependency)
 }
@@ -4358,11 +4290,12 @@
 }
 #if LANG_CXX11
 inline void FileDescriptorProto::add_dependency(::std::string&& value) {
-  dependency_.Add()->assign(std::move(value));
+  dependency_.Add(std::move(value));
   // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
 }
 #endif
 inline void FileDescriptorProto::add_dependency(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   dependency_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.FileDescriptorProto.dependency)
 }
@@ -4683,6 +4616,7 @@
 }
 #endif
 inline void FileDescriptorProto::set_syntax(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_syntax();
   syntax_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.syntax)
@@ -4853,6 +4787,7 @@
 }
 #endif
 inline void DescriptorProto::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.name)
@@ -5164,6 +5099,7 @@
 }
 #endif
 inline void DescriptorProto::set_reserved_name(int index, const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   reserved_name_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.reserved_name)
 }
@@ -5182,11 +5118,12 @@
 }
 #if LANG_CXX11
 inline void DescriptorProto::add_reserved_name(::std::string&& value) {
-  reserved_name_.Add()->assign(std::move(value));
+  reserved_name_.Add(std::move(value));
   // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name)
 }
 #endif
 inline void DescriptorProto::add_reserved_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   reserved_name_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.DescriptorProto.reserved_name)
 }
@@ -5241,6 +5178,7 @@
 }
 #endif
 inline void FieldDescriptorProto::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.name)
@@ -5347,13 +5285,13 @@
 
 // optional string type_name = 6;
 inline bool FieldDescriptorProto::has_type_name() const {
-  return (_has_bits_[0] & 0x00000002u) != 0;
+  return (_has_bits_[0] & 0x00000004u) != 0;
 }
 inline void FieldDescriptorProto::set_has_type_name() {
-  _has_bits_[0] |= 0x00000002u;
+  _has_bits_[0] |= 0x00000004u;
 }
 inline void FieldDescriptorProto::clear_has_type_name() {
-  _has_bits_[0] &= ~0x00000002u;
+  _has_bits_[0] &= ~0x00000004u;
 }
 inline void FieldDescriptorProto::clear_type_name() {
   type_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -5377,6 +5315,7 @@
 }
 #endif
 inline void FieldDescriptorProto::set_type_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -5409,13 +5348,13 @@
 
 // optional string extendee = 2;
 inline bool FieldDescriptorProto::has_extendee() const {
-  return (_has_bits_[0] & 0x00000004u) != 0;
+  return (_has_bits_[0] & 0x00000002u) != 0;
 }
 inline void FieldDescriptorProto::set_has_extendee() {
-  _has_bits_[0] |= 0x00000004u;
+  _has_bits_[0] |= 0x00000002u;
 }
 inline void FieldDescriptorProto::clear_has_extendee() {
-  _has_bits_[0] &= ~0x00000004u;
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline void FieldDescriptorProto::clear_extendee() {
   extendee_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -5439,6 +5378,7 @@
 }
 #endif
 inline void FieldDescriptorProto::set_extendee(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_extendee();
   extendee_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.extendee)
@@ -5501,6 +5441,7 @@
 }
 #endif
 inline void FieldDescriptorProto::set_default_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -5587,6 +5528,7 @@
 }
 #endif
 inline void FieldDescriptorProto::set_json_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_json_name();
   json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.json_name)
@@ -5698,6 +5640,7 @@
 }
 #endif
 inline void OneofDescriptorProto::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.OneofDescriptorProto.name)
@@ -5809,6 +5752,7 @@
 }
 #endif
 inline void EnumDescriptorProto::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.EnumDescriptorProto.name)
@@ -5950,6 +5894,7 @@
 }
 #endif
 inline void EnumValueDescriptorProto::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValueDescriptorProto.name)
@@ -6085,6 +6030,7 @@
 }
 #endif
 inline void ServiceDescriptorProto::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.ServiceDescriptorProto.name)
@@ -6226,6 +6172,7 @@
 }
 #endif
 inline void MethodDescriptorProto::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_name();
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.name)
@@ -6288,6 +6235,7 @@
 }
 #endif
 inline void MethodDescriptorProto::set_input_type(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -6350,6 +6298,7 @@
 }
 #endif
 inline void MethodDescriptorProto::set_output_type(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -6509,6 +6458,7 @@
 }
 #endif
 inline void FileOptions::set_java_package(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -6571,6 +6521,7 @@
 }
 #endif
 inline void FileOptions::set_java_outer_classname(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -6730,6 +6681,7 @@
 }
 #endif
 inline void FileOptions::set_go_package(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -6912,6 +6864,7 @@
 }
 #endif
 inline void FileOptions::set_objc_class_prefix(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -6974,6 +6927,7 @@
 }
 #endif
 inline void FileOptions::set_csharp_namespace(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_csharp_namespace();
   csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_namespace)
@@ -7036,6 +6990,7 @@
 }
 #endif
 inline void FileOptions::set_swift_prefix(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_swift_prefix();
   swift_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.swift_prefix)
@@ -7098,6 +7053,7 @@
 }
 #endif
 inline void FileOptions::set_php_class_prefix(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_php_class_prefix();
   php_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_class_prefix)
@@ -7319,13 +7275,13 @@
 
 // optional bool packed = 2;
 inline bool FieldOptions::has_packed() const {
-  return (_has_bits_[0] & 0x00000004u) != 0;
+  return (_has_bits_[0] & 0x00000002u) != 0;
 }
 inline void FieldOptions::set_has_packed() {
-  _has_bits_[0] |= 0x00000004u;
+  _has_bits_[0] |= 0x00000002u;
 }
 inline void FieldOptions::clear_has_packed() {
-  _has_bits_[0] &= ~0x00000004u;
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline void FieldOptions::clear_packed() {
   packed_ = false;
@@ -7343,13 +7299,13 @@
 
 // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
 inline bool FieldOptions::has_jstype() const {
-  return (_has_bits_[0] & 0x00000002u) != 0;
+  return (_has_bits_[0] & 0x00000020u) != 0;
 }
 inline void FieldOptions::set_has_jstype() {
-  _has_bits_[0] |= 0x00000002u;
+  _has_bits_[0] |= 0x00000020u;
 }
 inline void FieldOptions::clear_has_jstype() {
-  _has_bits_[0] &= ~0x00000002u;
+  _has_bits_[0] &= ~0x00000020u;
 }
 inline void FieldOptions::clear_jstype() {
   jstype_ = 0;
@@ -7368,13 +7324,13 @@
 
 // optional bool lazy = 5 [default = false];
 inline bool FieldOptions::has_lazy() const {
-  return (_has_bits_[0] & 0x00000008u) != 0;
+  return (_has_bits_[0] & 0x00000004u) != 0;
 }
 inline void FieldOptions::set_has_lazy() {
-  _has_bits_[0] |= 0x00000008u;
+  _has_bits_[0] |= 0x00000004u;
 }
 inline void FieldOptions::clear_has_lazy() {
-  _has_bits_[0] &= ~0x00000008u;
+  _has_bits_[0] &= ~0x00000004u;
 }
 inline void FieldOptions::clear_lazy() {
   lazy_ = false;
@@ -7392,13 +7348,13 @@
 
 // optional bool deprecated = 3 [default = false];
 inline bool FieldOptions::has_deprecated() const {
-  return (_has_bits_[0] & 0x00000010u) != 0;
+  return (_has_bits_[0] & 0x00000008u) != 0;
 }
 inline void FieldOptions::set_has_deprecated() {
-  _has_bits_[0] |= 0x00000010u;
+  _has_bits_[0] |= 0x00000008u;
 }
 inline void FieldOptions::clear_has_deprecated() {
-  _has_bits_[0] &= ~0x00000010u;
+  _has_bits_[0] &= ~0x00000008u;
 }
 inline void FieldOptions::clear_deprecated() {
   deprecated_ = false;
@@ -7416,13 +7372,13 @@
 
 // optional bool weak = 10 [default = false];
 inline bool FieldOptions::has_weak() const {
-  return (_has_bits_[0] & 0x00000020u) != 0;
+  return (_has_bits_[0] & 0x00000010u) != 0;
 }
 inline void FieldOptions::set_has_weak() {
-  _has_bits_[0] |= 0x00000020u;
+  _has_bits_[0] |= 0x00000010u;
 }
 inline void FieldOptions::clear_has_weak() {
-  _has_bits_[0] &= ~0x00000020u;
+  _has_bits_[0] &= ~0x00000010u;
 }
 inline void FieldOptions::clear_weak() {
   weak_ = false;
@@ -7819,6 +7775,7 @@
 }
 #endif
 inline void UninterpretedOption_NamePart::set_name_part(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -7939,6 +7896,7 @@
 }
 #endif
 inline void UninterpretedOption::set_identifier_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -8073,6 +8031,7 @@
 }
 #endif
 inline void UninterpretedOption::set_string_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -8135,6 +8094,7 @@
 }
 #endif
 inline void UninterpretedOption::set_aggregate_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -8261,6 +8221,7 @@
 }
 #endif
 inline void SourceCodeInfo_Location::set_leading_comments(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -8323,6 +8284,7 @@
 }
 #endif
 inline void SourceCodeInfo_Location::set_trailing_comments(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   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)
@@ -8379,6 +8341,7 @@
 }
 #endif
 inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   leading_detached_comments_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
 }
@@ -8397,11 +8360,12 @@
 }
 #if LANG_CXX11
 inline void SourceCodeInfo_Location::add_leading_detached_comments(::std::string&& value) {
-  leading_detached_comments_.Add()->assign(std::move(value));
+  leading_detached_comments_.Add(std::move(value));
   // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
 }
 #endif
 inline void SourceCodeInfo_Location::add_leading_detached_comments(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   leading_detached_comments_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
 }
@@ -8520,6 +8484,7 @@
 }
 #endif
 inline void GeneratedCodeInfo_Annotation::set_source_file(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   set_has_source_file();
   source_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto
index be22368..f859c42 100644
--- a/src/google/protobuf/descriptor.proto
+++ b/src/google/protobuf/descriptor.proto
@@ -445,7 +445,7 @@
   optional bool map_entry = 7;
 
   reserved 8;  // javalite_serializable
-
+  reserved 9;  // javanano_as_lite
 
   // The parser stores options it doesn't recognize here. See above.
   repeated UninterpretedOption uninterpreted_option = 999;
@@ -565,6 +565,7 @@
   // is a formalization for deprecating enums.
   optional bool deprecated = 3 [default=false];
 
+  reserved 5;  // javanano_as_lite
 
   // The parser stores options it doesn't recognize here. See above.
   repeated UninterpretedOption uninterpreted_option = 999;
diff --git a/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc
index 57ae960..4e46b2a 100644
--- a/src/google/protobuf/descriptor_database.cc
+++ b/src/google/protobuf/descriptor_database.cc
@@ -199,7 +199,7 @@
 bool SimpleDescriptorDatabase::DescriptorIndex<Value>::FindAllExtensionNumbers(
     const string& containing_type,
     std::vector<int>* output) {
-  typename std::map<pair<string, int>, Value>::const_iterator it =
+  typename std::map<std::pair<string, int>, Value>::const_iterator it =
       by_extension_.lower_bound(std::make_pair(containing_type, 0));
   bool success = false;
 
@@ -213,7 +213,7 @@
 }
 
 template <typename Value>
-typename map<string, Value>::iterator
+typename std::map<string, Value>::iterator
 SimpleDescriptorDatabase::DescriptorIndex<Value>::FindLastLessOrEqual(
     const string& name) {
   // Find the last key in the map which sorts less than or equal to the
diff --git a/src/google/protobuf/descriptor_database.h b/src/google/protobuf/descriptor_database.h
index be97a6d..28f8af7 100644
--- a/src/google/protobuf/descriptor_database.h
+++ b/src/google/protobuf/descriptor_database.h
@@ -102,6 +102,18 @@
   }
 
 
+  // Finds the file names and appends them to the output in an
+  // undefined order. This method is best-effort: it's not guaranteed that the
+  // database will find all files. Returns true if the database supports
+  // searching all file names, otherwise returns false and leaves output
+  // unchanged.
+  //
+  // This method has a default implementation that always returns
+  // false.
+  virtual bool FindAllFileNames(std::vector<string>* output) {
+    return false;
+  }
+
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorDatabase);
 };
diff --git a/src/google/protobuf/descriptor_database_unittest.cc b/src/google/protobuf/descriptor_database_unittest.cc
index 05d6765..7e81d70 100644
--- a/src/google/protobuf/descriptor_database_unittest.cc
+++ b/src/google/protobuf/descriptor_database_unittest.cc
@@ -44,7 +44,6 @@
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/text_format.h>
-#include <google/protobuf/stubs/strutil.h>
 
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
index 7ec7515..7523893 100644
--- a/src/google/protobuf/descriptor_unittest.cc
+++ b/src/google/protobuf/descriptor_unittest.cc
@@ -44,6 +44,7 @@
 #include <google/protobuf/compiler/parser.h>
 #include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/unittest_custom_options.pb.h>
+#include <google/protobuf/unittest_lazy_dependencies.pb.h>
 #include <google/protobuf/unittest_proto3_arena.pb.h>
 #include <google/protobuf/io/tokenizer.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
@@ -52,7 +53,6 @@
 #include <google/protobuf/descriptor_database.h>
 #include <google/protobuf/dynamic_message.h>
 #include <google/protobuf/text_format.h>
-#include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/substitute.h>
 
 #include <google/protobuf/stubs/common.h>
@@ -501,7 +501,7 @@
   for (int i = 0; i < file->dependency_count(); ++i) {
     ExtractDebugString(file->dependency(i), visited, debug_strings);
   }
-  debug_strings->push_back(make_pair(file->name(), file->DebugString()));
+  debug_strings->push_back(std::make_pair(file->name(), file->DebugString()));
 }
 
 class SimpleErrorCollector : public google::protobuf::io::ErrorCollector {
@@ -6066,6 +6066,7 @@
       "conflicts with field \"ab\". This is not allowed in proto3.\n");
 }
 
+
 // ===================================================================
 // DescriptorDatabase
 
@@ -6824,6 +6825,360 @@
 
 // ===================================================================
 
+class LazilyBuildDependenciesTest : public testing::Test {
+ public:
+  LazilyBuildDependenciesTest() : pool_(&db_, NULL) {
+    pool_.InternalSetLazilyBuildDependencies();
+  }
+
+  void ParseProtoAndAddToDb(const char* proto) {
+    FileDescriptorProto tmp;
+    ASSERT_TRUE(TextFormat::ParseFromString(proto, &tmp));
+    db_.Add(tmp);
+  }
+
+  void ParseProtoAndAddToDb(const string& proto) {
+    FileDescriptorProto tmp;
+    ASSERT_TRUE(TextFormat::ParseFromString(proto, &tmp));
+    db_.Add(tmp);
+  }
+
+  void AddSimpleMessageProtoFileToDb(const char* file_name,
+                                     const char* message_name) {
+    ParseProtoAndAddToDb("name: '" + string(file_name) +
+                         ".proto' "
+                         "package: \"protobuf_unittest\" "
+                         "message_type { "
+                         "  name:'" +
+                         string(message_name) +
+                         "' "
+                         "  field { name:'a' number:1 "
+                         "  label:LABEL_OPTIONAL "
+                         "  type_name:'int32' } "
+                         "}");
+  }
+
+  void AddSimpleEnumProtoFileToDb(const char* file_name, const char* enum_name,
+                                  const char* enum_value_name) {
+    ParseProtoAndAddToDb("name: '" + string(file_name) +
+                         ".proto' "
+                         "package: 'protobuf_unittest' "
+                         "enum_type { "
+                         "  name:'" +
+                         string(enum_name) +
+                         "' "
+                         "  value { name:'" +
+                         string(enum_value_name) +
+                         "' number:1 } "
+                         "}");
+  }
+
+ protected:
+  SimpleDescriptorDatabase db_;
+  DescriptorPool pool_;
+};
+
+TEST_F(LazilyBuildDependenciesTest, Message) {
+  ParseProtoAndAddToDb(
+      "name: 'foo.proto' "
+      "package: 'protobuf_unittest' "
+      "dependency: 'bar.proto' "
+      "message_type { "
+      "  name:'Foo' "
+      "  field { name:'bar' number:1 label:LABEL_OPTIONAL "
+      "type_name:'.protobuf_unittest.Bar' } "
+      "}");
+  AddSimpleMessageProtoFileToDb("bar", "Bar");
+
+  // Verify neither has been built yet.
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("foo.proto"));
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
+
+  const FileDescriptor* file = pool_.FindFileByName("foo.proto");
+
+  // Verify only foo gets built when asking for foo.proto
+  EXPECT_TRUE(file != NULL);
+  EXPECT_TRUE(pool_.InternalIsFileLoaded("foo.proto"));
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
+
+  // Verify calling FindFieldBy* works when the type of the field was
+  // not built at cross link time. Verify this doesn't build the file
+  // the field's type is defined in, as well.
+  const Descriptor* desc = file->FindMessageTypeByName("Foo");
+  const FieldDescriptor* field = desc->FindFieldByName("bar");
+  EXPECT_TRUE(field != NULL);
+  EXPECT_EQ(field, desc->FindFieldByNumber(1));
+  EXPECT_EQ(field, desc->FindFieldByLowercaseName("bar"));
+  EXPECT_EQ(field, desc->FindFieldByCamelcaseName("bar"));
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
+
+  // Finally, verify that if we call message_type() on the field, we will
+  // buid the file where the message is defined, and get a valid descriptor
+  EXPECT_TRUE(field->message_type() != NULL);
+  EXPECT_TRUE(pool_.InternalIsFileLoaded("bar.proto"));
+}
+
+TEST_F(LazilyBuildDependenciesTest, Enum) {
+  ParseProtoAndAddToDb(
+      "name: 'foo.proto' "
+      "package: 'protobuf_unittest' "
+      "dependency: 'enum1.proto' "
+      "dependency: 'enum2.proto' "
+      "message_type { "
+      "  name:'Lazy' "
+      "  field { name:'enum1' number:1 label:LABEL_OPTIONAL "
+      "type_name:'.protobuf_unittest.Enum1' } "
+      "  field { name:'enum2' number:1 label:LABEL_OPTIONAL "
+      "type_name:'.protobuf_unittest.Enum2' } "
+      "}");
+  AddSimpleEnumProtoFileToDb("enum1", "Enum1", "ENUM1");
+  AddSimpleEnumProtoFileToDb("enum2", "Enum2", "ENUM2");
+
+  const FileDescriptor* file = pool_.FindFileByName("foo.proto");
+
+  // Verify calling enum_type() on a field whose definition is not
+  // yet built will build the file and return a descriptor.
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("enum1.proto"));
+  const Descriptor* desc = file->FindMessageTypeByName("Lazy");
+  EXPECT_TRUE(desc != NULL);
+  const FieldDescriptor* field = desc->FindFieldByName("enum1");
+  EXPECT_TRUE(field != NULL);
+  EXPECT_TRUE(field->enum_type() != NULL);
+  EXPECT_TRUE(pool_.InternalIsFileLoaded("enum1.proto"));
+
+  // Verify calling default_value_enum() on a field whose definition is not
+  // yet built will build the file and return a descriptor to the value.
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("enum2.proto"));
+  field = desc->FindFieldByName("enum2");
+  EXPECT_TRUE(field != NULL);
+  EXPECT_TRUE(field->default_value_enum() != NULL);
+  EXPECT_TRUE(pool_.InternalIsFileLoaded("enum2.proto"));
+}
+
+TEST_F(LazilyBuildDependenciesTest, Type) {
+  ParseProtoAndAddToDb(
+      "name: 'foo.proto' "
+      "package: 'protobuf_unittest' "
+      "dependency: 'message1.proto' "
+      "dependency: 'message2.proto' "
+      "dependency: 'enum1.proto' "
+      "dependency: 'enum2.proto' "
+      "message_type { "
+      "  name:'Lazy' "
+      "  field { name:'message1' number:1 label:LABEL_OPTIONAL "
+      "type_name:'.protobuf_unittest.Message1' } "
+      "  field { name:'message2' number:1 label:LABEL_OPTIONAL "
+      "type_name:'.protobuf_unittest.Message2' } "
+      "  field { name:'enum1' number:1 label:LABEL_OPTIONAL "
+      "type_name:'.protobuf_unittest.Enum1' } "
+      "  field { name:'enum2' number:1 label:LABEL_OPTIONAL "
+      "type_name:'.protobuf_unittest.Enum2' } "
+      "}");
+  AddSimpleMessageProtoFileToDb("message1", "Message1");
+  AddSimpleMessageProtoFileToDb("message2", "Message2");
+  AddSimpleEnumProtoFileToDb("enum1", "Enum1", "ENUM1");
+  AddSimpleEnumProtoFileToDb("enum2", "Enum2", "ENUM2");
+
+  const FileDescriptor* file = pool_.FindFileByName("foo.proto");
+
+  // Verify calling type() on a field that is a message type will
+  // build the type defined in another file.
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("message1.proto"));
+  const Descriptor* desc = file->FindMessageTypeByName("Lazy");
+  EXPECT_TRUE(desc != NULL);
+  const FieldDescriptor* field = desc->FindFieldByName("message1");
+  EXPECT_TRUE(field != NULL);
+  EXPECT_EQ(field->type(), FieldDescriptor::TYPE_MESSAGE);
+  EXPECT_TRUE(pool_.InternalIsFileLoaded("message1.proto"));
+
+  // Verify calling cpp_type() on a field that is a message type will
+  // build the type defined in another file.
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("message2.proto"));
+  field = desc->FindFieldByName("message2");
+  EXPECT_TRUE(field != NULL);
+  EXPECT_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_MESSAGE);
+  EXPECT_TRUE(pool_.InternalIsFileLoaded("message2.proto"));
+
+  // Verify calling type() on a field that is an enum type will
+  // build the type defined in another file.
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("enum1.proto"));
+  field = desc->FindFieldByName("enum1");
+  EXPECT_TRUE(field != NULL);
+  EXPECT_EQ(field->type(), FieldDescriptor::TYPE_ENUM);
+  EXPECT_TRUE(pool_.InternalIsFileLoaded("enum1.proto"));
+
+  // Verify calling cpp_type() on a field that is an enum type will
+  // build the type defined in another file.
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("enum2.proto"));
+  field = desc->FindFieldByName("enum2");
+  EXPECT_TRUE(field != NULL);
+  EXPECT_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_ENUM);
+  EXPECT_TRUE(pool_.InternalIsFileLoaded("enum2.proto"));
+}
+
+TEST_F(LazilyBuildDependenciesTest, Extension) {
+  ParseProtoAndAddToDb(
+      "name: 'foo.proto' "
+      "package: 'protobuf_unittest' "
+      "dependency: 'bar.proto' "
+      "dependency: 'baz.proto' "
+      "extension { extendee: '.protobuf_unittest.Bar' name:'bar' number:11"
+      "            label:LABEL_OPTIONAL type_name:'.protobuf_unittest.Baz' }");
+  ParseProtoAndAddToDb(
+      "name: 'bar.proto' "
+      "package: 'protobuf_unittest' "
+      "message_type { "
+      "  name:'Bar' "
+      "  extension_range { start: 10 end: 20 }"
+      "}");
+  AddSimpleMessageProtoFileToDb("baz", "Baz");
+
+  // Verify none have been built yet.
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("foo.proto"));
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto"));
+
+  const FileDescriptor* file = pool_.FindFileByName("foo.proto");
+
+  // Verify foo.bar gets loaded, and bar.proto gets loaded
+  // to register the extension. baz.proto should not get loaded.
+  EXPECT_TRUE(file != NULL);
+  EXPECT_TRUE(pool_.InternalIsFileLoaded("foo.proto"));
+  EXPECT_TRUE(pool_.InternalIsFileLoaded("bar.proto"));
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto"));
+}
+
+TEST_F(LazilyBuildDependenciesTest, Service) {
+  ParseProtoAndAddToDb(
+      "name: 'foo.proto' "
+      "package: 'protobuf_unittest' "
+      "dependency: 'message1.proto' "
+      "dependency: 'message2.proto' "
+      "dependency: 'message3.proto' "
+      "dependency: 'message4.proto' "
+      "service {"
+      "  name: 'LazyService'"
+      "  method { name: 'A' input_type:  '.protobuf_unittest.Message1' "
+      "                     output_type: '.protobuf_unittest.Message2' }"
+      "}");
+  AddSimpleMessageProtoFileToDb("message1", "Message1");
+  AddSimpleMessageProtoFileToDb("message2", "Message2");
+  AddSimpleMessageProtoFileToDb("message3", "Message3");
+  AddSimpleMessageProtoFileToDb("message4", "Message4");
+
+  const FileDescriptor* file = pool_.FindFileByName("foo.proto");
+
+  // Verify calling FindServiceByName or FindMethodByName doesn't build the
+  // files defining the input and output type, and input_type() and
+  // output_type() does indeed build the appropriate files.
+  const ServiceDescriptor* service = file->FindServiceByName("LazyService");
+  EXPECT_TRUE(service != NULL);
+  const MethodDescriptor* method = service->FindMethodByName("A");
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("message1.proto"));
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("message2.proto"));
+  EXPECT_TRUE(method != NULL);
+  EXPECT_TRUE(method->input_type() != NULL);
+  EXPECT_TRUE(pool_.InternalIsFileLoaded("message1.proto"));
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("message2.proto"));
+  EXPECT_TRUE(method->output_type() != NULL);
+  EXPECT_TRUE(pool_.InternalIsFileLoaded("message2.proto"));
+}
+
+
+TEST_F(LazilyBuildDependenciesTest, GeneratedFile) {
+  // Most testing is done with custom pools with lazy dependencies forced on,
+  // do some sanity checking that lazy imports is on by default for the
+  // generated pool, and do custom options testing with generated to
+  // be able to use the GetExtension ids for the custom options.
+
+  // Verify none of the files are loaded yet.
+  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+      "google/protobuf/unittest_lazy_dependencies.proto"));
+  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+      "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
+  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+      "google/protobuf/unittest_lazy_dependencies_enum.proto"));
+
+  // Verify calling autogenerated function to get a descriptor in the base
+  // file will build that file but none of it's imports. This verifies that
+  // lazily_build_dependencies_ is set on the generated pool, and also that
+  // the generated function "descriptor()" doesn't somehow subvert the laziness
+  // by manually loading the dependencies or something.
+  EXPECT_TRUE(protobuf_unittest::lazy_imports::ImportedMessage::descriptor() !=
+              NULL);
+  EXPECT_TRUE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+      "google/protobuf/unittest_lazy_dependencies.proto"));
+  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+      "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
+  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+      "google/protobuf/unittest_lazy_dependencies_enum.proto"));
+
+  // Verify custom options work when defined in an import that isn't loaded,
+  // and that a non-default value of a custom option doesn't load the file
+  // where that enum is defined.
+  const google::protobuf::MessageOptions& options =
+      protobuf_unittest::lazy_imports::MessageCustomOption::descriptor()
+          ->options();
+  protobuf_unittest::lazy_imports::LazyEnum custom_option_value =
+      options.GetExtension(protobuf_unittest::lazy_imports::lazy_enum_option);
+
+  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+      "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
+  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+      "google/protobuf/unittest_lazy_dependencies_enum.proto"));
+  EXPECT_EQ(custom_option_value, protobuf_unittest::lazy_imports::LAZY_ENUM_1);
+
+  const google::protobuf::MessageOptions& options2 =
+      protobuf_unittest::lazy_imports::MessageCustomOption2::descriptor()
+          ->options();
+  custom_option_value =
+      options2.GetExtension(protobuf_unittest::lazy_imports::lazy_enum_option);
+
+  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+      "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
+  EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
+      "google/protobuf/unittest_lazy_dependencies_enum.proto"));
+  EXPECT_EQ(custom_option_value, protobuf_unittest::lazy_imports::LAZY_ENUM_0);
+}
+
+TEST_F(LazilyBuildDependenciesTest, Dependency) {
+  ParseProtoAndAddToDb(
+      "name: 'foo.proto' "
+      "package: 'protobuf_unittest' "
+      "dependency: 'bar.proto' "
+      "message_type { "
+      "  name:'Foo' "
+      "  field { name:'bar' number:1 label:LABEL_OPTIONAL "
+      "type_name:'.protobuf_unittest.Bar' } "
+      "}");
+  ParseProtoAndAddToDb(
+      "name: 'bar.proto' "
+      "package: 'protobuf_unittest' "
+      "dependency: 'baz.proto' "
+      "message_type { "
+      "  name:'Bar' "
+      "  field { name:'baz' number:1 label:LABEL_OPTIONAL "
+      "type_name:'.protobuf_unittest.Baz' } "
+      "}");
+  AddSimpleMessageProtoFileToDb("baz", "Baz");
+
+  const FileDescriptor* foo_file = pool_.FindFileByName("foo.proto");
+  EXPECT_TRUE(foo_file != NULL);
+  // As expected, requesting foo.proto shouldn't build it's dependencies
+  EXPECT_TRUE(pool_.InternalIsFileLoaded("foo.proto"));
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto"));
+
+  // Verify calling dependency(N) will build the dependency, but
+  // not that file's dependencies.
+  const FileDescriptor* bar_file = foo_file->dependency(0);
+  EXPECT_TRUE(bar_file != NULL);
+  EXPECT_TRUE(pool_.InternalIsFileLoaded("bar.proto"));
+  EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto"));
+}
+
+// ===================================================================
+
 
 }  // namespace descriptor_unittest
 }  // namespace protobuf
diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc
index e046cc5..ae1a5e0 100644
--- a/src/google/protobuf/duration.pb.cc
+++ b/src/google/protobuf/duration.pb.cc
@@ -31,11 +31,26 @@
 
 }  // namespace
 
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+    const TableStruct::entries[] = {
+  {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+    const TableStruct::aux[] = {
+  ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+    TableStruct::schema[] = {
+  { NULL, NULL, 0, -1, -1, false },
+};
+
 const ::google::protobuf::uint32 TableStruct::offsets[] = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Duration, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Duration, seconds_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Duration, nanos_),
 };
@@ -186,7 +201,7 @@
 }
 const ::google::protobuf::Descriptor* Duration::descriptor() {
   protobuf_google_2fprotobuf_2fduration_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fduration_2eproto::file_level_metadata[0].descriptor;
+  return protobuf_google_2fprotobuf_2fduration_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const Duration& Duration::default_instance() {
@@ -266,6 +281,9 @@
 void Duration::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Duration)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // int64 seconds = 1;
   if (this->seconds() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->seconds(), output);
@@ -281,8 +299,10 @@
 
 ::google::protobuf::uint8* Duration::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Duration)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // int64 seconds = 1;
   if (this->seconds() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(1, this->seconds(), target);
@@ -341,6 +361,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Duration)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.seconds() != 0) {
     set_seconds(from.seconds());
   }
@@ -394,7 +417,7 @@
 
 ::google::protobuf::Metadata Duration::GetMetadata() const {
   protobuf_google_2fprotobuf_2fduration_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fduration_2eproto::file_level_metadata[0];
+  return protobuf_google_2fprotobuf_2fduration_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h
index 591c11d..9de33fe 100644
--- a/src/google/protobuf/duration.pb.h
+++ b/src/google/protobuf/duration.pb.h
@@ -22,6 +22,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/message.h>
@@ -43,6 +44,9 @@
 namespace protobuf_google_2fprotobuf_2fduration_2eproto {
 // Internal implementation detail -- do not call these.
 struct LIBPROTOBUF_EXPORT TableStruct {
+  static const ::google::protobuf::internal::ParseTableField entries[];
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+  static const ::google::protobuf::internal::ParseTable schema[];
   static const ::google::protobuf::uint32 offsets[];
   static void InitDefaultsImpl();
   static void Shutdown();
@@ -78,6 +82,8 @@
     return reinterpret_cast<const Duration*>(
                &_Duration_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    0;
 
   void UnsafeArenaSwap(Duration* other);
   void Swap(Duration* other);
@@ -101,11 +107,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -154,7 +155,7 @@
   ::google::protobuf::int64 seconds_;
   ::google::protobuf::int32 nanos_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fduration_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fduration_2eproto::TableStruct;
 };
 // ===================================================================
 
diff --git a/src/google/protobuf/duration.proto b/src/google/protobuf/duration.proto
index 7f461f4..975fce4 100644
--- a/src/google/protobuf/duration.proto
+++ b/src/google/protobuf/duration.proto
@@ -47,6 +47,8 @@
 // two Timestamp values is a Duration and it can be added or subtracted
 // from a Timestamp. Range is approximately +-10,000 years.
 //
+// # Examples
+//
 // Example 1: Compute Duration from two Timestamps in pseudo code.
 //
 //     Timestamp start = ...;
@@ -87,11 +89,22 @@
 //     duration = Duration()
 //     duration.FromTimedelta(td)
 //
+// # JSON Mapping
+//
+// In JSON format, the Duration type is encoded as a string rather than an
+// object, where the string ends in the suffix "s" (indicating seconds) and
+// is preceded by the number of seconds, with nanoseconds expressed as
+// fractional seconds. For example, 3 seconds with 0 nanoseconds should be
+// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
+// be expressed in JSON format as "3.000000001s", and 3 seconds and 1
+// microsecond should be expressed in JSON format as "3.000001s".
+//
 //
 message Duration {
 
   // Signed seconds of the span of time. Must be from -315,576,000,000
-  // to +315,576,000,000 inclusive.
+  // to +315,576,000,000 inclusive. Note: these bounds are computed from:
+  // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
   int64 seconds = 1;
 
   // Signed fractions of a second at nanosecond resolution of the span
diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc
index d6bde49..ee8113e 100644
--- a/src/google/protobuf/dynamic_message.cc
+++ b/src/google/protobuf/dynamic_message.cc
@@ -77,13 +77,14 @@
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/generated_message_reflection.h>
 #include <google/protobuf/arenastring.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/map_field.h>
 #include <google/protobuf/map_field_inl.h>
+#include <google/protobuf/map_type_handler.h>
 #include <google/protobuf/reflection_ops.h>
 #include <google/protobuf/repeated_field.h>
-#include <google/protobuf/map_type_handler.h>
-#include <google/protobuf/extension_set.h>
 #include <google/protobuf/wire_format.h>
-#include <google/protobuf/map_field.h>
+
 
 namespace google {
 namespace protobuf {
@@ -239,6 +240,7 @@
     // looking back at this field. This would assume details about the
     // implementation of scoped_ptr.
     const DynamicMessage* prototype;
+    int weak_field_map_offset;  // The offset for the weak_field_map;
 
     TypeInfo() : prototype(NULL) {}
 
@@ -323,7 +325,6 @@
   // constructor.)
 
   const Descriptor* descriptor = type_info_->type;
-
   // Initialize oneof cases.
   for (int i = 0 ; i < descriptor->oneof_decl_count(); ++i) {
     new (OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * i))
@@ -336,7 +337,6 @@
   if (type_info_->extensions_offset != -1) {
     new (OffsetToPointer(type_info_->extensions_offset)) ExtensionSet;
   }
-
   for (int i = 0; i < descriptor->field_count(); i++) {
     const FieldDescriptor* field = descriptor->field(i);
     void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
@@ -537,7 +537,6 @@
   for (int i = 0; i < descriptor->field_count(); i++) {
     const FieldDescriptor* field = descriptor->field(i);
     void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
-
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
         !field->is_repeated()) {
       // For fields with message types, we need to cross-link with the
@@ -694,6 +693,7 @@
   // All the fields.
   //
   // TODO(b/31226269):  Optimize the order of fields to minimize padding.
+  int num_weak_fields = 0;
   for (int i = 0; i < type->field_count(); i++) {
     // Make sure field is aligned to avoid bus errors.
     // Oneof fields do not use any space.
@@ -717,6 +717,8 @@
   type_info->internal_metadata_offset = size;
   size += sizeof(InternalMetadataWithArena);
 
+  type_info->weak_field_map_offset = -1;
+
   // Align the final size to make sure no clever allocators think that
   // alignment is not necessary.
   type_info->size = size;
@@ -738,7 +740,6 @@
     }
   }
   size = AlignOffset(size);
-
   // Allocate the prototype + oneof fields.
   void* base = operator new(size);
   memset(base, 0, size);
@@ -752,7 +753,7 @@
   type_info->prototype = static_cast<DynamicMessage*>(base);
   DynamicMessage* prototype = new(base) DynamicMessage(type_info);
 
-  if (type->oneof_decl_count() > 0) {
+  if (type->oneof_decl_count() > 0 || num_weak_fields > 0) {
     // Construct default oneof instance.
     ConstructDefaultOneofInstance(type_info->type,
                                   type_info->offsets.get(),
@@ -767,7 +768,8 @@
       type_info->internal_metadata_offset,
       type_info->extensions_offset,
       type_info->oneof_case_offset,
-      type_info->size};
+      type_info->size,
+      type_info->weak_field_map_offset};
 
   type_info->reflection.reset(new GeneratedMessageReflection(
       type_info->type, schema, type_info->pool, this));
@@ -781,12 +783,12 @@
 void DynamicMessageFactory::ConstructDefaultOneofInstance(
     const Descriptor* type,
     const uint32 offsets[],
-    void* default_oneof_instance) {
+    void* default_oneof_or_weak_instance) {
   for (int i = 0; i < type->oneof_decl_count(); i++) {
     for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
       const FieldDescriptor* field = type->oneof_decl(i)->field(j);
       void* field_ptr = reinterpret_cast<uint8*>(
-          default_oneof_instance) + offsets[field->index()];
+          default_oneof_or_weak_instance) + offsets[field->index()];
       switch (field->cpp_type()) {
 #define HANDLE_TYPE(CPPTYPE, TYPE)                                      \
         case FieldDescriptor::CPPTYPE_##CPPTYPE:                        \
diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc
index 31cba09..7119505 100644
--- a/src/google/protobuf/empty.pb.cc
+++ b/src/google/protobuf/empty.pb.cc
@@ -31,11 +31,26 @@
 
 }  // namespace
 
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+    const TableStruct::entries[] = {
+  {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+    const TableStruct::aux[] = {
+  ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+    TableStruct::schema[] = {
+  { NULL, NULL, 0, -1, -1, false },
+};
+
 const ::google::protobuf::uint32 TableStruct::offsets[] = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Empty, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
 };
 
 static const ::google::protobuf::internal::MigrationSchema schemas[] = {
@@ -176,7 +191,7 @@
 }
 const ::google::protobuf::Descriptor* Empty::descriptor() {
   protobuf_google_2fprotobuf_2fempty_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fempty_2eproto::file_level_metadata[0].descriptor;
+  return protobuf_google_2fprotobuf_2fempty_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const Empty& Empty::default_instance() {
@@ -221,13 +236,18 @@
 void Empty::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Empty)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // @@protoc_insertion_point(serialize_end:google.protobuf.Empty)
 }
 
 ::google::protobuf::uint8* Empty::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Empty)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Empty)
   return target;
 }
@@ -262,6 +282,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Empty)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
 }
 
 void Empty::CopyFrom(const ::google::protobuf::Message& from) {
@@ -307,7 +330,7 @@
 
 ::google::protobuf::Metadata Empty::GetMetadata() const {
   protobuf_google_2fprotobuf_2fempty_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fempty_2eproto::file_level_metadata[0];
+  return protobuf_google_2fprotobuf_2fempty_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h
index a75d6dd..2c59955 100644
--- a/src/google/protobuf/empty.pb.h
+++ b/src/google/protobuf/empty.pb.h
@@ -22,6 +22,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/message.h>
@@ -43,6 +44,9 @@
 namespace protobuf_google_2fprotobuf_2fempty_2eproto {
 // Internal implementation detail -- do not call these.
 struct LIBPROTOBUF_EXPORT TableStruct {
+  static const ::google::protobuf::internal::ParseTableField entries[];
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+  static const ::google::protobuf::internal::ParseTable schema[];
   static const ::google::protobuf::uint32 offsets[];
   static void InitDefaultsImpl();
   static void Shutdown();
@@ -78,6 +82,8 @@
     return reinterpret_cast<const Empty*>(
                &_Empty_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    0;
 
   void UnsafeArenaSwap(Empty* other);
   void Swap(Empty* other);
@@ -101,11 +107,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -140,7 +141,7 @@
   typedef void InternalArenaConstructable_;
   typedef void DestructorSkippable_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fempty_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fempty_2eproto::TableStruct;
 };
 // ===================================================================
 
diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h
index f5aa8de..cb8ed21 100644
--- a/src/google/protobuf/extension_set.h
+++ b/src/google/protobuf/extension_set.h
@@ -416,7 +416,8 @@
                                                            uint8* target) const;
 
   // For backward-compatibility, versions of two of the above methods that
-  // are never forced to serialize deterministically.
+  // serialize deterministically iff SetDefaultSerializationDeterministic()
+  // has been called.
   uint8* SerializeWithCachedSizesToArray(int start_field_number,
                                          int end_field_number,
                                          uint8* target) const;
@@ -435,7 +436,11 @@
   // be linked in).  It's up to the protocol compiler to avoid calling this on
   // such ExtensionSets (easy enough since lite messages don't implement
   // SpaceUsed()).
-  int SpaceUsedExcludingSelf() const;
+  size_t SpaceUsedExcludingSelfLong() const;
+
+  int SpaceUsedExcludingSelf() const {
+    return internal::FromIntSize(SpaceUsedExcludingSelfLong());
+  }
 
  private:
 
@@ -457,7 +462,7 @@
 
     virtual bool IsInitialized() const = 0;
     virtual int ByteSize() const = 0;
-    virtual int SpaceUsed() const = 0;
+    virtual size_t SpaceUsedLong() const = 0;
 
     virtual void MergeFrom(const LazyMessageExtension& other) = 0;
     virtual void Clear() = 0;
@@ -556,7 +561,7 @@
     void Clear();
     int GetSize() const;
     void Free();
-    int SpaceUsedExcludingSelf() const;
+    size_t SpaceUsedExcludingSelfLong() const;
   };
   typedef std::map<int, Extension> ExtensionMap;
 
@@ -620,7 +625,7 @@
   //   class.
 
   // Defined in extension_set_heavy.cc.
-  static inline int RepeatedMessage_SpaceUsedExcludingSelf(
+  static inline size_t RepeatedMessage_SpaceUsedExcludingSelfLong(
       RepeatedPtrFieldBase* field);
 
   // The Extension struct is small enough to be passed by value, so we use it
@@ -1100,7 +1105,7 @@
 // parameter, and thus make an instance of ExtensionIdentifier have no
 // actual contents.  However, if we did that, then using at extension
 // identifier would not necessarily cause the compiler to output any sort
-// of reference to any simple defined in the extension's .pb.o file.  Some
+// of reference to any symbol defined in the extension's .pb.o file.  Some
 // linkers will actually drop object files that are not explicitly referenced,
 // but that would be bad because it would cause this extension to not be
 // registered at static initialization, and therefore using it would crash.
diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc
index 8f8f180..3649104 100644
--- a/src/google/protobuf/extension_set_heavy.cc
+++ b/src/google/protobuf/extension_set_heavy.cc
@@ -340,32 +340,32 @@
   }
 }
 
-int ExtensionSet::SpaceUsedExcludingSelf() const {
-  int total_size =
+size_t ExtensionSet::SpaceUsedExcludingSelfLong() const {
+  size_t total_size =
       extensions_.size() * sizeof(ExtensionMap::value_type);
   for (ExtensionMap::const_iterator iter = extensions_.begin(),
        end = extensions_.end();
        iter != end;
        ++iter) {
-    total_size += iter->second.SpaceUsedExcludingSelf();
+    total_size += iter->second.SpaceUsedExcludingSelfLong();
   }
   return total_size;
 }
 
-inline int ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelf(
+inline size_t ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelfLong(
     RepeatedPtrFieldBase* field) {
-  return field->SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
+  return field->SpaceUsedExcludingSelfLong<GenericTypeHandler<Message> >();
 }
 
-int ExtensionSet::Extension::SpaceUsedExcludingSelf() const {
-  int total_size = 0;
+size_t ExtensionSet::Extension::SpaceUsedExcludingSelfLong() const {
+  size_t total_size = 0;
   if (is_repeated) {
     switch (cpp_type(type)) {
-#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
-      case FieldDescriptor::CPPTYPE_##UPPERCASE:                   \
-        total_size += sizeof(*repeated_##LOWERCASE##_value) +      \
-            repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\
-        break
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
+  case FieldDescriptor::CPPTYPE_##UPPERCASE:                                  \
+    total_size += sizeof(*repeated_##LOWERCASE##_value) +                     \
+                  repeated_##LOWERCASE##_value->SpaceUsedExcludingSelfLong(); \
+    break
 
       HANDLE_TYPE(  INT32,   int32);
       HANDLE_TYPE(  INT64,   int64);
@@ -380,24 +380,25 @@
 
       case FieldDescriptor::CPPTYPE_MESSAGE:
         // repeated_message_value is actually a RepeatedPtrField<MessageLite>,
-        // but MessageLite has no SpaceUsed(), so we must directly call
-        // RepeatedPtrFieldBase::SpaceUsedExcludingSelf() with a different type
-        // handler.
-        total_size += sizeof(*repeated_message_value) +
-            RepeatedMessage_SpaceUsedExcludingSelf(repeated_message_value);
+        // but MessageLite has no SpaceUsedLong(), so we must directly call
+        // RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong() with a different
+        // type handler.
+        total_size +=
+            sizeof(*repeated_message_value) +
+            RepeatedMessage_SpaceUsedExcludingSelfLong(repeated_message_value);
         break;
     }
   } else {
     switch (cpp_type(type)) {
       case FieldDescriptor::CPPTYPE_STRING:
         total_size += sizeof(*string_value) +
-                      StringSpaceUsedExcludingSelf(*string_value);
+                      StringSpaceUsedExcludingSelfLong(*string_value);
         break;
       case FieldDescriptor::CPPTYPE_MESSAGE:
         if (is_lazy) {
-          total_size += lazymessage_value->SpaceUsed();
+          total_size += lazymessage_value->SpaceUsedLong();
         } else {
-          total_size += down_cast<Message*>(message_value)->SpaceUsed();
+          total_size += down_cast<Message*>(message_value)->SpaceUsedLong();
         }
         break;
       default:
diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc
index d6b823c..772d273 100644
--- a/src/google/protobuf/extension_set_unittest.cc
+++ b/src/google/protobuf/extension_set_unittest.cc
@@ -32,6 +32,7 @@
 //  Based on original Protocol Buffers design by
 //  Sanjay Ghemawat, Jeff Dean, and others.
 
+#include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/extension_set.h>
 #include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/unittest_mset.pb.h>
@@ -46,7 +47,6 @@
 
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
 #include <google/protobuf/stubs/stl_util.h>
diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc
index b054dff..094c4cc 100644
--- a/src/google/protobuf/field_mask.pb.cc
+++ b/src/google/protobuf/field_mask.pb.cc
@@ -31,11 +31,26 @@
 
 }  // namespace
 
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+    const TableStruct::entries[] = {
+  {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+    const TableStruct::aux[] = {
+  ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+    TableStruct::schema[] = {
+  { NULL, NULL, 0, -1, -1, false },
+};
+
 const ::google::protobuf::uint32 TableStruct::offsets[] = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldMask, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldMask, paths_),
 };
 
@@ -159,7 +174,7 @@
 }
 const ::google::protobuf::Descriptor* FieldMask::descriptor() {
   protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::file_level_metadata[0].descriptor;
+  return protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const FieldMask& FieldMask::default_instance() {
@@ -231,6 +246,9 @@
 void FieldMask::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.FieldMask)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated string paths = 1;
   for (int i = 0, n = this->paths_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -246,8 +264,10 @@
 
 ::google::protobuf::uint8* FieldMask::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldMask)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated string paths = 1;
   for (int i = 0, n = this->paths_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -300,6 +320,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldMask)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   paths_.MergeFrom(from.paths_);
 }
 
@@ -326,13 +349,13 @@
   InternalSwap(other);
 }
 void FieldMask::InternalSwap(FieldMask* other) {
-  paths_.UnsafeArenaSwap(&other->paths_);
+  paths_.InternalSwap(&other->paths_);
   std::swap(_cached_size_, other->_cached_size_);
 }
 
 ::google::protobuf::Metadata FieldMask::GetMetadata() const {
   protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::file_level_metadata[0];
+  return protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -364,6 +387,7 @@
 }
 #endif
 void FieldMask::set_paths(int index, const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   paths_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.FieldMask.paths)
 }
@@ -382,11 +406,12 @@
 }
 #if LANG_CXX11
 void FieldMask::add_paths(::std::string&& value) {
-  paths_.Add()->assign(std::move(value));
+  paths_.Add(std::move(value));
   // @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths)
 }
 #endif
 void FieldMask::add_paths(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   paths_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.FieldMask.paths)
 }
diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h
index b609f23..ca2cb25 100644
--- a/src/google/protobuf/field_mask.pb.h
+++ b/src/google/protobuf/field_mask.pb.h
@@ -22,6 +22,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/message.h>
@@ -43,6 +44,9 @@
 namespace protobuf_google_2fprotobuf_2ffield_5fmask_2eproto {
 // Internal implementation detail -- do not call these.
 struct LIBPROTOBUF_EXPORT TableStruct {
+  static const ::google::protobuf::internal::ParseTableField entries[];
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+  static const ::google::protobuf::internal::ParseTable schema[];
   static const ::google::protobuf::uint32 offsets[];
   static void InitDefaultsImpl();
   static void Shutdown();
@@ -72,6 +76,8 @@
     return reinterpret_cast<const FieldMask*>(
                &_FieldMask_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    0;
 
   void Swap(FieldMask* other);
 
@@ -94,11 +100,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -148,7 +149,7 @@
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   ::google::protobuf::RepeatedPtrField< ::std::string> paths_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::TableStruct;
 };
 // ===================================================================
 
@@ -184,6 +185,7 @@
 }
 #endif
 inline void FieldMask::set_paths(int index, const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   paths_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.FieldMask.paths)
 }
@@ -202,11 +204,12 @@
 }
 #if LANG_CXX11
 inline void FieldMask::add_paths(::std::string&& value) {
-  paths_.Add()->assign(std::move(value));
+  paths_.Add(std::move(value));
   // @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths)
 }
 #endif
 inline void FieldMask::add_paths(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   paths_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.FieldMask.paths)
 }
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc
index 2f8f825..9aebd90 100644
--- a/src/google/protobuf/generated_message_reflection.cc
+++ b/src/google/protobuf/generated_message_reflection.cc
@@ -190,7 +190,9 @@
       schema_(schema),
       descriptor_pool_((pool == NULL) ? DescriptorPool::generated_pool()
                                       : pool),
-      message_factory_(factory) {
+      message_factory_(factory),
+      last_non_weak_field_index_(-1) {
+  last_non_weak_field_index_ = descriptor_->field_count() - 1;
 }
 
 GeneratedMessageReflection::~GeneratedMessageReflection() {}
@@ -231,28 +233,25 @@
   return MutableInternalMetadataWithArena(message)->mutable_unknown_fields();
 }
 
-int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
+size_t GeneratedMessageReflection::SpaceUsedLong(const Message& message) const {
   // object_size_ already includes the in-memory representation of each field
   // in the message, so we only need to account for additional memory used by
   // the fields.
-  int total_size = schema_.GetObjectSize();
+  size_t total_size = schema_.GetObjectSize();
 
-  total_size += GetUnknownFields(message).SpaceUsedExcludingSelf();
+  total_size += GetUnknownFields(message).SpaceUsedExcludingSelfLong();
 
   if (schema_.HasExtensionSet()) {
-    total_size += GetExtensionSet(message).SpaceUsedExcludingSelf();
+    total_size += GetExtensionSet(message).SpaceUsedExcludingSelfLong();
   }
-
-  const int field_count = descriptor_->field_count();
-  for (int i = 0; i < field_count; i++) {
+  for (int i = 0; i <= last_non_weak_field_index_; i++) {
     const FieldDescriptor* field = descriptor_->field(i);
-
     if (field->is_repeated()) {
       switch (field->cpp_type()) {
 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
         case FieldDescriptor::CPPTYPE_##UPPERCASE :                           \
           total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field)     \
-                          .SpaceUsedExcludingSelf();                          \
+                          .SpaceUsedExcludingSelfLong();                      \
           break
 
         HANDLE_TYPE( INT32,  int32);
@@ -270,21 +269,21 @@
             default:  // TODO(kenton):  Support other string reps.
             case FieldOptions::STRING:
               total_size += GetRaw<RepeatedPtrField<string> >(message, field)
-                              .SpaceUsedExcludingSelf();
+                                .SpaceUsedExcludingSelfLong();
               break;
           }
           break;
 
         case FieldDescriptor::CPPTYPE_MESSAGE:
           if (IsMapFieldInApi(field)) {
-            total_size +=
-                GetRaw<MapFieldBase>(message, field).SpaceUsedExcludingSelf();
+            total_size += GetRaw<MapFieldBase>(message, field)
+                              .SpaceUsedExcludingSelfLong();
           } else {
             // We don't know which subclass of RepeatedPtrFieldBase the type is,
             // so we use RepeatedPtrFieldBase directly.
             total_size +=
                 GetRaw<RepeatedPtrFieldBase>(message, field)
-                  .SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
+                    .SpaceUsedExcludingSelfLong<GenericTypeHandler<Message> >();
           }
 
           break;
@@ -320,7 +319,8 @@
               if (ptr != default_ptr) {
                 // string fields are represented by just a pointer, so also
                 // include sizeof(string) as well.
-                total_size += sizeof(*ptr) + StringSpaceUsedExcludingSelf(*ptr);
+                total_size +=
+                    sizeof(*ptr) + StringSpaceUsedExcludingSelfLong(*ptr);
               }
               break;
             }
@@ -335,14 +335,13 @@
           } else {
             const Message* sub_message = GetRaw<const Message*>(message, field);
             if (sub_message != NULL) {
-              total_size += sub_message->SpaceUsed();
+              total_size += sub_message->SpaceUsedLong();
             }
           }
           break;
       }
     }
   }
-
   return total_size;
 }
 
@@ -643,14 +642,11 @@
     }
   }
 
-  const int field_count = descriptor_->field_count();
-  for (int i = 0; i < field_count; i++) {
+  for (int i = 0; i <= last_non_weak_field_index_; i++) {
     const FieldDescriptor* field = descriptor_->field(i);
-    if (!field->containing_oneof()) {
-      SwapField(message1, message2, field);
-    }
+    if (field->containing_oneof()) continue;
+    SwapField(message1, message2, field);
   }
-
   const int oneof_decl_count = descriptor_->oneof_decl_count();
   for (int i = 0; i < oneof_decl_count; i++) {
     SwapOneofField(message1, message2, descriptor_->oneof_decl(i));
@@ -782,7 +778,6 @@
       ClearOneofField(message, field);
       return;
     }
-
     if (HasBit(*message, field)) {
       ClearBit(message, field);
 
@@ -1026,10 +1021,8 @@
   const uint32* const has_bits_indices = schema_.has_bit_indices_;
   const uint32* const oneof_case_array =
       &GetConstRefAtOffset<uint32>(message, schema_.oneof_case_offset_);
-
-  const int field_count = descriptor_->field_count();
-  output->reserve(field_count);
-  for (int i = 0; i < field_count; i++) {
+  output->reserve(descriptor_->field_count());
+  for (int i = 0; i <= last_non_weak_field_index_; i++) {
     const FieldDescriptor* field = descriptor_->field(i);
     if (field->is_repeated()) {
       if (FieldSize(message, field) > 0) {
@@ -1052,7 +1045,6 @@
       }
     }
   }
-
   if (schema_.HasExtensionSet()) {
     GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_,
                                           output);
@@ -1458,8 +1450,7 @@
         GetExtensionSet(message).GetMessage(
           field->number(), field->message_type(), factory));
   } else {
-    const Message* result;
-    result = GetRaw<const Message*>(message, field);
+    const Message* result = GetRaw<const Message*>(message, field);
     if (result == NULL) {
       result = DefaultRaw<const Message*>(field);
     }
@@ -1479,6 +1470,7 @@
         MutableExtensionSet(message)->MutableMessage(field, factory));
   } else {
     Message* result;
+
     Message** result_holder = MutableRaw<Message*>(message, field);
 
     if (field->containing_oneof()) {
@@ -1976,6 +1968,7 @@
 // Simple accessors for manipulating has_bits_.
 inline bool GeneratedMessageReflection::HasBit(
     const Message& message, const FieldDescriptor* field) const {
+  GOOGLE_DCHECK(!field->options().weak());
   if (schema_.HasHasbits()) {
     return IsIndexInHasBitSet(GetHasBits(message), schema_.HasBitIndex(field));
   }
@@ -2031,6 +2024,7 @@
 
 inline void GeneratedMessageReflection::SetBit(
     Message* message, const FieldDescriptor* field) const {
+  GOOGLE_DCHECK(!field->options().weak());
   if (!schema_.HasHasbits()) {
     return;
   }
@@ -2041,6 +2035,7 @@
 
 inline void GeneratedMessageReflection::ClearBit(
     Message* message, const FieldDescriptor* field) const {
+  GOOGLE_DCHECK(!field->options().weak());
   if (!schema_.HasHasbits()) {
     return;
   }
@@ -2051,6 +2046,7 @@
 
 inline void GeneratedMessageReflection::SwapBit(
     Message* message1, Message* message2, const FieldDescriptor* field) const {
+  GOOGLE_DCHECK(!field->options().weak());
   if (!schema_.HasHasbits()) {
     return;
   }
@@ -2236,16 +2232,16 @@
     MigrationSchema migration_schema) {
   ReflectionSchema result;
   result.default_instance_ = *default_instance;
-  // First 5 offsets are offsets to the special fields. The following offsets
+  // First 6 offsets are offsets to the special fields. The following offsets
   // are the proto fields.
-  result.offsets_ = offsets + migration_schema.offsets_index + 4;
+  result.offsets_ = offsets + migration_schema.offsets_index + 5;
   result.has_bit_indices_ = offsets + migration_schema.has_bit_indices_index;
   result.has_bits_offset_ = offsets[migration_schema.offsets_index + 0];
   result.metadata_offset_ = offsets[migration_schema.offsets_index + 1];
   result.extensions_offset_ = offsets[migration_schema.offsets_index + 2];
   result.oneof_case_offset_ = offsets[migration_schema.offsets_index + 3];
   result.object_size_ = migration_schema.object_size;
-  result.weak_field_map_offset_ = 0;
+  result.weak_field_map_offset_ = offsets[migration_schema.offsets_index + 4];
   return result;
 }
 
@@ -2275,7 +2271,7 @@
     if (!descriptor->options().map_entry()) {
       // Only set reflection for non map types.
       file_level_metadata_->reflection = new GeneratedMessageReflection(
-          descriptor, MigrationToReflectionSchema(default_instance_data_++,
+          descriptor, MigrationToReflectionSchema(default_instance_data_,
                                                   offsets_, *schemas_),
           ::google::protobuf::DescriptorPool::generated_pool(), factory_);
       for (int i = 0; i < descriptor->enum_type_count(); i++) {
@@ -2283,6 +2279,7 @@
       }
       schemas_++;
     }
+    default_instance_data_++;
     file_level_metadata_++;
   }
 
diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h
index 8b1362a..b4fdbb1 100644
--- a/src/google/protobuf/generated_message_reflection.h
+++ b/src/google/protobuf/generated_message_reflection.h
@@ -62,7 +62,15 @@
 class DescriptorPool;
 class MapKey;
 class MapValueRef;
-}
+}  // namespace protobuf
+
+
+namespace protobuf {
+namespace flat {
+class MetadataBuilder;
+}  // namespace flat
+}  // namespace protobuf
+
 
 namespace protobuf {
 namespace internal {
@@ -73,6 +81,7 @@
 
 // Defined in other files.
 class ExtensionSet;             // extension_set.h
+class WeakFieldMap;             // weak_field_map.h
 
 // This struct describes the internal layout of the message, hence this is
 // used to act on the message reflectively.
@@ -83,17 +92,17 @@
 //                  embedded message fields *must* have non-NULL pointers
 //                  in the default instance.)
 //   offsets:       An array of ints giving the byte offsets.
-//                  For each oneof field, the offset is relative to the
-//                  default_oneof_instance. These can be computed at compile
-//                  time using the
-//                  PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET() macro.
-//                  For each none oneof field, the offset is related to
-//                  the start of the message object.  These can be computed
-//                  at compile time using the
+//                  For each oneof or weak field, the offset is relative to the
+//                  default_instance. These can be computed at compile time
+//                  using the
+//                  GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET()
+//                  macro. For each none oneof field, the offset is related to
+//                  the start of the message object.  These can be computed at
+//                  compile time using the
 //                  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro.
 //                  Besides offsets for all fields, this array also contains
-//                  offsets for oneof unions. The offset of the i-th oneof
-//                  union is offsets[descriptor->field_count() + i].
+//                  offsets for oneof unions. The offset of the i-th oneof union
+//                  is offsets[descriptor->field_count() + i].
 //   has_bit_indices:  Mapping from field indexes to their index in the has
 //                  bit array.
 //   has_bits_offset:  Offset in the message of an array of uint32s of size
@@ -114,6 +123,9 @@
 //                  by sizeof().
 //   arena_offset:  If a message doesn't have a unknown_field_set that stores
 //                  the arena, it must have a direct pointer to the arena.
+//   weak_field_map_offset: If the message proto has weak fields, this is the
+//                  offset of _weak_field_map_ in the generated proto. Otherwise
+//                  -1.
 struct ReflectionSchema {
  public:
   // Size of a google::protobuf::Message object of this type.
@@ -187,6 +199,9 @@
                      offsets_[field->index()];
   }
 
+
+  bool HasWeakFields() const { return weak_field_map_offset_ > 0; }
+
   // These members are intended to be private, but we cannot actually make them
   // private because this prevents us from using aggregate initialization of
   // them, ie.
@@ -240,8 +255,7 @@
 //    of whatever type the individual field would be.  Strings and
 //    Messages use RepeatedPtrFields while everything else uses
 //    RepeatedFields.
-class LIBPROTOBUF_EXPORT GeneratedMessageReflection PROTOBUF_FINAL
-    : public Reflection {
+class GeneratedMessageReflection PROTOBUF_FINAL : public Reflection {
  public:
   // Constructs a GeneratedMessageReflection.
   // Parameters:
@@ -263,7 +277,7 @@
   const UnknownFieldSet& GetUnknownFields(const Message& message) const;
   UnknownFieldSet* MutableUnknownFields(Message* message) const;
 
-  int SpaceUsed(const Message& message) const;
+  size_t SpaceUsedLong(const Message& message) const;
 
   bool HasField(const Message& message, const FieldDescriptor* field) const;
   int FieldSize(const Message& message, const FieldDescriptor* field) const;
@@ -481,7 +495,7 @@
       const Descriptor* message_type) const;
 
  private:
-  friend class GeneratedMessage;
+  friend class google::protobuf::flat::MetadataBuilder;
   friend class upb::google_opensource::GMR_Handlers;
 
   const Descriptor* const descriptor_;
@@ -489,6 +503,11 @@
   const DescriptorPool* const descriptor_pool_;
   MessageFactory* const message_factory_;
 
+  // Last non weak field index. This is an optimization when most weak fields
+  // are at the end of the containing message. If a message proto doesn't
+  // contain weak fields, then this field equals descriptor_->field_count().
+  int last_non_weak_field_index_;
+
   template <class T>
   const T& GetRawNonOneof(const Message& message,
                           const FieldDescriptor* field) const;
@@ -614,40 +633,6 @@
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection);
 };
 
-// Returns the offset of the given field within the given aggregate type.
-// This is equivalent to the ANSI C offsetof() macro.  However, according
-// to the C++ standard, offsetof() only works on POD types, and GCC
-// enforces this requirement with a warning.  In practice, this rule is
-// unnecessarily strict; there is probably no compiler or platform on
-// which the offsets of the direct fields of a class are non-constant.
-// Fields inherited from superclasses *can* have non-constant offsets,
-// but that's not what this macro will be used for.
-#if defined(__clang__)
-// For Clang we use __builtin_offsetof() and suppress the warning,
-// to avoid Control Flow Integrity and UBSan vptr sanitizers from
-// crashing while trying to validate the invalid reinterpet_casts.
-#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD)    \
-  _Pragma("clang diagnostic push")                            \
-  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"")  \
-  __builtin_offsetof(TYPE, FIELD)                             \
-  _Pragma("clang diagnostic pop")
-#else
-// Note that we calculate relative to the pointer value 16 here since if we
-// just use zero, GCC complains about dereferencing a NULL pointer.  We
-// choose 16 rather than some other number just in case the compiler would
-// be confused by an unaligned pointer.
-#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD)    \
-  static_cast< ::google::protobuf::uint32>(                            \
-      reinterpret_cast<const char*>(                                   \
-          &reinterpret_cast<const TYPE*>(16)->FIELD) -                 \
-      reinterpret_cast<const char*>(16))
-#endif
-
-#define PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD)     \
-  static_cast< ::google::protobuf::uint32>(                           \
-      reinterpret_cast<const char*>(&(ONEOF->FIELD))                  \
-      - reinterpret_cast<const char*>(ONEOF))
-
 // There are some places in proto2 where dynamic_cast would be useful as an
 // optimization.  For example, take Message::MergeFrom(const Message& other).
 // For a given generated message FooMessage, we generate these two methods:
diff --git a/src/google/protobuf/generated_message_table_driven.cc b/src/google/protobuf/generated_message_table_driven.cc
new file mode 100644
index 0000000..e281266
--- /dev/null
+++ b/src/google/protobuf/generated_message_table_driven.cc
@@ -0,0 +1,676 @@
+// 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/generated_message_table_driven.h>
+
+#include <google/protobuf/stubs/type_traits.h>
+
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/metadata_lite.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/wire_format_lite.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+
+namespace {
+
+enum StringType {
+  StringType_STRING = 0,
+  StringType_CORD = 1,
+  StringType_STRING_PIECE = 2
+};
+
+template <typename Type>
+inline Type* Raw(MessageLite* msg, int64 offset) {
+  return reinterpret_cast<Type*>(reinterpret_cast<uint8*>(msg) + offset);
+}
+
+template <typename Type>
+inline const Type* Raw(const MessageLite* msg, int64 offset) {
+  return reinterpret_cast<const Type*>(reinterpret_cast<const uint8*>(msg) +
+                                       offset);
+}
+
+inline Arena* GetArena(MessageLite* msg, int64 arena_offset) {
+  if (GOOGLE_PREDICT_FALSE(arena_offset == -1)) {
+    return NULL;
+  }
+
+  return Raw<InternalMetadataWithArenaLite>(msg, arena_offset)->arena();
+}
+
+template <typename Type>
+inline Type* AddField(MessageLite* msg, int64 offset) {
+#if LANG_CXX11
+  static_assert(std::is_trivially_copy_assignable<Type>::value,
+                "Do not assign");
+#endif
+
+  google::protobuf::RepeatedField<Type>* repeated =
+      Raw<google::protobuf::RepeatedField<Type> >(msg, offset);
+  return repeated->Add();
+}
+
+template <>
+inline string* AddField<string>(MessageLite* msg, int64 offset) {
+  google::protobuf::RepeatedPtrField<string>* repeated =
+      Raw<google::protobuf::RepeatedPtrField<string> >(msg, offset);
+  return repeated->Add();
+}
+
+
+template <typename Type>
+inline void AddField(MessageLite* msg, int64 offset, Type value) {
+#if LANG_CXX11
+  static_assert(std::is_trivially_copy_assignable<Type>::value,
+                "Do not assign");
+#endif
+  *AddField<Type>(msg, offset) = value;
+}
+
+inline void SetBit(uint32* has_bits, uint32 has_bit_index) {
+  GOOGLE_DCHECK(has_bits != NULL);
+
+  uint32 mask = static_cast<uint32>(1u) << (has_bit_index % 32);
+  has_bits[has_bit_index / 32u] |= mask;
+}
+
+template <typename Type>
+inline Type* MutableField(MessageLite* msg, uint32* has_bits,
+                          uint32 has_bit_index, int64 offset) {
+  SetBit(has_bits, has_bit_index);
+  return Raw<Type>(msg, offset);
+}
+
+template <typename Type>
+inline void SetField(MessageLite* msg, uint32* has_bits, uint32 has_bit_index,
+                     int64 offset, Type value) {
+#if LANG_CXX11
+  static_assert(std::is_trivially_copy_assignable<Type>::value,
+                "Do not assign");
+#endif
+  *MutableField<Type>(msg, has_bits, has_bit_index, offset) = value;
+}
+
+template <bool repeated, bool validate, StringType ctype>
+static inline bool HandleString(io::CodedInputStream* input, MessageLite* msg,
+                                Arena* arena, uint32* has_bits,
+                                uint32 has_bit_index, int64 offset,
+                                const void* default_ptr, bool strict_utf8,
+                                const char* field_name) {
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+  const char* sdata;
+  size_t size;
+#endif
+
+    string* value;
+    if (repeated) {
+      value = AddField<string>(msg, offset);
+      GOOGLE_DCHECK(value != NULL);
+    } else {
+      // TODO(ckennelly): Is this optimal?
+      value = MutableField<ArenaStringPtr>(msg, has_bits, has_bit_index, offset)
+                  ->Mutable(static_cast<const string*>(default_ptr), arena);
+      GOOGLE_DCHECK(value != NULL);
+    }
+
+    if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadString(input, value))) {
+      return false;
+    }
+
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+    sdata = value->data();
+    size = value->size();
+#endif
+
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+  if (validate) {
+    if (strict_utf8) {
+      if (GOOGLE_PREDICT_FALSE(!WireFormatLite::VerifyUtf8String(
+              sdata, size, WireFormatLite::PARSE, field_name))) {
+        return false;
+      }
+    } else {
+      WireFormatLite::VerifyUTF8String(
+          sdata, size, WireFormat::PARSE, field_name);
+    }
+  }
+#endif
+
+  return true;
+}
+
+string* MutableUnknownFields(MessageLite* msg, int64 arena_offset) {
+  return Raw<InternalMetadataWithArenaLite>(msg, arena_offset)
+      ->mutable_unknown_fields();
+}
+
+// RepeatedMessageTypeHandler allows us to operate on RepeatedPtrField fields
+// without instantiating the specific template.
+class RepeatedMessageTypeHandler {
+ public:
+  typedef MessageLite Type;
+  static Arena* GetArena(Type* t) { return t->GetArena(); }
+  static void* GetMaybeArenaPointer(Type* t) {
+    return t->GetMaybeArenaPointer();
+  }
+  static inline Type* NewFromPrototype(const Type* prototype,
+                                       Arena* arena = NULL) {
+    return prototype->New(arena);
+  }
+  static void Delete(Type* t, Arena* arena = NULL) {
+    if (arena == NULL) {
+      delete t;
+    }
+  }
+};
+
+inline bool ReadGroup(int field_number, io::CodedInputStream* input,
+                      MessageLite* value, const ParseTable& table) {
+  if (GOOGLE_PREDICT_FALSE(!input->IncrementRecursionDepth())) {
+    return false;
+  }
+
+  if (GOOGLE_PREDICT_FALSE(!MergePartialFromCodedStream(value, table, input))) {
+    return false;
+  }
+
+  input->DecrementRecursionDepth();
+  // Make sure the last thing read was an end tag for this group.
+  if (GOOGLE_PREDICT_FALSE(!input->LastTagWas(WireFormatLite::MakeTag(
+          field_number, WireFormatLite::WIRETYPE_END_GROUP)))) {
+    return false;
+  }
+
+  return true;
+}
+
+inline bool ReadMessage(io::CodedInputStream* input, MessageLite* value,
+                        const ParseTable& table) {
+  int length;
+  if (GOOGLE_PREDICT_FALSE(!input->ReadVarintSizeAsInt(&length))) {
+    return false;
+  }
+
+  std::pair<io::CodedInputStream::Limit, int> p =
+      input->IncrementRecursionDepthAndPushLimit(length);
+  if (GOOGLE_PREDICT_FALSE(p.second < 0 ||
+                    !MergePartialFromCodedStream(value, table, input))) {
+    return false;
+  }
+
+  // Make sure that parsing stopped when the limit was hit, not at an endgroup
+  // tag.
+  return input->DecrementRecursionDepthAndPopLimit(p.first);
+}
+
+}  // namespace
+
+class MergePartialFromCodedStreamHelper {
+ public:
+  static MessageLite* Add(RepeatedPtrFieldBase* field,
+                          const MessageLite* prototype) {
+    return field->Add<RepeatedMessageTypeHandler>(
+        const_cast<MessageLite*>(prototype));
+  }
+};
+
+bool MergePartialFromCodedStream(MessageLite* msg, const ParseTable& table,
+                                 io::CodedInputStream* input) {
+  // We require that has_bits are present, as to avoid having to check for them
+  // for every field.
+  //
+  // TODO(ckennelly):  Make this a compile-time parameter with templates.
+  GOOGLE_DCHECK_GE(table.has_bits_offset, 0);
+  uint32* has_bits = Raw<uint32>(msg, table.has_bits_offset);
+  GOOGLE_DCHECK(has_bits != NULL);
+
+  while (true) {
+    uint32 tag = input->ReadTag();
+
+    const WireFormatLite::WireType wire_type =
+        WireFormatLite::GetTagWireType(tag);
+    const int field_number = WireFormatLite::GetTagFieldNumber(tag);
+
+    if (GOOGLE_PREDICT_FALSE(field_number > table.max_field_number)) {
+      GOOGLE_DCHECK(!table.unknown_field_set);
+      ::google::protobuf::io::StringOutputStream unknown_fields_string(
+          MutableUnknownFields(msg, table.arena_offset));
+      ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
+          &unknown_fields_string, false);
+
+      if (!::google::protobuf::internal::WireFormatLite::SkipField(
+          input, tag, &unknown_fields_stream)) {
+        return false;
+      }
+
+      continue;
+    }
+
+    // We implicitly verify that data points to a valid field as we check the
+    // wire types.  Entries in table.fields[i] that do not correspond to valid
+    // field numbers have their normal_wiretype and packed_wiretype fields set
+    // with the kInvalidMask value.  As wire_type cannot take on that value, we
+    // will never match.
+    const ParseTableField* data = table.fields + field_number;
+
+    // TODO(ckennelly): Avoid sign extension
+    const int64 has_bit_index = data->has_bit_index;
+    const int64 offset = data->offset;
+    const unsigned char processing_type = data->processing_type;
+
+    if (data->normal_wiretype == static_cast<unsigned char>(wire_type)) {
+      // TODO(ckennelly): Use a computed goto on GCC/LLVM or otherwise eliminate
+      // the bounds check on processing_type.
+
+      switch (processing_type) {
+#define STR(S) #S
+#define HANDLE_TYPE(TYPE, CPPTYPE)                                        \
+  case (WireFormatLite::TYPE_##TYPE): {                                   \
+    CPPTYPE value;                                                        \
+    if (GOOGLE_PREDICT_FALSE(                                                    \
+            (!WireFormatLite::ReadPrimitive<                              \
+                CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)))) { \
+      return false;                                                       \
+    }                                                                     \
+    SetField(msg, has_bits, has_bit_index, offset, value);                \
+    break;                                                                \
+  }                                                                       \
+  case (WireFormatLite::TYPE_##TYPE) | kRepeatedMask: {                   \
+    google::protobuf::RepeatedField<CPPTYPE>* values =                              \
+        Raw<google::protobuf::RepeatedField<CPPTYPE> >(msg, offset);                \
+    if (GOOGLE_PREDICT_FALSE((!WireFormatLite::ReadRepeatedPrimitive<            \
+                       CPPTYPE, WireFormatLite::TYPE_##TYPE>(             \
+            data->tag_size, tag, input, values)))) {                      \
+      return false;                                                       \
+    }                                                                     \
+    break;                                                                \
+  }
+
+        HANDLE_TYPE(INT32, int32)
+        HANDLE_TYPE(INT64, int64)
+        HANDLE_TYPE(SINT32, int32)
+        HANDLE_TYPE(SINT64, int64)
+        HANDLE_TYPE(UINT32, uint32)
+        HANDLE_TYPE(UINT64, uint64)
+
+        HANDLE_TYPE(FIXED32, uint32)
+        HANDLE_TYPE(FIXED64, uint64)
+        HANDLE_TYPE(SFIXED32, int32)
+        HANDLE_TYPE(SFIXED64, int64)
+
+        HANDLE_TYPE(FLOAT, float)
+        HANDLE_TYPE(DOUBLE, double)
+
+        HANDLE_TYPE(BOOL, bool)
+#undef HANDLE_TYPE
+#undef STR
+        case WireFormatLite::TYPE_BYTES:
+#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+        case WireFormatLite::TYPE_STRING:
+#endif
+        {
+          GOOGLE_DCHECK(!table.unknown_field_set);
+          Arena* const arena = GetArena(msg, table.arena_offset);
+          const void* default_ptr = table.aux[field_number].strings.default_ptr;
+
+          if (GOOGLE_PREDICT_FALSE((!HandleString<false, false, StringType_STRING>(
+                  input, msg, arena, has_bits, has_bit_index, offset,
+                  default_ptr, false, NULL)))) {
+            return false;
+          }
+          break;
+        }
+        case (WireFormatLite::TYPE_BYTES) | kRepeatedMask:
+#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+        case (WireFormatLite::TYPE_STRING) | kRepeatedMask:
+#endif
+        {
+          GOOGLE_DCHECK(!table.unknown_field_set);
+          Arena* const arena = GetArena(msg, table.arena_offset);
+          const void* default_ptr =
+              table.aux[field_number].strings.default_ptr;
+
+          if (GOOGLE_PREDICT_FALSE((!HandleString<true, false, StringType_STRING>(
+                  input, msg, arena, has_bits, has_bit_index, offset,
+                  default_ptr, false, NULL)))) {
+            return false;
+          }
+          break;
+        }
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+        case (WireFormatLite::TYPE_STRING): {
+          GOOGLE_DCHECK(!table.unknown_field_set);
+          Arena* const arena = GetArena(msg, table.arena_offset);
+          const void* default_ptr = table.aux[field_number].strings.default_ptr;
+          const char* field_name = table.aux[field_number].strings.field_name;
+          const bool strict_utf8 = table.aux[field_number].strings.strict_utf8;
+
+          if (GOOGLE_PREDICT_FALSE((!HandleString<false, true, StringType_STRING>(
+                  input, msg, arena, has_bits, has_bit_index, offset,
+                  default_ptr, strict_utf8, field_name)))) {
+            return false;
+          }
+          break;
+        }
+        case (WireFormatLite::TYPE_STRING) | kRepeatedMask: {
+          GOOGLE_DCHECK(!table.unknown_field_set);
+          Arena* const arena = GetArena(msg, table.arena_offset);
+          const void* default_ptr = table.aux[field_number].strings.default_ptr;
+          const char* field_name = table.aux[field_number].strings.field_name;
+          const bool strict_utf8 = table.aux[field_number].strings.strict_utf8;
+
+          if (GOOGLE_PREDICT_FALSE((!HandleString<true, true, StringType_STRING>(
+                  input, msg, arena, has_bits, has_bit_index, offset,
+                  default_ptr, strict_utf8, field_name)))) {
+            return false;
+          }
+          break;
+        }
+#endif
+        case WireFormatLite::TYPE_ENUM: {
+          int value;
+          if (GOOGLE_PREDICT_FALSE((!WireFormatLite::ReadPrimitive<
+                             int, WireFormatLite::TYPE_ENUM>(input, &value)))) {
+            return false;
+          }
+
+          AuxillaryParseTableField::EnumValidator validator =
+              table.aux[field_number].enums.validator;
+          if (validator(value)) {
+            SetField(msg, has_bits, has_bit_index, offset, value);
+          } else {
+            GOOGLE_DCHECK(!table.unknown_field_set);
+
+            ::google::protobuf::io::StringOutputStream unknown_fields_string(
+                MutableUnknownFields(msg, table.arena_offset));
+            ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
+                &unknown_fields_string, false);
+            unknown_fields_stream.WriteVarint32(tag);
+            unknown_fields_stream.WriteVarint32(value);
+          }
+          break;
+        }
+        case WireFormatLite::TYPE_ENUM | kRepeatedMask: {
+          int value;
+          if (GOOGLE_PREDICT_FALSE((!WireFormatLite::ReadPrimitive<
+                             int, WireFormatLite::TYPE_ENUM>(input, &value)))) {
+            return false;
+          }
+
+          AuxillaryParseTableField::EnumValidator validator =
+              table.aux[field_number].enums.validator;
+          if (validator(value)) {
+            AddField(msg, offset, value);
+          } else {
+            GOOGLE_DCHECK(!table.unknown_field_set);
+
+            ::google::protobuf::io::StringOutputStream unknown_fields_string(
+                MutableUnknownFields(msg, table.arena_offset));
+            ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
+                &unknown_fields_string, false);
+            unknown_fields_stream.WriteVarint32(tag);
+            unknown_fields_stream.WriteVarint32(value);
+          }
+
+          break;
+        }
+        case WireFormatLite::TYPE_GROUP: {
+          MessageLite** submsg_holder =
+              MutableField<MessageLite*>(msg, has_bits, has_bit_index, offset);
+          MessageLite* submsg = *submsg_holder;
+
+          if (submsg == NULL) {
+            GOOGLE_DCHECK(!table.unknown_field_set);
+            Arena* const arena = GetArena(msg, table.arena_offset);
+            const MessageLite* prototype =
+                table.aux[field_number].messages.default_message();
+            submsg = prototype->New(arena);
+            *submsg_holder = submsg;
+          }
+
+          const ParseTable* ptable =
+              table.aux[field_number].messages.parse_table;
+
+          if (ptable) {
+            if (GOOGLE_PREDICT_FALSE(
+                    !ReadGroup(field_number, input, submsg, *ptable))) {
+              return false;
+            }
+          } else if (!WireFormatLite::ReadGroup(field_number, input, submsg)) {
+            return false;
+          }
+
+          break;
+        }
+        case WireFormatLite::TYPE_GROUP | kRepeatedMask: {
+          RepeatedPtrFieldBase* field = Raw<RepeatedPtrFieldBase>(msg, offset);
+          const MessageLite* prototype =
+              table.aux[field_number].messages.default_message();
+          GOOGLE_DCHECK(prototype != NULL);
+
+          MessageLite* submsg =
+              MergePartialFromCodedStreamHelper::Add(field, prototype);
+          const ParseTable* ptable =
+              table.aux[field_number].messages.parse_table;
+
+          if (ptable) {
+            if (GOOGLE_PREDICT_FALSE(
+                    !ReadGroup(field_number, input, submsg, *ptable))) {
+              return false;
+            }
+          } else if (!WireFormatLite::ReadGroup(field_number, input, submsg)) {
+            return false;
+          }
+
+          break;
+        }
+        case WireFormatLite::TYPE_MESSAGE: {
+          MessageLite** submsg_holder =
+              MutableField<MessageLite*>(msg, has_bits, has_bit_index, offset);
+          MessageLite* submsg = *submsg_holder;
+
+          if (submsg == NULL) {
+            GOOGLE_DCHECK(!table.unknown_field_set);
+            Arena* const arena = GetArena(msg, table.arena_offset);
+            const MessageLite* prototype =
+                table.aux[field_number].messages.default_message();
+            submsg = prototype->New(arena);
+            *submsg_holder = submsg;
+          }
+
+          const ParseTable* ptable =
+              table.aux[field_number].messages.parse_table;
+
+          if (ptable) {
+            if (GOOGLE_PREDICT_FALSE(!ReadMessage(input, submsg, *ptable))) {
+              return false;
+            }
+          } else if (!WireFormatLite::ReadMessage(input, submsg)) {
+            return false;
+          }
+
+          break;
+        }
+        // TODO(ckennelly):  Adapt ReadMessageNoVirtualNoRecursionDepth and
+        // manage input->IncrementRecursionDepth() here.
+        case WireFormatLite::TYPE_MESSAGE | kRepeatedMask: {
+          RepeatedPtrFieldBase* field = Raw<RepeatedPtrFieldBase>(msg, offset);
+          const MessageLite* prototype =
+              table.aux[field_number].messages.default_message();
+          GOOGLE_DCHECK(prototype != NULL);
+
+          MessageLite* submsg =
+              MergePartialFromCodedStreamHelper::Add(field, prototype);
+          const ParseTable* ptable =
+              table.aux[field_number].messages.parse_table;
+
+          if (ptable) {
+            if (GOOGLE_PREDICT_FALSE(!ReadMessage(input, submsg, *ptable))) {
+              return false;
+            }
+          } else if (!WireFormatLite::ReadMessage(input, submsg)) {
+            return false;
+          }
+
+          break;
+        }
+        case 0: {
+          // Done.
+          return true;
+        }
+        default:
+          break;
+      }
+    } else if (data->packed_wiretype == static_cast<unsigned char>(wire_type)) {
+      // Non-packable fields have their packed_wiretype masked with
+      // kNotPackedMask, which is impossible to match here.
+      GOOGLE_DCHECK(processing_type & kRepeatedMask);
+      GOOGLE_DCHECK_NE(processing_type, kRepeatedMask);
+
+
+
+      // TODO(ckennelly): Use a computed goto on GCC/LLVM.
+      //
+      // Mask out kRepeatedMask bit, allowing the jump table to be smaller.
+      switch (static_cast<WireFormatLite::FieldType>(
+          processing_type ^ kRepeatedMask)) {
+#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)                 \
+  case WireFormatLite::TYPE_##TYPE: {                                     \
+    google::protobuf::RepeatedField<CPPTYPE>* values =                              \
+        Raw<google::protobuf::RepeatedField<CPPTYPE> >(msg, offset);                \
+    if (GOOGLE_PREDICT_FALSE(                                                    \
+            (!WireFormatLite::ReadPackedPrimitive<                        \
+                CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, values)))) { \
+      return false;                                                       \
+    }                                                                     \
+    break;                                                                \
+  }
+
+        HANDLE_PACKED_TYPE(INT32, int32, Int32)
+        HANDLE_PACKED_TYPE(INT64, int64, Int64)
+        HANDLE_PACKED_TYPE(SINT32, int32, Int32)
+        HANDLE_PACKED_TYPE(SINT64, int64, Int64)
+        HANDLE_PACKED_TYPE(UINT32, uint32, UInt32)
+        HANDLE_PACKED_TYPE(UINT64, uint64, UInt64)
+
+        HANDLE_PACKED_TYPE(FIXED32, uint32, UInt32)
+        HANDLE_PACKED_TYPE(FIXED64, uint64, UInt64)
+        HANDLE_PACKED_TYPE(SFIXED32, int32, Int32)
+        HANDLE_PACKED_TYPE(SFIXED64, int64, Int64)
+
+        HANDLE_PACKED_TYPE(FLOAT, float, Float)
+        HANDLE_PACKED_TYPE(DOUBLE, double, Double)
+
+        HANDLE_PACKED_TYPE(BOOL, bool, Bool)
+#undef HANDLE_PACKED_TYPE
+        case WireFormatLite::TYPE_ENUM: {
+          // To avoid unnecessarily calling MutableUnknownFields (which mutates
+          // InternalMetadataWithArena) when all inputs in the repeated series
+          // are valid, we implement our own parser rather than call
+          // WireFormat::ReadPackedEnumPreserveUnknowns.
+          uint32 length;
+          if (GOOGLE_PREDICT_FALSE(!input->ReadVarint32(&length))) {
+            return false;
+          }
+
+          AuxillaryParseTableField::EnumValidator validator =
+              table.aux[field_number].enums.validator;
+          google::protobuf::RepeatedField<int>* values =
+              Raw<google::protobuf::RepeatedField<int> >(msg, offset);
+          string* unknown_fields = NULL;
+
+          io::CodedInputStream::Limit limit = input->PushLimit(length);
+          while (input->BytesUntilLimit() > 0) {
+            int value;
+            if (GOOGLE_PREDICT_FALSE(
+                    (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                        int, WireFormatLite::TYPE_ENUM>(input, &value)))) {
+              return false;
+            }
+
+            if (validator(value)) {
+              values->Add(value);
+            } else {
+              if (GOOGLE_PREDICT_FALSE(unknown_fields == NULL)) {
+                GOOGLE_DCHECK(!table.unknown_field_set);
+                unknown_fields = MutableUnknownFields(msg, table.arena_offset);
+              }
+
+              ::google::protobuf::io::StringOutputStream unknown_fields_string(
+                  unknown_fields);
+              ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
+                  &unknown_fields_string, false);
+              unknown_fields_stream.WriteVarint32(tag);
+              unknown_fields_stream.WriteVarint32(value);
+            }
+          }
+          input->PopLimit(limit);
+
+          break;
+        }
+        case WireFormatLite::TYPE_STRING:
+        case WireFormatLite::TYPE_GROUP:
+        case WireFormatLite::TYPE_MESSAGE:
+        case WireFormatLite::TYPE_BYTES:
+          GOOGLE_DCHECK(false);
+          return false;
+        default:
+          break;
+      }
+    } else {
+      if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
+        // Must be the end of the message.
+        return true;
+      }
+
+      // process unknown field.
+      GOOGLE_DCHECK(!table.unknown_field_set);
+      ::google::protobuf::io::StringOutputStream unknown_fields_string(
+          MutableUnknownFields(msg, table.arena_offset));
+      ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
+          &unknown_fields_string, false);
+
+      if (!::google::protobuf::internal::WireFormatLite::SkipField(
+          input, tag, &unknown_fields_stream)) {
+        return false;
+      }
+    }
+  }
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/generated_message_table_driven.h b/src/google/protobuf/generated_message_table_driven.h
new file mode 100644
index 0000000..557c57d
--- /dev/null
+++ b/src/google/protobuf/generated_message_table_driven.h
@@ -0,0 +1,173 @@
+// 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_MESSAGE_TABLE_DRIVEN_H__
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_H__
+
+#include <google/protobuf/message_lite.h>
+
+#if LANG_CXX11
+#define PROTOBUF_CONSTEXPR constexpr
+
+// We require C++11 and Clang to use constexpr for variables, as GCC 4.8
+// requires constexpr to be consistent between declarations of variables
+// unnecessarily (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58541).
+#ifdef __clang__
+#define PROTOBUF_CONSTEXPR_VAR constexpr
+#else  // !__clang__
+#define PROTOBUF_CONSTEXPR_VAR
+#endif  // !_clang
+
+#else
+#define PROTOBUF_CONSTEXPR
+#define PROTOBUF_CONSTEXPR_VAR
+#endif
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+static PROTOBUF_CONSTEXPR const unsigned char kOneofMask = 0x40;
+static PROTOBUF_CONSTEXPR const unsigned char kRepeatedMask = 0x20;
+// Check this against types.
+
+static PROTOBUF_CONSTEXPR const unsigned char kNotPackedMask = 0x10;
+static PROTOBUF_CONSTEXPR const unsigned char kInvalidMask = 0x20;
+
+enum ProcessingTypes {
+  TYPE_STRING_CORD = 19,
+  TYPE_STRING_STRING_PIECE = 20,
+  TYPE_BYTES_CORD = 21,
+  TYPE_BYTES_STRING_PIECE = 22,
+};
+
+#if LANG_CXX11
+static_assert(TYPE_BYTES_STRING_PIECE < kRepeatedMask, "Invalid enum");
+#endif
+
+// TODO(ckennelly):  Add a static assertion to ensure that these masks do not
+// conflict with wiretypes.
+
+// ParseTableField is kept small to help simplify instructions for computing
+// offsets, as we will always need this information to parse a field.
+// Additional data, needed for some types, is stored in
+// AuxillaryParseTableField.
+struct ParseTableField {
+  uint32 offset;
+  uint32 has_bit_index;
+  unsigned char normal_wiretype;
+  unsigned char packed_wiretype;
+
+  // processing_type is given by:
+  //   (FieldDescriptor->type() << 1) | FieldDescriptor->is_packed()
+  unsigned char processing_type;
+
+  unsigned char tag_size;
+};
+
+struct ParseTable;
+
+union AuxillaryParseTableField {
+  typedef bool (*EnumValidator)(int);
+
+  // Enums
+  struct enum_aux {
+    EnumValidator validator;
+    const char* name;
+  };
+  enum_aux enums;
+  // Group, messages
+  struct message_aux {
+    // ExplicitlyInitialized<T> -> T requires a reinterpret_cast, which prevents
+    // the tables from being constructed as a constexpr.  We use void to avoid
+    // the cast.
+    const void* default_message_void;
+    const MessageLite* default_message() const {
+      return static_cast<const MessageLite*>(default_message_void);
+    }
+    const ParseTable* parse_table;
+  };
+  message_aux messages;
+  // Strings
+  struct string_aux {
+    const void* default_ptr;
+    const char* field_name;
+    bool strict_utf8;
+    const char* name;
+  };
+  string_aux strings;
+
+#if LANG_CXX11
+  AuxillaryParseTableField() = default;
+#else
+  AuxillaryParseTableField() { }
+#endif
+  PROTOBUF_CONSTEXPR AuxillaryParseTableField(
+      AuxillaryParseTableField::enum_aux e) : enums(e) {}
+  PROTOBUF_CONSTEXPR AuxillaryParseTableField(
+      AuxillaryParseTableField::message_aux m) : messages(m) {}
+  PROTOBUF_CONSTEXPR AuxillaryParseTableField(
+      AuxillaryParseTableField::string_aux s) : strings(s) {}
+};
+
+struct ParseTable {
+  const ParseTableField* fields;
+  const AuxillaryParseTableField* aux;
+  int max_field_number;
+  // TODO(ckennelly): Do something with this padding.
+
+  // TODO(ckennelly): Vet these for sign extension.
+  int64 has_bits_offset;
+  int64 arena_offset;
+  int  unknown_field_set;
+};
+
+// TODO(jhen): Remove the __NVCC__ check when we get a version of nvcc that
+// supports these checks.
+#if LANG_CXX11 && !defined(__NVCC__)
+static_assert(sizeof(ParseTableField) <= 16, "ParseTableField is too large");
+// The tables must be composed of POD components to ensure link-time
+// initialization.
+static_assert(std::is_pod<ParseTableField>::value, "");
+static_assert(std::is_pod<AuxillaryParseTableField>::value, "");
+static_assert(std::is_pod<AuxillaryParseTableField::enum_aux>::value, "");
+static_assert(std::is_pod<AuxillaryParseTableField::message_aux>::value, "");
+static_assert(std::is_pod<AuxillaryParseTableField::string_aux>::value, "");
+static_assert(std::is_pod<ParseTable>::value, "");
+#endif
+
+bool MergePartialFromCodedStream(MessageLite* msg, const ParseTable& table,
+                                 io::CodedInputStream* input);
+
+}  // namespace internal
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_H__
diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc
index b4d2c9c..35d8156 100644
--- a/src/google/protobuf/generated_message_util.cc
+++ b/src/google/protobuf/generated_message_util.cc
@@ -58,7 +58,7 @@
   OnShutdown(&DeleteEmptyString);
 }
 
-int StringSpaceUsedExcludingSelf(const string& str) {
+size_t StringSpaceUsedExcludingSelfLong(const string& str) {
   const void* start = &str;
   const void* end = &str + 1;
   if (start <= str.data() && str.data() < end) {
diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h
index 1410183..903c4ee 100644
--- a/src/google/protobuf/generated_message_util.h
+++ b/src/google/protobuf/generated_message_util.h
@@ -41,12 +41,13 @@
 #include <assert.h>
 #include <string>
 
+#include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/once.h>
 #include <google/protobuf/has_bits.h>
 
 #ifndef PROTOBUF_FINAL
-#if LANG_CXX11
+#if LANG_CXX11 && !defined(__NVCC__)
 #define PROTOBUF_FINAL final
 #else
 #define PROTOBUF_FINAL
@@ -75,6 +76,43 @@
 #define GOOGLE_PROTOBUF_DEPRECATED_ATTR
 
 
+// Returns the offset of the given field within the given aggregate type.
+// This is equivalent to the ANSI C offsetof() macro.  However, according
+// to the C++ standard, offsetof() only works on POD types, and GCC
+// enforces this requirement with a warning.  In practice, this rule is
+// unnecessarily strict; there is probably no compiler or platform on
+// which the offsets of the direct fields of a class are non-constant.
+// Fields inherited from superclasses *can* have non-constant offsets,
+// but that's not what this macro will be used for.
+#if defined(__clang__)
+// For Clang we use __builtin_offsetof() and suppress the warning,
+// to avoid Control Flow Integrity and UBSan vptr sanitizers from
+// crashing while trying to validate the invalid reinterpet_casts.
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD)  \
+  _Pragma("clang diagnostic push")                                   \
+  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"")         \
+  __builtin_offsetof(TYPE, FIELD)                                    \
+  _Pragma("clang diagnostic pop")
+#else
+// Note that we calculate relative to the pointer value 16 here since if we
+// just use zero, GCC complains about dereferencing a NULL pointer.  We
+// choose 16 rather than some other number just in case the compiler would
+// be confused by an unaligned pointer.
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD)  \
+  static_cast<int>(                                                  \
+      reinterpret_cast<const char*>(                                 \
+          &reinterpret_cast<const TYPE*>(16)->FIELD) -               \
+      reinterpret_cast<const char*>(16))
+#endif
+
+#define GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD)  \
+  static_cast< ::google::protobuf::uint32>(                                                    \
+      reinterpret_cast<const char*>(&(ONEOF->FIELD))                        \
+      - reinterpret_cast<const char*>(ONEOF))
+// TODO(acozzette): remove this transitional macro after updating generated code
+#define PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD) \
+  GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD)
+
 // Constants for special floating point values.
 LIBPROTOBUF_EXPORT double Infinity();
 LIBPROTOBUF_EXPORT double NaN();
@@ -125,7 +163,7 @@
 
 // Default empty string object. Don't use this directly. Instead, call
 // GetEmptyString() to get the reference.
-LIBPROTOBUF_EXPORT extern ExplicitlyConstructed< ::std::string> fixed_address_empty_string;
+extern ExplicitlyConstructed< ::std::string> fixed_address_empty_string;
 LIBPROTOBUF_EXPORT extern ProtobufOnceType empty_string_once_init_;
 LIBPROTOBUF_EXPORT void InitEmptyString();
 
@@ -139,7 +177,7 @@
   return GetEmptyStringAlreadyInited();
 }
 
-LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str);
+size_t StringSpaceUsedExcludingSelfLong(const string& str);
 
 
 // True if IsInitialized() is true for all elements of t.  Type is expected
@@ -159,11 +197,21 @@
 // We compute sizes as size_t but cache them as int.  This function converts a
 // computed size to a cached size.  Since we don't proceed with serialization if
 // the total size was > INT_MAX, it is not important what this function returns
-// for inputs > INT_MAX.
+// for inputs > INT_MAX.  However this case should not error or GOOGLE_CHECK-fail,
+// because the full size_t resolution is still returned from ByteSizeLong() and
+// checked against INT_MAX; we can catch the overflow there.
 inline int ToCachedSize(size_t size) {
   return static_cast<int>(size);
 }
 
+// For cases where a legacy function returns an integer size.  We GOOGLE_DCHECK() that
+// the conversion will fit within an integer; if this is false then we are
+// losing information.
+inline int ToIntSize(size_t size) {
+  GOOGLE_DCHECK_LE(size, static_cast<size_t>(INT_MAX));
+  return static_cast<int>(size);
+}
+
 // We mainly calculate sizes in terms of size_t, but some functions that compute
 // sizes return "int".  These int sizes are expected to always be positive.
 // This function is more efficient than casting an int to size_t directly on
diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc
index 3c2e0fb..df4250e 100644
--- a/src/google/protobuf/io/coded_stream.cc
+++ b/src/google/protobuf/io/coded_stream.cc
@@ -76,10 +76,6 @@
   if (input_ != NULL) {
     BackUpInputToCurrentPosition();
   }
-
-  if (total_bytes_warning_threshold_ == -2) {
-    GOOGLE_LOG(WARNING) << "The total number of bytes read was " << total_bytes_read_;
-  }
 }
 
 // Static.
@@ -123,21 +119,15 @@
   Limit old_limit = current_limit_;
 
   // security: byte_limit is possibly evil, so check for negative values
-  // and overflow.
-  if (byte_limit >= 0 &&
-      byte_limit <= INT_MAX - current_position) {
+  // and overflow. Also check that the new requested limit is before the
+  // previous limit; otherwise we continue to enforce the previous limit.
+  if GOOGLE_PREDICT_TRUE(byte_limit >= 0 &&
+                  byte_limit <= INT_MAX - current_position &&
+                  byte_limit < current_limit_ - current_position) {
     current_limit_ = current_position + byte_limit;
-  } else {
-    // Negative or overflow.
-    current_limit_ = INT_MAX;
+    RecomputeBufferLimits();
   }
 
-  // We need to enforce all limits, not just the new one, so if the previous
-  // limit was before the new requested limit, we continue to enforce the
-  // previous limit.
-  current_limit_ = std::min(current_limit_, old_limit);
-
-  RecomputeBufferLimits();
   return old_limit;
 }
 
@@ -185,16 +175,12 @@
 
 void CodedInputStream::SetTotalBytesLimit(
     int total_bytes_limit, int warning_threshold) {
+  (void) warning_threshold;
+
   // Make sure the limit isn't already past, since this could confuse other
   // code.
   int current_position = CurrentPosition();
   total_bytes_limit_ = std::max(current_position, total_bytes_limit);
-  if (warning_threshold >= 0) {
-    total_bytes_warning_threshold_ = warning_threshold;
-  } else {
-    // warning_threshold is negative
-    total_bytes_warning_threshold_ = -1;
-  }
   RecomputeBufferLimits();
 }
 
@@ -605,20 +591,6 @@
     return false;
   }
 
-  if (total_bytes_warning_threshold_ >= 0 &&
-      total_bytes_read_ >= total_bytes_warning_threshold_) {
-      GOOGLE_LOG(INFO) << "Reading dangerously large protocol message.  If the "
-                   "message turns out to be larger than "
-                << total_bytes_limit_ << " bytes, parsing will be halted "
-                   "for security reasons.  To increase the limit (or to "
-                   "disable these warnings), see "
-                   "CodedInputStream::SetTotalBytesLimit() in "
-                   "google/protobuf/io/coded_stream.h.";
-
-    // Don't warn again for this stream, and print total size at the end.
-    total_bytes_warning_threshold_ = -2;
-  }
-
   const void* void_buffer;
   int buffer_size;
   if (NextNonEmpty(input_, &void_buffer, &buffer_size)) {
@@ -655,7 +627,7 @@
 
 // CodedOutputStream =================================================
 
-bool CodedOutputStream::default_serialization_deterministic_ = false;
+google::protobuf::internal::AtomicWord CodedOutputStream::default_serialization_deterministic_ = 0;
 
 CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
   : output_(output),
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h
index b71b4a9..20d8614 100644
--- a/src/google/protobuf/io/coded_stream.h
+++ b/src/google/protobuf/io/coded_stream.h
@@ -131,7 +131,9 @@
     #define PROTOBUF_LITTLE_ENDIAN 1
   #endif
 #endif
+#include <google/protobuf/stubs/atomicops.h>
 #include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
 
 namespace google {
 
@@ -371,11 +373,10 @@
   // maximum message length should be limited to the shortest length that
   // will not harm usability.  The theoretical shortest message that could
   // cause integer overflows is 512MB.  The default limit is 64MB.  Apps
-  // should set shorter limits if possible.  If warning_threshold is not -1,
-  // a warning will be printed to stderr after warning_threshold bytes are
-  // read.  For backwards compatibility all negative values get squashed to -1,
-  // as other negative values might have special internal meanings.
-  // An error will always be printed to stderr if the limit is reached.
+  // should set shorter limits if possible.  For backwards compatibility all
+  // negative values get squashed to -1, as other negative values might have
+  // special internal meanings.  An error will always be printed to stderr if
+  // the limit is reached.
   //
   // This is unrelated to PushLimit()/PopLimit().
   //
@@ -568,12 +569,6 @@
   // current_limit_.  Set using SetTotalBytesLimit().
   int total_bytes_limit_;
 
-  // If positive/0: Limit for bytes read after which a warning due to size
-  // should be logged.
-  // If -1: Printing of warning disabled. Can be set by client.
-  // If -2: Internal: Limit has been reached, print full size when destructing.
-  int total_bytes_warning_threshold_;
-
   // Current recursion budget, controlled by IncrementRecursionDepth() and
   // similar.  Starts at recursion_limit_ and goes down: if this reaches
   // -1 we are over budget.
@@ -581,6 +576,8 @@
   // Recursion depth limit, set by SetRecursionLimit().
   int recursion_limit_;
 
+  bool disable_strict_correctness_enforcement_;
+
   // See SetExtensionRegistry().
   const DescriptorPool* extension_pool_;
   MessageFactory* extension_factory_;
@@ -642,8 +639,6 @@
 
   static const int kDefaultTotalBytesLimit = INT_MAX;
 
-  static const int kDefaultTotalBytesWarningThreshold = 32 << 20;  // 32MB
-
   static int default_recursion_limit_;  // 100 by default.
 };
 
@@ -870,7 +865,7 @@
   }
 
   static bool IsDefaultSerializationDeterministic() {
-    return default_serialization_deterministic_;
+    return google::protobuf::internal::Acquire_Load(&default_serialization_deterministic_);
   }
 
  private:
@@ -885,7 +880,8 @@
   // See SetSerializationDeterministic() regarding these three fields.
   bool serialization_deterministic_is_overridden_;
   bool serialization_deterministic_override_;
-  static bool default_serialization_deterministic_;
+  // Conceptually, default_serialization_deterministic_ is an atomic bool.
+  static google::protobuf::internal::AtomicWord default_serialization_deterministic_;
 
   // Advance the buffer by a given number of bytes.
   void Advance(int amount);
@@ -904,10 +900,15 @@
   void WriteVarint64SlowPath(uint64 value);
 
   // See above.  Other projects may use "friend" to allow them to call this.
-  // Requires: no protocol buffer serialization in progress.
+  // After SetDefaultSerializationDeterministic() completes, all protocol
+  // buffer serializations will be deterministic by default.  Thread safe.
+  // However, the meaning of "after" is subtle here: to be safe, each thread
+  // that wants deterministic serialization by default needs to call
+  // SetDefaultSerializationDeterministic() or ensure on its own that another
+  // thread has done so.
   friend void ::google::protobuf::internal::MapTestForceDeterministic();
   static void SetDefaultSerializationDeterministic() {
-    default_serialization_deterministic_ = true;
+    google::protobuf::internal::Release_Store(&default_serialization_deterministic_, 1);
   }
 };
 
@@ -1395,9 +1396,9 @@
     current_limit_(kint32max),
     buffer_size_after_limit_(0),
     total_bytes_limit_(kDefaultTotalBytesLimit),
-    total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
     recursion_budget_(default_recursion_limit_),
     recursion_limit_(default_recursion_limit_),
+    disable_strict_correctness_enforcement_(true),
     extension_pool_(NULL),
     extension_factory_(NULL) {
   // Eagerly Refresh() so buffer space is immediately available.
@@ -1416,9 +1417,9 @@
     current_limit_(size),
     buffer_size_after_limit_(0),
     total_bytes_limit_(kDefaultTotalBytesLimit),
-    total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
     recursion_budget_(default_recursion_limit_),
     recursion_limit_(default_recursion_limit_),
+    disable_strict_correctness_enforcement_(true),
     extension_pool_(NULL),
     extension_factory_(NULL) {
   // Note that setting current_limit_ == size is important to prevent some
diff --git a/src/google/protobuf/io/coded_stream_unittest.cc b/src/google/protobuf/io/coded_stream_unittest.cc
index 31574d5..96f91ae 100644
--- a/src/google/protobuf/io/coded_stream_unittest.cc
+++ b/src/google/protobuf/io/coded_stream_unittest.cc
@@ -63,6 +63,7 @@
 namespace io {
 namespace {
 
+
 // ===================================================================
 // Data-Driven Test Infrastructure
 
@@ -1296,35 +1297,6 @@
   *out_warnings = scoped_log.GetMessages(WARNING);
 }
 
-TEST_F(CodedStreamTest, TotalBytesLimitWarning) {
-  std::vector<string> errors;
-  std::vector<string> warnings;
-  SetupTotalBytesLimitWarningTest(10240, 1024, &errors, &warnings);
-
-  EXPECT_EQ(0, errors.size());
-
-  EXPECT_EQ(1, warnings.size());
-  EXPECT_PRED_FORMAT2(testing::IsSubstring,
-    "The total number of bytes read was 2048",
-    warnings[0]);
-}
-
-TEST_F(CodedStreamTest, TotalBytesLimitWarningDisabled) {
-  std::vector<string> errors;
-  std::vector<string> warnings;
-
-  // Test with -1
-  SetupTotalBytesLimitWarningTest(10240, -1, &errors, &warnings);
-  EXPECT_EQ(0, errors.size());
-  EXPECT_EQ(0, warnings.size());
-
-  // Test again with -2, expecting the same result
-  SetupTotalBytesLimitWarningTest(10240, -2, &errors, &warnings);
-  EXPECT_EQ(0, errors.size());
-  EXPECT_EQ(0, warnings.size());
-}
-
-
 TEST_F(CodedStreamTest, RecursionLimit) {
   ArrayInputStream input(buffer_, sizeof(buffer_));
   CodedInputStream coded_input(&input);
@@ -1425,9 +1397,6 @@
   EXPECT_EQ(0, errors.size());
 }
 
-// ===================================================================
-
-
 }  // namespace
 }  // namespace io
 }  // namespace protobuf
diff --git a/src/google/protobuf/io/gzip_stream.h b/src/google/protobuf/io/gzip_stream.h
index df1a446..15b02fe 100644
--- a/src/google/protobuf/io/gzip_stream.h
+++ b/src/google/protobuf/io/gzip_stream.h
@@ -118,7 +118,7 @@
     ZLIB = 2,
   };
 
-  struct LIBPROTOBUF_EXPORT Options {
+  struct Options {
     // Defaults to GZIP.
     Format format;
 
diff --git a/src/google/protobuf/lite_unittest.cc b/src/google/protobuf/lite_unittest.cc
index 3ca3fba..90d59fb 100644
--- a/src/google/protobuf/lite_unittest.cc
+++ b/src/google/protobuf/lite_unittest.cc
@@ -36,14 +36,16 @@
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/arena_test_util.h>
-#include <google/protobuf/map_lite_unittest.pb.h>
 #include <google/protobuf/map_lite_test_util.h>
+#include <google/protobuf/map_lite_unittest.pb.h>
 #include <google/protobuf/test_util_lite.h>
 #include <google/protobuf/unittest_lite.pb.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 #include <google/protobuf/wire_format_lite.h>
 #include <google/protobuf/wire_format_lite_inl.h>
+#include <gtest/gtest.h>
+
 #include <google/protobuf/stubs/strutil.h>
 
 using namespace std;
@@ -51,9 +53,9 @@
 namespace {
 // Helper methods to test parsing merge behavior.
 void ExpectMessageMerged(const google::protobuf::unittest::TestAllTypesLite& message) {
-  GOOGLE_CHECK(message.optional_int32() == 3);
-  GOOGLE_CHECK(message.optional_int64() == 2);
-  GOOGLE_CHECK(message.optional_string() == "hello");
+  EXPECT_EQ(message.optional_int32(), 3);
+  EXPECT_EQ(message.optional_int64(), 2);
+  EXPECT_EQ(message.optional_string(), "hello");
 }
 
 void AssignParsingMergeMessages(
@@ -89,14 +91,8 @@
 
 }  // namespace
 
-#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
-
-int main(int argc, char* argv[]) {
-  string data, data2, packed_data;
+TEST(Lite, AllLite1) {
+  string data;
 
   {
     protobuf_unittest::TestAllTypesLite message, message2, message3;
@@ -113,7 +109,10 @@
     message.Clear();
     google::protobuf::TestUtilLite::ExpectClear(message);
   }
+}
 
+TEST(Lite, AllLite2) {
+  string data;
   {
     protobuf_unittest::TestAllExtensionsLite message, message2, message3;
     google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
@@ -129,6 +128,10 @@
     message.Clear();
     google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
   }
+}
+
+TEST(Lite, AllLite3) {
+  string data, packed_data;
 
   {
     protobuf_unittest::TestPackedTypesLite message, message2, message3;
@@ -152,7 +155,7 @@
     google::protobuf::TestUtilLite::SetPackedExtensions(&message);
     message2.CopyFrom(message);
     string packed_extensions_data = message.SerializeAsString();
-    GOOGLE_CHECK(packed_extensions_data == packed_data);
+    EXPECT_EQ(packed_extensions_data, packed_data);
     message3.ParseFromString(packed_extensions_data);
     google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message);
     google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2);
@@ -162,6 +165,10 @@
     message.Clear();
     google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
   }
+}
+
+TEST(Lite, AllLite5) {
+  string data;
 
   {
     // Test that if an optional or required message/group field appears multiple
@@ -209,11 +216,16 @@
         google::protobuf::unittest::TestParsingMergeLite::optional_ext));
 
     // Repeated fields should not be merged.
-    GOOGLE_CHECK(parsing_merge.repeated_all_types_size() == 3);
-    GOOGLE_CHECK(parsing_merge.repeatedgroup_size() == 3);
-    GOOGLE_CHECK(parsing_merge.ExtensionSize(
-        google::protobuf::unittest::TestParsingMergeLite::repeated_ext) == 3);
+    EXPECT_EQ(parsing_merge.repeated_all_types_size(), 3);
+    EXPECT_EQ(parsing_merge.repeatedgroup_size(), 3);
+    EXPECT_EQ(parsing_merge.ExtensionSize(
+                  google::protobuf::unittest::TestParsingMergeLite::repeated_ext),
+              3);
   }
+}
+
+TEST(Lite, AllLite6) {
+  string data;
 
   // Test unknown fields support for lite messages.
   {
@@ -231,6 +243,10 @@
     message.Clear();
     google::protobuf::TestUtilLite::ExpectClear(message);
   }
+}
+
+TEST(Lite, AllLite7) {
+  string data;
 
   {
     protobuf_unittest::TestAllExtensionsLite message, message2;
@@ -247,6 +263,10 @@
     message.Clear();
     google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
   }
+}
+
+TEST(Lite, AllLite8) {
+  string data;
 
   {
     protobuf_unittest::TestPackedTypesLite message, message2;
@@ -263,6 +283,10 @@
     message.Clear();
     google::protobuf::TestUtilLite::ExpectPackedClear(message);
   }
+}
+
+TEST(Lite, AllLite9) {
+  string data;
 
   {
     protobuf_unittest::TestPackedExtensionsLite message, message2;
@@ -279,6 +303,10 @@
     message.Clear();
     google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
   }
+}
+
+TEST(Lite, AllLite10) {
+  string data;
 
   {
     // Test Unknown fields swap
@@ -286,11 +314,15 @@
     SetAllTypesInEmptyMessageUnknownFields(&empty_message);
     SetSomeTypesInEmptyMessageUnknownFields(&empty_message2);
     data = empty_message.SerializeAsString();
-    data2 = empty_message2.SerializeAsString();
+    string data2 = empty_message2.SerializeAsString();
     empty_message.Swap(&empty_message2);
-    GOOGLE_CHECK_EQ(data, empty_message2.SerializeAsString());
-    GOOGLE_CHECK_EQ(data2, empty_message.SerializeAsString());
+    EXPECT_EQ(data, empty_message2.SerializeAsString());
+    EXPECT_EQ(data2, empty_message.SerializeAsString());
   }
+}
+
+TEST(Lite, AllLite11) {
+  string data;
 
   {
     // Test unknown fields swap with self
@@ -298,8 +330,12 @@
     SetAllTypesInEmptyMessageUnknownFields(&empty_message);
     data = empty_message.SerializeAsString();
     empty_message.Swap(&empty_message);
-    GOOGLE_CHECK_EQ(data, empty_message.SerializeAsString());
+    EXPECT_EQ(data, empty_message.SerializeAsString());
   }
+}
+
+TEST(Lite, AllLite12) {
+  string data;
 
   {
     // Test MergeFrom with unknown fields
@@ -324,8 +360,12 @@
     // We do not compare the serialized output of a normal message and a lite
     // message because the order of fields do not match. We convert lite message
     // back into normal message, then compare.
-    GOOGLE_CHECK_EQ(message.SerializeAsString(), message2.SerializeAsString());
+    EXPECT_EQ(message.SerializeAsString(), message2.SerializeAsString());
   }
+}
+
+TEST(Lite, AllLite13) {
+  string data;
 
   {
     // Test unknown enum value
@@ -345,18 +385,26 @@
     }
     message.ParseFromString(buffer);
     data = message.SerializeAsString();
-    GOOGLE_CHECK_EQ(data, buffer);
+    EXPECT_EQ(data, buffer);
   }
+}
+
+TEST(Lite, AllLite14) {
+  string data;
 
   {
     // Test Clear with unknown fields
     protobuf_unittest::TestEmptyMessageLite empty_message;
     SetAllTypesInEmptyMessageUnknownFields(&empty_message);
     empty_message.Clear();
-    GOOGLE_CHECK_EQ(0, empty_message.unknown_fields().size());
+    EXPECT_EQ(0, empty_message.unknown_fields().size());
   }
+}
 
-  // Tests for map lite =============================================
+// Tests for map lite =============================================
+
+TEST(Lite, AllLite15) {
+  string data;
 
   {
     // Accessors
@@ -368,6 +416,10 @@
     google::protobuf::MapLiteTestUtil::ModifyMapFields(&message);
     google::protobuf::MapLiteTestUtil::ExpectMapFieldsModified(message);
   }
+}
+
+TEST(Lite, AllLite16) {
+  string data;
 
   {
     // SetMapFieldsInitialized
@@ -376,6 +428,10 @@
     google::protobuf::MapLiteTestUtil::SetMapFieldsInitialized(&message);
     google::protobuf::MapLiteTestUtil::ExpectMapFieldsSetInitialized(message);
   }
+}
+
+TEST(Lite, AllLite17) {
+  string data;
 
   {
     // Clear
@@ -385,6 +441,10 @@
     message.Clear();
     google::protobuf::MapLiteTestUtil::ExpectClear(message);
   }
+}
+
+TEST(Lite, AllLite18) {
+  string data;
 
   {
     // ClearMessageMap
@@ -394,6 +454,10 @@
     google::protobuf::TestUtilLite::ExpectClear(
         (*message.mutable_map_int32_message())[0]);
   }
+}
+
+TEST(Lite, AllLite19) {
+  string data;
 
   {
     // CopyFrom
@@ -407,6 +471,10 @@
     message2.CopyFrom(message2);
     google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2);
   }
+}
+
+TEST(Lite, AllLite20) {
+  string data;
 
   {
     // CopyFromMessageMap
@@ -421,6 +489,10 @@
     EXPECT_EQ(1, message1.map_int32_message().at(0).repeated_int32_size());
     EXPECT_EQ(101, message1.map_int32_message().at(0).repeated_int32(0));
   }
+}
+
+TEST(Lite, AllLite21) {
+  string data;
 
   {
     // SwapWithEmpty
@@ -434,6 +506,10 @@
     google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2);
     google::protobuf::MapLiteTestUtil::ExpectClear(message1);
   }
+}
+
+TEST(Lite, AllLite22) {
+  string data;
 
   {
     // SwapWithSelf
@@ -445,6 +521,10 @@
     message.Swap(&message);
     google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message);
   }
+}
+
+TEST(Lite, AllLite23) {
+  string data;
 
   {
     // SwapWithOther
@@ -458,6 +538,10 @@
     google::protobuf::MapLiteTestUtil::ExpectMapFieldsModified(message1);
     google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2);
   }
+}
+
+TEST(Lite, AllLite24) {
+  string data;
 
   {
     // CopyConstructor
@@ -467,6 +551,10 @@
     protobuf_unittest::TestMapLite message2(message1);
     google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2);
   }
+}
+
+TEST(Lite, AllLite25) {
+  string data;
 
   {
     // CopyAssignmentOperator
@@ -481,6 +569,10 @@
     message2.operator=(message2);
     google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2);
   }
+}
+
+TEST(Lite, AllLite26) {
+  string data;
 
   {
     // NonEmptyMergeFrom
@@ -499,6 +591,10 @@
     message1.MergeFrom(message2);
     google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message1);
   }
+}
+
+TEST(Lite, AllLite27) {
+  string data;
 
   {
     // MergeFromMessageMap
@@ -513,6 +609,10 @@
     EXPECT_EQ(1, message1.map_int32_message().at(0).repeated_int32_size());
     EXPECT_EQ(101, message1.map_int32_message().at(0).repeated_int32(0));
   }
+}
+
+TEST(Lite, AllLite28) {
+  string data;
 
   {
     // Test the generated SerializeWithCachedSizesToArray()
@@ -527,6 +627,10 @@
     EXPECT_TRUE(message2.ParseFromString(data));
     google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2);
   }
+}
+
+TEST(Lite, AllLite29) {
+  string data;
 
   {
     // Test the generated SerializeWithCachedSizes()
@@ -547,8 +651,12 @@
     EXPECT_TRUE(message2.ParseFromString(data));
     google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2);
   }
+}
 
 
+TEST(Lite, AllLite32) {
+  string data;
+
   {
     // Proto2UnknownEnum
     protobuf_unittest::TestEnumMapPlusExtraLite from;
@@ -578,6 +686,10 @@
     EXPECT_EQ(protobuf_unittest::E_PROTO2_MAP_ENUM_EXTRA_LITE,
               from.unknown_map_field().at(0));
   }
+}
+
+TEST(Lite, AllLite33) {
+  string data;
 
   {
     // StandardWireFormat
@@ -588,6 +700,10 @@
     EXPECT_EQ(1, message.map_int32_int32().size());
     EXPECT_EQ(1, message.map_int32_int32().at(1));
   }
+}
+
+TEST(Lite, AllLite34) {
+  string data;
 
   {
     // UnorderedWireFormat
@@ -600,6 +716,10 @@
     EXPECT_EQ(1, message.map_int32_int32().size());
     EXPECT_EQ(1, message.map_int32_int32().at(2));
   }
+}
+
+TEST(Lite, AllLite35) {
+  string data;
 
   {
     // DuplicatedKeyWireFormat
@@ -612,6 +732,10 @@
     EXPECT_EQ(1, message.map_int32_int32().size());
     EXPECT_EQ(1, message.map_int32_int32().at(2));
   }
+}
+
+TEST(Lite, AllLite36) {
+  string data;
 
   {
     // DuplicatedValueWireFormat
@@ -624,6 +748,10 @@
     EXPECT_EQ(1, message.map_int32_int32().size());
     EXPECT_EQ(2, message.map_int32_int32().at(1));
   }
+}
+
+TEST(Lite, AllLite37) {
+  string data;
 
   {
     // MissedKeyWireFormat
@@ -636,6 +764,10 @@
     EXPECT_EQ(1, message.map_int32_int32().size());
     EXPECT_EQ(1, message.map_int32_int32().at(0));
   }
+}
+
+TEST(Lite, AllLite38) {
+  string data;
 
   {
     // MissedValueWireFormat
@@ -648,6 +780,10 @@
     EXPECT_EQ(1, message.map_int32_int32().size());
     EXPECT_EQ(0, message.map_int32_int32().at(1));
   }
+}
+
+TEST(Lite, AllLite39) {
+  string data;
 
   {
     // UnknownFieldWireFormat
@@ -660,6 +796,10 @@
     EXPECT_EQ(1, message.map_int32_int32().size());
     EXPECT_EQ(3, message.map_int32_int32().at(2));
   }
+}
+
+TEST(Lite, AllLite40) {
+  string data;
 
   {
     // CorruptedWireFormat
@@ -670,6 +810,10 @@
 
     EXPECT_FALSE(message.ParseFromString(data));
   }
+}
+
+TEST(Lite, AllLite41) {
+  string data;
 
   {
     // IsInitialized
@@ -685,6 +829,10 @@
     (*map_message.mutable_map_field())[0].set_c(0);
     EXPECT_TRUE(map_message.IsInitialized());
   }
+}
+
+TEST(Lite, AllLite42) {
+  string data;
 
   {
       // Check that adding more values to enum does not corrupt message
@@ -714,5 +862,4 @@
   }
 
   std::cout << "PASS" << std::endl;
-  return 0;
 }
diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h
index 88878b5..18ee365 100644
--- a/src/google/protobuf/map.h
+++ b/src/google/protobuf/map.h
@@ -37,7 +37,6 @@
 #ifndef GOOGLE_PROTOBUF_MAP_H__
 #define GOOGLE_PROTOBUF_MAP_H__
 
-#include <google/protobuf/stubs/hash.h>
 #include <iterator>
 #include <limits>  // To support Visual Studio 2008
 #include <set>
@@ -47,8 +46,7 @@
 #include <google/protobuf/arena.h>
 #include <google/protobuf/generated_enum_util.h>
 #include <google/protobuf/map_type_handler.h>
-#include <google/protobuf/message.h>
-#include <google/protobuf/descriptor.h>
+#include <google/protobuf/stubs/hash.h>
 #if __cpp_exceptions && LANG_CXX11
 #include <random>
 #endif
@@ -64,16 +62,14 @@
 template <typename Enum> struct is_proto_enum;
 
 namespace internal {
-template <typename Key, typename T,
+template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType key_wire_type,
-          WireFormatLite::FieldType value_wire_type,
-          int default_enum_value>
+          WireFormatLite::FieldType value_wire_type, int default_enum_value>
 class MapFieldLite;
 
-template <typename Key, typename T,
+template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType key_wire_type,
-          WireFormatLite::FieldType value_wire_type,
-          int default_enum_value>
+          WireFormatLite::FieldType value_wire_type, int default_enum_value>
 class MapField;
 
 template <typename Key, typename T>
@@ -84,389 +80,6 @@
 class GeneratedMessageReflection;
 }  // namespace internal
 
-#define TYPE_CHECK(EXPECTEDTYPE, METHOD)                        \
-  if (type() != EXPECTEDTYPE) {                                 \
-    GOOGLE_LOG(FATAL)                                                  \
-        << "Protocol Buffer map usage error:\n"                 \
-        << METHOD << " type does not match\n"                   \
-        << "  Expected : "                                      \
-        << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n"   \
-        << "  Actual   : "                                      \
-        << FieldDescriptor::CppTypeName(type());                \
-  }
-
-// MapKey is an union type for representing any possible
-// map key.
-class LIBPROTOBUF_EXPORT MapKey {
- public:
-  MapKey() : type_(0) {
-  }
-  MapKey(const MapKey& other) : type_(0) {
-    CopyFrom(other);
-  }
-
-  ~MapKey() {
-    if (type_ == FieldDescriptor::CPPTYPE_STRING) {
-      delete val_.string_value_;
-    }
-  }
-
-  FieldDescriptor::CppType type() const {
-    if (type_ == 0) {
-      GOOGLE_LOG(FATAL)
-          << "Protocol Buffer map usage error:\n"
-          << "MapKey::type MapKey is not initialized. "
-          << "Call set methods to initialize MapKey.";
-    }
-    return (FieldDescriptor::CppType)type_;
-  }
-
-  void SetInt64Value(int64 value) {
-    SetType(FieldDescriptor::CPPTYPE_INT64);
-    val_.int64_value_ = value;
-  }
-  void SetUInt64Value(uint64 value) {
-    SetType(FieldDescriptor::CPPTYPE_UINT64);
-    val_.uint64_value_ = value;
-  }
-  void SetInt32Value(int32 value) {
-    SetType(FieldDescriptor::CPPTYPE_INT32);
-    val_.int32_value_ = value;
-  }
-  void SetUInt32Value(uint32 value) {
-    SetType(FieldDescriptor::CPPTYPE_UINT32);
-    val_.uint32_value_ = value;
-  }
-  void SetBoolValue(bool value) {
-    SetType(FieldDescriptor::CPPTYPE_BOOL);
-    val_.bool_value_ = value;
-  }
-  void SetStringValue(const string& val) {
-    SetType(FieldDescriptor::CPPTYPE_STRING);
-    *val_.string_value_ = val;
-  }
-
-  int64 GetInt64Value() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
-               "MapKey::GetInt64Value");
-    return val_.int64_value_;
-  }
-  uint64 GetUInt64Value() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
-               "MapKey::GetUInt64Value");
-    return val_.uint64_value_;
-  }
-  int32 GetInt32Value() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
-               "MapKey::GetInt32Value");
-    return val_.int32_value_;
-  }
-  uint32 GetUInt32Value() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
-               "MapKey::GetUInt32Value");
-    return val_.uint32_value_;
-  }
-  bool GetBoolValue() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
-               "MapKey::GetBoolValue");
-    return val_.bool_value_;
-  }
-  const string& GetStringValue() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
-               "MapKey::GetStringValue");
-    return *val_.string_value_;
-  }
-
-  bool operator<(const MapKey& other) const {
-    if (type_ != other.type_) {
-      // We could define a total order that handles this case, but
-      // there currently no need.  So, for now, fail.
-      GOOGLE_LOG(FATAL) << "Unsupported: type mismatch";
-    }
-    switch (type()) {
-      case FieldDescriptor::CPPTYPE_DOUBLE:
-      case FieldDescriptor::CPPTYPE_FLOAT:
-      case FieldDescriptor::CPPTYPE_ENUM:
-      case FieldDescriptor::CPPTYPE_MESSAGE:
-        GOOGLE_LOG(FATAL) << "Unsupported";
-        return false;
-      case FieldDescriptor::CPPTYPE_STRING:
-        return *val_.string_value_ < *other.val_.string_value_;
-      case FieldDescriptor::CPPTYPE_INT64:
-        return val_.int64_value_ < other.val_.int64_value_;
-      case FieldDescriptor::CPPTYPE_INT32:
-        return val_.int32_value_ < other.val_.int32_value_;
-      case FieldDescriptor::CPPTYPE_UINT64:
-        return val_.uint64_value_ < other.val_.uint64_value_;
-      case FieldDescriptor::CPPTYPE_UINT32:
-        return val_.uint32_value_ < other.val_.uint32_value_;
-      case FieldDescriptor::CPPTYPE_BOOL:
-        return val_.bool_value_ < other.val_.bool_value_;
-    }
-    return false;
-  }
-
-  bool operator==(const MapKey& other) const {
-    if (type_ != other.type_) {
-      // To be consistent with operator<, we don't allow this either.
-      GOOGLE_LOG(FATAL) << "Unsupported: type mismatch";
-    }
-    switch (type()) {
-      case FieldDescriptor::CPPTYPE_DOUBLE:
-      case FieldDescriptor::CPPTYPE_FLOAT:
-      case FieldDescriptor::CPPTYPE_ENUM:
-      case FieldDescriptor::CPPTYPE_MESSAGE:
-        GOOGLE_LOG(FATAL) << "Unsupported";
-        break;
-      case FieldDescriptor::CPPTYPE_STRING:
-        return *val_.string_value_ == *other.val_.string_value_;
-      case FieldDescriptor::CPPTYPE_INT64:
-        return val_.int64_value_ == other.val_.int64_value_;
-      case FieldDescriptor::CPPTYPE_INT32:
-        return val_.int32_value_ == other.val_.int32_value_;
-      case FieldDescriptor::CPPTYPE_UINT64:
-        return val_.uint64_value_ == other.val_.uint64_value_;
-      case FieldDescriptor::CPPTYPE_UINT32:
-        return val_.uint32_value_ == other.val_.uint32_value_;
-      case FieldDescriptor::CPPTYPE_BOOL:
-        return val_.bool_value_ == other.val_.bool_value_;
-    }
-    GOOGLE_LOG(FATAL) << "Can't get here.";
-    return false;
-  }
-
-  void CopyFrom(const MapKey& other) {
-    SetType(other.type());
-    switch (type_) {
-      case FieldDescriptor::CPPTYPE_DOUBLE:
-      case FieldDescriptor::CPPTYPE_FLOAT:
-      case FieldDescriptor::CPPTYPE_ENUM:
-      case FieldDescriptor::CPPTYPE_MESSAGE:
-        GOOGLE_LOG(FATAL) << "Unsupported";
-        break;
-      case FieldDescriptor::CPPTYPE_STRING:
-        *val_.string_value_ = *other.val_.string_value_;
-        break;
-      case FieldDescriptor::CPPTYPE_INT64:
-        val_.int64_value_ = other.val_.int64_value_;
-        break;
-      case FieldDescriptor::CPPTYPE_INT32:
-        val_.int32_value_ = other.val_.int32_value_;
-        break;
-      case FieldDescriptor::CPPTYPE_UINT64:
-        val_.uint64_value_ = other.val_.uint64_value_;
-        break;
-      case FieldDescriptor::CPPTYPE_UINT32:
-        val_.uint32_value_ = other.val_.uint32_value_;
-        break;
-      case FieldDescriptor::CPPTYPE_BOOL:
-        val_.bool_value_ = other.val_.bool_value_;
-        break;
-    }
-  }
-
- private:
-  template <typename K, typename V>
-  friend class internal::TypeDefinedMapFieldBase;
-  friend class MapIterator;
-  friend class internal::DynamicMapField;
-
-  union KeyValue {
-    KeyValue() {}
-    string* string_value_;
-    int64 int64_value_;
-    int32 int32_value_;
-    uint64 uint64_value_;
-    uint32 uint32_value_;
-    bool bool_value_;
-  } val_;
-
-  void SetType(FieldDescriptor::CppType type) {
-    if (type_ == type) return;
-    if (type_ == FieldDescriptor::CPPTYPE_STRING) {
-      delete val_.string_value_;
-    }
-    type_ = type;
-    if (type_ == FieldDescriptor::CPPTYPE_STRING) {
-      val_.string_value_ = new string;
-    }
-  }
-
-  // type_ is 0 or a valid FieldDescriptor::CppType.
-  int type_;
-};
-
-// MapValueRef points to a map value.
-class LIBPROTOBUF_EXPORT MapValueRef {
- public:
-  MapValueRef() : data_(NULL), type_(0) {}
-
-  void SetInt64Value(int64 value) {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
-               "MapValueRef::SetInt64Value");
-    *reinterpret_cast<int64*>(data_) = value;
-  }
-  void SetUInt64Value(uint64 value) {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
-               "MapValueRef::SetUInt64Value");
-    *reinterpret_cast<uint64*>(data_) = value;
-  }
-  void SetInt32Value(int32 value) {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
-               "MapValueRef::SetInt32Value");
-    *reinterpret_cast<int32*>(data_) = value;
-  }
-  void SetUInt32Value(uint32 value) {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
-               "MapValueRef::SetUInt32Value");
-    *reinterpret_cast<uint32*>(data_) = value;
-  }
-  void SetBoolValue(bool value) {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
-               "MapValueRef::SetBoolValue");
-    *reinterpret_cast<bool*>(data_) = value;
-  }
-  // TODO(jieluo) - Checks that enum is member.
-  void SetEnumValue(int value) {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM,
-               "MapValueRef::SetEnumValue");
-    *reinterpret_cast<int*>(data_) = value;
-  }
-  void SetStringValue(const string& value) {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
-               "MapValueRef::SetStringValue");
-    *reinterpret_cast<string*>(data_) = value;
-  }
-  void SetFloatValue(float value) {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
-               "MapValueRef::SetFloatValue");
-    *reinterpret_cast<float*>(data_) = value;
-  }
-  void SetDoubleValue(double value) {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
-               "MapValueRef::SetDoubleValue");
-    *reinterpret_cast<double*>(data_) = value;
-  }
-
-  int64 GetInt64Value() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
-               "MapValueRef::GetInt64Value");
-    return *reinterpret_cast<int64*>(data_);
-  }
-  uint64 GetUInt64Value() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
-               "MapValueRef::GetUInt64Value");
-    return *reinterpret_cast<uint64*>(data_);
-  }
-  int32 GetInt32Value() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
-               "MapValueRef::GetInt32Value");
-    return *reinterpret_cast<int32*>(data_);
-  }
-  uint32 GetUInt32Value() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
-               "MapValueRef::GetUInt32Value");
-    return *reinterpret_cast<uint32*>(data_);
-  }
-  bool GetBoolValue() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
-               "MapValueRef::GetBoolValue");
-    return *reinterpret_cast<bool*>(data_);
-  }
-  int GetEnumValue() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM,
-               "MapValueRef::GetEnumValue");
-    return *reinterpret_cast<int*>(data_);
-  }
-  const string& GetStringValue() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
-               "MapValueRef::GetStringValue");
-    return *reinterpret_cast<string*>(data_);
-  }
-  float GetFloatValue() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
-               "MapValueRef::GetFloatValue");
-    return *reinterpret_cast<float*>(data_);
-  }
-  double GetDoubleValue() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
-               "MapValueRef::GetDoubleValue");
-    return *reinterpret_cast<double*>(data_);
-  }
-
-  const Message& GetMessageValue() const {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
-               "MapValueRef::GetMessageValue");
-    return *reinterpret_cast<Message*>(data_);
-  }
-
-  Message* MutableMessageValue() {
-    TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
-               "MapValueRef::MutableMessageValue");
-    return reinterpret_cast<Message*>(data_);
-  }
-
- private:
-  template <typename K, typename V,
-            internal::WireFormatLite::FieldType key_wire_type,
-            internal::WireFormatLite::FieldType value_wire_type,
-            int default_enum_value>
-  friend class internal::MapField;
-  template <typename K, typename V>
-  friend class internal::TypeDefinedMapFieldBase;
-  friend class MapIterator;
-  friend class internal::GeneratedMessageReflection;
-  friend class internal::DynamicMapField;
-
-  void SetType(FieldDescriptor::CppType type) {
-    type_ = type;
-  }
-
-  FieldDescriptor::CppType type() const {
-    if (type_ == 0 || data_ == NULL) {
-      GOOGLE_LOG(FATAL)
-          << "Protocol Buffer map usage error:\n"
-          << "MapValueRef::type MapValueRef is not initialized.";
-    }
-    return (FieldDescriptor::CppType)type_;
-  }
-  void SetValue(const void* val) {
-    data_ = const_cast<void*>(val);
-  }
-  void CopyFrom(const MapValueRef& other) {
-    type_ = other.type_;
-    data_ = other.data_;
-  }
-  // Only used in DynamicMapField
-  void DeleteData() {
-    switch (type_) {
-#define HANDLE_TYPE(CPPTYPE, TYPE)                              \
-      case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: {        \
-        delete reinterpret_cast<TYPE*>(data_);                  \
-        break;                                                  \
-      }
-      HANDLE_TYPE(INT32, int32);
-      HANDLE_TYPE(INT64, int64);
-      HANDLE_TYPE(UINT32, uint32);
-      HANDLE_TYPE(UINT64, uint64);
-      HANDLE_TYPE(DOUBLE, double);
-      HANDLE_TYPE(FLOAT, float);
-      HANDLE_TYPE(BOOL, bool);
-      HANDLE_TYPE(STRING, string);
-      HANDLE_TYPE(ENUM, int32);
-      HANDLE_TYPE(MESSAGE, Message);
-#undef HANDLE_TYPE
-    }
-  }
-  // data_ point to a map value. MapValueRef does not
-  // own this value.
-  void* data_;
-  // type_ is 0 or a valid FieldDescriptor::CppType.
-  int type_;
-};
-
-#undef TYPE_CHECK
-
 // 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
 // its process of construction and destruction.
@@ -523,30 +136,18 @@
   typedef size_t size_type;
   typedef hash<Key> hasher;
 
-  explicit Map(bool old_style = false)
-      : arena_(NULL),
-        default_enum_value_(0),
-        old_style_(old_style) {
-    Init();
-  }
-  explicit Map(Arena* arena, bool old_style = false)
-      : arena_(arena),
-        default_enum_value_(0),
-        old_style_(old_style) {
-    Init();
-  }
+  Map() : arena_(NULL), default_enum_value_(0) { Init(); }
+  explicit Map(Arena* arena) : arena_(arena), default_enum_value_(0) { Init(); }
+
   Map(const Map& other)
-      : arena_(NULL),
-        default_enum_value_(other.default_enum_value_),
-        old_style_(other.old_style_) {
+      : arena_(NULL), default_enum_value_(other.default_enum_value_) {
     Init();
     insert(other.begin(), other.end());
   }
+
   template <class InputIt>
-  Map(const InputIt& first, const InputIt& last, bool old_style = false)
-      : arena_(NULL),
-        default_enum_value_(0),
-        old_style_(old_style) {
+  Map(const InputIt& first, const InputIt& last)
+      : arena_(NULL), default_enum_value_(0) {
     Init();
     insert(first, last);
   }
@@ -554,22 +155,13 @@
   ~Map() {
     clear();
     if (arena_ == NULL) {
-      if (old_style_)
-        delete deprecated_elements_;
-      else
-        delete elements_;
+      delete elements_;
     }
   }
 
  private:
   void Init() {
-    if (old_style_)
-      deprecated_elements_ = Arena::Create<DeprecatedInnerMap>(
-          arena_, 0, hasher(), std::equal_to<Key>(),
-          MapAllocator<std::pair<const Key, MapPair<Key, T>*> >(arena_));
-    else
-      elements_ =
-          Arena::Create<InnerMap>(arena_, 0, hasher(), Allocator(arena_));
+    elements_ = Arena::Create<InnerMap>(arena_, 0, hasher(), Allocator(arena_));
   }
 
   // re-implement std::allocator to use arena allocator for memory allocation.
@@ -764,14 +356,13 @@
     };
     typedef typename Allocator::template rebind<Key*>::other KeyPtrAllocator;
     typedef std::set<Key*, KeyCompare, KeyPtrAllocator> Tree;
+    typedef typename Tree::iterator TreeIterator;
 
     // iterator and const_iterator are instantiations of iterator_base.
     template <typename KeyValueType>
-    class iterator_base {
-     public:
+    struct iterator_base {
       typedef KeyValueType& reference;
       typedef KeyValueType* pointer;
-      typedef typename Tree::iterator TreeIterator;
 
       // Invariants:
       // node_ is always correct. This is handy because the most common
@@ -780,7 +371,7 @@
       // are updated to be correct also, but those fields can become stale
       // if the underlying map is modified.  When those fields are needed they
       // are rechecked, and updated if necessary.
-      iterator_base() : node_(NULL) {}
+      iterator_base() : node_(NULL), m_(NULL), bucket_index_(0) {}
 
       explicit iterator_base(const InnerMap* m) : m_(m) {
         SearchFrom(m->index_of_first_non_null_);
@@ -791,22 +382,15 @@
       // can convert to const_iterator" is OK but the reverse direction is not.
       template <typename U>
       explicit iterator_base(const iterator_base<U>& it)
-          : node_(it.node_),
-            m_(it.m_),
-            bucket_index_(it.bucket_index_),
-            tree_it_(it.tree_it_) {}
+          : node_(it.node_), m_(it.m_), bucket_index_(it.bucket_index_) {}
 
       iterator_base(Node* n, const InnerMap* m, size_type index)
-          : node_(n),
-            m_(m),
-            bucket_index_(index) {}
+          : node_(n), m_(m), bucket_index_(index) {}
 
       iterator_base(TreeIterator tree_it, const InnerMap* m, size_type index)
-          : node_(NodePtrFromKeyPtr(*tree_it)),
-            m_(m),
-            bucket_index_(index),
-            tree_it_(tree_it) {
-        // Invariant: iterators that use tree_it_ have an even bucket_index_.
+          : node_(NodePtrFromKeyPtr(*tree_it)), m_(m), bucket_index_(index) {
+        // Invariant: iterators that use buckets with trees have an even
+        // bucket_index_.
         GOOGLE_DCHECK_EQ(bucket_index_ % 2, 0);
       }
 
@@ -824,8 +408,7 @@
           } else if (m_->TableEntryIsTree(bucket_index_)) {
             Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]);
             GOOGLE_DCHECK(!tree->empty());
-            tree_it_ = tree->begin();
-            node_ = NodePtrFromKeyPtr(*tree_it_);
+            node_ = NodePtrFromKeyPtr(*tree->begin());
             break;
           }
         }
@@ -843,16 +426,17 @@
 
       iterator_base& operator++() {
         if (node_->next == NULL) {
-          const bool is_list = revalidate_if_necessary();
+          TreeIterator tree_it;
+          const bool is_list = revalidate_if_necessary(&tree_it);
           if (is_list) {
             SearchFrom(bucket_index_ + 1);
           } else {
             GOOGLE_DCHECK_EQ(bucket_index_ & 1, 0);
             Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]);
-            if (++tree_it_ == tree->end()) {
+            if (++tree_it == tree->end()) {
               SearchFrom(bucket_index_ + 2);
             } else {
-              node_ = NodePtrFromKeyPtr(*tree_it_);
+              node_ = NodePtrFromKeyPtr(*tree_it);
             }
           }
         } else {
@@ -869,8 +453,9 @@
 
       // Assumes node_ and m_ are correct and non-NULL, but other fields may be
       // stale.  Fix them as needed.  Then return true iff node_ points to a
-      // Node in a list.
-      bool revalidate_if_necessary() {
+      // Node in a list.  If false is returned then *it is modified to be
+      // a valid iterator for node_.
+      bool revalidate_if_necessary(TreeIterator* it) {
         GOOGLE_DCHECK(node_ != NULL && m_ != NULL);
         // Force bucket_index_ to be in range.
         bucket_index_ &= (m_->num_buckets_ - 1);
@@ -891,16 +476,14 @@
         // not.  Revalidate just to be sure.  This case is rare enough that we
         // don't worry about potential optimizations, such as having a custom
         // find-like method that compares Node* instead of const Key&.
-        iterator_base i(m_->find(*KeyPtrFromNodePtr(node_)));
+        iterator_base i(m_->find(*KeyPtrFromNodePtr(node_), it));
         bucket_index_ = i.bucket_index_;
-        tree_it_ = i.tree_it_;
         return m_->TableEntryIsList(bucket_index_);
       }
 
       Node* node_;
       const InnerMap* m_;
       size_type bucket_index_;
-      TreeIterator tree_it_;
     };
 
    public:
@@ -952,7 +535,7 @@
     bool empty() const { return size() == 0; }
 
     iterator find(const Key& k) { return iterator(FindHelper(k).first); }
-    const_iterator find(const Key& k) const { return FindHelper(k).first; }
+    const_iterator find(const Key& k) const { return find(k, NULL); }
 
     // In traditional C++ style, this performs "insert if not present."
     std::pair<iterator, bool> insert(const KeyValuePair& kv) {
@@ -999,7 +582,8 @@
 
     void erase(iterator it) {
       GOOGLE_DCHECK_EQ(it.m_, this);
-      const bool is_list = it.revalidate_if_necessary();
+      typename Tree::iterator tree_it;
+      const bool is_list = it.revalidate_if_necessary(&tree_it);
       size_type b = it.bucket_index_;
       Node* const item = it.node_;
       if (is_list) {
@@ -1010,7 +594,7 @@
       } else {
         GOOGLE_DCHECK(TableEntryIsTree(b));
         Tree* tree = static_cast<Tree*>(table_[b]);
-        tree->erase(it.tree_it_);
+        tree->erase(*tree_it);
         if (tree->empty()) {
           // Force b to be the minimum of b and b ^ 1.  This is important
           // only because we want index_of_first_non_null_ to be correct.
@@ -1030,7 +614,14 @@
     }
 
    private:
+    const_iterator find(const Key& k, TreeIterator* it) const {
+      return FindHelper(k, it).first;
+    }
     std::pair<const_iterator, size_type> FindHelper(const Key& k) const {
+      return FindHelper(k, NULL);
+    }
+    std::pair<const_iterator, size_type> FindHelper(const Key& k,
+                                                    TreeIterator* it) const {
       size_type b = BucketNumber(k);
       if (TableEntryIsNonEmptyList(b)) {
         Node* node = static_cast<Node*>(table_[b]);
@@ -1048,6 +639,7 @@
         Key* key = const_cast<Key*>(&k);
         typename Tree::iterator tree_it = tree->find(key);
         if (tree_it != tree->end()) {
+          if (it != NULL) *it = tree_it;
           return std::make_pair(const_iterator(tree_it, this, b), b);
         }
       }
@@ -1358,72 +950,30 @@
     GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(InnerMap);
   };  // end of class InnerMap
 
-  typedef hash_map<Key, value_type*, hash<Key>, std::equal_to<Key>,
-                   MapAllocator<std::pair<const Key, MapPair<Key, T>*> > >
-      DeprecatedInnerMap;
-
  public:
   // Iterators
-  class iterator_base {
-   public:
-    // We support "old style" and "new style" iterators for now. This is
-    // temporary.  Also, for "iterator()" we have an unknown category.
-    // TODO(gpike): get rid of this.
-    enum IteratorStyle { kUnknown, kOld, kNew };
-    explicit iterator_base(IteratorStyle style) : iterator_style_(style) {}
-
-    bool OldStyle() const {
-      GOOGLE_DCHECK_NE(iterator_style_, kUnknown);
-      return iterator_style_ == kOld;
-    }
-    bool UnknownStyle() const {
-      return iterator_style_ == kUnknown;
-    }
-    bool SameStyle(const iterator_base& other) const {
-      return iterator_style_ == other.iterator_style_;
-    }
-
-   private:
-    IteratorStyle iterator_style_;
-  };
-
   class const_iterator
-      : private iterator_base,
-        public std::iterator<std::forward_iterator_tag, value_type, ptrdiff_t,
+      : public std::iterator<std::forward_iterator_tag, value_type, ptrdiff_t,
                              const value_type*, const value_type&> {
     typedef typename InnerMap::const_iterator InnerIt;
-    typedef typename DeprecatedInnerMap::const_iterator DeprecatedInnerIt;
 
    public:
-    const_iterator() : iterator_base(iterator_base::kUnknown) {}
-    explicit const_iterator(const DeprecatedInnerIt& dit)
-        : iterator_base(iterator_base::kOld), dit_(dit) {}
-    explicit const_iterator(const InnerIt& it)
-        : iterator_base(iterator_base::kNew), it_(it) {}
-
-    const_iterator(const const_iterator& other)
-        : iterator_base(other), it_(other.it_), dit_(other.dit_) {}
+    const_iterator() {}
+    explicit const_iterator(const InnerIt& it) : it_(it) {}
 
     const_reference operator*() const {
-      return this->OldStyle() ? *dit_->second : *it_->value();
+      return *it_->value();
     }
     const_pointer operator->() const { return &(operator*()); }
 
     const_iterator& operator++() {
-      if (this->OldStyle())
-        ++dit_;
-      else
-        ++it_;
+      ++it_;
       return *this;
     }
-    const_iterator operator++(int) {
-      return this->OldStyle() ? const_iterator(dit_++) : const_iterator(it_++);
-    }
+    const_iterator operator++(int) { return const_iterator(it_++); }
 
     friend bool operator==(const const_iterator& a, const const_iterator& b) {
-      if (!a.SameStyle(b)) return false;
-      if (a.UnknownStyle()) return true;
-      return a.OldStyle() ? (a.dit_ == b.dit_) : (a.it_ == b.it_);
+      return a.it_ == b.it_;
     }
     friend bool operator!=(const const_iterator& a, const const_iterator& b) {
       return !(a == b);
@@ -1431,48 +981,31 @@
 
    private:
     InnerIt it_;
-    DeprecatedInnerIt dit_;
   };
 
-  class iterator : private iterator_base,
-                   public std::iterator<std::forward_iterator_tag, value_type> {
+  class iterator : public std::iterator<std::forward_iterator_tag, value_type> {
     typedef typename InnerMap::iterator InnerIt;
-    typedef typename DeprecatedInnerMap::iterator DeprecatedInnerIt;
 
    public:
-    iterator() : iterator_base(iterator_base::kUnknown) {}
-    explicit iterator(const DeprecatedInnerIt& dit)
-        : iterator_base(iterator_base::kOld), dit_(dit) {}
-    explicit iterator(const InnerIt& it)
-        : iterator_base(iterator_base::kNew), it_(it) {}
+    iterator() {}
+    explicit iterator(const InnerIt& it) : it_(it) {}
 
-    reference operator*() const {
-      return this->OldStyle() ? *dit_->second : *it_->value();
-    }
+    reference operator*() const { return *it_->value(); }
     pointer operator->() const { return &(operator*()); }
 
     iterator& operator++() {
-      if (this->OldStyle())
-        ++dit_;
-      else
-        ++it_;
+      ++it_;
       return *this;
     }
-    iterator operator++(int) {
-      return this->OldStyle() ? iterator(dit_++) : iterator(it_++);
-    }
+    iterator operator++(int) { return iterator(it_++); }
 
     // Allow implicit conversion to const_iterator.
     operator const_iterator() const {
-      return this->OldStyle() ?
-          const_iterator(typename DeprecatedInnerMap::const_iterator(dit_)) :
-          const_iterator(typename InnerMap::const_iterator(it_));
+      return const_iterator(typename InnerMap::const_iterator(it_));
     }
 
     friend bool operator==(const iterator& a, const iterator& b) {
-      if (!a.SameStyle(b)) return false;
-      if (a.UnknownStyle()) return true;
-      return a.OldStyle() ? a.dit_ == b.dit_ : a.it_ == b.it_;
+      return a.it_ == b.it_;
     }
     friend bool operator!=(const iterator& a, const iterator& b) {
       return !(a == b);
@@ -1482,38 +1015,26 @@
     friend class Map;
 
     InnerIt it_;
-    DeprecatedInnerIt dit_;
   };
 
-  iterator begin() {
-    return old_style_ ? iterator(deprecated_elements_->begin())
-                      : iterator(elements_->begin());
-  }
-  iterator end() {
-    return old_style_ ? iterator(deprecated_elements_->end())
-                      : iterator(elements_->end());
-  }
+  iterator begin() { return iterator(elements_->begin()); }
+  iterator end() { return iterator(elements_->end()); }
   const_iterator begin() const {
-    return old_style_ ? const_iterator(deprecated_elements_->begin())
-                      : const_iterator(iterator(elements_->begin()));
+    return const_iterator(iterator(elements_->begin()));
   }
   const_iterator end() const {
-    return old_style_ ? const_iterator(deprecated_elements_->end())
-                      : const_iterator(iterator(elements_->end()));
+    return const_iterator(iterator(elements_->end()));
   }
   const_iterator cbegin() const { return begin(); }
   const_iterator cend() const { return end(); }
 
   // Capacity
-  size_type size() const {
-    return old_style_ ? deprecated_elements_->size() : elements_->size();
-  }
+  size_type size() const { return elements_->size(); }
   bool empty() const { return size() == 0; }
 
   // Element access
   T& operator[](const key_type& key) {
-    value_type** value =
-        old_style_ ? &(*deprecated_elements_)[key] : &(*elements_)[key];
+    value_type** value =  &(*elements_)[key];
     if (*value == NULL) {
       *value = CreateValueTypeInternal(key);
       internal::MapValueInitializer<google::protobuf::is_proto_enum<T>::value,
@@ -1540,13 +1061,9 @@
     return it == end() ? 0 : 1;
   }
   const_iterator find(const key_type& key) const {
-    return old_style_ ? const_iterator(deprecated_elements_->find(key))
-        : const_iterator(iterator(elements_->find(key)));
+    return const_iterator(iterator(elements_->find(key)));
   }
-  iterator find(const key_type& key) {
-    return old_style_ ? iterator(deprecated_elements_->find(key))
-                      : iterator(elements_->find(key));
-  }
+  iterator find(const key_type& key) { return iterator(elements_->find(key)); }
   std::pair<const_iterator, const_iterator> equal_range(
       const key_type& key) const {
     const_iterator it = find(key);
@@ -1569,23 +1086,12 @@
 
   // insert
   std::pair<iterator, bool> insert(const value_type& value) {
-    if (old_style_) {
-      iterator it = find(value.first);
-      if (it != end()) {
-        return std::pair<iterator, bool>(it, false);
-      } else {
-        return std::pair<iterator, bool>(
-            iterator(deprecated_elements_->insert(std::pair<Key, value_type*>(
-                value.first, CreateValueTypeInternal(value))).first), true);
-      }
-    } else {
-      std::pair<typename InnerMap::iterator, bool> p =
-          elements_->insert(value.first);
-      if (p.second) {
-        p.first->value() = CreateValueTypeInternal(value);
-      }
-      return std::pair<iterator, bool>(iterator(p.first), p.second);
+    std::pair<typename InnerMap::iterator, bool> p =
+        elements_->insert(value.first);
+    if (p.second) {
+      p.first->value() = CreateValueTypeInternal(value);
     }
+    return std::pair<iterator, bool>(iterator(p.first), p.second);
   }
   template <class InputIt>
   void insert(InputIt first, InputIt last) {
@@ -1610,10 +1116,7 @@
   iterator erase(iterator pos) {
     if (arena_ == NULL) delete pos.operator->();
     iterator i = pos++;
-    if (old_style_)
-      deprecated_elements_->erase(i.dit_);
-    else
-      elements_->erase(i.it_);
+    elements_->erase(i.it_);
     return pos;
   }
   void erase(iterator first, iterator last) {
@@ -1633,13 +1136,9 @@
   }
 
   void swap(Map& other) {
-    if (arena_ == other.arena_ && old_style_ == other.old_style_) {
+    if (arena_ == other.arena_) {
       std::swap(default_enum_value_, other.default_enum_value_);
-      if (old_style_) {
-        std::swap(deprecated_elements_, other.deprecated_elements_);
-      } else {
-        std::swap(elements_, other.elements_);
-      }
+      std::swap(elements_, other.elements_);
     } else {
       // TODO(zuguang): optimize this. The temporary copy can be allocated
       // in the same arena as the other message, and the "other = copy" can
@@ -1653,8 +1152,7 @@
   // Access to hasher.  Currently this returns a copy, but it may
   // be modified to return a const reference in the future.
   hasher hash_function() const {
-    return old_style_ ? deprecated_elements_->hash_function()
-                      : elements_->hash_function();
+    return elements_->hash_function();
   }
 
  private:
@@ -1692,19 +1190,12 @@
 
   Arena* arena_;
   int default_enum_value_;
-  // The following is a tagged union because we support two map styles
-  // for now.
-  // TODO(gpike): get rid of the old style.
-  const bool old_style_;
-  union {
-    InnerMap* elements_;
-    DeprecatedInnerMap* deprecated_elements_;
-  };
+  InnerMap* elements_;
 
   friend class ::google::protobuf::Arena;
   typedef void InternalArenaConstructable_;
   typedef void DestructorSkippable_;
-  template <typename K, typename V,
+  template <typename Derived, typename K, typename V,
             internal::WireFormatLite::FieldType key_wire_type,
             internal::WireFormatLite::FieldType value_wire_type,
             int default_enum_value>
@@ -1712,49 +1203,6 @@
 };
 
 }  // namespace protobuf
+
 }  // namespace google
-
-GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START
-template<>
-struct hash<google::protobuf::MapKey> {
-  size_t
-  operator()(const google::protobuf::MapKey& map_key) const {
-    switch (map_key.type()) {
-      case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
-      case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
-      case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
-      case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
-        GOOGLE_LOG(FATAL) << "Unsupported";
-        break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
-        return hash<string>()(map_key.GetStringValue());
-#if defined(GOOGLE_PROTOBUF_HAVE_64BIT_HASH)
-      case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
-        return hash< ::google::protobuf::int64>()(map_key.GetInt64Value());
-      case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
-        return hash< ::google::protobuf::uint64>()(map_key.GetUInt64Value());
-#else
-      case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
-      case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
-        GOOGLE_LOG(FATAL) << "Unsupported on this platform.";
-        break;
-#endif
-      case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
-        return hash< ::google::protobuf::int32>()(map_key.GetInt32Value());
-      case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
-        return hash< ::google::protobuf::uint32>()(map_key.GetUInt32Value());
-      case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
-        return hash<bool>()(map_key.GetBoolValue());
-    }
-    GOOGLE_LOG(FATAL) << "Can't get here.";
-    return 0;
-  }
-  bool
-  operator()(const google::protobuf::MapKey& map_key1,
-             const google::protobuf::MapKey& map_key2) const {
-    return map_key1 < map_key2;
-  }
-};
-GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END
-
 #endif  // GOOGLE_PROTOBUF_MAP_H__
diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h
index d7db9b0..0a7d9a9 100644
--- a/src/google/protobuf/map_entry.h
+++ b/src/google/protobuf/map_entry.h
@@ -43,10 +43,9 @@
 namespace protobuf {
 class Arena;
 namespace internal {
-template <typename Key, typename Value,
+template <typename Derived, typename Key, typename Value,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType,
-          int default_enum_value>
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
 class MapField;
 }
 }
@@ -54,30 +53,6 @@
 namespace protobuf {
 namespace internal {
 
-// Register all MapEntry default instances so we can delete them in
-// ShutdownProtobufLibrary().
-void LIBPROTOBUF_EXPORT RegisterMapEntryDefaultInstance(
-    MessageLite* default_instance);
-
-// This is the common base class for MapEntry. It is used by MapFieldBase in
-// reflection api, in which the static type of key and value is unknown.
-class LIBPROTOBUF_EXPORT MapEntryBase : public Message {
- public:
-  ::google::protobuf::Metadata GetMetadata() const {
-    ::google::protobuf::Metadata metadata;
-    metadata.descriptor = descriptor_;
-    metadata.reflection = reflection_;
-    return metadata;
-  }
-
- protected:
-  MapEntryBase() : descriptor_(NULL), reflection_(NULL) {  }
-  virtual ~MapEntryBase() {}
-
-  const Descriptor* descriptor_;
-  const Reflection* reflection_;
-};
-
 // MapEntry is the returned google::protobuf::Message when calling AddMessage of
 // google::protobuf::Reflection. In order to let it work with generated message
 // reflection, its in-memory type is the same as generated message with the same
@@ -105,212 +80,72 @@
 // while we need to explicitly specify the cpp type if proto type is
 // TYPE_MESSAGE to infer the in-memory type.  Moreover, default_enum_value is
 // used to initialize enum field in proto2.
-template <typename Key, typename Value,
+template <typename Derived, typename Key, typename Value,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType,
-          int default_enum_value>
-class MapEntry : public MapEntryBase {
-  // Provide utilities to parse/serialize key/value.  Provide utilities to
-  // manipulate internal stored type.
-  typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
-  typedef MapTypeHandler<kValueFieldType, Value> ValueTypeHandler;
-
-  // Enum type cannot be used for MapTypeHandler::Read. Define a type
-  // which will replace Enum with int.
-  typedef typename KeyTypeHandler::MapEntryAccessorType KeyMapEntryAccessorType;
-  typedef typename ValueTypeHandler::MapEntryAccessorType
-      ValueMapEntryAccessorType;
-
-  // Abbreviation for MapEntry
-  typedef typename google::protobuf::internal::MapEntry<
-      Key, Value, kKeyFieldType, kValueFieldType, default_enum_value> EntryType;
-
-  // Abbreviation for MapEntryLite
-  typedef typename google::protobuf::internal::MapEntryLite<
-      Key, Value, kKeyFieldType, kValueFieldType, default_enum_value>
-      EntryLiteType;
-
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+class LIBPROTOBUF_EXPORT MapEntry
+    : public MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
+                          kValueFieldType, default_enum_value> {
  public:
-  ~MapEntry() {
-    if (this == default_instance_) {
-      delete reflection_;
-    }
-  }
-
-  // accessors ======================================================
-
-  virtual inline const KeyMapEntryAccessorType& key() const {
-    return entry_lite_.key();
-  }
-  inline KeyMapEntryAccessorType* mutable_key() {
-    return entry_lite_.mutable_key();
-  }
-  virtual inline const ValueMapEntryAccessorType& value() const {
-    return entry_lite_.value();
-  }
-  inline ValueMapEntryAccessorType* mutable_value() {
-    return entry_lite_.mutable_value();
-  }
-
-  // implements Message =============================================
-
-  bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) {
-    return entry_lite_.MergePartialFromCodedStream(input);
-  }
-
-  size_t ByteSizeLong() const {
-    return entry_lite_.ByteSizeLong();
-  }
-
-  void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const {
-    entry_lite_.SerializeWithCachedSizes(output);
-  }
-
-  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(bool deterministic,
-                                                   ::google::protobuf::uint8* output) const {
-    return entry_lite_.InternalSerializeWithCachedSizesToArray(deterministic,
-                                                               output);
-  }
-
-  int GetCachedSize() const {
-    return entry_lite_.GetCachedSize();
-  }
-
-  bool IsInitialized() const {
-    return entry_lite_.IsInitialized();
-  }
-
-  Message* New() const {
-    MapEntry* entry = new MapEntry;
-    entry->descriptor_ = descriptor_;
-    entry->reflection_ = reflection_;
-    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 += entry_lite_.SpaceUsed();
-    return size;
-  }
-
-  void CopyFrom(const ::google::protobuf::Message& from) {
-    Clear();
-    MergeFrom(from);
-  }
-
-  void MergeFrom(const ::google::protobuf::Message& from) {
-    GOOGLE_CHECK_NE(&from, this);
-    const MapEntry* source = dynamic_cast_if_available<const MapEntry*>(&from);
-    if (source == NULL) {
-      ReflectionOps::Merge(from, this);
-    } else {
-      MergeFrom(*source);
-    }
-  }
-
-  void CopyFrom(const MapEntry& from) {
-    Clear();
-    MergeFrom(from);
-  }
-
-  void MergeFrom(const MapEntry& from) {
-    entry_lite_.MergeFrom(from.entry_lite_);
-  }
-
-  void Clear() {
-    entry_lite_.Clear();
-  }
-
-  void InitAsDefaultInstance() {
-    entry_lite_.InitAsDefaultInstance();
-  }
-
-  Arena* GetArena() const {
-    return entry_lite_.GetArena();
-  }
-
   // Create default MapEntry instance for given descriptor. Descriptor has to be
   // given when creating default MapEntry instance because different map field
   // 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;
+  static const Reflection* CreateReflection(const Descriptor* descriptor,
+                                            const Derived* entry) {
     ReflectionSchema schema = {
         entry,
         offsets_,
         has_bits_,
-        GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_._has_bits_),
-        GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _internal_metadata_),
+        GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _has_bits_),
+        GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry,
+                                                       _internal_metadata_),
         -1,
         -1,
         sizeof(MapEntry)};
     const Reflection* reflection = new GeneratedMessageReflection(
         descriptor, schema, DescriptorPool::generated_pool(),
         MessageFactory::generated_factory());
-    entry->descriptor_ = descriptor;
-    entry->reflection_ = reflection;
-    entry->set_default_instance(entry);
-    entry->InitAsDefaultInstance();
-    RegisterMapEntryDefaultInstance(entry);
-    return entry;
+    return reflection;
   }
 
+  MapEntry() : _internal_metadata_(NULL) {}
+  explicit MapEntry(Arena* arena)
+      : MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
+                     kValueFieldType, default_enum_value>(arena),
+        _internal_metadata_(arena) {}
+  typedef void InternalArenaConstructable_;
+  typedef void DestructorSkippable_;
+
  private:
-  MapEntry()
-      : _internal_metadata_(NULL), default_instance_(NULL), entry_lite_() {}
-
-  explicit MapEntry(Arena* arena)
-      : _internal_metadata_(arena),
-        default_instance_(NULL),
-        entry_lite_(arena) {}
-
-  inline Arena* GetArenaNoVirtual() const {
-    return entry_lite_.GetArenaNoVirtual();
-  }
-
-  void set_default_instance(MapEntry* default_instance) {
-    default_instance_ = default_instance;
-    entry_lite_.set_default_instance(&default_instance->entry_lite_);
-  }
-
   static uint32 offsets_[2];
   static uint32 has_bits_[2];
   InternalMetadataWithArena _internal_metadata_;
-  MapEntry* default_instance_;
-  EntryLiteType entry_lite_;
 
   friend class ::google::protobuf::Arena;
-  typedef void InternalArenaConstructable_;
-  typedef void DestructorSkippable_;
-  template <typename K, typename V, WireFormatLite::FieldType k_wire_type,
-            WireFormatLite::FieldType, int default_enum>
+  template <typename C, typename K, typename V,
+            WireFormatLite::FieldType k_wire_type, WireFormatLite::FieldType,
+            int default_enum>
   friend class internal::MapField;
   friend class internal::GeneratedMessageReflection;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry);
 };
 
-template <typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType,
+template <typename Derived, typename Key, typename Value,
+          WireFormatLite::FieldType kKeyFieldType,
           WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-uint32 MapEntry<Key, Value, kKeyFieldType, kValueFieldType,
-             default_enum_value>::offsets_[2] = {
-    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_.key_),
-    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_.value_),
+uint32 MapEntry<Derived, 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_),
 };
 
-template <typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType,
+template <typename Derived, typename Key, typename Value,
+          WireFormatLite::FieldType kKeyFieldType,
           WireFormatLite::FieldType kValueFieldType, int default_enum_value>
-uint32 MapEntry<Key, Value, kKeyFieldType, kValueFieldType,
-             default_enum_value>::has_bits_[2] = {0, 1};
+uint32 MapEntry<Derived, Key, Value, kKeyFieldType, kValueFieldType,
+                default_enum_value>::has_bits_[2] = {0, 1};
 
 }  // namespace internal
 }  // namespace protobuf
diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h
index 1243911..cd67f6e 100644
--- a/src/google/protobuf/map_entry_lite.h
+++ b/src/google/protobuf/map_entry_lite.h
@@ -32,22 +32,21 @@
 #define GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
 
 #include <assert.h>
+
+#include <google/protobuf/arena.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,
+template <typename Derived, typename Key, typename Value,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType,
-          int default_enum_value>
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
 class MapEntry;
-template <typename Key, typename Value,
+template <typename Derived, typename Key, typename Value,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType,
-          int default_enum_value>
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
 class MapFieldLite;
 }  // namespace internal
 }  // namespace protobuf
@@ -87,13 +86,14 @@
   }
 };
 
-// MapEntryLite is used to implement parsing and serialization of map for lite
-// runtime.
-template <typename Key, typename Value,
+// MapEntryImpl is used to implement parsing and serialization of map entries.
+// It uses Curious Recursive Template Pattern (CRTP) to provide the type of
+// the eventual code to the template code.
+template <typename Derived, typename Base, typename Key, typename Value,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType,
-          int default_enum_value>
-class MapEntryLite : public MessageLite {
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+class LIBPROTOBUF_EXPORT MapEntryImpl : public Base {
+ protected:
   // Provide utilities to parse/serialize key/value.  Provide utilities to
   // manipulate internal stored type.
   typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
@@ -122,7 +122,30 @@
   static const size_t kTagSize = 1;
 
  public:
-  ~MapEntryLite() {
+  // Work-around for a compiler bug (see repeated_field.h).
+  typedef void MapEntryHasMergeTypeTrait;
+  typedef Derived EntryType;
+  typedef Key EntryKeyType;
+  typedef Value EntryValueType;
+  static const WireFormatLite::FieldType kEntryKeyFieldType = kKeyFieldType;
+  static const WireFormatLite::FieldType kEntryValueFieldType = kValueFieldType;
+  static const int kEntryDefaultEnumValue = default_enum_value;
+
+  MapEntryImpl() : default_instance_(NULL), arena_(NULL) {
+    KeyTypeHandler::Initialize(&key_, NULL);
+    ValueTypeHandler::InitializeMaybeByDefaultEnum(&value_, default_enum_value,
+                                                   NULL);
+    _has_bits_[0] = 0;
+  }
+
+  explicit MapEntryImpl(Arena* arena) : default_instance_(NULL), arena_(arena) {
+    KeyTypeHandler::Initialize(&key_, arena);
+    ValueTypeHandler::InitializeMaybeByDefaultEnum(&value_, default_enum_value,
+                                                   arena);
+    _has_bits_[0] = 0;
+  }
+
+  ~MapEntryImpl() {
     if (this != default_instance_) {
       if (GetArenaNoVirtual() != NULL) return;
       KeyTypeHandler::DeleteNoArena(key_);
@@ -151,12 +174,12 @@
 
   // implements MessageLite =========================================
 
-  // MapEntryLite is for implementation only and this function isn't called
+  // MapEntryImpl 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));
+    MergeFromInternal(*::google::protobuf::down_cast<const Derived*>(&other));
   }
 
   bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) {
@@ -238,26 +261,29 @@
 
   bool IsInitialized() const { return ValueTypeHandler::IsInitialized(value_); }
 
-  MessageLite* New() const {
-    MapEntryLite* entry = new MapEntryLite;
+  Base* New() const {
+    Derived* entry = new Derived;
     entry->default_instance_ = default_instance_;
     return entry;
   }
 
-  MessageLite* New(Arena* arena) const {
-    MapEntryLite* entry = Arena::CreateMessage<MapEntryLite>(arena);
+  Base* New(Arena* arena) const {
+    Derived* entry = Arena::CreateMessage<Derived>(arena);
     entry->default_instance_ = default_instance_;
     return entry;
   }
 
-  int SpaceUsed() const {
-    int size = sizeof(MapEntryLite);
-    size += KeyTypeHandler::SpaceUsedInMapEntry(key_);
-    size += ValueTypeHandler::SpaceUsedInMapEntry(value_);
+  size_t SpaceUsedLong() const {
+    size_t size = sizeof(Derived);
+    size += KeyTypeHandler::SpaceUsedInMapEntryLong(key_);
+    size += ValueTypeHandler::SpaceUsedInMapEntryLong(value_);
     return size;
   }
 
-  void MergeFrom(const MapEntryLite& from) {
+ protected:
+  // We can't declare this function directly here as it would hide the other
+  // overload (const Message&).
+  void MergeFromInternal(const MapEntryImpl& from) {
     if (from._has_bits_[0]) {
       if (from.has_key()) {
         KeyTypeHandler::EnsureMutable(&key_, GetArenaNoVirtual());
@@ -272,6 +298,7 @@
     }
   }
 
+ public:
   void Clear() {
     KeyTypeHandler::Clear(&key_, GetArenaNoVirtual());
     ValueTypeHandler::ClearMaybeByDefaultEnum(
@@ -280,6 +307,10 @@
     clear_has_value();
   }
 
+  void set_default_instance(MapEntryImpl* default_instance) {
+    default_instance_ = default_instance;
+  }
+
   void InitAsDefaultInstance() {
     KeyTypeHandler::AssignDefaultValue(&key_);
     ValueTypeHandler::AssignDefaultValue(&value_);
@@ -289,24 +320,18 @@
     return GetArenaNoVirtual();
   }
 
-  // Create a MapEntryLite for given key and value from google::protobuf::Map in
+  // Create a MapEntryImpl 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::CreateMessage<MapEnumEntryWrapper<
-        Key, Value, kKeyFieldType, kValueFieldType, default_enum_value> >(
-        arena, key, value);
+  static Derived* EnumWrap(const Key& key, const Value value, Arena* arena) {
+    return Arena::CreateMessage<MapEnumEntryWrapper>(arena, key, value);
   }
 
   // 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::CreateMessage<MapEntryWrapper<Key, Value, kKeyFieldType,
-                                                kValueFieldType,
-                                                default_enum_value> >(
-        arena, key, value);
+  // MapEntryImpl from google::protobuf::Map in serialization.
+  static Derived* Wrap(const Key& key, const Value& value, Arena* arena) {
+    return Arena::CreateMessage<MapEntryWrapper>(arena, key, value);
   }
 
   // Parsing using MergePartialFromCodedStream, above, is not as
@@ -411,7 +436,7 @@
     Value* value_ptr_;
     // On the fast path entry_ is not used.  And, when entry_ is used, it's set
     // to mf_->NewEntry(), so in the arena case we must call entry_.release.
-    google::protobuf::scoped_ptr<MapEntryLite> entry_;
+    google::protobuf::scoped_ptr<MapEntryImpl> entry_;
   };
 
  protected:
@@ -433,21 +458,17 @@
   // 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 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::KeyMapEntryAccessorType KeyMapEntryAccessorType;
-    typedef typename Base::ValueMapEntryAccessorType ValueMapEntryAccessorType;
+  class MapEntryWrapper : public Derived {
+    typedef Derived BaseClass;
+    typedef typename BaseClass::KeyMapEntryAccessorType KeyMapEntryAccessorType;
+    typedef
+        typename BaseClass::ValueMapEntryAccessorType ValueMapEntryAccessorType;
 
    public:
-    MapEntryWrapper(Arena* arena, const K& key, const V& value)
-        : MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum>(arena),
-          key_(key),
-          value_(value) {
-      Base::set_has_key();
-      Base::set_has_value();
+    MapEntryWrapper(Arena* arena, const Key& key, const Value& value)
+        : Derived(arena), key_(key), value_(value) {
+      BaseClass::set_has_key();
+      BaseClass::set_has_value();
     }
     inline const KeyMapEntryAccessorType& key() const { return key_; }
     inline const ValueMapEntryAccessorType& value() const { return value_; }
@@ -467,21 +488,17 @@
   // 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 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::KeyMapEntryAccessorType KeyMapEntryAccessorType;
-    typedef typename Base::ValueMapEntryAccessorType ValueMapEntryAccessorType;
+  class MapEnumEntryWrapper : public Derived {
+    typedef Derived BaseClass;
+    typedef typename BaseClass::KeyMapEntryAccessorType KeyMapEntryAccessorType;
+    typedef
+        typename BaseClass::ValueMapEntryAccessorType ValueMapEntryAccessorType;
 
    public:
-    MapEnumEntryWrapper(Arena* arena, const K& key, const V& value)
-        : MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum>(arena),
-          key_(key),
-          value_(value) {
-      Base::set_has_key();
-      Base::set_has_value();
+    MapEnumEntryWrapper(Arena* arena, const Key& key, const Value& value)
+        : Derived(arena), key_(key), value_(value) {
+      BaseClass::set_has_key();
+      BaseClass::set_has_value();
     }
     inline const KeyMapEntryAccessorType& key() const { return key_; }
     inline const ValueMapEntryAccessorType& value() const { return value_; }
@@ -494,30 +511,11 @@
     typedef void DestructorSkippable_;
   };
 
-  MapEntryLite() : default_instance_(NULL), arena_(NULL) {
-    KeyTypeHandler::Initialize(&key_, NULL);
-    ValueTypeHandler::InitializeMaybeByDefaultEnum(
-        &value_, default_enum_value, NULL);
-    _has_bits_[0] = 0;
-  }
-
-  explicit MapEntryLite(Arena* arena)
-      : default_instance_(NULL), arena_(arena) {
-    KeyTypeHandler::Initialize(&key_, arena);
-    ValueTypeHandler::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_;
+  MapEntryImpl* default_instance_;
 
   KeyOnMemory key_;
   ValueOnMemory value_;
@@ -527,14 +525,33 @@
   friend class ::google::protobuf::Arena;
   typedef void InternalArenaConstructable_;
   typedef void DestructorSkippable_;
-  template <typename K, typename V, WireFormatLite::FieldType,
+  template <typename C, typename K, typename V, WireFormatLite::FieldType,
             WireFormatLite::FieldType, int>
   friend class internal::MapEntry;
-  template <typename K, typename V, WireFormatLite::FieldType,
+  template <typename C, typename K, typename V, WireFormatLite::FieldType,
             WireFormatLite::FieldType, int>
   friend class internal::MapFieldLite;
 
-  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryLite);
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryImpl);
+};
+
+template <typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType,
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+class LIBPROTOBUF_EXPORT MapEntryLite
+    : public MapEntryImpl<MapEntryLite<Key, Value, kKeyFieldType,
+                                       kValueFieldType, default_enum_value>,
+                          MessageLite, Key, Value, kKeyFieldType,
+                          kValueFieldType, default_enum_value> {
+ public:
+  typedef MapEntryImpl<MapEntryLite, MessageLite, Key, Value, kKeyFieldType,
+                       kValueFieldType, default_enum_value>
+      SuperType;
+  MapEntryLite() {}
+  explicit MapEntryLite(Arena* arena) : SuperType(arena) {}
+  void MergeFrom(const MapEntryLite<Key, Value, kKeyFieldType, kValueFieldType,
+                                    default_enum_value>& other) {
+    MergeFromInternal(other);
+  }
 };
 
 // Helpers for deterministic serialization =============================
diff --git a/src/google/protobuf/map_field.cc b/src/google/protobuf/map_field.cc
index 49f9181..4cde0aa 100644
--- a/src/google/protobuf/map_field.cc
+++ b/src/google/protobuf/map_field.cc
@@ -37,31 +37,6 @@
 namespace protobuf {
 namespace internal {
 
-ProtobufOnceType map_entry_default_instances_once_;
-Mutex* map_entry_default_instances_mutex_;
-vector<MessageLite*>* map_entry_default_instances_;
-
-void DeleteMapEntryDefaultInstances() {
-  for (int i = 0; i < map_entry_default_instances_->size(); ++i) {
-    delete map_entry_default_instances_->at(i);
-  }
-  delete map_entry_default_instances_mutex_;
-  delete map_entry_default_instances_;
-}
-
-void InitMapEntryDefaultInstances() {
-  map_entry_default_instances_mutex_ = new Mutex();
-  map_entry_default_instances_ = new vector<MessageLite*>();
-  OnShutdown(&DeleteMapEntryDefaultInstances);
-}
-
-void RegisterMapEntryDefaultInstance(MessageLite* default_instance) {
-  ::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 && arena_ == NULL) delete repeated_field_;
 }
@@ -77,27 +52,21 @@
   return repeated_field_;
 }
 
-int MapFieldBase::SpaceUsedExcludingSelf() const {
+size_t MapFieldBase::SpaceUsedExcludingSelfLong() const {
   mutex_.Lock();
-  int size = SpaceUsedExcludingSelfNoLock();
+  size_t size = SpaceUsedExcludingSelfNoLock();
   mutex_.Unlock();
   return size;
 }
 
-int MapFieldBase::SpaceUsedExcludingSelfNoLock() const {
+size_t MapFieldBase::SpaceUsedExcludingSelfNoLock() const {
   if (repeated_field_ != NULL) {
-    return repeated_field_->SpaceUsedExcludingSelf();
+    return repeated_field_->SpaceUsedExcludingSelfLong();
   } else {
     return 0;
   }
 }
 
-void MapFieldBase::InitMetadataOnce() const {
-  GOOGLE_CHECK(entry_descriptor_ != NULL);
-  GOOGLE_CHECK(assign_descriptor_callback_ != NULL);
-  (*assign_descriptor_callback_)();
-}
-
 void MapFieldBase::SetMapDirty() { state_ = STATE_MODIFIED_MAP; }
 
 void MapFieldBase::SetRepeatedDirty() { state_ = STATE_MODIFIED_REPEATED; }
@@ -421,13 +390,13 @@
   }
 }
 
-int DynamicMapField::SpaceUsedExcludingSelfNoLock() const {
-  int size = 0;
+size_t DynamicMapField::SpaceUsedExcludingSelfNoLock() const {
+  size_t size = 0;
   if (MapFieldBase::repeated_field_ != NULL) {
-    size += MapFieldBase::repeated_field_->SpaceUsedExcludingSelf();
+    size += MapFieldBase::repeated_field_->SpaceUsedExcludingSelfLong();
   }
   size += sizeof(map_);
-  int map_size = map_.size();
+  size_t map_size = map_.size();
   if (map_size) {
     Map<MapKey, MapValueRef>::const_iterator it = map_.begin();
     size += sizeof(it->first) * map_size;
@@ -456,7 +425,7 @@
       case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
         while (it != map_.end()) {
           const Message& message = it->second.GetMessageValue();
-          size += message.GetReflection()->SpaceUsed(message);
+          size += message.GetReflection()->SpaceUsedLong(message);
           ++it;
         }
         break;
diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h
index d6af853..6d90407 100644
--- a/src/google/protobuf/map_field.h
+++ b/src/google/protobuf/map_field.h
@@ -36,6 +36,7 @@
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/generated_message_reflection.h>
 #include <google/protobuf/arena.h>
+#include <google/protobuf/descriptor.h>
 #include <google/protobuf/map_entry.h>
 #include <google/protobuf/map_field_lite.h>
 #include <google/protobuf/map_type_handler.h>
@@ -62,14 +63,10 @@
   MapFieldBase()
       : 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),
         state_(STATE_MODIFIED_MAP) {
     // Mutex's destructor needs to be called explicitly to release resources
     // acquired in its constructor.
@@ -99,11 +96,15 @@
 
   // Returns the number of bytes used by the repeated field, excluding
   // sizeof(*this)
-  int SpaceUsedExcludingSelf() const;
+  size_t SpaceUsedExcludingSelfLong() const;
+
+  int SpaceUsedExcludingSelf() const {
+    return internal::ToIntSize(SpaceUsedExcludingSelfLong());
+  }
 
  protected:
   // Gets the size of space used by map field.
-  virtual int SpaceUsedExcludingSelfNoLock() const;
+  virtual size_t SpaceUsedExcludingSelfNoLock() const;
 
   // Synchronizes the content in Map to RepeatedPtrField if there is any change
   // to Map after last synchronization.
@@ -124,9 +125,6 @@
   // Provides derived class the access to repeated field.
   void* MutableRepeatedPtrField() const;
 
-  // Creates descriptor for only one time.
-  void InitMetadataOnce() const;
-
   enum State {
     STATE_MODIFIED_MAP = 0,       // map has newly added data that has not been
                                   // synchronized to repeated field
@@ -137,13 +135,6 @@
 
   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
-  // cannot initialize its own descriptor by calling generated
-  // descriptor-assign-function. Thus, we need to register a callback to
-  // initialize MapEntry's descriptor.
-  const Descriptor** entry_descriptor_;
-  void (*assign_descriptor_callback_)();
 
   mutable Mutex mutex_;  // The thread to synchronize map and repeated field
                          // needs to get lock first;
@@ -211,27 +202,24 @@
 // This class provides access 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,
+template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType,
-          int default_enum_value = 0>
-class MapField : public TypeDefinedMapFieldBase<Key, T>,
-                 public MapFieldLite<Key, T, kKeyFieldType, kValueFieldType,
-                                     default_enum_value> {
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value = 0>
+class MapField : public TypeDefinedMapFieldBase<Key, T> {
   // Provide utilities to parse/serialize key/value.  Provide utilities to
   // manipulate internal stored type.
   typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
   typedef MapTypeHandler<kValueFieldType, T> ValueTypeHandler;
 
   // Define message type for internal repeated field.
-  typedef MapEntry<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>
-      EntryType;
+  typedef Derived 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;
+  typedef MapFieldLite<Derived, 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
@@ -241,58 +229,62 @@
   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();
+  MapField() {}
+  explicit MapField(Arena* arena)
+      : TypeDefinedMapFieldBase<Key, T>(arena), impl_(arena) {}
 
   // Implement MapFieldBase
   bool ContainsMapKey(const MapKey& map_key) const;
   bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val);
   bool DeleteMapValue(const MapKey& map_key);
 
-  // Accessors
-  const Map<Key, T>& GetMap() const;
-  Map<Key, T>* MutableMap();
+  const Map<Key, T>& GetMap() const {
+    MapFieldBase::SyncMapWithRepeatedField();
+    return impl_.GetMap();
+  }
+
+  Map<Key, T>* MutableMap() {
+    MapFieldBase::SyncMapWithRepeatedField();
+    Map<Key, T>* result = impl_.MutableMap();
+    MapFieldBase::SetMapDirty();
+    return result;
+  }
 
   // Convenient methods for generated message implementation.
   int size() const;
   void Clear();
-  void MergeFrom(const MapFieldLiteType& other);
-  void Swap(MapFieldLiteType* other);
+  void MergeFrom(const MapField& other);
+  void Swap(MapField* other);
 
-  // Allocates metadata only if this MapField is part of a generated message.
-  void SetEntryDescriptor(const Descriptor** descriptor);
-  void SetAssignDescriptorCallback(void (*callback)());
+  // Used in the implementation of parsing. Caller should take the ownership iff
+  // arena_ is NULL.
+  EntryType* NewEntry() const { return impl_.NewEntry(); }
+  // Used in the implementation of serializing enum value type. Caller should
+  // take the ownership iff arena_ is NULL.
+  EntryType* NewEnumEntryWrapper(const Key& key, const T t) const {
+    return impl_.NewEnumEntryWrapper(key, t);
+  }
+  // Used in the implementation of serializing other value types. Caller should
+  // take the ownership iff arena_ is NULL.
+  EntryType* NewEntryWrapper(const Key& key, const T& t) const {
+    return impl_.NewEntryWrapper(key, t);
+  }
 
  private:
+  MapFieldLiteType impl_;
+
   typedef void InternalArenaConstructable_;
   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();
-
   // Implements MapFieldBase
   void SyncRepeatedFieldWithMapNoLock() const;
   void SyncMapWithRepeatedFieldNoLock() const;
-  int SpaceUsedExcludingSelfNoLock() const;
+  size_t SpaceUsedExcludingSelfNoLock() const;
 
   void SetMapIteratorValue(MapIterator* map_iter) const;
 
-  mutable const EntryType* default_entry_;
-
   friend class ::google::protobuf::Arena;
+  friend class MapFieldStateTest;  // For testing, it needs raw access to impl_
 };
 
 class LIBPROTOBUF_EXPORT DynamicMapField: public TypeDefinedMapFieldBase<MapKey, MapValueRef> {
@@ -318,12 +310,395 @@
   // Implements MapFieldBase
   void SyncRepeatedFieldWithMapNoLock() const;
   void SyncMapWithRepeatedFieldNoLock() const;
-  int SpaceUsedExcludingSelfNoLock() const;
+  size_t SpaceUsedExcludingSelfNoLock() const;
   void SetMapIteratorValue(MapIterator* map_iter) const;
 };
 
 }  // namespace internal
 
+#define TYPE_CHECK(EXPECTEDTYPE, METHOD)                        \
+  if (type() != EXPECTEDTYPE) {                                 \
+    GOOGLE_LOG(FATAL)                                                  \
+        << "Protocol Buffer map usage error:\n"                 \
+        << METHOD << " type does not match\n"                   \
+        << "  Expected : "                                      \
+        << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n"   \
+        << "  Actual   : "                                      \
+        << FieldDescriptor::CppTypeName(type());                \
+  }
+
+// MapKey is an union type for representing any possible
+// map key.
+class LIBPROTOBUF_EXPORT MapKey {
+ public:
+  MapKey() : type_(0) {
+  }
+  MapKey(const MapKey& other) : type_(0) {
+    CopyFrom(other);
+  }
+
+  ~MapKey() {
+    if (type_ == FieldDescriptor::CPPTYPE_STRING) {
+      delete val_.string_value_;
+    }
+  }
+
+  FieldDescriptor::CppType type() const {
+    if (type_ == 0) {
+      GOOGLE_LOG(FATAL)
+          << "Protocol Buffer map usage error:\n"
+          << "MapKey::type MapKey is not initialized. "
+          << "Call set methods to initialize MapKey.";
+    }
+    return (FieldDescriptor::CppType)type_;
+  }
+
+  void SetInt64Value(int64 value) {
+    SetType(FieldDescriptor::CPPTYPE_INT64);
+    val_.int64_value_ = value;
+  }
+  void SetUInt64Value(uint64 value) {
+    SetType(FieldDescriptor::CPPTYPE_UINT64);
+    val_.uint64_value_ = value;
+  }
+  void SetInt32Value(int32 value) {
+    SetType(FieldDescriptor::CPPTYPE_INT32);
+    val_.int32_value_ = value;
+  }
+  void SetUInt32Value(uint32 value) {
+    SetType(FieldDescriptor::CPPTYPE_UINT32);
+    val_.uint32_value_ = value;
+  }
+  void SetBoolValue(bool value) {
+    SetType(FieldDescriptor::CPPTYPE_BOOL);
+    val_.bool_value_ = value;
+  }
+  void SetStringValue(const string& val) {
+    SetType(FieldDescriptor::CPPTYPE_STRING);
+    *val_.string_value_ = val;
+  }
+
+  int64 GetInt64Value() const {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
+               "MapKey::GetInt64Value");
+    return val_.int64_value_;
+  }
+  uint64 GetUInt64Value() const {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
+               "MapKey::GetUInt64Value");
+    return val_.uint64_value_;
+  }
+  int32 GetInt32Value() const {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
+               "MapKey::GetInt32Value");
+    return val_.int32_value_;
+  }
+  uint32 GetUInt32Value() const {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
+               "MapKey::GetUInt32Value");
+    return val_.uint32_value_;
+  }
+  bool GetBoolValue() const {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
+               "MapKey::GetBoolValue");
+    return val_.bool_value_;
+  }
+  const string& GetStringValue() const {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
+               "MapKey::GetStringValue");
+    return *val_.string_value_;
+  }
+
+  bool operator<(const MapKey& other) const {
+    if (type_ != other.type_) {
+      // We could define a total order that handles this case, but
+      // there currently no need.  So, for now, fail.
+      GOOGLE_LOG(FATAL) << "Unsupported: type mismatch";
+    }
+    switch (type()) {
+      case FieldDescriptor::CPPTYPE_DOUBLE:
+      case FieldDescriptor::CPPTYPE_FLOAT:
+      case FieldDescriptor::CPPTYPE_ENUM:
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        GOOGLE_LOG(FATAL) << "Unsupported";
+        return false;
+      case FieldDescriptor::CPPTYPE_STRING:
+        return *val_.string_value_ < *other.val_.string_value_;
+      case FieldDescriptor::CPPTYPE_INT64:
+        return val_.int64_value_ < other.val_.int64_value_;
+      case FieldDescriptor::CPPTYPE_INT32:
+        return val_.int32_value_ < other.val_.int32_value_;
+      case FieldDescriptor::CPPTYPE_UINT64:
+        return val_.uint64_value_ < other.val_.uint64_value_;
+      case FieldDescriptor::CPPTYPE_UINT32:
+        return val_.uint32_value_ < other.val_.uint32_value_;
+      case FieldDescriptor::CPPTYPE_BOOL:
+        return val_.bool_value_ < other.val_.bool_value_;
+    }
+    return false;
+  }
+
+  bool operator==(const MapKey& other) const {
+    if (type_ != other.type_) {
+      // To be consistent with operator<, we don't allow this either.
+      GOOGLE_LOG(FATAL) << "Unsupported: type mismatch";
+    }
+    switch (type()) {
+      case FieldDescriptor::CPPTYPE_DOUBLE:
+      case FieldDescriptor::CPPTYPE_FLOAT:
+      case FieldDescriptor::CPPTYPE_ENUM:
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        GOOGLE_LOG(FATAL) << "Unsupported";
+        break;
+      case FieldDescriptor::CPPTYPE_STRING:
+        return *val_.string_value_ == *other.val_.string_value_;
+      case FieldDescriptor::CPPTYPE_INT64:
+        return val_.int64_value_ == other.val_.int64_value_;
+      case FieldDescriptor::CPPTYPE_INT32:
+        return val_.int32_value_ == other.val_.int32_value_;
+      case FieldDescriptor::CPPTYPE_UINT64:
+        return val_.uint64_value_ == other.val_.uint64_value_;
+      case FieldDescriptor::CPPTYPE_UINT32:
+        return val_.uint32_value_ == other.val_.uint32_value_;
+      case FieldDescriptor::CPPTYPE_BOOL:
+        return val_.bool_value_ == other.val_.bool_value_;
+    }
+    GOOGLE_LOG(FATAL) << "Can't get here.";
+    return false;
+  }
+
+  void CopyFrom(const MapKey& other) {
+    SetType(other.type());
+    switch (type_) {
+      case FieldDescriptor::CPPTYPE_DOUBLE:
+      case FieldDescriptor::CPPTYPE_FLOAT:
+      case FieldDescriptor::CPPTYPE_ENUM:
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        GOOGLE_LOG(FATAL) << "Unsupported";
+        break;
+      case FieldDescriptor::CPPTYPE_STRING:
+        *val_.string_value_ = *other.val_.string_value_;
+        break;
+      case FieldDescriptor::CPPTYPE_INT64:
+        val_.int64_value_ = other.val_.int64_value_;
+        break;
+      case FieldDescriptor::CPPTYPE_INT32:
+        val_.int32_value_ = other.val_.int32_value_;
+        break;
+      case FieldDescriptor::CPPTYPE_UINT64:
+        val_.uint64_value_ = other.val_.uint64_value_;
+        break;
+      case FieldDescriptor::CPPTYPE_UINT32:
+        val_.uint32_value_ = other.val_.uint32_value_;
+        break;
+      case FieldDescriptor::CPPTYPE_BOOL:
+        val_.bool_value_ = other.val_.bool_value_;
+        break;
+    }
+  }
+
+ private:
+  template <typename K, typename V>
+  friend class internal::TypeDefinedMapFieldBase;
+  friend class MapIterator;
+  friend class internal::DynamicMapField;
+
+  union KeyValue {
+    KeyValue() {}
+    string* string_value_;
+    int64 int64_value_;
+    int32 int32_value_;
+    uint64 uint64_value_;
+    uint32 uint32_value_;
+    bool bool_value_;
+  } val_;
+
+  void SetType(FieldDescriptor::CppType type) {
+    if (type_ == type) return;
+    if (type_ == FieldDescriptor::CPPTYPE_STRING) {
+      delete val_.string_value_;
+    }
+    type_ = type;
+    if (type_ == FieldDescriptor::CPPTYPE_STRING) {
+      val_.string_value_ = new string;
+    }
+  }
+
+  // type_ is 0 or a valid FieldDescriptor::CppType.
+  int type_;
+};
+
+// MapValueRef points to a map value.
+class LIBPROTOBUF_EXPORT MapValueRef {
+ public:
+  MapValueRef() : data_(NULL), type_(0) {}
+
+  void SetInt64Value(int64 value) {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
+               "MapValueRef::SetInt64Value");
+    *reinterpret_cast<int64*>(data_) = value;
+  }
+  void SetUInt64Value(uint64 value) {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
+               "MapValueRef::SetUInt64Value");
+    *reinterpret_cast<uint64*>(data_) = value;
+  }
+  void SetInt32Value(int32 value) {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
+               "MapValueRef::SetInt32Value");
+    *reinterpret_cast<int32*>(data_) = value;
+  }
+  void SetUInt32Value(uint32 value) {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
+               "MapValueRef::SetUInt32Value");
+    *reinterpret_cast<uint32*>(data_) = value;
+  }
+  void SetBoolValue(bool value) {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
+               "MapValueRef::SetBoolValue");
+    *reinterpret_cast<bool*>(data_) = value;
+  }
+  // TODO(jieluo) - Checks that enum is member.
+  void SetEnumValue(int value) {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM,
+               "MapValueRef::SetEnumValue");
+    *reinterpret_cast<int*>(data_) = value;
+  }
+  void SetStringValue(const string& value) {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
+               "MapValueRef::SetStringValue");
+    *reinterpret_cast<string*>(data_) = value;
+  }
+  void SetFloatValue(float value) {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
+               "MapValueRef::SetFloatValue");
+    *reinterpret_cast<float*>(data_) = value;
+  }
+  void SetDoubleValue(double value) {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
+               "MapValueRef::SetDoubleValue");
+    *reinterpret_cast<double*>(data_) = value;
+  }
+
+  int64 GetInt64Value() const {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
+               "MapValueRef::GetInt64Value");
+    return *reinterpret_cast<int64*>(data_);
+  }
+  uint64 GetUInt64Value() const {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
+               "MapValueRef::GetUInt64Value");
+    return *reinterpret_cast<uint64*>(data_);
+  }
+  int32 GetInt32Value() const {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
+               "MapValueRef::GetInt32Value");
+    return *reinterpret_cast<int32*>(data_);
+  }
+  uint32 GetUInt32Value() const {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
+               "MapValueRef::GetUInt32Value");
+    return *reinterpret_cast<uint32*>(data_);
+  }
+  bool GetBoolValue() const {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
+               "MapValueRef::GetBoolValue");
+    return *reinterpret_cast<bool*>(data_);
+  }
+  int GetEnumValue() const {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM,
+               "MapValueRef::GetEnumValue");
+    return *reinterpret_cast<int*>(data_);
+  }
+  const string& GetStringValue() const {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
+               "MapValueRef::GetStringValue");
+    return *reinterpret_cast<string*>(data_);
+  }
+  float GetFloatValue() const {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
+               "MapValueRef::GetFloatValue");
+    return *reinterpret_cast<float*>(data_);
+  }
+  double GetDoubleValue() const {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
+               "MapValueRef::GetDoubleValue");
+    return *reinterpret_cast<double*>(data_);
+  }
+
+  const Message& GetMessageValue() const {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
+               "MapValueRef::GetMessageValue");
+    return *reinterpret_cast<Message*>(data_);
+  }
+
+  Message* MutableMessageValue() {
+    TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
+               "MapValueRef::MutableMessageValue");
+    return reinterpret_cast<Message*>(data_);
+  }
+
+ private:
+  template <typename Derived, typename K, typename V,
+            internal::WireFormatLite::FieldType key_wire_type,
+            internal::WireFormatLite::FieldType value_wire_type,
+            int default_enum_value>
+  friend class internal::MapField;
+  template <typename K, typename V>
+  friend class internal::TypeDefinedMapFieldBase;
+  friend class MapIterator;
+  friend class internal::GeneratedMessageReflection;
+  friend class internal::DynamicMapField;
+
+  void SetType(FieldDescriptor::CppType type) {
+    type_ = type;
+  }
+
+  FieldDescriptor::CppType type() const {
+    if (type_ == 0 || data_ == NULL) {
+      GOOGLE_LOG(FATAL)
+          << "Protocol Buffer map usage error:\n"
+          << "MapValueRef::type MapValueRef is not initialized.";
+    }
+    return (FieldDescriptor::CppType)type_;
+  }
+  void SetValue(const void* val) {
+    data_ = const_cast<void*>(val);
+  }
+  void CopyFrom(const MapValueRef& other) {
+    type_ = other.type_;
+    data_ = other.data_;
+  }
+  // Only used in DynamicMapField
+  void DeleteData() {
+    switch (type_) {
+#define HANDLE_TYPE(CPPTYPE, TYPE)                              \
+      case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: {        \
+        delete reinterpret_cast<TYPE*>(data_);                  \
+        break;                                                  \
+      }
+      HANDLE_TYPE(INT32, int32);
+      HANDLE_TYPE(INT64, int64);
+      HANDLE_TYPE(UINT32, uint32);
+      HANDLE_TYPE(UINT64, uint64);
+      HANDLE_TYPE(DOUBLE, double);
+      HANDLE_TYPE(FLOAT, float);
+      HANDLE_TYPE(BOOL, bool);
+      HANDLE_TYPE(STRING, string);
+      HANDLE_TYPE(ENUM, int32);
+      HANDLE_TYPE(MESSAGE, Message);
+#undef HANDLE_TYPE
+    }
+  }
+  // data_ point to a map value. MapValueRef does not
+  // own this value.
+  void* data_;
+  // type_ is 0 or a valid FieldDescriptor::CppType.
+  int type_;
+};
+
+#undef TYPE_CHECK
+
 class LIBPROTOBUF_EXPORT MapIterator {
  public:
   MapIterator(Message* message, const FieldDescriptor* field) {
@@ -373,7 +748,7 @@
   template <typename Key, typename T>
   friend class internal::TypeDefinedMapFieldBase;
   friend class internal::DynamicMapField;
-  template <typename Key, typename T,
+  template <typename Derived, typename Key, typename T,
             internal::WireFormatLite::FieldType kKeyFieldType,
             internal::WireFormatLite::FieldType kValueFieldType,
             int default_enum_value>
@@ -392,6 +767,42 @@
 };
 
 }  // namespace protobuf
-
 }  // namespace google
+
+GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START
+template<>
+struct hash<google::protobuf::MapKey> {
+  size_t
+  operator()(const google::protobuf::MapKey& map_key) const {
+    switch (map_key.type()) {
+      case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
+      case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
+      case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
+      case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
+        GOOGLE_LOG(FATAL) << "Unsupported";
+        break;
+      case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
+        return hash<string>()(map_key.GetStringValue());
+      case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
+        return hash< ::google::protobuf::int64>()(map_key.GetInt64Value());
+      case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
+        return hash< ::google::protobuf::int32>()(map_key.GetInt32Value());
+      case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
+        return hash< ::google::protobuf::uint64>()(map_key.GetUInt64Value());
+      case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
+        return hash< ::google::protobuf::uint32>()(map_key.GetUInt32Value());
+      case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
+        return hash<bool>()(map_key.GetBoolValue());
+    }
+    GOOGLE_LOG(FATAL) << "Can't get here.";
+    return 0;
+  }
+  bool
+  operator()(const google::protobuf::MapKey& map_key1,
+             const google::protobuf::MapKey& map_key2) const {
+    return map_key1 < map_key2;
+  }
+};
+GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END
+
 #endif  // GOOGLE_PROTOBUF_MAP_FIELD_H__
diff --git a/src/google/protobuf/map_field_inl.h b/src/google/protobuf/map_field_inl.h
index 2d84b0a..8c5da3c 100644
--- a/src/google/protobuf/map_field_inl.h
+++ b/src/google/protobuf/map_field_inl.h
@@ -162,81 +162,32 @@
 
 // ----------------------------------------------------------------------
 
-template <typename Key, typename T,
+template <typename Derived, 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,
-          WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType,
-          int default_enum_value>
-MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::MapField(
-    Arena* arena)
-    : TypeDefinedMapFieldBase<Key, T>(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)) {}
-
-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)
-    : TypeDefinedMapFieldBase<Key, T>(arena),
-      MapFieldLite<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>(
-          arena),
-      default_entry_(down_cast<const EntryType*>(default_entry)) {}
-
-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 {
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+int MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
+             default_enum_value>::size() const {
   MapFieldBase::SyncMapWithRepeatedField();
-  return MapFieldLiteType::GetInternalMap().size();
+  return impl_.GetMap().size();
 }
 
-template <typename Key, typename T,
+template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType,
-          int default_enum_value>
-void
-MapField<Key, T, kKeyFieldType, kValueFieldType,
-         default_enum_value>::Clear() {
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
+              default_enum_value>::Clear() {
   MapFieldBase::SyncMapWithRepeatedField();
-  MapFieldLiteType::MutableInternalMap()->clear();
+  impl_.MutableMap()->clear();
   MapFieldBase::SetMapDirty();
 }
 
-template <typename Key, typename T,
+template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType,
-          int default_enum_value>
-void MapField<Key, T, kKeyFieldType, kValueFieldType,
-              default_enum_value>::SetMapIteratorValue(
-                  MapIterator* map_iter) const {
-  const Map<Key, T>& map = GetMap();
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
+              default_enum_value>::SetMapIteratorValue(MapIterator* map_iter)
+    const {
+  const Map<Key, T>& map = impl_.GetMap();
   typename Map<Key, T>::const_iterator iter =
       TypeDefinedMapFieldBase<Key, T>::InternalGetIterator(map_iter);
   if (iter == map.end()) return;
@@ -244,27 +195,23 @@
   map_iter->value_.SetValue(&iter->second);
 }
 
-template <typename Key, typename T,
+template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType,
-          int default_enum_value>
-bool MapField<Key, T, kKeyFieldType, kValueFieldType,
-              default_enum_value>::ContainsMapKey(
-                  const MapKey& map_key) const {
-  const Map<Key, T>& map = GetMap();
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+bool MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
+              default_enum_value>::ContainsMapKey(const MapKey& map_key) const {
+  const Map<Key, T>& map = impl_.GetMap();
   const Key& key = UnwrapMapKey<Key>(map_key);
   typename Map<Key, T>::const_iterator iter = map.find(key);
   return iter != map.end();
 }
 
-template <typename Key, typename T,
+template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType,
-          int default_enum_value>
-bool MapField<Key, T, kKeyFieldType, kValueFieldType,
-              default_enum_value>::InsertOrLookupMapValue(
-                  const MapKey& map_key,
-                  MapValueRef* val) {
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+bool MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
+              default_enum_value>::InsertOrLookupMapValue(const MapKey& map_key,
+                                                          MapValueRef* val) {
   // Always use mutable map because users may change the map value by
   // MapValueRef.
   Map<Key, T>* map = MutableMap();
@@ -280,118 +227,41 @@
   return false;
 }
 
-template <typename Key, typename T,
+template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType,
-          int default_enum_value>
-bool MapField<Key, T, kKeyFieldType, kValueFieldType,
-              default_enum_value>::DeleteMapValue(
-                  const MapKey& map_key) {
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+bool MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
+              default_enum_value>::DeleteMapValue(const MapKey& map_key) {
   const Key& key = UnwrapMapKey<Key>(map_key);
   return MutableMap()->erase(key);
 }
 
-template <typename Key, typename T,
+template <typename Derived, 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>::GetMap() const {
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
+              default_enum_value>::MergeFrom(const MapField& other) {
   MapFieldBase::SyncMapWithRepeatedField();
-  return MapFieldLiteType::GetInternalMap();
-}
-
-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>::MutableMap() {
-  MapFieldBase::SyncMapWithRepeatedField();
-  Map<Key, T>* result = MapFieldLiteType::MutableInternalMap();
-  MapFieldBase::SetMapDirty();
-  return result;
-}
-
-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);
-  MapFieldBase::SyncMapWithRepeatedField();
-  down_other.SyncMapWithRepeatedField();
-  MapFieldLiteType::MergeFrom(other);
+  other.SyncMapWithRepeatedField();
+  impl_.MergeFrom(other.impl_);
   MapFieldBase::SetMapDirty();
 }
 
-template <typename Key, typename T,
+template <typename Derived, 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(this->MapFieldBase::repeated_field_, down_other->repeated_field_);
-  MapFieldLiteType::Swap(other);
-  std::swap(this->MapFieldBase::state_, down_other->state_);
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
+              default_enum_value>::Swap(MapField* other) {
+  std::swap(MapFieldBase::repeated_field_, other->repeated_field_);
+  impl_.Swap(&other->impl_);
+  std::swap(MapFieldBase::state_, other->state_);
 }
 
-template <typename Key, typename T,
+template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType,
-          int default_enum_value>
-void
-MapField<Key, T, kKeyFieldType, kValueFieldType,
-         default_enum_value>::SetEntryDescriptor(
-    const Descriptor** descriptor) {
-  this->MapFieldBase::entry_descriptor_ = descriptor;
-}
-
-template <typename Key, typename T,
-          WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType,
-          int default_enum_value>
-void
-MapField<Key, T, kKeyFieldType, kValueFieldType,
-         default_enum_value>::SetAssignDescriptorCallback(void (*callback)()) {
-  this->MapFieldBase::assign_descriptor_callback_ = callback;
-}
-
-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,
-          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,
-          WireFormatLite::FieldType kKeyFieldType,
-          WireFormatLite::FieldType kValueFieldType,
-          int default_enum_value>
-void
-MapField<Key, T, kKeyFieldType, kValueFieldType,
-         default_enum_value>::SyncRepeatedFieldWithMapNoLock() const {
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
+              default_enum_value>::SyncRepeatedFieldWithMapNoLock() const {
   if (this->MapFieldBase::repeated_field_ == NULL) {
     if (this->MapFieldBase::arena_ == NULL) {
       this->MapFieldBase::repeated_field_ = new RepeatedPtrField<Message>();
@@ -401,33 +271,35 @@
               this->MapFieldBase::arena_);
     }
   }
-  const Map<Key, T>& map = GetInternalMap();
+  const Map<Key, T>& map = impl_.GetMap();
   RepeatedPtrField<EntryType>* repeated_field =
       reinterpret_cast<RepeatedPtrField<EntryType>*>(
           this->MapFieldBase::repeated_field_);
 
   repeated_field->Clear();
 
+  // The only way we can get at this point is through reflection and the
+  // only way we can get the reflection object is by having called GetReflection
+  // on the encompassing field. So that type must have existed and hence we
+  // know that this MapEntry default_type has also already been constructed.
+  // So it's safe to just call internal_default_instance().
+  const Message* default_entry = Derived::internal_default_instance();
   for (typename Map<Key, T>::const_iterator it = map.begin();
        it != map.end(); ++it) {
-    InitDefaultEntryOnce();
-    GOOGLE_CHECK(default_entry_ != NULL);
     EntryType* new_entry =
-        down_cast<EntryType*>(default_entry_->New(this->MapFieldBase::arena_));
+        down_cast<EntryType*>(default_entry->New(this->MapFieldBase::arena_));
     repeated_field->AddAllocated(new_entry);
     (*new_entry->mutable_key()) = it->first;
     (*new_entry->mutable_value()) = it->second;
   }
 }
 
-template <typename Key, typename T,
+template <typename Derived, 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();
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
+              default_enum_value>::SyncMapWithRepeatedFieldNoLock() const {
+  Map<Key, T>* map = const_cast<MapField*>(this)->impl_.MutableMap();
   RepeatedPtrField<EntryType>* repeated_field =
       reinterpret_cast<RepeatedPtrField<EntryType>*>(
           this->MapFieldBase::repeated_field_);
@@ -444,44 +316,24 @@
   }
 }
 
-template <typename Key, typename T,
+template <typename Derived, 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;
+          WireFormatLite::FieldType kValueFieldType, int default_enum_value>
+size_t MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
+                default_enum_value>::SpaceUsedExcludingSelfNoLock() const {
+  size_t size = 0;
   if (this->MapFieldBase::repeated_field_ != NULL) {
-    size += this->MapFieldBase::repeated_field_->SpaceUsedExcludingSelf();
+    size += this->MapFieldBase::repeated_field_->SpaceUsedExcludingSelfLong();
   }
-  Map<Key, T>* map = const_cast<MapField*>(this)->MutableInternalMap();
+  Map<Key, T>* map = const_cast<MapField*>(this)->impl_.MutableMap();
   size += sizeof(*map);
-  for (typename Map<Key, T>::iterator it = map->begin();
-       it != map->end(); ++it) {
-    size += KeyTypeHandler::SpaceUsedInMap(it->first);
-    size += ValueTypeHandler::SpaceUsedInMap(it->second);
+  for (typename Map<Key, T>::iterator it = map->begin(); it != map->end();
+       ++it) {
+    size += KeyTypeHandler::SpaceUsedInMapLong(it->first);
+    size += ValueTypeHandler::SpaceUsedInMapLong(it->second);
   }
   return size;
 }
-
-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) {
-    MapFieldBase::InitMetadataOnce();
-    GOOGLE_CHECK(*this->MapFieldBase::entry_descriptor_ != NULL);
-    default_entry_ = down_cast<const EntryType*>(
-        MessageFactory::generated_factory()->GetPrototype(
-            *this->MapFieldBase::entry_descriptor_));
-  }
-}
-
 }  // namespace internal
 }  // namespace protobuf
 
diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h
index cb0a4a4..2d10239 100644
--- a/src/google/protobuf/map_field_lite.h
+++ b/src/google/protobuf/map_field_lite.h
@@ -41,223 +41,69 @@
 // This class provides access 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,
+template <typename Derived, typename Key, typename T,
           WireFormatLite::FieldType key_wire_type,
-          WireFormatLite::FieldType value_wire_type,
-          int default_enum_value = 0>
+          WireFormatLite::FieldType value_wire_type, int default_enum_value = 0>
 class MapFieldLite {
   // Define message type for internal repeated field.
-  typedef MapEntryLite<Key, T, key_wire_type, value_wire_type,
-                       default_enum_value> EntryType;
+  typedef Derived EntryType;
 
  public:
-  MapFieldLite();
-  explicit MapFieldLite(Arena* arena);
-  virtual ~MapFieldLite();
+  MapFieldLite() : arena_(NULL) { SetDefaultEnumValue(); }
+
+  explicit MapFieldLite(Arena* arena) : arena_(arena), map_(arena) {
+    SetDefaultEnumValue();
+  }
 
   // Accessors
-  virtual const Map<Key, T>& GetMap() const;
-  virtual Map<Key, T>* MutableMap();
+  const Map<Key, T>& GetMap() const { return map_; }
+  Map<Key, T>* MutableMap() { return &map_; }
 
   // Convenient methods for generated message implementation.
-  virtual int size() const;
-  virtual void Clear();
-  virtual void MergeFrom(const MapFieldLite& other);
-  virtual void Swap(MapFieldLite* other);
+  int size() const { return map_.size(); }
+  void Clear() { return map_.clear(); }
+  void 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;
+    }
+  }
+  void Swap(MapFieldLite* other) { map_.swap(other->map_); }
 
   // Set default enum value only for proto2 map field whose value is enum type.
-  void SetDefaultEnumValue();
+  void SetDefaultEnumValue() {
+    MutableMap()->SetDefaultEnumValue(default_enum_value);
+  }
 
   // Used in the implementation of parsing. Caller should take the ownership iff
   // arena_ is NULL.
-  EntryType* NewEntry() const;
+  EntryType* NewEntry() const {
+    if (arena_ == NULL) {
+      return new EntryType();
+    } else {
+      return Arena::CreateMessage<EntryType>(arena_);
+    }
+  }
   // Used in the implementation of serializing enum value type. Caller should
   // take the ownership iff arena_ is NULL.
-  EntryType* NewEnumEntryWrapper(const Key& key, const T t) const;
+  EntryType* NewEnumEntryWrapper(const Key& key, const T t) const {
+    return EntryType::EnumWrap(key, t, arena_);
+  }
   // Used in the implementation of serializing other value types. Caller should
   // take the ownership iff arena_ is NULL.
-  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();
+  EntryType* NewEntryWrapper(const Key& key, const T& t) const {
+    return EntryType::Wrap(key, t, arena_);
+  }
 
  private:
   typedef void DestructorSkippable_;
 
   Arena* arena_;
-  Map<Key, T>* map_;
+  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::CreateMessage<Map<Key, T> >(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
diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc
index dd5061c..8617a36 100644
--- a/src/google/protobuf/map_field_test.cc
+++ b/src/google/protobuf/map_field_test.cc
@@ -101,8 +101,10 @@
 
 class MapFieldBasePrimitiveTest : public ::testing::Test {
  protected:
-  typedef MapField<int32, int32, WireFormatLite::TYPE_INT32,
-                   WireFormatLite::TYPE_INT32, false> MapFieldType;
+  typedef unittest::TestMap::TestMap_MapInt32Int32Entry EntryType;
+  typedef MapField<EntryType, int32, int32, WireFormatLite::TYPE_INT32,
+                   WireFormatLite::TYPE_INT32, false>
+      MapFieldType;
 
   MapFieldBasePrimitiveTest() {
     // Get descriptors
@@ -113,9 +115,7 @@
     value_descriptor_ = map_descriptor_->FindFieldByName("value");
 
     // Build map field
-    default_entry_ =
-        MessageFactory::generated_factory()->GetPrototype(map_descriptor_);
-    map_field_.reset(new MapFieldType(default_entry_));
+    map_field_.reset(new MapFieldType);
     map_field_base_ = map_field_.get();
     map_ = map_field_->MutableMap();
     initial_value_map_[0] = 100;
@@ -130,7 +130,6 @@
   const Descriptor* map_descriptor_;
   const FieldDescriptor* key_descriptor_;
   const FieldDescriptor* value_descriptor_;
-  const Message* default_entry_;
   std::map<int32, int32> initial_value_map_;  // copy of initial values inserted
 };
 
@@ -177,8 +176,7 @@
     // repeated fields are allocated from arenas.
     // NoHeapChecker no_heap;
 
-    MapFieldType* map_field =
-        Arena::CreateMessage<MapFieldType>(&arena, default_entry_);
+    MapFieldType* map_field = Arena::CreateMessage<MapFieldType>(&arena);
 
     // Set content in map
     (*map_field->MutableMap())[100] = 101;
@@ -208,19 +206,13 @@
     : public testing::TestWithParam<State> {
  public:
  protected:
-  typedef MapField<int32, int32, WireFormatLite::TYPE_INT32,
-                   WireFormatLite::TYPE_INT32, false> MapFieldType;
-  typedef MapFieldLite<int32, int32, WireFormatLite::TYPE_INT32,
-                       WireFormatLite::TYPE_INT32, false> MapFieldLiteType;
+  typedef unittest::TestMap::TestMap_MapInt32Int32Entry EntryType;
+  typedef MapField<EntryType, int32, int32, WireFormatLite::TYPE_INT32,
+                   WireFormatLite::TYPE_INT32, false>
+      MapFieldType;
   MapFieldStateTest() : state_(GetParam()) {
     // Build map field
-    const Descriptor* map_descriptor =
-        unittest::TestMap::descriptor()
-            ->FindFieldByName("map_int32_int32")
-            ->message_type();
-    default_entry_ =
-        MessageFactory::generated_factory()->GetPrototype(map_descriptor);
-    map_field_.reset(new MapFieldType(default_entry_));
+    map_field_.reset(new MapFieldType());
     map_field_base_ = map_field_.get();
 
     Expect(map_field_.get(), MAP_DIRTY, 0, 0, true);
@@ -257,8 +249,8 @@
     MakeMapDirty(map_field);
     MapFieldBase* map_field_base = map_field;
     map_field_base->MutableRepeatedField();
-    Map<int32, int32>* map = implicit_cast<MapFieldLiteType*>(map_field)
-                                 ->MapFieldLiteType::MutableMap();
+    // We use MutableMap on impl_ because we don't want to disturb the syncing
+    Map<int32, int32>* map = map_field->impl_.MutableMap();
     map->clear();
 
     Expect(map_field, REPEATED_DIRTY, 0, 1, false);
@@ -270,8 +262,8 @@
     MapFieldBaseStub* stub =
         reinterpret_cast<MapFieldBaseStub*>(map_field_base);
 
-    Map<int32, int32>* map = implicit_cast<MapFieldLiteType*>(map_field)
-                                 ->MapFieldLiteType::MutableMap();
+    // We use MutableMap on impl_ because we don't want to disturb the syncing
+    Map<int32, int32>* map = map_field->impl_.MutableMap();
     RepeatedPtrField<Message>* repeated_field = stub->InternalRepeatedField();
 
     switch (state) {
@@ -302,7 +294,6 @@
   google::protobuf::scoped_ptr<MapFieldType> map_field_;
   MapFieldBase* map_field_base_;
   State state_;
-  const Message* default_entry_;
 };
 
 INSTANTIATE_TEST_CASE_P(MapFieldStateTestInstance, MapFieldStateTest,
@@ -327,7 +318,7 @@
 }
 
 TEST_P(MapFieldStateTest, MergeFromClean) {
-  MapFieldType other(default_entry_);
+  MapFieldType other;
   AddOneStillClean(&other);
 
   map_field_->MergeFrom(other);
@@ -342,7 +333,7 @@
 }
 
 TEST_P(MapFieldStateTest, MergeFromMapDirty) {
-  MapFieldType other(default_entry_);
+  MapFieldType other;
   MakeMapDirty(&other);
 
   map_field_->MergeFrom(other);
@@ -357,7 +348,7 @@
 }
 
 TEST_P(MapFieldStateTest, MergeFromRepeatedDirty) {
-  MapFieldType other(default_entry_);
+  MapFieldType other;
   MakeRepeatedDirty(&other);
 
   map_field_->MergeFrom(other);
@@ -372,7 +363,7 @@
 }
 
 TEST_P(MapFieldStateTest, SwapClean) {
-  MapFieldType other(default_entry_);
+  MapFieldType other;
   AddOneStillClean(&other);
 
   map_field_->Swap(&other);
@@ -395,7 +386,7 @@
 }
 
 TEST_P(MapFieldStateTest, SwapMapDirty) {
-  MapFieldType other(default_entry_);
+  MapFieldType other;
   MakeMapDirty(&other);
 
   map_field_->Swap(&other);
@@ -418,7 +409,7 @@
 }
 
 TEST_P(MapFieldStateTest, SwapRepeatedDirty) {
-  MapFieldType other(default_entry_);
+  MapFieldType other;
   MakeRepeatedDirty(&other);
 
   map_field_->Swap(&other);
diff --git a/src/google/protobuf/map_proto2_unittest.proto b/src/google/protobuf/map_proto2_unittest.proto
index e9360a5..20d58f9 100644
--- a/src/google/protobuf/map_proto2_unittest.proto
+++ b/src/google/protobuf/map_proto2_unittest.proto
@@ -84,3 +84,8 @@
   map<bool, TestIntIntMap> m_bool = 11;
   map<string, TestIntIntMap> m_string = 12;
 }
+
+// Test maps in submessages.
+message TestSubmessageMaps {
+  optional TestMaps m = 1;
+}
diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc
index 43fe0f4..3fe4451 100644
--- a/src/google/protobuf/map_test.cc
+++ b/src/google/protobuf/map_test.cc
@@ -54,10 +54,13 @@
 #include <google/protobuf/testing/file.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>
+#include <google/protobuf/map_unittest.pb.h>
 #include <google/protobuf/test_util.h>
 #include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/descriptor_database.h>
@@ -70,12 +73,8 @@
 #include <google/protobuf/text_format.h>
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/wire_format_lite_inl.h>
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/tokenizer.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
-#include <google/protobuf/util/time_util.h>
 #include <google/protobuf/util/message_differencer.h>
-#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/util/time_util.h>
 #include <google/protobuf/stubs/substitute.h>
 #include <gmock/gmock.h>
 #include <google/protobuf/testing/googletest.h>
@@ -97,17 +96,15 @@
 
 // Map API Test =====================================================
 
-// Parameterized tests on whether to use old style maps.
-class MapImplTest : public testing::TestWithParam<bool> {
+class MapImplTest : public ::testing::Test {
  protected:
   MapImplTest()
-      : map_ptr_(new Map<int32, int32>(GetParam())),
+      : map_ptr_(new Map<int32, int32>()),
         map_(*map_ptr_),
         const_map_(*map_ptr_) {
     EXPECT_TRUE(map_.empty());
     EXPECT_EQ(0, map_.size());
   }
-  ~MapImplTest() {}
 
   void ExpectSingleElement(int32 key, int32 value) {
     EXPECT_FALSE(map_.empty());
@@ -178,7 +175,7 @@
   const Map<int32, int32>& const_map_;
 };
 
-TEST_P(MapImplTest, OperatorBracket) {
+TEST_F(MapImplTest, OperatorBracket) {
   int32 key = 0;
   int32 value1 = 100;
   int32 value2 = 101;
@@ -192,7 +189,7 @@
   ExpectSingleElement(key, value2);
 }
 
-TEST_P(MapImplTest, OperatorBracketNonExist) {
+TEST_F(MapImplTest, OperatorBracketNonExist) {
   int32 key = 0;
   int32 default_value = 0;
 
@@ -200,7 +197,7 @@
   ExpectSingleElement(key, default_value);
 }
 
-TEST_P(MapImplTest, MutableAt) {
+TEST_F(MapImplTest, MutableAt) {
   int32 key = 0;
   int32 value1 = 100;
   int32 value2 = 101;
@@ -214,15 +211,15 @@
 
 #ifdef PROTOBUF_HAS_DEATH_TEST
 
-TEST_P(MapImplTest, MutableAtNonExistDeathTest) {
+TEST_F(MapImplTest, MutableAtNonExistDeathTest) {
   EXPECT_DEATH(map_.at(0), "");
 }
 
-TEST_P(MapImplTest, ImmutableAtNonExistDeathTest) {
+TEST_F(MapImplTest, ImmutableAtNonExistDeathTest) {
   EXPECT_DEATH(const_map_.at(0), "");
 }
 
-TEST_P(MapImplTest, UsageErrors) {
+TEST_F(MapImplTest, UsageErrors) {
   MapKey key;
   key.SetInt64Value(1);
   EXPECT_DEATH(key.GetUInt64Value(),
@@ -239,23 +236,23 @@
 
 #endif  // PROTOBUF_HAS_DEATH_TEST
 
-TEST_P(MapImplTest, CountNonExist) {
+TEST_F(MapImplTest, CountNonExist) {
   EXPECT_EQ(0, map_.count(0));
 }
 
-TEST_P(MapImplTest, MutableFindNonExist) {
+TEST_F(MapImplTest, MutableFindNonExist) {
   EXPECT_TRUE(map_.end() == map_.find(0));
 }
 
-TEST_P(MapImplTest, ImmutableFindNonExist) {
+TEST_F(MapImplTest, ImmutableFindNonExist) {
   EXPECT_TRUE(const_map_.end() == const_map_.find(0));
 }
 
-TEST_P(MapImplTest, ConstEnd) {
+TEST_F(MapImplTest, ConstEnd) {
   EXPECT_TRUE(const_map_.end() == const_map_.cend());
 }
 
-TEST_P(MapImplTest, GetReferenceFromIterator) {
+TEST_F(MapImplTest, GetReferenceFromIterator) {
   for (int i = 0; i < 10; i++) {
     map_[i] = i;
   }
@@ -278,7 +275,7 @@
   }
 }
 
-TEST_P(MapImplTest, IteratorBasic) {
+TEST_F(MapImplTest, IteratorBasic) {
   map_[0] = 0;
 
   // Default constructible (per forward iterator requirements).
@@ -320,10 +317,9 @@
 // A naive begin() implementation will cause begin() to get slower and slower
 // if one erases elements at the "front" of the hash map, and we'd like to
 // avoid that, as std::unordered_map does.
-TEST_P(MapImplTest, BeginIsFast) {
-  // Disable this test for both new and old implementations.
-  if (/*GetParam()*/true) return;
-  Map<int32, int32> map(false);  // This test uses new-style maps only.
+TEST_F(MapImplTest, BeginIsFast) {
+  if (true) return;  // TODO(gpike): make this less flaky and re-enable it.
+  Map<int32, int32> map;
   const int kTestSize = 250000;
   // Create a random-looking map of size n.  Use non-negative integer keys.
   uint32 frog = 123983;
@@ -371,7 +367,7 @@
 // Try to create kTestSize keys that will land in just a few buckets, and
 // time the insertions, to get a rough estimate of whether an O(n^2) worst case
 // was triggered.  This test is a hacky, but probably better than nothing.
-TEST_P(MapImplTest, HashFlood) {
+TEST_F(MapImplTest, HashFlood) {
   const int kTestSize = 1024;  // must be a power of 2
   std::set<int> s;
   for (int i = 0; s.size() < kTestSize; i++) {
@@ -404,6 +400,22 @@
   EXPECT_LE(x1, x0 * 20);
 }
 
+TEST_F(MapImplTest, CopyIteratorStressTest) {
+  std::vector<Map<int32, int32>::iterator> v;
+  const int kIters = 1e5;
+  for (uint32 i = 0; i < kIters; i++) {
+    int32 key = (3 + i * (5 + i * (-8 + i * (62 + i)))) & 0x77777777;
+    map_[key] = i;
+    v.push_back(map_.find(key));
+  }
+  for (std::vector<Map<int32, int32>::iterator>::const_iterator it = v.begin();
+       it != v.end(); it++) {
+    Map<int32, int32>::iterator i = *it;
+    ASSERT_EQ(i->first, (*it)->first);
+    ASSERT_EQ(i->second, (*it)->second);
+  }
+}
+
 template <typename T, typename U>
 static void TestValidityForAllKeysExcept(int key_to_avoid,
                                          const T& check_map,
@@ -468,11 +480,11 @@
 }
 
 // Create and test an n-element Map, with emphasis on iterator correctness.
-static void StressTestIterators(int n, bool test_old_style_proto2_maps) {
+static void StressTestIterators(int n) {
   GOOGLE_LOG(INFO) << "StressTestIterators " << n;
   GOOGLE_CHECK_GT(n, 0);
   // Create a random-looking map of size n.  Use non-negative integer keys.
-  Map<int, int> m(test_old_style_proto2_maps);
+  Map<int, int> m;
   uint32 frog = 123987 + n;
   int last_key = 0;
   int counter = 0;
@@ -530,10 +542,7 @@
   }
 }
 
-TEST_P(MapImplTest, IteratorInvalidation) {
-  // As multiple underlying hash_map implementations do not follow the
-  // validation requirement, the test is disabled for old-style maps.
-  if (GetParam()) return;
+TEST_F(MapImplTest, IteratorInvalidation) {
   // Create a set of pseudo-random sizes to test.
 #ifndef NDEBUG
   const int kMaxSizeToTest = 100 * 1000;
@@ -555,15 +564,12 @@
   s.insert(3);
   // Now, the real work.
   for (std::set<int>::iterator i = s.begin(); i != s.end(); ++i) {
-    StressTestIterators(*i, GetParam());
+    StressTestIterators(*i);
   }
 }
 
 // Test that erase() revalidates iterators.
-TEST_P(MapImplTest, EraseRevalidates) {
-  // As multiple underlying hash_map implementations do not follow the
-  // validation requirement, the test is disabled for old-style maps.
-  if (GetParam()) return;
+TEST_F(MapImplTest, EraseRevalidates) {
   map_[3] = map_[13] = map_[20] = 0;
   const int initial_size = map_.size();
   EXPECT_EQ(3, initial_size);
@@ -595,7 +601,7 @@
   return true;
 }
 
-TEST_P(MapImplTest, IteratorConstness) {
+TEST_F(MapImplTest, IteratorConstness) {
   map_[0] = 0;
   EXPECT_TRUE(IsConstHelper(*map_.cbegin()));
   EXPECT_TRUE(IsConstHelper(*const_map_.begin()));
@@ -608,14 +614,14 @@
   return false;
 }
 
-TEST_P(MapImplTest, IteratorCategory) {
+TEST_F(MapImplTest, IteratorCategory) {
   EXPECT_TRUE(IsForwardIteratorHelper(
       std::iterator_traits<Map<int, int>::iterator>::iterator_category()));
   EXPECT_TRUE(IsForwardIteratorHelper(std::iterator_traits<
       Map<int, int>::const_iterator>::iterator_category()));
 }
 
-TEST_P(MapImplTest, InsertSingle) {
+TEST_F(MapImplTest, InsertSingle) {
   int32 key = 0;
   int32 value1 = 100;
   int32 value2 = 101;
@@ -640,7 +646,7 @@
   EXPECT_FALSE(result2.second);
 }
 
-TEST_P(MapImplTest, InsertByIterator) {
+TEST_F(MapImplTest, InsertByIterator) {
   int32 key1 = 0;
   int32 key2 = 1;
   int32 value1a = 100;
@@ -663,7 +669,7 @@
   ExpectElements(map1);
 }
 
-TEST_P(MapImplTest, EraseSingleByKey) {
+TEST_F(MapImplTest, EraseSingleByKey) {
   int32 key = 0;
   int32 value = 100;
 
@@ -681,7 +687,7 @@
   EXPECT_EQ(0, map_.erase(key));
 }
 
-TEST_P(MapImplTest, EraseMutipleByKey) {
+TEST_F(MapImplTest, EraseMutipleByKey) {
   // erase in one specific order to trigger corner cases
   for (int i = 0; i < 5; i++) {
     map_[i] = i;
@@ -708,7 +714,7 @@
   EXPECT_TRUE(map_.end() == map_.find(2));
 }
 
-TEST_P(MapImplTest, EraseSingleByIterator) {
+TEST_F(MapImplTest, EraseSingleByIterator) {
   int32 key = 0;
   int32 value = 100;
 
@@ -723,7 +729,7 @@
   EXPECT_TRUE(map_.begin() == map_.end());
 }
 
-TEST_P(MapImplTest, ValidIteratorAfterErase) {
+TEST_F(MapImplTest, ValidIteratorAfterErase) {
   for (int i = 0; i < 10; i++) {
     map_[i] = i;
   }
@@ -743,7 +749,7 @@
   EXPECT_EQ(5, map_.size());
 }
 
-TEST_P(MapImplTest, EraseByIterator) {
+TEST_F(MapImplTest, EraseByIterator) {
   int32 key1 = 0;
   int32 key2 = 1;
   int32 value1 = 100;
@@ -764,7 +770,7 @@
   EXPECT_TRUE(map_.begin() == map_.end());
 }
 
-TEST_P(MapImplTest, Clear) {
+TEST_F(MapImplTest, Clear) {
   int32 key = 0;
   int32 value = 100;
 
@@ -798,16 +804,16 @@
   EXPECT_EQ(value2, other.at(key2));
 }
 
-TEST_P(MapImplTest, CopyConstructorWithArena) {
+TEST_F(MapImplTest, CopyConstructorWithArena) {
   Arena a;
   CopyConstructorHelper(&a, &map_);
 }
 
-TEST_P(MapImplTest, CopyConstructorWithoutArena) {
+TEST_F(MapImplTest, CopyConstructorWithoutArena) {
   CopyConstructorHelper(NULL, &map_);
 }
 
-TEST_P(MapImplTest, IterConstructor) {
+TEST_F(MapImplTest, IterConstructor) {
   int32 key1 = 0;
   int32 key2 = 1;
   int32 value1 = 100;
@@ -817,15 +823,14 @@
   map[key1] = value1;
   map[key2] = value2;
 
-  Map<int32, int32> new_map(map.begin(), map.end(),
-                            GetParam());
+  Map<int32, int32> new_map(map.begin(), map.end());
 
   EXPECT_EQ(2, new_map.size());
   EXPECT_EQ(value1, new_map.at(key1));
   EXPECT_EQ(value2, new_map.at(key2));
 }
 
-TEST_P(MapImplTest, Assigner) {
+TEST_F(MapImplTest, Assigner) {
   int32 key1 = 0;
   int32 key2 = 1;
   int32 value1 = 100;
@@ -837,7 +842,7 @@
 
   map_.insert(map.begin(), map.end());
 
-  Map<int32, int32> other(GetParam());
+  Map<int32, int32> other;
   int32 key_other = 123;
   int32 value_other = 321;
   other[key_other] = value_other;
@@ -855,16 +860,9 @@
   EXPECT_EQ(2, other.size());
   EXPECT_EQ(value1, other.at(key1));
   EXPECT_EQ(value2, other.at(key2));
-
-  // Try assignment to a map with a different choice of "style."
-  Map<int32, int32> m(!GetParam());
-  m = other;
-  EXPECT_EQ(2, m.size());
-  EXPECT_EQ(value1, m.at(key1));
-  EXPECT_EQ(value2, m.at(key2));
 }
 
-TEST_P(MapImplTest, Rehash) {
+TEST_F(MapImplTest, Rehash) {
   const int test_size = 50;
   std::map<int32, int32> reference_map;
   for (int i = 0; i < test_size; i++) {
@@ -881,7 +879,7 @@
   EXPECT_TRUE(map_.empty());
 }
 
-TEST_P(MapImplTest, EqualRange) {
+TEST_F(MapImplTest, EqualRange) {
   int key = 100, key_missing = 101;
   map_[key] = 100;
 
@@ -905,14 +903,14 @@
   EXPECT_TRUE(const_map_.end() == const_range.second);
 }
 
-TEST_P(MapImplTest, ConvertToStdMap) {
+TEST_F(MapImplTest, ConvertToStdMap) {
   map_[100] = 101;
   std::map<int32, int32> std_map(map_.begin(), map_.end());
   EXPECT_EQ(1, std_map.size());
   EXPECT_EQ(101, std_map[100]);
 }
 
-TEST_P(MapImplTest, ConvertToStdVectorOfPairs) {
+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());
@@ -920,8 +918,8 @@
   EXPECT_EQ(101, std_vec[0].second);
 }
 
-TEST_P(MapImplTest, SwapSameStyle) {
-  Map<int32, int32> another(GetParam());  // same old_style_ value
+TEST_F(MapImplTest, SwapBasic) {
+  Map<int32, int32> another;
   map_[9398] = 41999;
   another[9398] = 41999;
   another[8070] = 42056;
@@ -933,23 +931,10 @@
       testing::Pair(9398, 41999)));
 }
 
-TEST_P(MapImplTest, SwapDifferentStyle) {
-  Map<int32, int32> another(!GetParam());  // different old_style_ value
-  map_[9398] = 41999;
-  another[9398] = 41999;
-  another[8070] = 42056;
-  another.swap(map_);
-  EXPECT_THAT(another, testing::UnorderedElementsAre(
-      testing::Pair(9398, 41999)));
-  EXPECT_THAT(map_, testing::UnorderedElementsAre(
-      testing::Pair(8070, 42056),
-      testing::Pair(9398, 41999)));
-}
-
-TEST_P(MapImplTest, SwapArena) {
+TEST_F(MapImplTest, SwapArena) {
   Arena arena1, arena2;
-  Map<int32, int32> m1(&arena1, false);
-  Map<int32, int32> m2(&arena2, false);
+  Map<int32, int32> m1(&arena1);
+  Map<int32, int32> m2(&arena2);
   map_[9398] = 41999;
   m1[9398] = 41999;
   m1[8070] = 42056;
@@ -969,8 +954,6 @@
       testing::Pair(9398, 41999)));
 }
 
-INSTANTIATE_TEST_CASE_P(BoolSequence, MapImplTest, testing::Bool());
-
 // Map Field Reflection Test ========================================
 
 static int Func(int i, int j) {
@@ -2980,6 +2963,27 @@
   TestDeterministicSerialization(t, "golden_message_maps");
 }
 
+TEST(MapSerializationTest, DeterministicSubmessage) {
+  protobuf_unittest::TestSubmessageMaps p;
+  protobuf_unittest::TestMaps t;
+  const string filename = "golden_message_maps";
+  string golden;
+  GOOGLE_CHECK_OK(File::GetContents(
+      TestSourceDir() + "/google/protobuf/testdata/" + filename,
+      &golden, true));
+  t.ParseFromString(golden);
+  *(p.mutable_m()) = t;
+  std::vector<string> v;
+  // Use multiple attempts to increase the chance of a failure if something is
+  // buggy.  For example, each separate copy of a map might use a different
+  // randomly-chosen hash function.
+  const int kAttempts = 10;
+  for (int i = 0; i < kAttempts; i++) {
+    protobuf_unittest::TestSubmessageMaps q(p);
+    ASSERT_EQ(DeterministicSerialization(q), DeterministicSerialization(p));
+  }
+}
+
 // Text Format Test =================================================
 
 TEST(TextFormatMapTest, SerializeAndParse) {
diff --git a/src/google/protobuf/map_test_util_impl.h b/src/google/protobuf/map_test_util_impl.h
index b3ba4e0..ad4d1a3 100644
--- a/src/google/protobuf/map_test_util_impl.h
+++ b/src/google/protobuf/map_test_util_impl.h
@@ -33,14 +33,9 @@
 
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
+#include <gtest/gtest.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
 
@@ -265,23 +260,23 @@
 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());
+  ASSERT_EQ(2, message.map_int32_int32().size());
+  ASSERT_EQ(2, message.map_int64_int64().size());
+  ASSERT_EQ(2, message.map_uint32_uint32().size());
+  ASSERT_EQ(2, message.map_uint64_uint64().size());
+  ASSERT_EQ(2, message.map_sint32_sint32().size());
+  ASSERT_EQ(2, message.map_sint64_sint64().size());
+  ASSERT_EQ(2, message.map_fixed32_fixed32().size());
+  ASSERT_EQ(2, message.map_fixed64_fixed64().size());
+  ASSERT_EQ(2, message.map_sfixed32_sfixed32().size());
+  ASSERT_EQ(2, message.map_sfixed64_sfixed64().size());
+  ASSERT_EQ(2, message.map_int32_float().size());
+  ASSERT_EQ(2, message.map_int32_double().size());
+  ASSERT_EQ(2, message.map_bool_bool().size());
+  ASSERT_EQ(2, message.map_string_string().size());
+  ASSERT_EQ(2, message.map_int32_bytes().size());
+  ASSERT_EQ(2, message.map_int32_enum().size());
+  ASSERT_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));
diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h
index ac987cb..301b37f 100644
--- a/src/google/protobuf/map_type_handler.h
+++ b/src/google/protobuf/map_type_handler.h
@@ -186,9 +186,9 @@
   static inline Type* EnsureMutable(Type** value, Arena* arena);
   // SpaceUsedInMapEntry: Return bytes used by value in MapEntry, excluding
   // those already calculate in sizeof(MapField).
-  static inline int SpaceUsedInMapEntry(const Type* value);
+  static inline size_t SpaceUsedInMapEntryLong(const Type* value);
   // Return bytes used by value in Map.
-  static inline int SpaceUsedInMap(const Type& value);
+  static inline size_t SpaceUsedInMapLong(const Type& value);
   // Assign default value to given instance.
   static inline void AssignDefaultValue(Type** value);
   // Return default instance if value is not initialized when calling const
@@ -224,9 +224,7 @@
     static inline void Write(int field, const MapEntryAccessorType& value,    \
                              io::CodedOutputStream* output);                  \
     static inline uint8* InternalWriteToArray(                                \
-        int field,                                                            \
-        const MapEntryAccessorType& value,                                    \
-        bool deterministic,                                                   \
+        int field, const MapEntryAccessorType& value, bool deterministic,     \
         uint8* target);                                                       \
     static inline uint8* WriteToArray(int field,                              \
                                       const MapEntryAccessorType& value,      \
@@ -242,9 +240,9 @@
     static inline void ClearMaybeByDefaultEnum(TypeOnMemory* value,           \
                                                Arena* arena,                  \
                                                int default_enum);             \
-    static inline int SpaceUsedInMapEntry(const TypeOnMemory& value);         \
-    static inline int SpaceUsedInMap(const TypeOnMemory& value);              \
-    static inline int SpaceUsedInMap(const string& value);                    \
+    static inline size_t SpaceUsedInMapEntryLong(const TypeOnMemory& value);  \
+    static inline size_t SpaceUsedInMapLong(const TypeOnMemory& value);       \
+    static inline size_t SpaceUsedInMapLong(const string& value);             \
     static inline void AssignDefaultValue(TypeOnMemory* value);               \
     static inline const MapEntryAccessorType& DefaultIfNotInitialized(        \
         const TypeOnMemory& value, const TypeOnMemory& default_value);        \
@@ -467,16 +465,15 @@
 }
 
 template <typename Type>
-inline int
-MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
-                        Type>::SpaceUsedInMapEntry(const Type* value) {
-  return value->SpaceUsed();
+inline size_t MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
+                             Type>::SpaceUsedInMapEntryLong(const Type* value) {
+  return value->SpaceUsedLong();
 }
 
 template <typename Type>
-int MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::SpaceUsedInMap(
+size_t MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::SpaceUsedInMapLong(
     const Type& value) {
-  return value.SpaceUsed();
+  return value.SpaceUsedLong();
 }
 
 template <typename Type>
@@ -507,7 +504,7 @@
 template <typename Type>
 inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
                                     Type>::AssignDefaultValue(Type** value) {
-  *value = const_cast<Type*>(&Type::default_instance());
+  *value = const_cast<Type*>(Type::internal_default_instance());
 }
 
 template <typename Type>
@@ -559,19 +556,21 @@
     return value.Get();                                                        \
   }                                                                            \
   template <typename Type>                                                     \
-  inline int                                                                   \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapEntry( \
+  inline size_t                                                                \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType,                             \
+                 Type>::SpaceUsedInMapEntryLong(const TypeOnMemory& value) {   \
+    return sizeof(value);                                                      \
+  }                                                                            \
+  template <typename Type>                                                     \
+  inline size_t                                                                \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapLong(  \
       const TypeOnMemory& value) {                                             \
     return sizeof(value);                                                      \
   }                                                                            \
   template <typename Type>                                                     \
-  inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType,                  \
-                            Type>::SpaceUsedInMap(const TypeOnMemory& value) { \
-    return sizeof(value);                                                      \
-  }                                                                            \
-  template <typename Type>                                                     \
-  inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType,                  \
-                            Type>::SpaceUsedInMap(const string& value) {       \
+  inline size_t                                                                \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapLong(  \
+      const string& value) {                                                   \
     return sizeof(value);                                                      \
   }                                                                            \
   template <typename Type>                                                     \
@@ -647,14 +646,15 @@
     return value;                                                              \
   }                                                                            \
   template <typename Type>                                                     \
-  inline int                                                                   \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapEntry( \
-      const TypeOnMemory& value) {                                             \
+  inline size_t                                                                \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType,                             \
+                 Type>::SpaceUsedInMapEntryLong(const TypeOnMemory& value) {   \
     return 0;                                                                  \
   }                                                                            \
   template <typename Type>                                                     \
-  inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType,                  \
-                            Type>::SpaceUsedInMap(const TypeOnMemory& value) { \
+  inline size_t                                                                \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapLong(  \
+      const TypeOnMemory& value) {                                             \
     return sizeof(Type);                                                       \
   }                                                                            \
   template <typename Type>                                                     \
@@ -663,11 +663,9 @@
     *value = 0;                                                                \
   }                                                                            \
   template <typename Type>                                                     \
-  inline void                                                                  \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType,                             \
-                 Type>::ClearMaybeByDefaultEnum(TypeOnMemory* value,           \
-                                                Arena* arena,                  \
-                                                int default_enum_value) {      \
+  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::         \
+      ClearMaybeByDefaultEnum(TypeOnMemory* value, Arena* arena,               \
+                              int default_enum_value) {                        \
     *value = static_cast<TypeOnMemory>(default_enum_value);                    \
   }                                                                            \
   template <typename Type>                                                     \
@@ -688,11 +686,9 @@
     *value = 0;                                                                \
   }                                                                            \
   template <typename Type>                                                     \
-  inline void                                                                  \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType,                             \
-                 Type>::InitializeMaybeByDefaultEnum(TypeOnMemory* value,      \
-                                                     int default_enum_value,   \
-                                                     Arena* arena) {           \
+  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::         \
+      InitializeMaybeByDefaultEnum(TypeOnMemory* value,                        \
+                                   int default_enum_value, Arena* arena) {     \
     *value = static_cast<TypeOnMemory>(default_enum_value);                    \
   }                                                                            \
   template <typename Type>                                                     \
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc
index 6800e4c..2134f95 100644
--- a/src/google/protobuf/message.cc
+++ b/src/google/protobuf/message.cc
@@ -158,8 +158,8 @@
                 "Must implement one or the other.";
 }
 
-int Message::SpaceUsed() const {
-  return GetReflection()->SpaceUsed(*this);
+size_t Message::SpaceUsedLong() const {
+  return GetReflection()->SpaceUsedLong(*this);
 }
 
 bool Message::SerializeToFileDescriptor(int file_descriptor) const {
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index 4d14584..7d9bb8a 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -245,7 +245,9 @@
   // using reflection (rather than the generated code implementation for
   // ByteSize()). Like ByteSize(), its CPU time is linear in the number of
   // fields defined for the proto.
-  virtual int SpaceUsed() const;
+  virtual size_t SpaceUsedLong() const;
+
+  int SpaceUsed() const { return internal::ToIntSize(SpaceUsedLong()); }
 
   // Debugging & Testing----------------------------------------------
 
@@ -417,7 +419,11 @@
   virtual UnknownFieldSet* MutableUnknownFields(Message* message) const = 0;
 
   // Estimate the amount of memory used by the message object.
-  virtual int SpaceUsed(const Message& message) const = 0;
+  virtual size_t SpaceUsedLong(const Message& message) const = 0;
+
+  int SpaceUsed(const Message& message) const {
+    return internal::ToIntSize(SpaceUsedLong(message));
+  }
 
   // Check if the given non-repeated field is set.
   virtual bool HasField(const Message& message,
diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc
index b8cb3f4..fda84b5 100644
--- a/src/google/protobuf/message_lite.cc
+++ b/src/google/protobuf/message_lite.cc
@@ -222,6 +222,11 @@
 
 // ===================================================================
 
+uint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const {
+  return InternalSerializeWithCachedSizesToArray(
+      io::CodedOutputStream::IsDefaultSerializationDeterministic(), target);
+}
+
 uint8* MessageLite::InternalSerializeWithCachedSizesToArray(
     bool deterministic, uint8* target) const {
   // We only optimize this when using optimize_for = SPEED.  In other cases
diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h
index 5e5ed30..046a736 100644
--- a/src/google/protobuf/message_lite.h
+++ b/src/google/protobuf/message_lite.h
@@ -42,6 +42,7 @@
 #include <climits>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/generated_message_util.h>
 
 
 namespace google {
@@ -248,11 +249,7 @@
   virtual size_t ByteSizeLong() const = 0;
 
   // Legacy ByteSize() API.
-  int ByteSize() const {
-    size_t result = ByteSizeLong();
-    GOOGLE_DCHECK_LE(result, static_cast<size_t>(INT_MAX));
-    return static_cast<int>(result);
-  }
+  int ByteSize() const { return internal::ToIntSize(ByteSizeLong()); }
 
   // Serializes the message without recomputing the size.  The message must not
   // have changed since the last call to ByteSize(), and the value returned by
@@ -260,11 +257,17 @@
   virtual void SerializeWithCachedSizes(
       io::CodedOutputStream* output) const = 0;
 
-  // A version of SerializeWithCachedSizesToArray, below, that does
-  // not guarantee deterministic serialization.
-  virtual uint8* SerializeWithCachedSizesToArray(uint8* target) const {
-    return InternalSerializeWithCachedSizesToArray(false, target);
-  }
+  // Functions below here are not part of the public interface.  It isn't
+  // enforced, but they should be treated as private, and will be private
+  // at some future time.  Unfortunately the implementation of the "friend"
+  // keyword in GCC is broken at the moment, but we expect it will be fixed.
+
+  // Like SerializeWithCachedSizes, but writes directly to *target, returning
+  // a pointer to the byte immediately after the last byte written.  "target"
+  // must point at a byte array of at least ByteSize() bytes.  Whether to use
+  // deterministic serialization, e.g., maps in sorted order, is determined by
+  // CodedOutputStream::IsDefaultSerializationDeterministic().
+  virtual uint8* SerializeWithCachedSizesToArray(uint8* target) const;
 
   // Returns the result of the last call to ByteSize().  An embedded message's
   // size is needed both to serialize it (because embedded messages are
@@ -279,16 +282,6 @@
   // method.)
   virtual int GetCachedSize() const = 0;
 
-  // Functions below here are not part of the public interface.  It isn't
-  // enforced, but they should be treated as private, and will be private
-  // at some future time.  Unfortunately the implementation of the "friend"
-  // keyword in GCC is broken at the moment, but we expect it will be fixed.
-
-  // Like SerializeWithCachedSizes, but writes directly to *target, returning
-  // a pointer to the byte immediately after the last byte written.  "target"
-  // must point at a byte array of at least ByteSize() bytes.  If deterministic
-  // is true then we use deterministic serialization, e.g., map keys are sorted.
-  // FOR INTERNAL USE ONLY!
   virtual uint8* InternalSerializeWithCachedSizesToArray(bool deterministic,
                                                          uint8* target) const;
 
diff --git a/src/google/protobuf/message_unittest.cc b/src/google/protobuf/message_unittest.cc
index c1b05bc..0469f4c 100644
--- a/src/google/protobuf/message_unittest.cc
+++ b/src/google/protobuf/message_unittest.cc
@@ -551,6 +551,17 @@
   ASSERT_EQ(0, dest.repeated_uint64_size());
 }
 
+TEST(MessageTest, IsInitialized) {
+  protobuf_unittest::TestIsInitialized msg;
+  EXPECT_TRUE(msg.IsInitialized());
+  protobuf_unittest::TestIsInitialized::SubMessage* sub_message = msg.mutable_sub_message();
+  EXPECT_TRUE(msg.IsInitialized());
+  protobuf_unittest::TestIsInitialized::SubMessage::SubGroup* sub_group = sub_message->mutable_subgroup();
+  EXPECT_FALSE(msg.IsInitialized());
+  sub_group->set_i(1);
+  EXPECT_TRUE(msg.IsInitialized());
+}
+
 TEST(MessageFactoryTest, GeneratedFactoryLookup) {
   EXPECT_EQ(
     MessageFactory::generated_factory()->GetPrototype(
diff --git a/src/google/protobuf/metadata.h b/src/google/protobuf/metadata.h
index dca1fa4..0a6507c 100644
--- a/src/google/protobuf/metadata.h
+++ b/src/google/protobuf/metadata.h
@@ -38,134 +38,13 @@
 #ifndef GOOGLE_PROTOBUF_METADATA_H__
 #define GOOGLE_PROTOBUF_METADATA_H__
 
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/arena.h>
-#include <google/protobuf/arenastring.h>
-#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/metadata_lite.h>
 #include <google/protobuf/unknown_field_set.h>
 
 namespace google {
 namespace protobuf {
 namespace internal {
 
-// This is the representation for messages that support arena allocation. It
-// uses a tagged pointer to either store the Arena pointer, if there are no
-// unknown fields, or a pointer to a block of memory with both the Arena pointer
-// and the UnknownFieldSet, if there are unknown fields. This optimization
-// allows for "zero-overhead" storage of the Arena pointer, relative to the
-// above baseline implementation.
-//
-// The tagged pointer uses the LSB to disambiguate cases, and uses bit 0 == 0 to
-// indicate an arena pointer and bit 0 == 1 to indicate a UFS+Arena-container
-// pointer.
-template <class T, class Derived>
-class InternalMetadataWithArenaBase {
- public:
-  InternalMetadataWithArenaBase() : ptr_(NULL) {}
-  explicit InternalMetadataWithArenaBase(Arena* arena) : ptr_(arena) {}
-
-  ~InternalMetadataWithArenaBase() {
-    if (have_unknown_fields() && arena() == NULL) {
-      delete PtrValue<Container>();
-    }
-    ptr_ = NULL;
-  }
-
-  GOOGLE_ATTRIBUTE_ALWAYS_INLINE const T& unknown_fields() const {
-    if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) {
-      return PtrValue<Container>()->unknown_fields;
-    } else {
-      return Derived::default_instance();
-    }
-  }
-
-  GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* mutable_unknown_fields() {
-    if (GOOGLE_PREDICT_TRUE(have_unknown_fields())) {
-      return &PtrValue<Container>()->unknown_fields;
-    } else {
-      return mutable_unknown_fields_slow();
-    }
-  }
-
-  GOOGLE_ATTRIBUTE_ALWAYS_INLINE Arena* arena() const {
-    if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) {
-      return PtrValue<Container>()->arena;
-    } else {
-      return PtrValue<Arena>();
-    }
-  }
-
-  GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool have_unknown_fields() const {
-    return PtrTag() == kTagContainer;
-  }
-
-  GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(Derived* other) {
-    // Semantics here are that we swap only the unknown fields, not the arena
-    // pointer. We cannot simply swap ptr_ with other->ptr_ because we need to
-    // maintain our own arena ptr. Also, our ptr_ and other's ptr_ may be in
-    // different states (direct arena pointer vs. container with UFS) so we
-    // cannot simply swap ptr_ and then restore the arena pointers. We reuse
-    // UFS's swap implementation instead.
-    if (have_unknown_fields() || other->have_unknown_fields()) {
-      static_cast<Derived*>(this)->DoSwap(other->mutable_unknown_fields());
-    }
-  }
-
-  GOOGLE_ATTRIBUTE_ALWAYS_INLINE void MergeFrom(const Derived& other) {
-    if (other.have_unknown_fields()) {
-      static_cast<Derived*>(this)->DoMergeFrom(other.unknown_fields());
-    }
-  }
-
-  GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Clear() {
-    if (have_unknown_fields()) {
-      static_cast<Derived*>(this)->DoClear();
-    }
-  }
-
-  GOOGLE_ATTRIBUTE_ALWAYS_INLINE void* raw_arena_ptr() const {
-    return ptr_;
-  }
-
- private:
-  void* ptr_;
-
-  // Tagged pointer implementation.
-  enum {
-    // ptr_ is an Arena*.
-    kTagArena = 0,
-    // ptr_ is a Container*.
-    kTagContainer = 1,
-  };
-  static const intptr_t kPtrTagMask = 1;
-  static const intptr_t kPtrValueMask = ~kPtrTagMask;
-
-  // Accessors for pointer tag and pointer value.
-  GOOGLE_ATTRIBUTE_ALWAYS_INLINE int PtrTag() const {
-    return reinterpret_cast<intptr_t>(ptr_) & kPtrTagMask;
-  }
-
-  template<typename U> U* PtrValue() const {
-    return reinterpret_cast<U*>(
-        reinterpret_cast<intptr_t>(ptr_) & kPtrValueMask);
-  }
-
-  // If ptr_'s tag is kTagContainer, it points to an instance of this struct.
-  struct Container {
-    T unknown_fields;
-    Arena* arena;
-  };
-
-  GOOGLE_ATTRIBUTE_NOINLINE T* mutable_unknown_fields_slow() {
-    Arena* my_arena = arena();
-    Container* container = Arena::Create<Container>(my_arena);
-    ptr_ = reinterpret_cast<void*>(
-        reinterpret_cast<intptr_t>(container) | kTagContainer);
-    container->arena = my_arena;
-    return &(container->unknown_fields);
-  }
-};
-
 class InternalMetadataWithArena
     : public InternalMetadataWithArenaBase<UnknownFieldSet,
                                            InternalMetadataWithArena> {
@@ -192,36 +71,6 @@
   }
 };
 
-// We store unknown fields as a string right now, because there is currently no
-// good interface for reading unknown fields into an ArenaString.  We may want
-// to revisit this to allow unknown fields to be parsed onto the Arena.
-class InternalMetadataWithArenaLite
-    : public InternalMetadataWithArenaBase<string,
-                                           InternalMetadataWithArenaLite> {
- public:
-  InternalMetadataWithArenaLite() {}
-
-  explicit InternalMetadataWithArenaLite(Arena* arena)
-      : InternalMetadataWithArenaBase<string,
-                                           InternalMetadataWithArenaLite>(arena) {}
-
-  void DoSwap(string* other) {
-    mutable_unknown_fields()->swap(*other);
-  }
-
-  void DoMergeFrom(const string& other) {
-    mutable_unknown_fields()->append(other);
-  }
-
-  void DoClear() {
-    mutable_unknown_fields()->clear();
-  }
-
-  static const string& default_instance() {
-    return GetEmptyStringAlreadyInited();
-  }
-};
-
 }  // namespace internal
 }  // namespace protobuf
 
diff --git a/src/google/protobuf/metadata_lite.h b/src/google/protobuf/metadata_lite.h
new file mode 100644
index 0000000..840c02e
--- /dev/null
+++ b/src/google/protobuf/metadata_lite.h
@@ -0,0 +1,193 @@
+// 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_METADATA_LITE_H__
+#define GOOGLE_PROTOBUF_METADATA_LITE_H__
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/generated_message_util.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// This is the representation for messages that support arena allocation. It
+// uses a tagged pointer to either store the Arena pointer, if there are no
+// unknown fields, or a pointer to a block of memory with both the Arena pointer
+// and the UnknownFieldSet, if there are unknown fields. This optimization
+// allows for "zero-overhead" storage of the Arena pointer, relative to the
+// above baseline implementation.
+//
+// The tagged pointer uses the LSB to disambiguate cases, and uses bit 0 == 0 to
+// indicate an arena pointer and bit 0 == 1 to indicate a UFS+Arena-container
+// pointer.
+template <class T, class Derived>
+class InternalMetadataWithArenaBase {
+ public:
+  InternalMetadataWithArenaBase() : ptr_(NULL) {}
+  explicit InternalMetadataWithArenaBase(Arena* arena) : ptr_(arena) {}
+
+  ~InternalMetadataWithArenaBase() {
+    if (have_unknown_fields() && arena() == NULL) {
+      delete PtrValue<Container>();
+    }
+    ptr_ = NULL;
+  }
+
+  GOOGLE_ATTRIBUTE_ALWAYS_INLINE const T& unknown_fields() const {
+    if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) {
+      return PtrValue<Container>()->unknown_fields;
+    } else {
+      return Derived::default_instance();
+    }
+  }
+
+  GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* mutable_unknown_fields() {
+    if (GOOGLE_PREDICT_TRUE(have_unknown_fields())) {
+      return &PtrValue<Container>()->unknown_fields;
+    } else {
+      return mutable_unknown_fields_slow();
+    }
+  }
+
+  GOOGLE_ATTRIBUTE_ALWAYS_INLINE Arena* arena() const {
+    if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) {
+      return PtrValue<Container>()->arena;
+    } else {
+      return PtrValue<Arena>();
+    }
+  }
+
+  GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool have_unknown_fields() const {
+    return PtrTag() == kTagContainer;
+  }
+
+  GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(Derived* other) {
+    // Semantics here are that we swap only the unknown fields, not the arena
+    // pointer. We cannot simply swap ptr_ with other->ptr_ because we need to
+    // maintain our own arena ptr. Also, our ptr_ and other's ptr_ may be in
+    // different states (direct arena pointer vs. container with UFS) so we
+    // cannot simply swap ptr_ and then restore the arena pointers. We reuse
+    // UFS's swap implementation instead.
+    if (have_unknown_fields() || other->have_unknown_fields()) {
+      static_cast<Derived*>(this)->DoSwap(other->mutable_unknown_fields());
+    }
+  }
+
+  GOOGLE_ATTRIBUTE_ALWAYS_INLINE void MergeFrom(const Derived& other) {
+    if (other.have_unknown_fields()) {
+      static_cast<Derived*>(this)->DoMergeFrom(other.unknown_fields());
+    }
+  }
+
+  GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Clear() {
+    if (have_unknown_fields()) {
+      static_cast<Derived*>(this)->DoClear();
+    }
+  }
+
+  GOOGLE_ATTRIBUTE_ALWAYS_INLINE void* raw_arena_ptr() const {
+    return ptr_;
+  }
+
+ private:
+  void* ptr_;
+
+  // Tagged pointer implementation.
+  enum {
+    // ptr_ is an Arena*.
+    kTagArena = 0,
+    // ptr_ is a Container*.
+    kTagContainer = 1,
+  };
+  static const intptr_t kPtrTagMask = 1;
+  static const intptr_t kPtrValueMask = ~kPtrTagMask;
+
+  // Accessors for pointer tag and pointer value.
+  GOOGLE_ATTRIBUTE_ALWAYS_INLINE int PtrTag() const {
+    return reinterpret_cast<intptr_t>(ptr_) & kPtrTagMask;
+  }
+
+  template<typename U> U* PtrValue() const {
+    return reinterpret_cast<U*>(
+        reinterpret_cast<intptr_t>(ptr_) & kPtrValueMask);
+  }
+
+  // If ptr_'s tag is kTagContainer, it points to an instance of this struct.
+  struct Container {
+    T unknown_fields;
+    Arena* arena;
+  };
+
+  GOOGLE_ATTRIBUTE_NOINLINE T* mutable_unknown_fields_slow() {
+    Arena* my_arena = arena();
+    Container* container = Arena::Create<Container>(my_arena);
+    ptr_ = reinterpret_cast<void*>(
+        reinterpret_cast<intptr_t>(container) | kTagContainer);
+    container->arena = my_arena;
+    return &(container->unknown_fields);
+  }
+};
+
+// We store unknown fields as a string right now, because there is currently no
+// good interface for reading unknown fields into an ArenaString.  We may want
+// to revisit this to allow unknown fields to be parsed onto the Arena.
+class InternalMetadataWithArenaLite
+    : public InternalMetadataWithArenaBase<string,
+                                           InternalMetadataWithArenaLite> {
+ public:
+  InternalMetadataWithArenaLite() {}
+
+  explicit InternalMetadataWithArenaLite(Arena* arena)
+      : InternalMetadataWithArenaBase(arena) {}
+
+  void DoSwap(string* other) {
+    mutable_unknown_fields()->swap(*other);
+  }
+
+  void DoMergeFrom(const string& other) {
+    mutable_unknown_fields()->append(other);
+  }
+
+  void DoClear() {
+    mutable_unknown_fields()->clear();
+  }
+
+  static const string& default_instance() {
+    return GetEmptyStringAlreadyInited();
+  }
+};
+
+}  // namespace internal
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_METADATA_LITE_H__
diff --git a/src/google/protobuf/reflection.h b/src/google/protobuf/reflection.h
index d5a6653..fcb9a43 100755
--- a/src/google/protobuf/reflection.h
+++ b/src/google/protobuf/reflection.h
@@ -570,8 +570,8 @@
   typedef RepeatedFieldRefIterator<T> iterator;
   typedef RepeatedFieldAccessor AccessorType;
   typedef string AccessorValueType;
-  typedef string IteratorValueType;
-  typedef string* IteratorPointerType;
+  typedef const string IteratorValueType;
+  typedef const string* IteratorPointerType;
   static const FieldDescriptor::CppType cpp_type =
       FieldDescriptor::CPPTYPE_STRING;
   static const Descriptor* GetMessageFieldDescriptor() {
diff --git a/src/google/protobuf/reflection_ops_unittest.cc b/src/google/protobuf/reflection_ops_unittest.cc
index 8645317..9cedb34 100644
--- a/src/google/protobuf/reflection_ops_unittest.cc
+++ b/src/google/protobuf/reflection_ops_unittest.cc
@@ -41,6 +41,7 @@
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
+
 #include <google/protobuf/stubs/strutil.h>
 
 namespace google {
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index db5893b..074319e 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -51,8 +51,9 @@
 #include <algorithm>
 #endif
 
-#include <string>
 #include <iterator>
+#include <limits>
+#include <string>
 #include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
@@ -76,6 +77,8 @@
 
 namespace internal {
 
+class MergePartialFromCodedStreamHelper;
+
 static const int kMinRepeatedFieldAllocationSize = 4;
 
 // A utility function for logging that doesn't need any template types.
@@ -155,6 +158,7 @@
   // The new element is uninitialized if |Element| is a POD type.
   // Should be called only if Capacity() > Size().
   Element* AddAlreadyReserved();
+  Element* AddNAlreadyReserved(int elements);
   int Capacity() const;
 
   // Like STL resize.  Uses value to fill appended elements.
@@ -216,7 +220,11 @@
 
   // Returns the number of bytes used by the repeated field, excluding
   // sizeof(*this)
-  int SpaceUsedExcludingSelf() const;
+  size_t SpaceUsedExcludingSelfLong() const;
+
+  int SpaceUsedExcludingSelf() const {
+    return internal::ToIntSize(SpaceUsedExcludingSelfLong());
+  }
 
   // Removes the element referenced by position.
   //
@@ -238,6 +246,11 @@
     return GetArenaNoVirtual();
   }
 
+  // For internal use only.
+  //
+  // This is public due to it being called by generated code.
+  inline void InternalSwap(RepeatedField* other);
+
  private:
   static const int kInitialSize = 0;
   // A note on the representation here (see also comment below for
@@ -276,8 +289,6 @@
   // Copy the elements of |from| into |to|.
   void CopyArray(Element* to, const Element* from, int size);
 
-  inline void InternalSwap(RepeatedField* other);
-
   // Internal helper expected by Arena methods.
   inline Arena* GetArenaNoVirtual() const {
     return (rep_ == NULL) ? NULL : rep_->arena;
@@ -303,6 +314,9 @@
       }
     }
   }
+
+  friend class internal::WireFormatLite;
+  const Element* unsafe_data() const;
 };
 
 template<typename Element>
@@ -321,7 +335,8 @@
 // shouldn't be necessary, but our compiler doesn't optimize std::copy very
 // effectively.
 template <typename Element,
-          bool HasTrivialCopy = has_trivial_copy<Element>::value>
+          bool HasTrivialCopy =
+              has_trivial_copy<Element>::value>
 struct ElementCopier {
   void operator()(Element* to, const Element* from, int array_size);
 };
@@ -335,8 +350,8 @@
 // exist on the contained type. In particular, we rely on MergeFrom() existing
 // as a general proxy for the fact that a copy will work, and we also provide a
 // specific override for string*.
-template<typename T>
-struct TypeImplementsMergeBehavior {
+template <typename T>
+struct TypeImplementsMergeBehaviorProbeForMergeFrom {
   typedef char HasMerge;
   typedef long HasNoMerge;
 
@@ -360,8 +375,13 @@
                (sizeof(Check<T>(0)) == sizeof(HasMerge))> type;
 };
 
-template<>
-struct TypeImplementsMergeBehavior< ::std::string > {
+template <typename T, typename = void>
+struct TypeImplementsMergeBehavior :
+    TypeImplementsMergeBehaviorProbeForMergeFrom<T> {};
+
+
+template <>
+struct TypeImplementsMergeBehavior< ::std::string> {
   typedef google::protobuf::internal::true_type type;
 };
 
@@ -379,7 +399,7 @@
 //     static void Merge(const Type& from, Type* to);
 //
 //     // Only needs to be implemented if SpaceUsedExcludingSelf() is called.
-//     static int SpaceUsed(const Type&);
+//     static int SpaceUsedLong(const Type&);
 //   };
 class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
  protected:
@@ -389,10 +409,10 @@
   friend class GeneratedMessageReflection;
 
   // ExtensionSet stores repeated message extensions as
-  // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to
-  // implement SpaceUsed(), and thus need to call SpaceUsedExcludingSelf()
-  // reinterpreting MessageLite as Message.  ExtensionSet also needs to make
-  // use of AddFromCleared(), which is not part of the public interface.
+  // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to implement
+  // SpaceUsedLong(), and thus need to call SpaceUsedExcludingSelfLong()
+  // reinterpreting MessageLite as Message.  ExtensionSet also needs to make use
+  // of AddFromCleared(), which is not part of the public interface.
   friend class ExtensionSet;
 
   // The MapFieldBase implementation needs to call protected methods directly,
@@ -400,6 +420,10 @@
   // subclass.
   friend class MapFieldBase;
 
+  // The table-driven MergePartialFromCodedStream implementation needs to
+  // operate on RepeatedPtrField<MessageLite>.
+  friend class MergePartialFromCodedStreamHelper;
+
   // To parse directly into a proto2 generated class, the upb class GMR_Handlers
   // needs to be able to modify a RepeatedPtrFieldBase directly.
   friend class upb::google_opensource::GMR_Handlers;
@@ -426,7 +450,7 @@
 #if LANG_CXX11
   template <typename TypeHandler>
   void Add(typename TypeHandler::Type&& value,
-           std::enable_if<TypeHandler::Moveable>* dummy = NULL);
+           internal::enable_if<TypeHandler::Moveable>* dummy = NULL);
 #endif
 
   template <typename TypeHandler>
@@ -459,7 +483,7 @@
   void SwapElements(int index1, int index2);
 
   template <typename TypeHandler>
-  int SpaceUsedExcludingSelf() const;
+  size_t SpaceUsedExcludingSelfLong() const;
 
 
   // Advanced memory management --------------------------------------
@@ -583,14 +607,12 @@
 #if LANG_CXX11
   static const bool Moveable = false;
 #endif
+
   static inline GenericType* New(Arena* arena) {
     return ::google::protobuf::Arena::CreateMaybeMessage<Type>(
         arena, static_cast<GenericType*>(0));
   }
-  // We force NewFromPrototype() to be non-inline to reduce code size:
-  // else, several other methods get inlined copies of message types'
-  // constructors.
-  GOOGLE_ATTRIBUTE_NOINLINE static GenericType* NewFromPrototype(
+  static inline GenericType* NewFromPrototype(
       const GenericType* prototype, ::google::protobuf::Arena* arena = NULL);
   static inline void Delete(GenericType* value, Arena* arena) {
     if (arena == NULL) {
@@ -607,8 +629,8 @@
   static inline void Clear(GenericType* value) { value->Clear(); }
   GOOGLE_ATTRIBUTE_NOINLINE static void Merge(const GenericType& from,
                                        GenericType* to);
-  static inline int SpaceUsed(const GenericType& value) {
-    return value.SpaceUsed();
+  static inline size_t SpaceUsedLong(const GenericType& value) {
+    return value.SpaceUsedLong();
   }
   static inline const Type& default_instance() {
     return Type::default_instance();
@@ -626,11 +648,9 @@
   to->MergeFrom(from);
 }
 
-// NewFromPrototype() and Merge() cannot be defined here; if they're declared
-// inline the compiler will complain about not matching GOOGLE_ATTRIBUTE_NOINLINE
-// above, and if not, compilation will result in multiple definitions.  These
-// are therefore declared as specializations here and defined in
-// message_lite.cc.
+// NewFromPrototype() and Merge() are not defined inline here, as we will need
+// to do a virtual function dispatch anyways to go from Message* to call
+// New/Merge.
 template<>
 MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
     const MessageLite* prototype, google::protobuf::Arena* arena);
@@ -708,7 +728,7 @@
     return Arena::Create<string>(arena);
   }
 #if LANG_CXX11
-  static inline string* New(Arena* arena, std::string&& value) {
+  static inline string* New(Arena* arena, string&& value) {
     return Arena::Create<string>(arena, std::move(value));
   }
 #endif
@@ -732,12 +752,11 @@
   static inline const Type& default_instance() {
     return ::google::protobuf::internal::GetEmptyString();
   }
-  static int SpaceUsed(const string& value)  {
-    return static_cast<int>(sizeof(value)) + StringSpaceUsedExcludingSelf(value);
+  static size_t SpaceUsedLong(const string& value)  {
+    return sizeof(value) + StringSpaceUsedExcludingSelfLong(value);
   }
 };
 
-
 }  // namespace internal
 
 // RepeatedPtrField is like RepeatedField, but used for repeated strings or
@@ -842,10 +861,11 @@
 
   // Custom STL-like iterator that iterates over and returns the underlying
   // pointers to Element rather than Element itself.
-  typedef internal::RepeatedPtrOverPtrsIterator<Element, void*>
-  pointer_iterator;
-  typedef internal::RepeatedPtrOverPtrsIterator<const Element, const void*>
-  const_pointer_iterator;
+  typedef internal::RepeatedPtrOverPtrsIterator<Element*, void*>
+      pointer_iterator;
+  typedef internal::RepeatedPtrOverPtrsIterator<const Element* const,
+                                                const void* const>
+      const_pointer_iterator;
   pointer_iterator pointer_begin();
   const_pointer_iterator pointer_begin() const;
   pointer_iterator pointer_end();
@@ -853,7 +873,11 @@
 
   // Returns (an estimate of) the number of bytes used by the repeated field,
   // excluding sizeof(*this).
-  int SpaceUsedExcludingSelf() const;
+  size_t SpaceUsedExcludingSelfLong() const;
+
+  int SpaceUsedExcludingSelf() const {
+    return internal::ToIntSize(SpaceUsedExcludingSelfLong());
+  }
 
   // Advanced memory management --------------------------------------
   // When hardcore memory management becomes necessary -- as it sometimes
@@ -970,6 +994,11 @@
     return GetArenaNoVirtual();
   }
 
+  // For internal use only.
+  //
+  // This is public due to it being called by generated code.
+  using RepeatedPtrFieldBase::InternalSwap;
+
  private:
   // Note:  RepeatedPtrField SHOULD NOT be subclassed by users.
   class TypeHandler;
@@ -1089,6 +1118,14 @@
 }
 
 template<typename Element>
+inline Element* RepeatedField<Element>::AddNAlreadyReserved(int elements) {
+  GOOGLE_DCHECK_LE(current_size_ + elements, total_size_);
+  Element* ret = &rep_->elements[current_size_];
+  current_size_ += elements;
+  return ret;
+}
+
+template<typename Element>
 inline void RepeatedField<Element>::Resize(int new_size, const Element& value) {
   GOOGLE_DCHECK_GE(new_size, 0);
   if (new_size > current_size_) {
@@ -1208,9 +1245,17 @@
   return rep_ ? rep_->elements : NULL;
 }
 
+template <typename Element>
+inline const Element* RepeatedField<Element>::unsafe_data() const {
+  GOOGLE_DCHECK(rep_);
+  return rep_->elements;
+}
 
 template <typename Element>
 inline void RepeatedField<Element>::InternalSwap(RepeatedField* other) {
+  GOOGLE_DCHECK(this != other);
+  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
+
   std::swap(rep_, other->rep_);
   std::swap(current_size_, other->current_size_);
   std::swap(total_size_, other->total_size_);
@@ -1219,7 +1264,7 @@
 template <typename Element>
 void RepeatedField<Element>::Swap(RepeatedField* other) {
   if (this == other) return;
-  if (GetArenaNoVirtual() ==  other->GetArenaNoVirtual()) {
+  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
     InternalSwap(other);
   } else {
     RepeatedField<Element> temp(other->GetArenaNoVirtual());
@@ -1232,7 +1277,6 @@
 template <typename Element>
 void RepeatedField<Element>::UnsafeArenaSwap(RepeatedField* other) {
   if (this == other) return;
-  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
   InternalSwap(other);
 }
 
@@ -1274,9 +1318,8 @@
 }
 
 template <typename Element>
-inline int RepeatedField<Element>::SpaceUsedExcludingSelf() const {
-  return rep_ ?
-      (total_size_ * sizeof(Element) + kRepHeaderSize) : 0;
+inline size_t RepeatedField<Element>::SpaceUsedExcludingSelfLong() const {
+  return rep_ ? (total_size_ * sizeof(Element) + kRepHeaderSize) : 0;
 }
 
 // Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant
@@ -1288,9 +1331,9 @@
   Arena* arena = GetArenaNoVirtual();
   new_size = std::max(google::protobuf::internal::kMinRepeatedFieldAllocationSize,
                       std::max(total_size_ * 2, new_size));
-  GOOGLE_CHECK_LE(static_cast<size_t>(new_size),
-           (std::numeric_limits<size_t>::max() - kRepHeaderSize) /
-           sizeof(Element))
+  GOOGLE_DCHECK_LE(
+      static_cast<size_t>(new_size),
+      (std::numeric_limits<size_t>::max() - kRepHeaderSize) / sizeof(Element))
       << "Requested size is too large to fit into size_t.";
   size_t bytes = kRepHeaderSize + sizeof(Element) * new_size;
   if (arena == NULL) {
@@ -1476,9 +1519,10 @@
 template <typename TypeHandler>
 inline void RepeatedPtrFieldBase::Add(
     typename TypeHandler::Type&& value,
-    std::enable_if<TypeHandler::Moveable>*) {
+    internal::enable_if<TypeHandler::Moveable>*) {
   if (rep_ != NULL && current_size_ < rep_->allocated_size) {
-    cast<TypeHandler>(rep_->elements[current_size_++]) = std::move(value);
+    *cast<TypeHandler>(rep_->elements[current_size_++]) = std::move(value);
+    return;
   }
   if (!rep_ || rep_->allocated_size == total_size_) {
     Reserve(total_size_ + 1);
@@ -1606,11 +1650,11 @@
 }
 
 template <typename TypeHandler>
-inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const {
-  int allocated_bytes = total_size_ * sizeof(void*);
+inline size_t RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong() const {
+  size_t allocated_bytes = total_size_ * sizeof(void*);
   if (rep_ != NULL) {
     for (int i = 0; i < rep_->allocated_size; ++i) {
-      allocated_bytes += TypeHandler::SpaceUsed(
+      allocated_bytes += TypeHandler::SpaceUsedLong(
           *cast<TypeHandler>(rep_->elements[i]));
     }
     allocated_bytes += kRepHeaderSize;
@@ -1819,7 +1863,6 @@
     : public internal::StringTypeHandler {
 };
 
-
 template <typename Element>
 inline RepeatedPtrField<Element>::RepeatedPtrField()
   : RepeatedPtrFieldBase() {}
@@ -2036,7 +2079,6 @@
 template <typename Element>
 inline void RepeatedPtrField<Element>::UnsafeArenaSwap(
     RepeatedPtrField* other) {
-  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
   if (this == other)
       return;
   RepeatedPtrFieldBase::InternalSwap(other);
@@ -2053,8 +2095,8 @@
 }
 
 template <typename Element>
-inline int RepeatedPtrField<Element>::SpaceUsedExcludingSelf() const {
-  return RepeatedPtrFieldBase::SpaceUsedExcludingSelf<TypeHandler>();
+inline size_t RepeatedPtrField<Element>::SpaceUsedExcludingSelfLong() const {
+  return RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong<TypeHandler>();
 }
 
 template <typename Element>
@@ -2212,18 +2254,17 @@
 // the array.
 // The VoidPtr template parameter holds the type-agnostic pointer value
 // referenced by the iterator.  It should either be "void *" for a mutable
-// iterator, or "const void *" for a constant iterator.
-template<typename Element, typename VoidPtr>
+// iterator, or "const void* const" for a constant iterator.
+template <typename Element, typename VoidPtr>
 class RepeatedPtrOverPtrsIterator
-    : public std::iterator<std::random_access_iterator_tag, Element*> {
+    : public std::iterator<std::random_access_iterator_tag, Element> {
  public:
   typedef RepeatedPtrOverPtrsIterator<Element, VoidPtr> iterator;
-  typedef std::iterator<
-          std::random_access_iterator_tag, Element*> superclass;
+  typedef std::iterator<std::random_access_iterator_tag, Element> superclass;
 
   // Shadow the value_type in std::iterator<> because const_iterator::value_type
   // needs to be T, not const T.
-  typedef typename remove_const<Element*>::type value_type;
+  typedef typename remove_const<Element>::type value_type;
 
   // Let the compiler know that these are type names, so we don't have to
   // write "typename" in front of them everywhere.
@@ -2235,7 +2276,7 @@
   explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {}
 
   // dereferenceable
-  reference operator*() const { return *reinterpret_cast<Element**>(it_); }
+  reference operator*() const { return *reinterpret_cast<Element*>(it_); }
   pointer   operator->() const { return &(operator*()); }
 
   // {inc,dec}rementable
@@ -2291,6 +2332,9 @@
 };
 
 void RepeatedPtrFieldBase::InternalSwap(RepeatedPtrFieldBase* other) {
+  GOOGLE_DCHECK(this != other);
+  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
+
   std::swap(rep_, other->rep_);
   std::swap(current_size_, other->current_size_);
   std::swap(total_size_, other->total_size_);
@@ -2337,7 +2381,7 @@
 template <typename Element>
 inline typename RepeatedPtrField<Element>::const_pointer_iterator
 RepeatedPtrField<Element>::pointer_begin() const {
-  return const_pointer_iterator(const_cast<const void**>(raw_mutable_data()));
+  return const_pointer_iterator(const_cast<const void* const*>(raw_data()));
 }
 template <typename Element>
 inline typename RepeatedPtrField<Element>::pointer_iterator
@@ -2348,7 +2392,7 @@
 inline typename RepeatedPtrField<Element>::const_pointer_iterator
 RepeatedPtrField<Element>::pointer_end() const {
   return const_pointer_iterator(
-      const_cast<const void**>(raw_mutable_data() + size()));
+      const_cast<const void* const*>(raw_data() + size()));
 }
 
 
diff --git a/src/google/protobuf/repeated_field_reflection_unittest.cc b/src/google/protobuf/repeated_field_reflection_unittest.cc
index fcebe5c..fd46656 100644
--- a/src/google/protobuf/repeated_field_reflection_unittest.cc
+++ b/src/google/protobuf/repeated_field_reflection_unittest.cc
@@ -189,8 +189,8 @@
   }
 }
 
-template<typename Ref, typename MessageType, typename ValueType>
-void TestRepeatedFieldRefIterator(
+template <typename Ref, typename MessageType, typename ValueType>
+void TestRepeatedFieldRefIteratorForPrimitive(
     const Ref& handle, const MessageType& message,
     ValueType (MessageType::*GetFunc)(int) const) {
   int index = 0;
@@ -202,6 +202,21 @@
   EXPECT_EQ(handle.size(), index);
 }
 
+template <typename MessageType, typename ValueType>
+void TestRepeatedFieldRefIteratorForString(
+    const RepeatedFieldRef<string>& handle, const MessageType& message,
+    ValueType (MessageType::*GetFunc)(int) const) {
+  int index = 0;
+  for (typename RepeatedFieldRef<string>::const_iterator it = handle.begin();
+       it != handle.end(); ++it) {
+    // Test both operator* and operator->
+    EXPECT_EQ((message.*GetFunc)(index), *it);
+    EXPECT_EQ((message.*GetFunc)(index).size(), it->size());
+    ++index;
+  }
+  EXPECT_EQ(handle.size(), index);
+}
+
 TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForRegularFields) {
   TestAllTypes message;
   const Reflection* refl = message.GetReflection();
@@ -312,12 +327,12 @@
   }
 
   // Test iterators.
-  TestRepeatedFieldRefIterator(rf_int32, message,
-                               &TestAllTypes::repeated_int32);
-  TestRepeatedFieldRefIterator(rf_double, message,
-                               &TestAllTypes::repeated_double);
-  TestRepeatedFieldRefIterator(rf_string, message,
-                               &TestAllTypes::repeated_string);
+  TestRepeatedFieldRefIteratorForPrimitive(rf_int32, message,
+                                           &TestAllTypes::repeated_int32);
+  TestRepeatedFieldRefIteratorForPrimitive(rf_double, message,
+                                           &TestAllTypes::repeated_double);
+  TestRepeatedFieldRefIteratorForString(rf_string, message,
+                                        &TestAllTypes::repeated_string);
 
   // Test iterators for message fields.
   typedef RepeatedFieldRef<ForeignMessage>::iterator MessageIterator;
@@ -474,10 +489,10 @@
     EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(i));
   }
 
-  TestRepeatedFieldRefIterator(enum_ref, message,
-                               &TestAllTypes::repeated_nested_enum);
-  TestRepeatedFieldRefIterator(int32_ref, message,
-                               &TestAllTypes::repeated_nested_enum);
+  TestRepeatedFieldRefIteratorForPrimitive(enum_ref, message,
+                                           &TestAllTypes::repeated_nested_enum);
+  TestRepeatedFieldRefIteratorForPrimitive(int32_ref, message,
+                                           &TestAllTypes::repeated_nested_enum);
 
   // Test Add()
   mutable_enum_ref.Add(TestAllTypes::FOO);
diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc
index ec1074c..043cc74 100644
--- a/src/google/protobuf/repeated_field_unittest.cc
+++ b/src/google/protobuf/repeated_field_unittest.cc
@@ -45,9 +45,9 @@
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/unittest.pb.h>
-#include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
+#include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/stl_util.h>
 
 namespace google {
diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc
index 50e17da..3244444 100644
--- a/src/google/protobuf/source_context.pb.cc
+++ b/src/google/protobuf/source_context.pb.cc
@@ -31,11 +31,26 @@
 
 }  // namespace
 
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+    const TableStruct::entries[] = {
+  {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+    const TableStruct::aux[] = {
+  ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+    TableStruct::schema[] = {
+  { NULL, NULL, 0, -1, -1, false },
+};
+
 const ::google::protobuf::uint32 TableStruct::offsets[] = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceContext, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceContext, file_name_),
 };
 
@@ -165,7 +180,7 @@
 }
 const ::google::protobuf::Descriptor* SourceContext::descriptor() {
   protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::file_level_metadata[0].descriptor;
+  return protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const SourceContext& SourceContext::default_instance() {
@@ -236,6 +251,9 @@
 void SourceContext::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.SourceContext)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string file_name = 1;
   if (this->file_name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -251,8 +269,10 @@
 
 ::google::protobuf::uint8* SourceContext::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceContext)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string file_name = 1;
   if (this->file_name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -305,6 +325,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceContext)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.file_name().size() > 0) {
 
     file_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.file_name_);
@@ -340,7 +363,7 @@
 
 ::google::protobuf::Metadata SourceContext::GetMetadata() const {
   protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::file_level_metadata[0];
+  return protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -368,6 +391,7 @@
 }
 #endif
 void SourceContext::set_file_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.SourceContext.file_name)
diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h
index 1088838..5eeef14 100644
--- a/src/google/protobuf/source_context.pb.h
+++ b/src/google/protobuf/source_context.pb.h
@@ -22,6 +22,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/message.h>
@@ -43,6 +44,9 @@
 namespace protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto {
 // Internal implementation detail -- do not call these.
 struct LIBPROTOBUF_EXPORT TableStruct {
+  static const ::google::protobuf::internal::ParseTableField entries[];
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+  static const ::google::protobuf::internal::ParseTable schema[];
   static const ::google::protobuf::uint32 offsets[];
   static void InitDefaultsImpl();
   static void Shutdown();
@@ -72,6 +76,8 @@
     return reinterpret_cast<const SourceContext*>(
                &_SourceContext_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    0;
 
   void Swap(SourceContext* other);
 
@@ -94,11 +100,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -140,7 +141,7 @@
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   ::google::protobuf::internal::ArenaStringPtr file_name_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::TableStruct;
 };
 // ===================================================================
 
@@ -172,6 +173,7 @@
 }
 #endif
 inline void SourceContext::set_file_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.SourceContext.file_name)
diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc
index a1aa51e..825810b 100644
--- a/src/google/protobuf/struct.pb.cc
+++ b/src/google/protobuf/struct.pb.cc
@@ -19,6 +19,8 @@
 
 namespace google {
 namespace protobuf {
+class Struct_FieldsEntryDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Struct::Struct_FieldsEntry> {
+} _Struct_FieldsEntry_default_instance_;
 class StructDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Struct> {
 } _Struct_default_instance_;
 class ValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Value> {
@@ -43,37 +45,58 @@
 
 }  // namespace
 
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+    const TableStruct::entries[] = {
+  {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+    const TableStruct::aux[] = {
+  ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+    TableStruct::schema[] = {
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+};
+
 const ::google::protobuf::uint32 TableStruct::offsets[] = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Struct, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Struct, fields_),
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Value, _internal_metadata_),
   ~0u,  // no _extensions_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Value, _oneof_case_[0]),
-  PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), null_value_),
-  PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), number_value_),
-  PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), string_value_),
-  PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), bool_value_),
-  PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), struct_value_),
-  PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), list_value_),
+  ~0u,  // no _weak_field_map_
+  GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), null_value_),
+  GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), number_value_),
+  GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), string_value_),
+  GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), bool_value_),
+  GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), struct_value_),
+  GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), list_value_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Value, kind_),
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListValue, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListValue, values_),
 };
 
 static const ::google::protobuf::internal::MigrationSchema schemas[] = {
   { 0, -1, sizeof(Struct)},
-  { 5, -1, sizeof(Value)},
-  { 16, -1, sizeof(ListValue)},
+  { 6, -1, sizeof(Value)},
+  { 18, -1, sizeof(ListValue)},
 };
 
 static ::google::protobuf::Message const * const file_default_instances[] = {
+  reinterpret_cast<const ::google::protobuf::Message*>(&_Struct_FieldsEntry_default_instance_),
   reinterpret_cast<const ::google::protobuf::Message*>(&_Struct_default_instance_),
   reinterpret_cast<const ::google::protobuf::Message*>(&_Value_default_instance_),
   reinterpret_cast<const ::google::protobuf::Message*>(&_ListValue_default_instance_),
@@ -87,6 +110,7 @@
   AssignDescriptors(
       "google/protobuf/struct.proto", schemas, file_default_instances, TableStruct::offsets, factory,
       file_level_metadata, file_level_enum_descriptors, NULL);
+file_level_metadata[0].reflection = Struct::Struct_FieldsEntry::CreateReflection(file_level_metadata[0].descriptor, _Struct_FieldsEntry_default_instance_.get_mutable());
 }
 
 void protobuf_AssignDescriptorsOnce() {
@@ -98,16 +122,6 @@
 void protobuf_RegisterTypes(const ::std::string&) {
   protobuf_AssignDescriptorsOnce();
   ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 4);
-  const ::google::protobuf::Descriptor* Struct_FieldsEntry_descriptor = protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[0].descriptor;
-  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
-        Struct_FieldsEntry_descriptor,
-        ::google::protobuf::internal::MapEntry<
-            ::std::string,
-            ::google::protobuf::Value,
-            ::google::protobuf::internal::WireFormatLite::TYPE_STRING,
-            ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE,
-            0>::CreateDefaultInstance(
-                Struct_FieldsEntry_descriptor));
 }
 
 }  // namespace
@@ -125,9 +139,12 @@
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   ::google::protobuf::internal::InitProtobufDefaults();
+  _Struct_FieldsEntry_default_instance_.DefaultConstruct();
   _Struct_default_instance_.DefaultConstruct();
   _Value_default_instance_.DefaultConstruct();
   _ListValue_default_instance_.DefaultConstruct();
+  _Struct_FieldsEntry_default_instance_.get_mutable()->set_default_instance(_Struct_FieldsEntry_default_instance_.get_mutable());
+  _Struct_FieldsEntry_default_instance_.get_mutable()->InitAsDefaultInstance();
   _Value_default_instance_.null_value_ = 0;
   _Value_default_instance_.number_value_ = 0;
   _Value_default_instance_.string_value_.UnsafeSetDefault(
@@ -200,6 +217,20 @@
 
 // ===================================================================
 
+Struct::Struct_FieldsEntry::Struct_FieldsEntry() {}
+Struct::Struct_FieldsEntry::Struct_FieldsEntry(::google::protobuf::Arena* arena) : SuperType(arena) {}
+::google::protobuf::Metadata Struct::Struct_FieldsEntry::GetMetadata() const {
+  protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
+  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[0];
+}
+void Struct::Struct_FieldsEntry::MergeFrom(
+    const ::google::protobuf::Message& other) {
+  ::google::protobuf::Message::MergeFrom(other);
+}
+void Struct::Struct_FieldsEntry::MergeFrom(const Struct_FieldsEntry& other) {
+  MergeFromInternal(other);
+}
+
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
 #endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
@@ -233,21 +264,11 @@
       _internal_metadata_(NULL),
       _cached_size_(0) {
   _internal_metadata_.MergeFrom(from._internal_metadata_);
-  const ::google::protobuf::Descriptor*& Struct_FieldsEntry_descriptor = protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[0].descriptor;
-  fields_.SetAssignDescriptorCallback(
-      protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce);
-  fields_.SetEntryDescriptor(
-      &Struct_FieldsEntry_descriptor);
   fields_.MergeFrom(from.fields_);
   // @@protoc_insertion_point(copy_constructor:google.protobuf.Struct)
 }
 
 void Struct::SharedCtor() {
-  const ::google::protobuf::Descriptor*& Struct_FieldsEntry_descriptor = protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[0].descriptor;
-  fields_.SetAssignDescriptorCallback(
-      protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce);
-  fields_.SetEntryDescriptor(
-      &Struct_FieldsEntry_descriptor);
   _cached_size_ = 0;
 }
 
@@ -277,7 +298,7 @@
 }
 const ::google::protobuf::Descriptor* Struct::descriptor() {
   protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[1].descriptor;
+  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const Struct& Struct::default_instance() {
@@ -308,8 +329,8 @@
       case 1: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(10u)) {
-          DO_(input->IncrementRecursionDepth());
           Struct_FieldsEntry::Parser< ::google::protobuf::internal::MapField<
+              Struct_FieldsEntry,
               ::std::string, ::google::protobuf::Value,
               ::google::protobuf::internal::WireFormatLite::TYPE_STRING,
               ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE,
@@ -324,7 +345,6 @@
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -352,6 +372,9 @@
 void Struct::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Struct)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // map<string, .google.protobuf.Value> fields = 1;
   if (!this->fields().empty()) {
     typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_pointer
@@ -412,8 +435,10 @@
 
 ::google::protobuf::uint8* Struct::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Struct)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // map<string, .google.protobuf.Value> fields = 1;
   if (!this->fields().empty()) {
     typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_pointer
@@ -527,6 +552,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Struct)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   fields_.MergeFrom(from.fields_);
 }
 
@@ -574,7 +602,7 @@
 
 ::google::protobuf::Metadata Struct::GetMetadata() const {
   protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[1];
+  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -701,7 +729,7 @@
 }
 const ::google::protobuf::Descriptor* Value::descriptor() {
   protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[2].descriptor;
+  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const Value& Value::default_instance() {
@@ -877,6 +905,9 @@
 void Value::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Value)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // .google.protobuf.NullValue null_value = 1;
   if (has_null_value()) {
     ::google::protobuf::internal::WireFormatLite::WriteEnum(
@@ -920,8 +951,10 @@
 
 ::google::protobuf::uint8* Value::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Value)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // .google.protobuf.NullValue null_value = 1;
   if (has_null_value()) {
     target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
@@ -953,14 +986,14 @@
   if (has_struct_value()) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        5, *kind_.struct_value_, false, target);
+        5, *kind_.struct_value_, deterministic, target);
   }
 
   // .google.protobuf.ListValue list_value = 6;
   if (has_list_value()) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        6, *kind_.list_value_, false, target);
+        6, *kind_.list_value_, deterministic, target);
   }
 
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Value)
@@ -1039,6 +1072,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Value)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   switch (from.kind_case()) {
     case kNullValue: {
       set_null_value(from.null_value());
@@ -1115,7 +1151,7 @@
 
 ::google::protobuf::Metadata Value::GetMetadata() const {
   protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[2];
+  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1211,6 +1247,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value)
 }
 void Value::set_string_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   if (!has_string_value()) {
     clear_kind();
     set_has_string_value();
@@ -1568,7 +1605,7 @@
 }
 const ::google::protobuf::Descriptor* ListValue::descriptor() {
   protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[3].descriptor;
+  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const ListValue& ListValue::default_instance() {
@@ -1599,13 +1636,11 @@
       case 1: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(10u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_values()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -1633,6 +1668,9 @@
 void ListValue::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.ListValue)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.Value values = 1;
   for (unsigned int i = 0, n = this->values_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
@@ -1644,13 +1682,15 @@
 
 ::google::protobuf::uint8* ListValue::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ListValue)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.Value values = 1;
   for (unsigned int i = 0, n = this->values_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        1, this->values(i), false, target);
+        1, this->values(i), deterministic, target);
   }
 
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ListValue)
@@ -1698,6 +1738,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ListValue)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   values_.MergeFrom(from.values_);
 }
 
@@ -1739,13 +1782,13 @@
   InternalSwap(other);
 }
 void ListValue::InternalSwap(ListValue* other) {
-  values_.UnsafeArenaSwap(&other->values_);
+  values_.InternalSwap(&other->values_);
   std::swap(_cached_size_, other->_cached_size_);
 }
 
 ::google::protobuf::Metadata ListValue::GetMetadata() const {
   protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[3];
+  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h
index 043f0c3..816aa79 100644
--- a/src/google/protobuf/struct.pb.h
+++ b/src/google/protobuf/struct.pb.h
@@ -22,12 +22,13 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/message.h>
 #include <google/protobuf/repeated_field.h>  // IWYU pragma: export
 #include <google/protobuf/extension_set.h>  // IWYU pragma: export
-#include <google/protobuf/map.h>
+#include <google/protobuf/map.h>  // IWYU pragma: export
 #include <google/protobuf/map_field_inl.h>
 #include <google/protobuf/generated_enum_reflection.h>
 #include <google/protobuf/unknown_field_set.h>
@@ -40,6 +41,9 @@
 class Struct;
 class StructDefaultTypeInternal;
 LIBPROTOBUF_EXPORT extern StructDefaultTypeInternal _Struct_default_instance_;
+class Struct_FieldsEntry;
+class Struct_FieldsEntryDefaultTypeInternal;
+LIBPROTOBUF_EXPORT extern Struct_FieldsEntryDefaultTypeInternal _Struct_FieldsEntry_default_instance_;
 class Value;
 class ValueDefaultTypeInternal;
 LIBPROTOBUF_EXPORT extern ValueDefaultTypeInternal _Value_default_instance_;
@@ -52,6 +56,9 @@
 namespace protobuf_google_2fprotobuf_2fstruct_2eproto {
 // Internal implementation detail -- do not call these.
 struct LIBPROTOBUF_EXPORT TableStruct {
+  static const ::google::protobuf::internal::ParseTableField entries[];
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+  static const ::google::protobuf::internal::ParseTable schema[];
   static const ::google::protobuf::uint32 offsets[];
   static void InitDefaultsImpl();
   static void Shutdown();
@@ -110,6 +117,8 @@
     return reinterpret_cast<const Struct*>(
                &_Struct_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    1;
 
   void UnsafeArenaSwap(Struct* other);
   void Swap(Struct* other);
@@ -133,11 +142,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -181,19 +185,34 @@
   friend class ::google::protobuf::Arena;
   typedef void InternalArenaConstructable_;
   typedef void DestructorSkippable_;
-  typedef ::google::protobuf::internal::MapEntryLite<
+  public:
+  class Struct_FieldsEntry : public ::google::protobuf::internal::MapEntry<Struct_FieldsEntry, 
       ::std::string, ::google::protobuf::Value,
       ::google::protobuf::internal::WireFormatLite::TYPE_STRING,
       ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE,
-      0 >
-      Struct_FieldsEntry;
+      0 > {
+  public:
+    typedef ::google::protobuf::internal::MapEntry<Struct_FieldsEntry, 
+      ::std::string, ::google::protobuf::Value,
+      ::google::protobuf::internal::WireFormatLite::TYPE_STRING,
+      ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE,
+      0 > SuperType;
+    Struct_FieldsEntry();
+    Struct_FieldsEntry(::google::protobuf::Arena* arena);
+    void MergeFrom(const ::google::protobuf::Message& other) PROTOBUF_FINAL;
+    void MergeFrom(const Struct_FieldsEntry& other);
+    static const Message* internal_default_instance() { return reinterpret_cast<const Message*>(&_Struct_FieldsEntry_default_instance_); }
+    ::google::protobuf::Metadata GetMetadata() const;
+  };
   ::google::protobuf::internal::MapField<
+      Struct_FieldsEntry,
       ::std::string, ::google::protobuf::Value,
       ::google::protobuf::internal::WireFormatLite::TYPE_STRING,
       ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE,
       0 > fields_;
+  private:
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fstruct_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fstruct_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
 
@@ -232,6 +251,8 @@
     return reinterpret_cast<const Value*>(
                &_Value_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    2;
 
   void UnsafeArenaSwap(Value* other);
   void Swap(Value* other);
@@ -255,11 +276,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -396,7 +412,7 @@
   mutable int _cached_size_;
   ::google::protobuf::uint32 _oneof_case_[1];
 
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fstruct_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fstruct_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
 
@@ -425,6 +441,8 @@
     return reinterpret_cast<const ListValue*>(
                &_ListValue_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    3;
 
   void UnsafeArenaSwap(ListValue* other);
   void Swap(ListValue* other);
@@ -448,11 +466,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -500,7 +513,7 @@
   typedef void DestructorSkippable_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value > values_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fstruct_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fstruct_2eproto::TableStruct;
 };
 // ===================================================================
 
@@ -624,6 +637,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value)
 }
 inline void Value::set_string_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   if (!has_string_value()) {
     clear_kind();
     set_has_string_value();
diff --git a/src/google/protobuf/test_util_lite.cc b/src/google/protobuf/test_util_lite.cc
index 388c0cb..79c5abe 100644
--- a/src/google/protobuf/test_util_lite.cc
+++ b/src/google/protobuf/test_util_lite.cc
@@ -35,14 +35,9 @@
 #include <google/protobuf/test_util_lite.h>
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
+#include <gtest/gtest.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 {
 
diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc
index 778b878..04c887e 100644
--- a/src/google/protobuf/text_format.cc
+++ b/src/google/protobuf/text_format.cc
@@ -74,18 +74,6 @@
           (str[1] >= '0' && str[1] < '8'));
 }
 
-inline bool GetAnyFieldDescriptors(const Message& message,
-                                   const FieldDescriptor** type_url_field,
-                                   const FieldDescriptor** value_field) {
-    const Descriptor* descriptor = message.GetDescriptor();
-    *type_url_field = descriptor->FindFieldByNumber(1);
-    *value_field = descriptor->FindFieldByNumber(2);
-    return (*type_url_field != NULL &&
-            (*type_url_field)->type() == FieldDescriptor::TYPE_STRING &&
-            *value_field != NULL &&
-            (*value_field)->type() == FieldDescriptor::TYPE_BYTES);
-}
-
 }  // namespace
 
 string Message::DebugString() const {
@@ -1322,6 +1310,7 @@
   return Parse(&input_stream, output);
 }
 
+
 bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
                                Message* output) {
   ParserImpl parser(output->GetDescriptor(), input, error_collector_,
@@ -1339,6 +1328,7 @@
   return Merge(&input_stream, output);
 }
 
+
 bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* /* input */,
                                         Message* output,
                                         ParserImpl* parser_impl) {
@@ -1387,6 +1377,7 @@
   return Parser().MergeFromString(input, output);
 }
 
+
 // ===========================================================================
 
 // The default implementation for FieldValuePrinter. The base class just
diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h
index 2873d33..560fd39 100644
--- a/src/google/protobuf/text_format.h
+++ b/src/google/protobuf/text_format.h
@@ -75,8 +75,8 @@
                                  io::ZeroCopyOutputStream* output);
 
   // Like Print(), but outputs directly to a string.
-  // Note: output will be cleared before prior to printing, and will
-  // be left empty even if printing fails.
+  // Note: output will be cleared prior to printing, and will be left empty
+  // even if printing fails.
   static bool PrintToString(const Message& message, string* output);
 
   // Like PrintUnknownFields(), but outputs directly to a string.
diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc
index e644133..422a86b 100644
--- a/src/google/protobuf/text_format_unittest.cc
+++ b/src/google/protobuf/text_format_unittest.cc
@@ -53,11 +53,11 @@
 #include <google/protobuf/unittest_mset_wire_format.pb.h>
 #include <google/protobuf/io/tokenizer.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
-#include <google/protobuf/stubs/mathlimits.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
+#include <google/protobuf/stubs/mathlimits.h>
 
 
 namespace google {
diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc
index c1865d9..b2fe28a 100644
--- a/src/google/protobuf/timestamp.pb.cc
+++ b/src/google/protobuf/timestamp.pb.cc
@@ -31,11 +31,26 @@
 
 }  // namespace
 
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+    const TableStruct::entries[] = {
+  {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+    const TableStruct::aux[] = {
+  ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+    TableStruct::schema[] = {
+  { NULL, NULL, 0, -1, -1, false },
+};
+
 const ::google::protobuf::uint32 TableStruct::offsets[] = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Timestamp, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Timestamp, seconds_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Timestamp, nanos_),
 };
@@ -186,7 +201,7 @@
 }
 const ::google::protobuf::Descriptor* Timestamp::descriptor() {
   protobuf_google_2fprotobuf_2ftimestamp_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ftimestamp_2eproto::file_level_metadata[0].descriptor;
+  return protobuf_google_2fprotobuf_2ftimestamp_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const Timestamp& Timestamp::default_instance() {
@@ -266,6 +281,9 @@
 void Timestamp::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Timestamp)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // int64 seconds = 1;
   if (this->seconds() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->seconds(), output);
@@ -281,8 +299,10 @@
 
 ::google::protobuf::uint8* Timestamp::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Timestamp)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // int64 seconds = 1;
   if (this->seconds() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(1, this->seconds(), target);
@@ -341,6 +361,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Timestamp)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.seconds() != 0) {
     set_seconds(from.seconds());
   }
@@ -394,7 +417,7 @@
 
 ::google::protobuf::Metadata Timestamp::GetMetadata() const {
   protobuf_google_2fprotobuf_2ftimestamp_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ftimestamp_2eproto::file_level_metadata[0];
+  return protobuf_google_2fprotobuf_2ftimestamp_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h
index e6fc09a..f7f669a 100644
--- a/src/google/protobuf/timestamp.pb.h
+++ b/src/google/protobuf/timestamp.pb.h
@@ -22,6 +22,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/message.h>
@@ -43,6 +44,9 @@
 namespace protobuf_google_2fprotobuf_2ftimestamp_2eproto {
 // Internal implementation detail -- do not call these.
 struct LIBPROTOBUF_EXPORT TableStruct {
+  static const ::google::protobuf::internal::ParseTableField entries[];
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+  static const ::google::protobuf::internal::ParseTable schema[];
   static const ::google::protobuf::uint32 offsets[];
   static void InitDefaultsImpl();
   static void Shutdown();
@@ -78,6 +82,8 @@
     return reinterpret_cast<const Timestamp*>(
                &_Timestamp_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    0;
 
   void UnsafeArenaSwap(Timestamp* other);
   void Swap(Timestamp* other);
@@ -101,11 +107,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -154,7 +155,7 @@
   ::google::protobuf::int64 seconds_;
   ::google::protobuf::int32 nanos_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2ftimestamp_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2ftimestamp_2eproto::TableStruct;
 };
 // ===================================================================
 
diff --git a/src/google/protobuf/timestamp.proto b/src/google/protobuf/timestamp.proto
index 67e2eba..b7cbd17 100644
--- a/src/google/protobuf/timestamp.proto
+++ b/src/google/protobuf/timestamp.proto
@@ -52,6 +52,8 @@
 // and from  RFC 3339 date strings.
 // See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
 //
+// # Examples
+//
 // Example 1: Compute Timestamp from POSIX `time()`.
 //
 //     Timestamp timestamp;
@@ -92,6 +94,29 @@
 //     timestamp = Timestamp()
 //     timestamp.GetCurrentTime()
 //
+// # JSON Mapping
+//
+// In JSON format, the Timestamp type is encoded as a string in the
+// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
+// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
+// where {year} is always expressed using four digits while {month}, {day},
+// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
+// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
+// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
+// is required, though only UTC (as indicated by "Z") is presently supported.
+//
+// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
+// 01:30 UTC on January 15, 2017.
+//
+// In JavaScript, one can convert a Date object to this format using the
+// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString]
+// method. In Python, a standard `datetime.datetime` object can be converted
+// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime)
+// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one
+// can use the Joda Time's [`ISODateTimeFormat.dateTime()`](
+// http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime())
+// to obtain a formatter capable of generating timestamps in this format.
+//
 //
 message Timestamp {
 
diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc
index 017392c..8f017a8 100644
--- a/src/google/protobuf/type.pb.cc
+++ b/src/google/protobuf/type.pb.cc
@@ -40,11 +40,30 @@
 
 }  // namespace
 
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+    const TableStruct::entries[] = {
+  {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+    const TableStruct::aux[] = {
+  ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+    TableStruct::schema[] = {
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+};
+
 const ::google::protobuf::uint32 TableStruct::offsets[] = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, fields_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, oneofs_),
@@ -55,6 +74,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, kind_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, cardinality_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, number_),
@@ -69,6 +89,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, enumvalue_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, options_),
@@ -78,6 +99,7 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, number_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, options_),
@@ -85,16 +107,17 @@
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, value_),
 };
 
 static const ::google::protobuf::internal::MigrationSchema schemas[] = {
   { 0, -1, sizeof(Type)},
-  { 10, -1, sizeof(Field)},
-  { 24, -1, sizeof(Enum)},
-  { 33, -1, sizeof(EnumValue)},
-  { 40, -1, sizeof(Option)},
+  { 11, -1, sizeof(Field)},
+  { 26, -1, sizeof(Enum)},
+  { 36, -1, sizeof(EnumValue)},
+  { 44, -1, sizeof(Option)},
 };
 
 static ::google::protobuf::Message const * const file_default_instances[] = {
@@ -449,7 +472,7 @@
 }
 const ::google::protobuf::Descriptor* Type::descriptor() {
   protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[0].descriptor;
+  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const Type& Type::default_instance() {
@@ -504,13 +527,11 @@
       case 2: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(18u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_fields()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -535,13 +556,11 @@
       case 4: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(34u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_options()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -596,6 +615,9 @@
 void Type::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Type)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -645,8 +667,10 @@
 
 ::google::protobuf::uint8* Type::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Type)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -662,7 +686,7 @@
   for (unsigned int i = 0, n = this->fields_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        2, this->fields(i), false, target);
+        2, this->fields(i), deterministic, target);
   }
 
   // repeated string oneofs = 3;
@@ -679,14 +703,14 @@
   for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        4, this->options(i), false, target);
+        4, this->options(i), deterministic, target);
   }
 
   // .google.protobuf.SourceContext source_context = 5;
   if (this->has_source_context()) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        5, *this->source_context_, false, target);
+        5, *this->source_context_, deterministic, target);
   }
 
   // .google.protobuf.Syntax syntax = 6;
@@ -779,6 +803,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Type)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   fields_.MergeFrom(from.fields_);
   oneofs_.MergeFrom(from.oneofs_);
   options_.MergeFrom(from.options_);
@@ -831,9 +858,9 @@
   InternalSwap(other);
 }
 void Type::InternalSwap(Type* other) {
-  fields_.UnsafeArenaSwap(&other->fields_);
-  oneofs_.UnsafeArenaSwap(&other->oneofs_);
-  options_.UnsafeArenaSwap(&other->options_);
+  fields_.InternalSwap(&other->fields_);
+  oneofs_.InternalSwap(&other->oneofs_);
+  options_.InternalSwap(&other->options_);
   name_.Swap(&other->name_);
   std::swap(source_context_, other->source_context_);
   std::swap(syntax_, other->syntax_);
@@ -842,7 +869,7 @@
 
 ::google::protobuf::Metadata Type::GetMetadata() const {
   protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[0];
+  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -862,6 +889,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.Type.name)
 }
 void Type::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
@@ -970,6 +998,7 @@
 }
 #endif
 void Type::set_oneofs(int index, const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   oneofs_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.Type.oneofs)
 }
@@ -988,11 +1017,12 @@
 }
 #if LANG_CXX11
 void Type::add_oneofs(::std::string&& value) {
-  oneofs_.Add()->assign(std::move(value));
+  oneofs_.Add(std::move(value));
   // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs)
 }
 #endif
 void Type::add_oneofs(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   oneofs_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.Type.oneofs)
 }
@@ -1214,7 +1244,7 @@
 }
 const ::google::protobuf::Descriptor* Field::descriptor() {
   protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[1].descriptor;
+  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const Field& Field::default_instance() {
@@ -1355,13 +1385,11 @@
       case 9: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(74u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_options()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -1421,6 +1449,9 @@
 void Field::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Field)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // .google.protobuf.Field.Kind kind = 1;
   if (this->kind() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteEnum(
@@ -1499,8 +1530,10 @@
 
 ::google::protobuf::uint8* Field::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Field)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // .google.protobuf.Field.Kind kind = 1;
   if (this->kind() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
@@ -1554,7 +1587,7 @@
   for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        9, this->options(i), false, target);
+        9, this->options(i), deterministic, target);
   }
 
   // string json_name = 10;
@@ -1683,6 +1716,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Field)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   options_.MergeFrom(from.options_);
   if (from.name().size() > 0) {
     set_name(from.name());
@@ -1751,7 +1787,7 @@
   InternalSwap(other);
 }
 void Field::InternalSwap(Field* other) {
-  options_.UnsafeArenaSwap(&other->options_);
+  options_.InternalSwap(&other->options_);
   name_.Swap(&other->name_);
   type_url_.Swap(&other->type_url_);
   json_name_.Swap(&other->json_name_);
@@ -1766,7 +1802,7 @@
 
 ::google::protobuf::Metadata Field::GetMetadata() const {
   protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[1];
+  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1828,6 +1864,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.Field.name)
 }
 void Field::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
@@ -1894,6 +1931,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.Field.type_url)
 }
 void Field::set_type_url(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   type_url_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
@@ -2018,6 +2056,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name)
 }
 void Field::set_json_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   json_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
@@ -2084,6 +2123,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.Field.default_value)
 }
 void Field::set_default_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   default_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
@@ -2259,7 +2299,7 @@
 }
 const ::google::protobuf::Descriptor* Enum::descriptor() {
   protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[2].descriptor;
+  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const Enum& Enum::default_instance() {
@@ -2313,13 +2353,11 @@
       case 2: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(18u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_enumvalue()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -2327,13 +2365,11 @@
       case 3: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(26u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_options()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -2388,6 +2424,9 @@
 void Enum::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Enum)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -2427,8 +2466,10 @@
 
 ::google::protobuf::uint8* Enum::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Enum)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -2444,21 +2485,21 @@
   for (unsigned int i = 0, n = this->enumvalue_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        2, this->enumvalue(i), false, target);
+        2, this->enumvalue(i), deterministic, target);
   }
 
   // repeated .google.protobuf.Option options = 3;
   for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        3, this->options(i), false, target);
+        3, this->options(i), deterministic, target);
   }
 
   // .google.protobuf.SourceContext source_context = 4;
   if (this->has_source_context()) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        4, *this->source_context_, false, target);
+        4, *this->source_context_, deterministic, target);
   }
 
   // .google.protobuf.Syntax syntax = 5;
@@ -2543,6 +2584,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Enum)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   enumvalue_.MergeFrom(from.enumvalue_);
   options_.MergeFrom(from.options_);
   if (from.name().size() > 0) {
@@ -2594,8 +2638,8 @@
   InternalSwap(other);
 }
 void Enum::InternalSwap(Enum* other) {
-  enumvalue_.UnsafeArenaSwap(&other->enumvalue_);
-  options_.UnsafeArenaSwap(&other->options_);
+  enumvalue_.InternalSwap(&other->enumvalue_);
+  options_.InternalSwap(&other->options_);
   name_.Swap(&other->name_);
   std::swap(source_context_, other->source_context_);
   std::swap(syntax_, other->syntax_);
@@ -2604,7 +2648,7 @@
 
 ::google::protobuf::Metadata Enum::GetMetadata() const {
   protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[2];
+  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -2624,6 +2668,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.Enum.name)
 }
 void Enum::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
@@ -2878,7 +2923,7 @@
 }
 const ::google::protobuf::Descriptor* EnumValue::descriptor() {
   protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[3].descriptor;
+  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const EnumValue& EnumValue::default_instance() {
@@ -2941,13 +2986,11 @@
       case 3: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(26u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_options()));
         } else {
           goto handle_unusual;
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
       }
 
@@ -2975,6 +3018,9 @@
 void EnumValue::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.EnumValue)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -3001,8 +3047,10 @@
 
 ::google::protobuf::uint8* EnumValue::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValue)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -3023,7 +3071,7 @@
   for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        3, this->options(i), false, target);
+        3, this->options(i), deterministic, target);
   }
 
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValue)
@@ -3085,6 +3133,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValue)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   options_.MergeFrom(from.options_);
   if (from.name().size() > 0) {
     set_name(from.name());
@@ -3132,7 +3183,7 @@
   InternalSwap(other);
 }
 void EnumValue::InternalSwap(EnumValue* other) {
-  options_.UnsafeArenaSwap(&other->options_);
+  options_.InternalSwap(&other->options_);
   name_.Swap(&other->name_);
   std::swap(number_, other->number_);
   std::swap(_cached_size_, other->_cached_size_);
@@ -3140,7 +3191,7 @@
 
 ::google::protobuf::Metadata EnumValue::GetMetadata() const {
   protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[3];
+  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -3160,6 +3211,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.name)
 }
 void EnumValue::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
@@ -3370,7 +3422,7 @@
 }
 const ::google::protobuf::Descriptor* Option::descriptor() {
   protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[4].descriptor;
+  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const Option& Option::default_instance() {
@@ -3453,6 +3505,9 @@
 void Option::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Option)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -3474,8 +3529,10 @@
 
 ::google::protobuf::uint8* Option::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Option)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -3491,7 +3548,7 @@
   if (this->has_value()) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
-        2, *this->value_, false, target);
+        2, *this->value_, deterministic, target);
   }
 
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Option)
@@ -3542,6 +3599,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Option)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.name().size() > 0) {
     set_name(from.name());
   }
@@ -3595,7 +3655,7 @@
 
 ::google::protobuf::Metadata Option::GetMetadata() const {
   protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[4];
+  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -3615,6 +3675,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.Option.name)
 }
 void Option::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h
index ae81600..56d77a4 100644
--- a/src/google/protobuf/type.pb.h
+++ b/src/google/protobuf/type.pb.h
@@ -22,6 +22,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/message.h>
@@ -64,6 +65,9 @@
 namespace protobuf_google_2fprotobuf_2ftype_2eproto {
 // Internal implementation detail -- do not call these.
 struct LIBPROTOBUF_EXPORT TableStruct {
+  static const ::google::protobuf::internal::ParseTableField entries[];
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+  static const ::google::protobuf::internal::ParseTable schema[];
   static const ::google::protobuf::uint32 offsets[];
   static void InitDefaultsImpl();
   static void Shutdown();
@@ -181,6 +185,8 @@
     return reinterpret_cast<const Type*>(
                &_Type_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    0;
 
   void UnsafeArenaSwap(Type* other);
   void Swap(Type* other);
@@ -204,11 +210,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -331,7 +332,7 @@
   ::google::protobuf::SourceContext* source_context_;
   int syntax_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
 
@@ -360,6 +361,8 @@
     return reinterpret_cast<const Field*>(
                &_Field_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    1;
 
   void UnsafeArenaSwap(Field* other);
   void Swap(Field* other);
@@ -383,11 +386,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -620,7 +618,7 @@
   ::google::protobuf::int32 oneof_index_;
   bool packed_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
 
@@ -649,6 +647,8 @@
     return reinterpret_cast<const Enum*>(
                &_Enum_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    2;
 
   void UnsafeArenaSwap(Enum* other);
   void Swap(Enum* other);
@@ -672,11 +672,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -776,7 +771,7 @@
   ::google::protobuf::SourceContext* source_context_;
   int syntax_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
 
@@ -805,6 +800,8 @@
     return reinterpret_cast<const EnumValue*>(
                &_EnumValue_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    3;
 
   void UnsafeArenaSwap(EnumValue* other);
   void Swap(EnumValue* other);
@@ -828,11 +825,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -902,7 +894,7 @@
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::int32 number_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
 
@@ -931,6 +923,8 @@
     return reinterpret_cast<const Option*>(
                &_Option_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    4;
 
   void UnsafeArenaSwap(Option* other);
   void Swap(Option* other);
@@ -954,11 +948,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -1025,7 +1014,7 @@
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::Any* value_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
 };
 // ===================================================================
 
@@ -1049,6 +1038,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.Type.name)
 }
 inline void Type::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
@@ -1157,6 +1147,7 @@
 }
 #endif
 inline void Type::set_oneofs(int index, const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   oneofs_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.Type.oneofs)
 }
@@ -1175,11 +1166,12 @@
 }
 #if LANG_CXX11
 inline void Type::add_oneofs(::std::string&& value) {
-  oneofs_.Add()->assign(std::move(value));
+  oneofs_.Add(std::move(value));
   // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs)
 }
 #endif
 inline void Type::add_oneofs(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   oneofs_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.Type.oneofs)
 }
@@ -1353,6 +1345,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.Field.name)
 }
 inline void Field::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
@@ -1419,6 +1412,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.Field.type_url)
 }
 inline void Field::set_type_url(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   type_url_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
@@ -1543,6 +1537,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name)
 }
 inline void Field::set_json_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   json_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
@@ -1609,6 +1604,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.Field.default_value)
 }
 inline void Field::set_default_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   default_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
@@ -1679,6 +1675,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.Enum.name)
 }
 inline void Enum::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
@@ -1874,6 +1871,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.name)
 }
 inline void EnumValue::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
@@ -1988,6 +1986,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.Option.name)
 }
 inline void Option::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto
index 188a4f4..2040487 100644
--- a/src/google/protobuf/unittest.proto
+++ b/src/google/protobuf/unittest.proto
@@ -433,7 +433,14 @@
 
 // Test that mutual recursion works.
 message TestMutualRecursionA {
+  message SubMessage {
+    optional TestMutualRecursionB b = 1;
+  }
   optional TestMutualRecursionB bb = 1;
+  optional group SubGroup = 2 {
+    optional SubMessage sub_message = 3;  // Needed because of bug in javatest
+    optional TestAllTypes not_in_this_scc = 4;
+  }
 }
 
 message TestMutualRecursionB {
@@ -441,6 +448,15 @@
   optional int32 optional_int32 = 2;
 }
 
+message TestIsInitialized {
+  message SubMessage {
+    optional group SubGroup = 1 {
+      required int32 i = 2;
+    }
+  }
+  optional SubMessage sub_message = 1;
+}
+
 // Test that groups have disjoint field numbers from their siblings and
 // parents.  This is NOT possible in proto1; only google.protobuf.  When attempting
 // to compile with proto1, this will emit an error; so we only include it
diff --git a/src/google/protobuf/unittest_lazy_dependencies.proto b/src/google/protobuf/unittest_lazy_dependencies.proto
new file mode 100644
index 0000000..2f5efd2
--- /dev/null
+++ b/src/google/protobuf/unittest_lazy_dependencies.proto
@@ -0,0 +1,75 @@
+// 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.
+
+// Author: trafacz@google.com (Todd Rafacz)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file we will use for unit testing.
+
+syntax = "proto2";
+
+import "google/protobuf/unittest_lazy_dependencies_custom_option.proto";
+
+// Some generic_services option(s) added automatically.
+// See:  http://go/proto2-generic-services-default
+option cc_generic_services = true;   // auto-added
+option java_generic_services = true; // auto-added
+option py_generic_services = true;   // auto-added
+option cc_enable_arenas = true;
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do "using namespace unittest = protobuf_unittest".
+package protobuf_unittest.lazy_imports;
+
+// Protos optimized for SPEED use a strict superset of the generated code
+// of equivalent ones optimized for CODE_SIZE, so we should optimize all our
+// tests for speed unless explicitly testing code size optimization.
+option optimize_for = SPEED;
+
+option java_outer_classname = "UnittestLazyImportsProto";
+
+// The following are used to test that the proto file
+// with the definition of the following field types is
+// not built when this proto file is built. Then test
+// that calling message_type() etc will build the correct
+// descriptor lazily and return it.
+
+message ImportedMessage {
+  optional LazyMessage lazy_message = 1;
+}
+
+message MessageCustomOption {
+}
+
+message MessageCustomOption2 {
+  option (lazy_enum_option) = LAZY_ENUM_0;
+}
diff --git a/src/google/protobuf/unittest_lazy_dependencies_custom_option.proto b/src/google/protobuf/unittest_lazy_dependencies_custom_option.proto
new file mode 100644
index 0000000..2243825
--- /dev/null
+++ b/src/google/protobuf/unittest_lazy_dependencies_custom_option.proto
@@ -0,0 +1,67 @@
+// 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.
+
+// Author: trafacz@google.com (Todd Rafacz)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file we will use for unit testing.
+
+syntax = "proto2";
+
+import "google/protobuf/unittest_lazy_dependencies_enum.proto";
+import "google/protobuf/descriptor.proto";
+
+// Some generic_services option(s) added automatically.
+// See:  http://go/proto2-generic-services-default
+option cc_generic_services = true;   // auto-added
+option java_generic_services = true; // auto-added
+option py_generic_services = true;   // auto-added
+option cc_enable_arenas = true;
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do "using namespace unittest = protobuf_unittest".
+package protobuf_unittest.lazy_imports;
+
+// Protos optimized for SPEED use a strict superset of the generated code
+// of equivalent ones optimized for CODE_SIZE, so we should optimize all our
+// tests for speed unless explicitly testing code size optimization.
+option optimize_for = SPEED;
+
+option java_outer_classname = "UnittestLazyImportsCustomOptionProto";
+
+message LazyMessage {
+  optional int32 a = 1;
+}
+
+extend google.protobuf.MessageOptions {
+  optional LazyEnum lazy_enum_option = 138596335 [default = LAZY_ENUM_1];
+}
diff --git a/src/google/protobuf/unittest_lazy_dependencies_enum.proto b/src/google/protobuf/unittest_lazy_dependencies_enum.proto
new file mode 100644
index 0000000..9be64d8
--- /dev/null
+++ b/src/google/protobuf/unittest_lazy_dependencies_enum.proto
@@ -0,0 +1,61 @@
+// 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.
+
+// Author: trafacz@google.com (Todd Rafacz)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file we will use for unit testing.
+
+syntax = "proto2";
+
+// Some generic_services option(s) added automatically.
+// See:  http://go/proto2-generic-services-default
+option cc_generic_services = true;   // auto-added
+option java_generic_services = true; // auto-added
+option py_generic_services = true;   // auto-added
+option cc_enable_arenas = true;
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do "using namespace unittest = protobuf_unittest".
+package protobuf_unittest.lazy_imports;
+
+// Protos optimized for SPEED use a strict superset of the generated code
+// of equivalent ones optimized for CODE_SIZE, so we should optimize all our
+// tests for speed unless explicitly testing code size optimization.
+option optimize_for = SPEED;
+
+option java_outer_classname = "UnittestLazyImportsEnumProto";
+
+enum LazyEnum {
+  LAZY_ENUM_0 = 0;
+  LAZY_ENUM_1 = 1;
+}
diff --git a/src/google/protobuf/unittest_proto3_arena.proto b/src/google/protobuf/unittest_proto3_arena.proto
index b835a6b..9375d85 100644
--- a/src/google/protobuf/unittest_proto3_arena.proto
+++ b/src/google/protobuf/unittest_proto3_arena.proto
@@ -96,6 +96,8 @@
       optional_public_import_message = 26;
 
   NestedMessage optional_lazy_message = 27 [lazy=true];
+  protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115
+      [lazy = true];
 
   // Repeated
   repeated    int32 repeated_int32    = 31;
diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc
index 9472c4f..0ada85e 100644
--- a/src/google/protobuf/unknown_field_set.cc
+++ b/src/google/protobuf/unknown_field_set.cc
@@ -123,21 +123,21 @@
   metadata->mutable_unknown_fields()->MergeFrom(other);
 }
 
-int UnknownFieldSet::SpaceUsedExcludingSelf() const {
+size_t UnknownFieldSet::SpaceUsedExcludingSelfLong() const {
   if (fields_ == NULL) return 0;
 
-  int total_size = sizeof(*fields_) + sizeof(UnknownField) * fields_->size();
+  size_t total_size = sizeof(*fields_) + sizeof(UnknownField) * fields_->size();
 
   for (int i = 0; i < fields_->size(); i++) {
     const UnknownField& field = (*fields_)[i];
     switch (field.type()) {
       case UnknownField::TYPE_LENGTH_DELIMITED:
-        total_size += sizeof(*field.length_delimited_.string_value_) +
-                      internal::StringSpaceUsedExcludingSelf(
-                          *field.length_delimited_.string_value_);
+        total_size += sizeof(*field.data_.length_delimited_.string_value_) +
+                      internal::StringSpaceUsedExcludingSelfLong(
+                          *field.data_.length_delimited_.string_value_);
         break;
       case UnknownField::TYPE_GROUP:
-        total_size += field.group_->SpaceUsed();
+        total_size += field.data_.group_->SpaceUsedLong();
         break;
       default:
         break;
@@ -146,7 +146,7 @@
   return total_size;
 }
 
-int UnknownFieldSet::SpaceUsed() const {
+size_t UnknownFieldSet::SpaceUsedLong() const {
   return sizeof(*this) + SpaceUsedExcludingSelf();
 }
 
@@ -154,7 +154,7 @@
   UnknownField field;
   field.number_ = number;
   field.SetType(UnknownField::TYPE_VARINT);
-  field.varint_ = value;
+  field.data_.varint_ = value;
   if (fields_ == NULL) fields_ = new std::vector<UnknownField>();
   fields_->push_back(field);
 }
@@ -163,7 +163,7 @@
   UnknownField field;
   field.number_ = number;
   field.SetType(UnknownField::TYPE_FIXED32);
-  field.fixed32_ = value;
+  field.data_.fixed32_ = value;
   if (fields_ == NULL) fields_ = new std::vector<UnknownField>();
   fields_->push_back(field);
 }
@@ -172,7 +172,7 @@
   UnknownField field;
   field.number_ = number;
   field.SetType(UnknownField::TYPE_FIXED64);
-  field.fixed64_ = value;
+  field.data_.fixed64_ = value;
   if (fields_ == NULL) fields_ = new std::vector<UnknownField>();
   fields_->push_back(field);
 }
@@ -181,10 +181,10 @@
   UnknownField field;
   field.number_ = number;
   field.SetType(UnknownField::TYPE_LENGTH_DELIMITED);
-  field.length_delimited_.string_value_ = new string;
+  field.data_.length_delimited_.string_value_ = new string;
   if (fields_ == NULL) fields_ = new std::vector<UnknownField>();
   fields_->push_back(field);
-  return field.length_delimited_.string_value_;
+  return field.data_.length_delimited_.string_value_;
 }
 
 
@@ -192,10 +192,10 @@
   UnknownField field;
   field.number_ = number;
   field.SetType(UnknownField::TYPE_GROUP);
-  field.group_ = new UnknownFieldSet;
+  field.data_.group_ = new UnknownFieldSet;
   if (fields_ == NULL) fields_ = new std::vector<UnknownField>();
   fields_->push_back(field);
-  return field.group_;
+  return field.data_.group_;
 }
 
 void UnknownFieldSet::AddField(const UnknownField& field) {
@@ -276,10 +276,10 @@
 void UnknownField::Delete() {
   switch (type()) {
     case UnknownField::TYPE_LENGTH_DELIMITED:
-      delete length_delimited_.string_value_;
+      delete data_.length_delimited_.string_value_;
       break;
     case UnknownField::TYPE_GROUP:
-      delete group_;
+      delete data_.group_;
       break;
     default:
       break;
@@ -291,10 +291,10 @@
 void UnknownField::Reset() {
   switch (type()) {
     case UnknownField::TYPE_LENGTH_DELIMITED:
-      length_delimited_.string_value_ = NULL;
+      data_.length_delimited_.string_value_ = NULL;
       break;
     case UnknownField::TYPE_GROUP: {
-      group_ = NULL;
+      data_.group_ = NULL;
       break;
     }
     default:
@@ -305,13 +305,13 @@
 void UnknownField::DeepCopy(const UnknownField& other) {
   switch (type()) {
     case UnknownField::TYPE_LENGTH_DELIMITED:
-      length_delimited_.string_value_ = new string(
-          *length_delimited_.string_value_);
+      data_.length_delimited_.string_value_ = new string(
+          *data_.length_delimited_.string_value_);
       break;
     case UnknownField::TYPE_GROUP: {
       UnknownFieldSet* group = new UnknownFieldSet();
-      group->InternalMergeFrom(*group_);
-      group_ = group;
+      group->InternalMergeFrom(*data_.group_);
+      data_.group_ = group;
       break;
     }
     default:
@@ -323,14 +323,14 @@
 void UnknownField::SerializeLengthDelimitedNoTag(
     io::CodedOutputStream* output) const {
   GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
-  const string& data = *length_delimited_.string_value_;
+  const string& data = *data_.length_delimited_.string_value_;
   output->WriteVarint32(data.size());
   output->WriteRawMaybeAliased(data.data(), data.size());
 }
 
 uint8* UnknownField::SerializeLengthDelimitedNoTagToArray(uint8* target) const {
   GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
-  const string& data = *length_delimited_.string_value_;
+  const string& data = *data_.length_delimited_.string_value_;
   target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target);
   target = io::CodedOutputStream::WriteStringToArray(data, target);
   return target;
diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h
index c2ad891..002ea8e 100644
--- a/src/google/protobuf/unknown_field_set.h
+++ b/src/google/protobuf/unknown_field_set.h
@@ -43,6 +43,7 @@
 #include <vector>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/generated_message_util.h>
 
 namespace google {
 namespace protobuf {
@@ -106,10 +107,18 @@
   // Computes (an estimate of) the total number of bytes currently used for
   // storing the unknown fields in memory. Does NOT include
   // sizeof(*this) in the calculation.
-  int SpaceUsedExcludingSelf() const;
+  size_t SpaceUsedExcludingSelfLong() const;
+
+  int SpaceUsedExcludingSelf() const {
+    return internal::ToIntSize(SpaceUsedExcludingSelfLong());
+  }
 
   // Version of SpaceUsed() including sizeof(*this).
-  int SpaceUsed() const;
+  size_t SpaceUsedLong() const;
+
+  int SpaceUsed() const {
+    return internal::ToIntSize(SpaceUsedLong());
+  }
 
   // Returns the number of fields present in the UnknownFieldSet.
   inline int field_count() const;
@@ -214,8 +223,6 @@
 
   inline size_t GetLengthDelimitedSize() const;
 
- private:
-  friend class UnknownFieldSet;
 
   // If this UnknownField contains a pointer, delete it.
   void Delete();
@@ -243,7 +250,7 @@
     uint64 fixed64_;
     mutable union LengthDelimited length_delimited_;
     UnknownFieldSet* group_;
-  };
+  } data_;
 };
 
 // ===================================================================
@@ -287,6 +294,8 @@
 }
 
 
+
+
 inline int UnknownField::number() const { return number_; }
 inline UnknownField::Type UnknownField::type() const {
   return static_cast<Type>(type_);
@@ -294,53 +303,53 @@
 
 inline uint64 UnknownField::varint() const {
   assert(type() == TYPE_VARINT);
-  return varint_;
+  return data_.varint_;
 }
 inline uint32 UnknownField::fixed32() const {
   assert(type() == TYPE_FIXED32);
-  return fixed32_;
+  return data_.fixed32_;
 }
 inline uint64 UnknownField::fixed64() const {
   assert(type() == TYPE_FIXED64);
-  return fixed64_;
+  return data_.fixed64_;
 }
 inline const string& UnknownField::length_delimited() const {
   assert(type() == TYPE_LENGTH_DELIMITED);
-  return *length_delimited_.string_value_;
+  return *data_.length_delimited_.string_value_;
 }
 inline const UnknownFieldSet& UnknownField::group() const {
   assert(type() == TYPE_GROUP);
-  return *group_;
+  return *data_.group_;
 }
 
 inline void UnknownField::set_varint(uint64 value) {
   assert(type() == TYPE_VARINT);
-  varint_ = value;
+  data_.varint_ = value;
 }
 inline void UnknownField::set_fixed32(uint32 value) {
   assert(type() == TYPE_FIXED32);
-  fixed32_ = value;
+  data_.fixed32_ = value;
 }
 inline void UnknownField::set_fixed64(uint64 value) {
   assert(type() == TYPE_FIXED64);
-  fixed64_ = value;
+  data_.fixed64_ = value;
 }
 inline void UnknownField::set_length_delimited(const string& value) {
   assert(type() == TYPE_LENGTH_DELIMITED);
-  length_delimited_.string_value_->assign(value);
+  data_.length_delimited_.string_value_->assign(value);
 }
 inline string* UnknownField::mutable_length_delimited() {
   assert(type() == TYPE_LENGTH_DELIMITED);
-  return length_delimited_.string_value_;
+  return data_.length_delimited_.string_value_;
 }
 inline UnknownFieldSet* UnknownField::mutable_group() {
   assert(type() == TYPE_GROUP);
-  return group_;
+  return data_.group_;
 }
 
 inline size_t UnknownField::GetLengthDelimitedSize() const {
   GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
-  return length_delimited_.string_value_->size();
+  return data_.length_delimited_.string_value_->size();
 }
 
 inline void UnknownField::SetType(Type type) {
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc
index b33ad20..5763d0c 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.cc
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc
@@ -189,6 +189,39 @@
   field_scrub_callback_.reset(field_scrub_callback.release());
 }
 
+DefaultValueObjectWriter::Node* DefaultValueObjectWriter::CreateNewNode(
+    const string& name, const google::protobuf::Type* type, NodeKind kind,
+    const DataPiece& data, bool is_placeholder, const std::vector<string>& path,
+    bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback) {
+  return new Node(name, type, kind, data, is_placeholder, path,
+                  suppress_empty_list, field_scrub_callback);
+}
+
+DefaultValueObjectWriter::Node* DefaultValueObjectWriter::CreateNewNode(
+    const string& name, const google::protobuf::Type* type, NodeKind kind,
+    const DataPiece& data, bool is_placeholder, const std::vector<string>& path,
+    bool suppress_empty_list, bool preserve_proto_field_names,
+    FieldScrubCallBack* field_scrub_callback) {
+  return new Node(name, type, kind, data, is_placeholder, path,
+                  suppress_empty_list, preserve_proto_field_names,
+                  field_scrub_callback);
+}
+
+DefaultValueObjectWriter::Node::Node(
+    const string& name, const google::protobuf::Type* type, NodeKind kind,
+    const DataPiece& data, bool is_placeholder, const std::vector<string>& path,
+    bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback)
+    : name_(name),
+      type_(type),
+      kind_(kind),
+      is_any_(false),
+      data_(data),
+      is_placeholder_(is_placeholder),
+      path_(path),
+      suppress_empty_list_(suppress_empty_list),
+      preserve_proto_field_names_(false),
+      field_scrub_callback_(field_scrub_callback) {}
+
 DefaultValueObjectWriter::Node::Node(
     const string& name, const google::protobuf::Type* type, NodeKind kind,
     const DataPiece& data, bool is_placeholder, const std::vector<string>& path,
@@ -473,10 +506,10 @@
     StringPiece name) {
   if (current_ == NULL) {
     std::vector<string> path;
-    root_.reset(new Node(name.ToString(), &type_, OBJECT, DataPiece::NullData(),
-                         false, path, suppress_empty_list_,
-                         preserve_proto_field_names_,
-                         field_scrub_callback_.get()));
+    root_.reset(CreateNewNode(string(name), &type_, OBJECT,
+                              DataPiece::NullData(), false, path,
+                              suppress_empty_list_, preserve_proto_field_names_,
+                              field_scrub_callback_.get()));
     root_->PopulateChildren(typeinfo_);
     current_ = root_.get();
     return this;
@@ -486,14 +519,15 @@
   if (current_->kind() == LIST || current_->kind() == MAP || child == NULL) {
     // If current_ is a list or a map node, we should create a new child and use
     // the type of current_ as the type of the new child.
-    google::protobuf::scoped_ptr<Node> node(new Node(
-        name.ToString(), ((current_->kind() == LIST || current_->kind() == MAP)
-                              ? current_->type()
-                              : NULL),
-        OBJECT, DataPiece::NullData(), false,
-        child == NULL ? current_->path() : child->path(),
-        suppress_empty_list_, preserve_proto_field_names_,
-        field_scrub_callback_.get()));
+    google::protobuf::scoped_ptr<Node> node(
+        CreateNewNode(string(name),
+                      ((current_->kind() == LIST || current_->kind() == MAP)
+                           ? current_->type()
+                           : NULL),
+                      OBJECT, DataPiece::NullData(), false,
+                      child == NULL ? current_->path() : child->path(),
+                      suppress_empty_list_, preserve_proto_field_names_,
+                      field_scrub_callback_.get()));
     child = node.get();
     current_->AddChild(node.release());
   }
@@ -523,10 +557,10 @@
     StringPiece name) {
   if (current_ == NULL) {
     std::vector<string> path;
-    root_.reset(new Node(name.ToString(), &type_, LIST, DataPiece::NullData(),
-                         false, path, suppress_empty_list_,
-                         preserve_proto_field_names_,
-                         field_scrub_callback_.get()));
+    root_.reset(CreateNewNode(string(name), &type_, LIST, DataPiece::NullData(),
+                              false, path, suppress_empty_list_,
+                              preserve_proto_field_names_,
+                              field_scrub_callback_.get()));
     current_ = root_.get();
     return this;
   }
@@ -534,10 +568,10 @@
   Node* child = current_->FindChild(name);
   if (child == NULL || child->kind() != LIST) {
     google::protobuf::scoped_ptr<Node> node(
-        new Node(name.ToString(), NULL, LIST, DataPiece::NullData(), false,
-                 child == NULL ? current_->path() : child->path(),
-                 suppress_empty_list_, preserve_proto_field_names_,
-                 field_scrub_callback_.get()));
+        CreateNewNode(string(name), NULL, LIST, DataPiece::NullData(), false,
+                      child == NULL ? current_->path() : child->path(),
+                      suppress_empty_list_, preserve_proto_field_names_,
+                      field_scrub_callback_.get()));
     child = node.get();
     current_->AddChild(node.release());
   }
@@ -596,10 +630,10 @@
   if (child == NULL || child->kind() != PRIMITIVE) {
     // No children are found, creates a new child.
     google::protobuf::scoped_ptr<Node> node(
-        new Node(name.ToString(), NULL, PRIMITIVE, data, false,
-                 child == NULL ? current_->path() : child->path(),
-                 suppress_empty_list_, preserve_proto_field_names_,
-                 field_scrub_callback_.get()));
+        CreateNewNode(string(name), NULL, PRIMITIVE, data, false,
+                      child == NULL ? current_->path() : child->path(),
+                      suppress_empty_list_, preserve_proto_field_names_,
+                      field_scrub_callback_.get()));
     current_->AddChild(node.release());
   } else {
     child->set_data(data);
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h
index ddf2359..ef2cc98 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.h
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.h
@@ -127,9 +127,11 @@
   void set_suppress_empty_list(bool value) { suppress_empty_list_ = value; }
 
   // If set to true, original proto field names are used
-  void set_preserve_proto_field_names(bool value) { preserve_proto_field_names_ = value; }
+  void set_preserve_proto_field_names(bool value) {
+    preserve_proto_field_names_ = value;
+  }
 
- private:
+ protected:
   enum NodeKind {
     PRIMITIVE = 0,
     OBJECT = 1,
@@ -144,7 +146,12 @@
     Node(const string& name, const google::protobuf::Type* type, NodeKind kind,
          const DataPiece& data, bool is_placeholder,
          const std::vector<string>& path, bool suppress_empty_list,
-         bool preserve_proto_field_names, FieldScrubCallBack* field_scrub_callback);
+         FieldScrubCallBack* field_scrub_callback);
+    Node(const string& name, const google::protobuf::Type* type, NodeKind kind,
+         const DataPiece& data, bool is_placeholder,
+         const std::vector<string>& path, bool suppress_empty_list,
+         bool preserve_proto_field_names,
+         FieldScrubCallBack* field_scrub_callback);
     virtual ~Node() {
       for (int i = 0; i < children_.size(); ++i) {
         delete children_[i];
@@ -160,7 +167,7 @@
     // Populates children of this Node based on its type. If there are already
     // children created, they will be merged to the result. Caller should pass
     // in TypeInfo for looking up types of the children.
-    void PopulateChildren(const TypeInfo* typeinfo);
+    virtual void PopulateChildren(const TypeInfo* typeinfo);
 
     // If this node is a leaf (has data), writes the current node to the
     // ObjectWriter; if not, then recursively writes the children to the
@@ -190,7 +197,7 @@
       is_placeholder_ = is_placeholder;
     }
 
-   private:
+   protected:
     // Returns the Value Type of a map given the Type of the map entry and a
     // TypeInfo instance.
     const google::protobuf::Type* GetMapValueType(
@@ -230,9 +237,32 @@
     // or not. This callback is owned by the creator of this node.
     FieldScrubCallBack* field_scrub_callback_;
 
+   private:
     GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Node);
   };
 
+  // Creates a new Node and returns it. Caller owns memory of returned object.
+  virtual Node* CreateNewNode(const string& name,
+                              const google::protobuf::Type* type, NodeKind kind,
+                              const DataPiece& data, bool is_placeholder,
+                              const std::vector<string>& path,
+                              bool suppress_empty_list,
+                              FieldScrubCallBack* field_scrub_callback);
+
+  // Creates a new Node and returns it. Caller owns memory of returned object.
+  virtual Node* CreateNewNode(const string& name,
+                              const google::protobuf::Type* type, NodeKind kind,
+                              const DataPiece& data, bool is_placeholder,
+                              const std::vector<string>& path,
+                              bool suppress_empty_list,
+                              bool preserve_proto_field_names,
+                              FieldScrubCallBack* field_scrub_callback);
+
+  // Creates a DataPiece containing the default value of the type of the field.
+  static DataPiece CreateDefaultDataPieceForField(
+      const google::protobuf::Field& field, const TypeInfo* typeinfo);
+
+ private:
   // Populates children of "node" if it is an "any" Node and its real type has
   // been given.
   void MaybePopulateChildrenOfAny(Node* node);
@@ -241,10 +271,6 @@
   // NULL.
   void WriteRoot();
 
-  // Creates a DataPiece containing the default value of the type of the field.
-  static DataPiece CreateDefaultDataPieceForField(
-      const google::protobuf::Field& field, const TypeInfo* typeinfo);
-
   // Adds or replaces the data_ of a primitive child node.
   void RenderDataPiece(StringPiece name, const DataPiece& data);
 
diff --git a/src/google/protobuf/util/internal/field_mask_utility.cc b/src/google/protobuf/util/internal/field_mask_utility.cc
index 53b90fb..38835f6 100644
--- a/src/google/protobuf/util/internal/field_mask_utility.cc
+++ b/src/google/protobuf/util/internal/field_mask_utility.cc
@@ -44,11 +44,6 @@
   return path_sink->Run(arg);
 }
 
-util::Status CreatePublicError(util::error::Code code,
-                                 const string& message) {
-  return util::Status(code, message);
-}
-
 // Appends a FieldMask path segment to a prefix.
 string AppendPathSegmentToPrefix(StringPiece prefix, StringPiece segment) {
   if (prefix.empty()) {
@@ -216,7 +211,7 @@
                           StrCat("Invalid FieldMask '", paths,
                                  "'. Cannot find matching ')' for all '('."));
   }
-  return util::Status::OK;
+  return util::Status();
 }
 
 }  // namespace converter
diff --git a/src/google/protobuf/util/internal/json_escaping.cc b/src/google/protobuf/util/internal/json_escaping.cc
index 47e4dd6..18b7f923 100644
--- a/src/google/protobuf/util/internal/json_escaping.cc
+++ b/src/google/protobuf/util/internal/json_escaping.cc
@@ -84,30 +84,6 @@
   "\\u009c", "\\u009d", "\\u009e", "\\u009f"
 };
 
-// Determines if the given char value is a unicode high-surrogate code unit.
-// Such values do not represent characters by themselves, but are used in the
-// representation of supplementary characters in the utf-16 encoding.
-inline bool IsHighSurrogate(uint16 c) {
-  // Optimized form of:
-  // return c >= kMinHighSurrogate && c <= kMaxHighSurrogate;
-  // (Reduced from 3 ALU instructions to 2 ALU instructions)
-  return (c & ~(JsonEscaping::kMaxHighSurrogate -
-                JsonEscaping::kMinHighSurrogate))
-      == JsonEscaping::kMinHighSurrogate;
-}
-
-// Determines if the given char value is a unicode low-surrogate code unit.
-// Such values do not represent characters by themselves, but are used in the
-// representation of supplementary characters in the utf-16 encoding.
-inline bool IsLowSurrogate(uint16 c) {
-  // Optimized form of:
-  // return c >= kMinLowSurrogate && c <= kMaxLowSurrogate;
-  // (Reduced from 3 ALU instructions to 2 ALU instructions)
-  return (c & ~(JsonEscaping::kMaxLowSurrogate -
-                JsonEscaping::kMinLowSurrogate))
-      == JsonEscaping::kMinLowSurrogate;
-}
-
 // Determines if the given char value is a unicode surrogate code unit (either
 // high-surrogate or low-surrogate).
 inline bool IsSurrogate(uint32 c) {
@@ -117,36 +93,12 @@
   return (c & 0xfffff800) == JsonEscaping::kMinHighSurrogate;
 }
 
-// Returns true if the given unicode code point cp is
-// in the supplementary character range.
-inline bool IsSupplementalCodePoint(uint32 cp) {
-  // Optimized form of:
-  // return kMinSupplementaryCodePoint <= cp && cp <= kMaxCodePoint;
-  // (Reduced from 3 ALU instructions to 2 ALU instructions)
-  return (cp & ~(JsonEscaping::kMinSupplementaryCodePoint - 1))
-      < JsonEscaping::kMaxCodePoint;
-}
-
 // Returns true if the given unicode code point cp is a valid
 // unicode code point (i.e. in the range 0 <= cp <= kMaxCodePoint).
 inline bool IsValidCodePoint(uint32 cp) {
   return cp <= JsonEscaping::kMaxCodePoint;
 }
 
-// Converts the specified surrogate pair to its supplementary code point value.
-// It is the callers' responsibility to validate the specified surrogate pair.
-inline uint32 ToCodePoint(uint16 high, uint16 low) {
-  // Optimized form of:
-  // return ((high - kMinHighSurrogate) << 10)
-  //     + (low - kMinLowSurrogate)
-  //     + kMinSupplementaryCodePoint;
-  // (Reduced from 5 ALU instructions to 3 ALU instructions)
-  return (high << 10) + low +
-      (JsonEscaping::kMinSupplementaryCodePoint
-       - (static_cast<unsigned>(JsonEscaping::kMinHighSurrogate) << 10)
-       - JsonEscaping::kMinLowSurrogate);
-}
-
 // Returns the low surrogate for the given unicode code point. The result is
 // meaningless if the given code point is not a supplementary character.
 inline uint16 ToLowSurrogate(uint32 cp) {
diff --git a/src/google/protobuf/util/internal/json_stream_parser.cc b/src/google/protobuf/util/internal/json_stream_parser.cc
index b38030c..047c14e 100644
--- a/src/google/protobuf/util/internal/json_stream_parser.cc
+++ b/src/google/protobuf/util/internal/json_stream_parser.cc
@@ -130,7 +130,7 @@
     // Don't point chunk to leftover_ because leftover_ will be updated in
     // ParseChunk(chunk).
     chunk_storage_.swap(leftover_);
-    json.AppendToString(&chunk_storage_);
+    StrAppend(&chunk_storage_, json);
     chunk = StringPiece(chunk_storage_);
   }
 
@@ -141,11 +141,11 @@
 
     // Any leftover characters are stashed in leftover_ for later parsing when
     // there is more data available.
-    chunk.substr(n).AppendToString(&leftover_);
+    StrAppend(&leftover_, chunk.substr(n));
     return status;
   } else {
-    chunk.CopyToString(&leftover_);
-    return util::Status::OK;
+    leftover_.assign(chunk.data(), chunk.size());
+    return util::Status();
   }
 }
 
@@ -153,7 +153,7 @@
   // If we do not expect anything and there is nothing left to parse we're all
   // done.
   if (stack_.empty() && leftover_.empty()) {
-    return util::Status::OK;
+    return util::Status();
   }
 
   // Storage for UTF8-coerced string.
@@ -184,7 +184,7 @@
 
 util::Status JsonStreamParser::ParseChunk(StringPiece chunk) {
   // Do not do any work if the chunk is empty.
-  if (chunk.empty()) return util::Status::OK;
+  if (chunk.empty()) return util::Status();
 
   p_ = json_ = chunk;
 
@@ -206,7 +206,7 @@
     // unparsed data left, we save it for later parse.
     leftover_ = p_.ToString();
   }
-  return util::Status::OK;
+  return util::Status();
 }
 
 util::Status JsonStreamParser::RunParser() {
@@ -252,15 +252,15 @@
         // If we have a key we still need to render, make sure to save off the
         // contents in our own storage.
         if (!key_.empty() && key_storage_.empty()) {
-          key_.AppendToString(&key_storage_);
+          StrAppend(&key_storage_, key_);
           key_ = StringPiece(key_storage_);
         }
-        result = util::Status::OK;
+        result = util::Status();
       }
       return result;
     }
   }
-  return util::Status::OK;
+  return util::Status();
 }
 
 util::Status JsonStreamParser::ParseValue(TokenType type) {
@@ -386,7 +386,7 @@
       // start fresh.
       string_open_ = 0;
       Advance();
-      return util::Status::OK;
+      return util::Status();
     }
     // Normal character, just advance past it.
     Advance();
@@ -468,7 +468,7 @@
   // Advance past the [final] code unit escape.
   p_.remove_prefix(kUnicodeEscapedLength);
   parsed_storage_.append(buf, len);
-  return util::Status::OK;
+  return util::Status();
 }
 
 util::Status JsonStreamParser::ParseNumber() {
@@ -542,7 +542,7 @@
     }
     result->type = NumberResult::DOUBLE;
     p_.remove_prefix(index);
-    return util::Status::OK;
+    return util::Status();
   }
 
   // Positive non-floating point number, parse as a uint64.
@@ -556,7 +556,7 @@
     }
     result->type = NumberResult::UINT;
     p_.remove_prefix(index);
-    return util::Status::OK;
+    return util::Status();
   }
 
   // Octal/Hex numbers are not valid JSON values.
@@ -569,7 +569,7 @@
   }
   result->type = NumberResult::INT;
   p_.remove_prefix(index);
-  return util::Status::OK;
+  return util::Status();
 }
 
 util::Status JsonStreamParser::HandleBeginObject() {
@@ -578,7 +578,7 @@
   ow_->StartObject(key_);
   key_ = StringPiece();
   stack_.push(ENTRY);
-  return util::Status::OK;
+  return util::Status();
 }
 
 util::Status JsonStreamParser::ParseObjectMid(TokenType type) {
@@ -590,13 +590,13 @@
   if (type == END_OBJECT) {
     Advance();
     ow_->EndObject();
-    return util::Status::OK;
+    return util::Status();
   }
   // Found a comma, advance past it and get ready for an entry.
   if (type == VALUE_SEPARATOR) {
     Advance();
     stack_.push(ENTRY);
-    return util::Status::OK;
+    return util::Status();
   }
   // Illegal token after key:value pair.
   return ReportFailure("Expected , or } after key:value pair.");
@@ -611,7 +611,7 @@
   if (type == END_OBJECT) {
     ow_->EndObject();
     Advance();
-    return util::Status::OK;
+    return util::Status();
   }
 
   util::Status result;
@@ -650,7 +650,7 @@
   if (type == ENTRY_SEPARATOR) {
     Advance();
     stack_.push(VALUE);
-    return util::Status::OK;
+    return util::Status();
   }
   return ReportFailure("Expected : between key:value pair.");
 }
@@ -661,7 +661,7 @@
   ow_->StartList(key_);
   key_ = StringPiece();
   stack_.push(ARRAY_VALUE);
-  return util::Status::OK;
+  return util::Status();
 }
 
 util::Status JsonStreamParser::ParseArrayValue(TokenType type) {
@@ -672,7 +672,7 @@
   if (type == END_ARRAY) {
     ow_->EndList();
     Advance();
-    return util::Status::OK;
+    return util::Status();
   }
 
   // The ParseValue call may push something onto the stack so we need to make
@@ -696,14 +696,14 @@
   if (type == END_ARRAY) {
     ow_->EndList();
     Advance();
-    return util::Status::OK;
+    return util::Status();
   }
 
   // Found a comma, advance past it and expect an array value next.
   if (type == VALUE_SEPARATOR) {
     Advance();
     stack_.push(ARRAY_VALUE);
-    return util::Status::OK;
+    return util::Status();
   }
   // Illegal token after array value.
   return ReportFailure("Expected , or ] after array value.");
@@ -713,27 +713,27 @@
   ow_->RenderBool(key_, true);
   key_ = StringPiece();
   p_.remove_prefix(true_len);
-  return util::Status::OK;
+  return util::Status();
 }
 
 util::Status JsonStreamParser::ParseFalse() {
   ow_->RenderBool(key_, false);
   key_ = StringPiece();
   p_.remove_prefix(false_len);
-  return util::Status::OK;
+  return util::Status();
 }
 
 util::Status JsonStreamParser::ParseNull() {
   ow_->RenderNull(key_);
   key_ = StringPiece();
   p_.remove_prefix(null_len);
-  return util::Status::OK;
+  return util::Status();
 }
 
 util::Status JsonStreamParser::ParseEmptyNull() {
   ow_->RenderNull(key_);
   key_ = StringPiece();
-  return util::Status::OK;
+  return util::Status();
 }
 
 bool JsonStreamParser::IsEmptyNullAllowed(TokenType type) {
@@ -793,7 +793,7 @@
   }
   // Since we aren't using the key storage, clear it out.
   key_storage_.clear();
-  return util::Status::OK;
+  return util::Status();
 }
 
 JsonStreamParser::TokenType JsonStreamParser::GetNextTokenType() {
diff --git a/src/google/protobuf/util/internal/proto_writer.h b/src/google/protobuf/util/internal/proto_writer.h
index 21dff88..0db8485 100644
--- a/src/google/protobuf/util/internal/proto_writer.h
+++ b/src/google/protobuf/util/internal/proto_writer.h
@@ -81,32 +81,32 @@
   virtual ~ProtoWriter();
 
   // ObjectWriter methods.
-  virtual ProtoWriter* StartObject(StringPiece name);
-  virtual ProtoWriter* EndObject();
-  virtual ProtoWriter* StartList(StringPiece name);
-  virtual ProtoWriter* EndList();
-  virtual ProtoWriter* RenderBool(StringPiece name, bool value) {
+  ProtoWriter* StartObject(StringPiece name);
+  ProtoWriter* EndObject();
+  ProtoWriter* StartList(StringPiece name);
+  ProtoWriter* EndList();
+  ProtoWriter* RenderBool(StringPiece name, bool value) {
     return RenderDataPiece(name, DataPiece(value));
   }
-  virtual ProtoWriter* RenderInt32(StringPiece name, int32 value) {
+  ProtoWriter* RenderInt32(StringPiece name, int32 value) {
     return RenderDataPiece(name, DataPiece(value));
   }
-  virtual ProtoWriter* RenderUint32(StringPiece name, uint32 value) {
+  ProtoWriter* RenderUint32(StringPiece name, uint32 value) {
     return RenderDataPiece(name, DataPiece(value));
   }
-  virtual ProtoWriter* RenderInt64(StringPiece name, int64 value) {
+  ProtoWriter* RenderInt64(StringPiece name, int64 value) {
     return RenderDataPiece(name, DataPiece(value));
   }
-  virtual ProtoWriter* RenderUint64(StringPiece name, uint64 value) {
+  ProtoWriter* RenderUint64(StringPiece name, uint64 value) {
     return RenderDataPiece(name, DataPiece(value));
   }
-  virtual ProtoWriter* RenderDouble(StringPiece name, double value) {
+  ProtoWriter* RenderDouble(StringPiece name, double value) {
     return RenderDataPiece(name, DataPiece(value));
   }
-  virtual ProtoWriter* RenderFloat(StringPiece name, float value) {
+  ProtoWriter* RenderFloat(StringPiece name, float value) {
     return RenderDataPiece(name, DataPiece(value));
   }
-  virtual ProtoWriter* RenderString(StringPiece name, StringPiece value) {
+  ProtoWriter* RenderString(StringPiece name, StringPiece value) {
     return RenderDataPiece(name,
                            DataPiece(value, use_strict_base64_decoding()));
   }
@@ -114,7 +114,7 @@
     return RenderDataPiece(
         name, DataPiece(value, false, use_strict_base64_decoding()));
   }
-  virtual ProtoWriter* RenderNull(StringPiece name) {
+  ProtoWriter* RenderNull(StringPiece name) {
     return RenderDataPiece(name, DataPiece::NullData());
   }
 
@@ -242,7 +242,7 @@
   ProtoWriter(const TypeInfo* typeinfo, const google::protobuf::Type& type,
               strings::ByteSink* output, ErrorListener* listener);
 
-  virtual ProtoElement* element() { return element_.get(); }
+  ProtoElement* element() { return element_.get(); }
 
   // Helper methods for calling ErrorListener. See error_listener.h.
   void InvalidName(StringPiece unknown_name, StringPiece message);
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc
index 61491af..025fbd4 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource.cc
@@ -240,7 +240,7 @@
   if (include_start_and_end) {
     ow->EndObject();
   }
-  return Status::OK;
+  return util::Status();
 }
 
 StatusOr<uint32> ProtoStreamObjectSource::RenderList(
@@ -322,7 +322,7 @@
     RETURN_IF_ERROR(RenderField(field, StringPiece(), ow));
   }
   stream_->PopLimit(old_limit);
-  return Status::OK;
+  return util::Status();
 }
 
 Status ProtoStreamObjectSource::RenderTimestamp(
@@ -346,7 +346,7 @@
   ow->RenderString(field_name,
                    ::google::protobuf::internal::FormatTime(seconds, nanos));
 
-  return Status::OK;
+  return util::Status();
 }
 
 Status ProtoStreamObjectSource::RenderDuration(
@@ -387,7 +387,7 @@
       FormatNanos(nanos, os->add_trailing_zeros_for_timestamp_and_duration_)
           .c_str());
   ow->RenderString(field_name, formatted_duration);
-  return Status::OK;
+  return util::Status();
 }
 
 Status ProtoStreamObjectSource::RenderDouble(const ProtoStreamObjectSource* os,
@@ -401,7 +401,7 @@
     os->stream_->ReadTag();
   }
   ow->RenderDouble(field_name, bit_cast<double>(buffer64));
-  return Status::OK;
+  return util::Status();
 }
 
 Status ProtoStreamObjectSource::RenderFloat(const ProtoStreamObjectSource* os,
@@ -415,7 +415,7 @@
     os->stream_->ReadTag();
   }
   ow->RenderFloat(field_name, bit_cast<float>(buffer32));
-  return Status::OK;
+  return util::Status();
 }
 
 Status ProtoStreamObjectSource::RenderInt64(const ProtoStreamObjectSource* os,
@@ -429,7 +429,7 @@
     os->stream_->ReadTag();
   }
   ow->RenderInt64(field_name, bit_cast<int64>(buffer64));
-  return Status::OK;
+  return util::Status();
 }
 
 Status ProtoStreamObjectSource::RenderUInt64(const ProtoStreamObjectSource* os,
@@ -443,7 +443,7 @@
     os->stream_->ReadTag();
   }
   ow->RenderUint64(field_name, bit_cast<uint64>(buffer64));
-  return Status::OK;
+  return util::Status();
 }
 
 Status ProtoStreamObjectSource::RenderInt32(const ProtoStreamObjectSource* os,
@@ -457,7 +457,7 @@
     os->stream_->ReadTag();
   }
   ow->RenderInt32(field_name, bit_cast<int32>(buffer32));
-  return Status::OK;
+  return util::Status();
 }
 
 Status ProtoStreamObjectSource::RenderUInt32(const ProtoStreamObjectSource* os,
@@ -471,7 +471,7 @@
     os->stream_->ReadTag();
   }
   ow->RenderUint32(field_name, bit_cast<uint32>(buffer32));
-  return Status::OK;
+  return util::Status();
 }
 
 Status ProtoStreamObjectSource::RenderBool(const ProtoStreamObjectSource* os,
@@ -486,7 +486,7 @@
     os->stream_->ReadTag();
   }
   ow->RenderBool(field_name, buffer64 != 0);
-  return Status::OK;
+  return util::Status();
 }
 
 Status ProtoStreamObjectSource::RenderString(const ProtoStreamObjectSource* os,
@@ -502,7 +502,7 @@
     os->stream_->ReadTag();
   }
   ow->RenderString(field_name, str);
-  return Status::OK;
+  return util::Status();
 }
 
 Status ProtoStreamObjectSource::RenderBytes(const ProtoStreamObjectSource* os,
@@ -518,7 +518,7 @@
     os->stream_->ReadTag();
   }
   ow->RenderBytes(field_name, str);
-  return Status::OK;
+  return util::Status();
 }
 
 Status ProtoStreamObjectSource::RenderStruct(const ProtoStreamObjectSource* os,
@@ -537,7 +537,7 @@
     }
   }
   ow->EndObject();
-  return Status::OK;
+  return util::Status();
 }
 
 Status ProtoStreamObjectSource::RenderStructValue(
@@ -553,7 +553,7 @@
     }
     RETURN_IF_ERROR(os->RenderField(field, field_name, ow));
   }
-  return Status::OK;
+  return util::Status();
 }
 
 // TODO(skarvaje): Avoid code duplication of for loops and SkipField logic.
@@ -566,7 +566,7 @@
   if (tag == 0) {
     ow->StartList(field_name);
     ow->EndList();
-    return Status::OK;
+    return util::Status();
   }
 
   while (tag != 0) {
@@ -578,7 +578,7 @@
     }
     ASSIGN_OR_RETURN(tag, os->RenderList(field, field_name, tag, ow));
   }
-  return Status::OK;
+  return util::Status();
 }
 
 Status ProtoStreamObjectSource::RenderAny(const ProtoStreamObjectSource* os,
@@ -620,7 +620,7 @@
       ow->RenderString("@type", type_url);
     }
     ow->EndObject();
-    return util::Status::OK;
+    return util::Status();
   }
 
   // If there is a value but no type, we cannot render it, so report an error.
@@ -685,7 +685,7 @@
     combined.append(ConvertFieldMaskPath(str, &ToCamelCase));
   }
   ow->RenderString(field_name, combined);
-  return Status::OK;
+  return util::Status();
 }
 
 
@@ -781,7 +781,7 @@
     // Render all other non-message types.
     return RenderNonMessageField(field, field_name, ow);
   }
-  return Status::OK;
+  return util::Status();
 }
 
 Status ProtoStreamObjectSource::RenderNonMessageField(
@@ -910,7 +910,7 @@
     default:
       break;
   }
-  return Status::OK;
+  return util::Status();
 }
 
 // TODO(skarvaje): Fix this to avoid code duplication.
@@ -1079,7 +1079,7 @@
         StrCat("Message too deep. Max recursion depth reached for type '",
                type_name, "', field '", field_name, "'"));
   }
-  return Status::OK;
+  return util::Status();
 }
 
 namespace {
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h
index 5f443d9..58d77c2 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.h
+++ b/src/google/protobuf/util/internal/protostream_objectsource.h
@@ -112,9 +112,7 @@
 
   // Sets whether to always output enums as ints, by default this is off, and
   // enums are rendered as strings.
-  void set_use_ints_for_enums(bool value) {
-    use_ints_for_enums_ = value;
-  }
+  void set_use_ints_for_enums(bool value) { use_ints_for_enums_ = value; }
 
   // Sets whether to use original proto field names
   void set_preserve_proto_field_names(bool value) {
diff --git a/src/google/protobuf/util/internal/protostream_objectsource_test.cc b/src/google/protobuf/util/internal/protostream_objectsource_test.cc
index e215c4a..06c9bb6 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource_test.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource_test.cc
@@ -111,7 +111,7 @@
 
   void DoTest(const Message& msg, const Descriptor* descriptor) {
     Status status = ExecuteTest(msg, descriptor);
-    EXPECT_EQ(Status::OK, status);
+    EXPECT_EQ(util::Status(), status);
   }
 
   Status ExecuteTest(const Message& msg, const Descriptor* descriptor) {
@@ -509,9 +509,7 @@
 
   UseIntsForEnums();
 
-  ow_.StartObject("")
-      ->RenderInt32("type", 3)
-      ->EndObject();
+  ow_.StartObject("")->RenderInt32("type", 3)->EndObject();
   DoTest(book, Book::descriptor());
 }
 
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc
index 6c9bc30..d4e15bc 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc
@@ -173,7 +173,7 @@
     *nanos = i_nanos * conversion;
   }
 
-  return Status::OK;
+  return Status();
 }
 
 }  // namespace
@@ -409,7 +409,7 @@
   // string value stays valid, we make a copy of the string value and update
   // DataPiece to reference our own copy.
   if (value_.type() == DataPiece::TYPE_STRING) {
-    value_.str().AppendToString(&value_storage_);
+    StrAppend(&value_storage_, value_.str());
     value_ = DataPiece(value_storage_, value_.use_strict_base64_decoding());
   } else if (value_.type() == DataPiece::TYPE_BYTES) {
     value_storage_ = value_.ToBytes().ValueOrDie();
@@ -862,7 +862,7 @@
           ow->ProtoWriter::RenderDataPiece(
               "string_value",
               DataPiece(SimpleItoa(int_value.ValueOrDie()), true));
-          return Status::OK;
+          return Status();
         }
       }
       struct_field_name = "number_value";
@@ -877,13 +877,22 @@
           ow->ProtoWriter::RenderDataPiece(
               "string_value",
               DataPiece(SimpleItoa(int_value.ValueOrDie()), true));
-          return Status::OK;
+          return Status();
         }
       }
       struct_field_name = "number_value";
       break;
     }
     case DataPiece::TYPE_DOUBLE: {
+      if (ow->options_.struct_integers_as_strings) {
+        StatusOr<double> double_value = data.ToDouble();
+        if (double_value.ok()) {
+          ow->ProtoWriter::RenderDataPiece(
+              "string_value",
+              DataPiece(SimpleDtoa(double_value.ValueOrDie()), true));
+          return Status();
+        }
+      }
       struct_field_name = "number_value";
       break;
     }
@@ -906,12 +915,12 @@
     }
   }
   ow->ProtoWriter::RenderDataPiece(struct_field_name, data);
-  return Status::OK;
+  return Status();
 }
 
 Status ProtoStreamObjectWriter::RenderTimestamp(ProtoStreamObjectWriter* ow,
                                                 const DataPiece& data) {
-  if (data.type() == DataPiece::TYPE_NULL) return Status::OK;
+  if (data.type() == DataPiece::TYPE_NULL) return Status();
   if (data.type() != DataPiece::TYPE_STRING) {
     return Status(INVALID_ARGUMENT,
                   StrCat("Invalid data type for timestamp, value is ",
@@ -930,19 +939,19 @@
 
   ow->ProtoWriter::RenderDataPiece("seconds", DataPiece(seconds));
   ow->ProtoWriter::RenderDataPiece("nanos", DataPiece(nanos));
-  return Status::OK;
+  return Status();
 }
 
 static inline util::Status RenderOneFieldPath(ProtoStreamObjectWriter* ow,
                                                 StringPiece path) {
   ow->ProtoWriter::RenderDataPiece(
       "paths", DataPiece(ConvertFieldMaskPath(path, &ToSnakeCase), true));
-  return Status::OK;
+  return Status();
 }
 
 Status ProtoStreamObjectWriter::RenderFieldMask(ProtoStreamObjectWriter* ow,
                                                 const DataPiece& data) {
-  if (data.type() == DataPiece::TYPE_NULL) return Status::OK;
+  if (data.type() == DataPiece::TYPE_NULL) return Status();
   if (data.type() != DataPiece::TYPE_STRING) {
     return Status(INVALID_ARGUMENT,
                   StrCat("Invalid data type for field mask, value is ",
@@ -959,7 +968,7 @@
 
 Status ProtoStreamObjectWriter::RenderDuration(ProtoStreamObjectWriter* ow,
                                                const DataPiece& data) {
-  if (data.type() == DataPiece::TYPE_NULL) return Status::OK;
+  if (data.type() == DataPiece::TYPE_NULL) return Status();
   if (data.type() != DataPiece::TYPE_STRING) {
     return Status(INVALID_ARGUMENT,
                   StrCat("Invalid data type for duration, value is ",
@@ -1004,14 +1013,14 @@
 
   ow->ProtoWriter::RenderDataPiece("seconds", DataPiece(seconds));
   ow->ProtoWriter::RenderDataPiece("nanos", DataPiece(nanos));
-  return Status::OK;
+  return Status();
 }
 
 Status ProtoStreamObjectWriter::RenderWrapperType(ProtoStreamObjectWriter* ow,
                                                   const DataPiece& data) {
-  if (data.type() == DataPiece::TYPE_NULL) return Status::OK;
+  if (data.type() == DataPiece::TYPE_NULL) return Status();
   ow->ProtoWriter::RenderDataPiece("value", data);
-  return Status::OK;
+  return Status();
 }
 
 ProtoStreamObjectWriter* ProtoStreamObjectWriter::RenderDataPiece(
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.h b/src/google/protobuf/util/internal/protostream_objectwriter.h
index 732971e..ab53491 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.h
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.h
@@ -76,11 +76,14 @@
  public:
   // Options that control ProtoStreamObjectWriter class's behavior.
   struct Options {
-    // Treats integer inputs in google.protobuf.Struct as strings. Normally,
-    // integer values are returned in double field "number_value" of
+    // Treats numeric inputs in google.protobuf.Struct as strings. Normally,
+    // numeric values are returned in double field "number_value" of
     // google.protobuf.Struct. However, this can cause precision loss for
-    // int64/uint64 inputs. This option is provided for cases that want to
-    // preserve integer precision.
+    // int64/uint64/double inputs. This option is provided for cases that want
+    // to preserve number precision.
+    //
+    // TODO(skarvaje): Rename to struct_numbers_as_strings as it covers double
+    // as well.
     bool struct_integers_as_strings;
 
     // Not treat unknown fields as an error. If there is an unknown fields,
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
index 97ef8ff..87d35b0 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
@@ -279,17 +279,13 @@
   ResetTypeInfo(TestJsonName1::descriptor());
   TestJsonName1 message1;
   message1.set_one_value(12345);
-  ow_->StartObject("")
-      ->RenderInt32("value", 12345)
-      ->EndObject();
+  ow_->StartObject("")->RenderInt32("value", 12345)->EndObject();
   CheckOutput(message1);
 
   ResetTypeInfo(TestJsonName2::descriptor());
   TestJsonName2 message2;
   message2.set_another_value(12345);
-  ow_->StartObject("")
-      ->RenderInt32("value", 12345)
-      ->EndObject();
+  ow_->StartObject("")->RenderInt32("value", 12345)->EndObject();
   CheckOutput(message2);
 }
 
@@ -1615,7 +1611,7 @@
 TEST_P(ProtoStreamObjectWriterStructTest, OptionStructIntAsStringsTest) {
   StructType struct_type;
   google::protobuf::Struct* s = struct_type.mutable_object();
-  s->mutable_fields()->operator[]("k1").set_number_value(123);
+  s->mutable_fields()->operator[]("k1").set_string_value("123");
   s->mutable_fields()->operator[]("k2").set_bool_value(true);
   s->mutable_fields()->operator[]("k3").set_string_value("-222222222");
   s->mutable_fields()->operator[]("k4").set_string_value("33333333");
diff --git a/src/google/protobuf/util/internal/type_info.cc b/src/google/protobuf/util/internal/type_info.cc
index a5d903f..85d0d5c 100644
--- a/src/google/protobuf/util/internal/type_info.cc
+++ b/src/google/protobuf/util/internal/type_info.cc
@@ -107,10 +107,12 @@
 
   virtual const google::protobuf::Field* FindField(
       const google::protobuf::Type* type, StringPiece camel_case_name) const {
-    std::map<const google::protobuf::Type*,
-            CamelCaseNameTable>::const_iterator it = indexed_types_.find(type);
-    const CamelCaseNameTable& camel_case_name_table = (it == indexed_types_.end())
-        ? PopulateNameLookupTable(type, &indexed_types_[type]) : it->second;
+    std::map<const google::protobuf::Type*, CamelCaseNameTable>::const_iterator
+        it = indexed_types_.find(type);
+    const CamelCaseNameTable& camel_case_name_table =
+        (it == indexed_types_.end())
+            ? PopulateNameLookupTable(type, &indexed_types_[type])
+            : it->second;
     StringPiece name =
         FindWithDefault(camel_case_name_table, camel_case_name, StringPiece());
     if (name.empty()) {
@@ -142,8 +144,8 @@
       const google::protobuf::Field& field = type->fields(i);
       StringPiece name = field.name();
       StringPiece camel_case_name = field.json_name();
-      const StringPiece* existing = InsertOrReturnExisting(
-          camel_case_name_table, camel_case_name, name);
+      const StringPiece* existing =
+          InsertOrReturnExisting(camel_case_name_table, camel_case_name, name);
       if (existing && *existing != name) {
         GOOGLE_LOG(WARNING) << "Field '" << name << "' and '" << *existing
                      << "' map to the same camel case name '" << camel_case_name
@@ -162,8 +164,8 @@
   mutable std::map<StringPiece, StatusOrType> cached_types_;
   mutable std::map<StringPiece, StatusOrEnum> cached_enums_;
 
-  mutable std::map<const google::protobuf::Type*,
-                   CamelCaseNameTable> indexed_types_;
+  mutable std::map<const google::protobuf::Type*, CamelCaseNameTable>
+      indexed_types_;
 };
 }  // namespace
 
diff --git a/src/google/protobuf/util/internal/utility.cc b/src/google/protobuf/util/internal/utility.cc
index 6daf24e..8cf42e4 100644
--- a/src/google/protobuf/util/internal/utility.cc
+++ b/src/google/protobuf/util/internal/utility.cc
@@ -48,16 +48,6 @@
 namespace util {
 namespace converter {
 
-namespace {
-const StringPiece SkipWhiteSpace(StringPiece str) {
-  StringPiece::size_type i;
-  for (i = 0; i < str.size() && isspace(str[i]); ++i) {
-  }
-  GOOGLE_DCHECK(i == str.size() || !isspace(str[i]));
-  return str.substr(i);
-}
-}  // namespace
-
 bool GetBoolOptionOrDefault(
     const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options,
     const string& option_name, bool default_value) {
diff --git a/src/google/protobuf/util/json_util.cc b/src/google/protobuf/util/json_util.cc
index 8595a88..c85f189 100644
--- a/src/google/protobuf/util/json_util.cc
+++ b/src/google/protobuf/util/json_util.cc
@@ -84,7 +84,7 @@
   converter::ProtoStreamObjectSource proto_source(&in_stream, resolver, type);
   proto_source.set_use_ints_for_enums(options.always_print_enums_as_ints);
   proto_source.set_preserve_proto_field_names(
-          options.preserve_proto_field_names);
+      options.preserve_proto_field_names);
   io::CodedOutputStream out_stream(json_output);
   converter::JsonObjectWriter json_writer(options.add_whitespace ? " " : "",
                                           &out_stream);
@@ -92,7 +92,7 @@
     converter::DefaultValueObjectWriter default_value_writer(
         resolver, type, &json_writer);
     default_value_writer.set_preserve_proto_field_names(
-            options.preserve_proto_field_names);
+        options.preserve_proto_field_names);
     return proto_source.WriteTo(&default_value_writer);
   } else {
     return proto_source.WriteTo(&json_writer);
@@ -113,7 +113,7 @@
 namespace {
 class StatusErrorListener : public converter::ErrorListener {
  public:
-  StatusErrorListener() : status_(util::Status::OK) {}
+  StatusErrorListener() {}
   virtual ~StatusErrorListener() {}
 
   util::Status GetStatus() { return status_; }
diff --git a/src/google/protobuf/util/json_util.h b/src/google/protobuf/util/json_util.h
index dd9a736..f4f4380 100644
--- a/src/google/protobuf/util/json_util.h
+++ b/src/google/protobuf/util/json_util.h
@@ -67,11 +67,11 @@
   // Whether to preserve proto field names
   bool preserve_proto_field_names;
 
-  JsonPrintOptions() : add_whitespace(false),
-                       always_print_primitive_fields(false),
-                       always_print_enums_as_ints(false),
-                       preserve_proto_field_names(false) {
-  }
+  JsonPrintOptions()
+      : add_whitespace(false),
+        always_print_primitive_fields(false),
+        always_print_enums_as_ints(false),
+        preserve_proto_field_names(false) {}
 };
 
 // DEPRECATED. Use JsonPrintOptions instead.
diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc
index 7c03d67..25c7e96 100644
--- a/src/google/protobuf/util/json_util_test.cc
+++ b/src/google/protobuf/util/json_util_test.cc
@@ -52,14 +52,10 @@
 using proto3::TestMessage;
 using proto3::TestMap;
 using proto3::TestOneof;
-using testing::MapIn;
+using google::protobuf::testing::MapIn;
 
 static const char kTypeUrlPrefix[] = "type.googleapis.com";
 
-static string GetTypeUrl(const Descriptor* message) {
-  return string(kTypeUrlPrefix) + "/" + message->full_name();
-}
-
 // As functions defined in json_util.h are just thin wrappers around the
 // JSON conversion code in //net/proto2/util/converter, in this test we
 // only cover some very basic cases to make sure the wrappers have forwarded
@@ -207,8 +203,7 @@
   JsonPrintOptions print_options;
   print_options.always_print_enums_as_ints = true;
 
-  string expected_json =
-    "{\"enumValue\":1,\"repeatedEnumValue\":[0,1]}";
+  string expected_json = "{\"enumValue\":1,\"repeatedEnumValue\":[0,1]}";
   EXPECT_EQ(expected_json, ToJson(orig, print_options));
 
   TestMessage parsed;
@@ -264,7 +259,8 @@
   JsonPrintOptions print_options;
   print_options.always_print_primitive_fields = true;
   JsonParseOptions parse_options;
-  EXPECT_EQ("{\"other\":\"\",\"things\":[],\"mapInput\":{}}", ToJson(message, print_options));
+  EXPECT_EQ("{\"other\":\"\",\"things\":[],\"mapInput\":{}}",
+            ToJson(message, print_options));
   MapIn other;
   ASSERT_TRUE(FromJson(ToJson(message, print_options), &other, parse_options));
   EXPECT_EQ(message.DebugString(), other.DebugString());
@@ -275,14 +271,10 @@
   JsonPrintOptions options;
   options.always_print_primitive_fields = true;
   message.mutable_oneof_message_value();
-  EXPECT_EQ(
-      "{\"oneofMessageValue\":{\"value\":0}}",
-      ToJson(message, options));
+  EXPECT_EQ("{\"oneofMessageValue\":{\"value\":0}}", ToJson(message, options));
 
   message.set_oneof_int32_value(1);
-  EXPECT_EQ(
-      "{\"oneofInt32Value\":1}",
-      ToJson(message, options));
+  EXPECT_EQ("{\"oneofInt32Value\":1}", ToJson(message, options));
 }
 
 TEST_F(JsonUtilTest, TestParseIgnoreUnknownFields) {
diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc
index 203d838..830850b 100644
--- a/src/google/protobuf/util/message_differencer.cc
+++ b/src/google/protobuf/util/message_differencer.cc
@@ -467,6 +467,10 @@
     google::protobuf::scoped_ptr<Message> data1;
     google::protobuf::scoped_ptr<Message> data2;
     if (UnpackAny(message1, &data1) && UnpackAny(message2, &data2)) {
+      // Avoid DFATAL for different descriptors in google.protobuf.Any payloads.
+      if (data1->GetDescriptor() != data2->GetDescriptor()) {
+        return false;
+      }
       return Compare(*data1, *data2, parent_fields);
     }
   }
@@ -849,7 +853,8 @@
       parent_fields->pop_back();
       fieldDifferent = true;
     } else if (reporter_ != NULL &&
-               specific_field.index != specific_field.new_index) {
+               specific_field.index != specific_field.new_index &&
+               !specific_field.field->is_map()) {
       parent_fields->push_back(specific_field);
       reporter_->ReportMoved(message1, message2, *parent_fields);
       parent_fields->pop_back();
@@ -1503,6 +1508,10 @@
       } else {
         printer_->PrintRaw(specific_field.field->name());
       }
+      if (specific_field.field->is_map()) {
+        // Don't print index in a map field; they are semantically unordered.
+        continue;
+      }
     } else {
       printer_->PrintRaw(SimpleItoa(specific_field.unknown_field_number));
     }
diff --git a/src/google/protobuf/util/message_differencer_unittest.cc b/src/google/protobuf/util/message_differencer_unittest.cc
index 30b27db..850b397 100755
--- a/src/google/protobuf/util/message_differencer_unittest.cc
+++ b/src/google/protobuf/util/message_differencer_unittest.cc
@@ -38,6 +38,7 @@
 #include <string>
 #include <vector>
 
+#include <google/protobuf/stubs/strutil.h>
 
 #include <google/protobuf/util/field_comparator.h>
 #include <google/protobuf/util/message_differencer.h>
@@ -54,7 +55,6 @@
 
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
 
@@ -2042,6 +2042,9 @@
   unittest::TestEmptyMessage empty1_;
   unittest::TestEmptyMessage empty2_;
 
+  unittest::TestMap map_proto1_;
+  unittest::TestMap map_proto2_;
+
   UnknownFieldSet* unknown1_;
   UnknownFieldSet* unknown2_;
 
@@ -2802,6 +2805,24 @@
   EXPECT_TRUE(util::MessageDifferencer::Equivalent(message1, message2));
 }
 
+TEST_F(ComparisonTest, MapTest) {
+  repeated_field_as_set();
+
+  Map<string, string>& map1 = *map_proto1_.mutable_map_string_string();
+  map1["1"] = "1";
+  map1["2"] = "2";
+  map1["3"] = "3";
+  Map<string, string>& map2 = *map_proto2_.mutable_map_string_string();
+  map2["3"] = "0";
+  map2["2"] = "2";
+  map2["1"] = "1";
+
+  EXPECT_EQ(
+      "added: map_string_string: { key: \"3\" value: \"0\" }\n"
+      "deleted: map_string_string: { key: \"3\" value: \"3\" }\n",
+      Run(map_proto1_, map_proto2_));
+}
+
 class MatchingTest : public testing::Test {
  public:
   typedef util::MessageDifferencer MessageDifferencer;
@@ -3146,6 +3167,24 @@
   EXPECT_TRUE(message_differencer.Compare(m1, m2));
 }
 
+TEST(Anytest, TreatAsSet_DifferentType) {
+  protobuf_unittest::TestField value1;
+  value1.set_a(20);
+  value1.set_b(30);
+  protobuf_unittest::TestDiffMessage value2;
+  value2.add_rv(40);
+
+  protobuf_unittest::TestAny m1, m2;
+  m1.add_repeated_any_value()->PackFrom(value1);
+  m1.add_repeated_any_value()->PackFrom(value2);
+  m2.add_repeated_any_value()->PackFrom(value2);
+  m2.add_repeated_any_value()->PackFrom(value1);
+
+  util::MessageDifferencer message_differencer;
+  message_differencer.TreatAsSet(GetFieldDescriptor(m1, "repeated_any_value"));
+  EXPECT_TRUE(message_differencer.Compare(m1, m2));
+}
+
 
 }  // namespace
 }  // namespace protobuf
diff --git a/src/google/protobuf/util/time_util.cc b/src/google/protobuf/util/time_util.cc
index b11f822..46a6f5a 100644
--- a/src/google/protobuf/util/time_util.cc
+++ b/src/google/protobuf/util/time_util.cc
@@ -49,11 +49,9 @@
 static const int kMicrosPerSecond = 1000000;
 static const int kMillisPerSecond = 1000;
 static const int kNanosPerMillisecond = 1000000;
-static const int kMicrosPerMillisecond = 1000;
 static const int kNanosPerMicrosecond = 1000;
 static const int kSecondsPerMinute = 60;  // Note that we ignore leap seconds.
 static const int kSecondsPerHour = 3600;
-static const char kTimestampFormat[] = "%E4Y-%m-%dT%H:%M:%S";
 
 template <typename T>
 T CreateNormalized(int64 seconds, int64 nanos);
@@ -376,19 +374,6 @@
 using google::protobuf::util::kNanosPerSecond;
 using google::protobuf::util::CreateNormalized;
 
-// Convert a Timestamp to uint128.
-void ToUint128(const Timestamp& value, uint128* result, bool* negative) {
-  if (value.seconds() < 0) {
-    *negative = true;
-    *result = static_cast<uint64>(-value.seconds());
-    *result = *result * kNanosPerSecond - static_cast<uint32>(value.nanos());
-  } else {
-    *negative = false;
-    *result = static_cast<uint64>(value.seconds());
-    *result = *result * kNanosPerSecond + static_cast<uint32>(value.nanos());
-  }
-}
-
 // Convert a Duration to uint128.
 void ToUint128(const Duration& value, uint128* result, bool* negative) {
   if (value.seconds() < 0 || value.nanos() < 0) {
@@ -402,21 +387,6 @@
   }
 }
 
-void ToTimestamp(const uint128& value, bool negative, Timestamp* timestamp) {
-  int64 seconds = static_cast<int64>(Uint128Low64(value / kNanosPerSecond));
-  int32 nanos = static_cast<int32>(Uint128Low64(value % kNanosPerSecond));
-  if (negative) {
-    seconds = -seconds;
-    nanos = -nanos;
-    if (nanos < 0) {
-      nanos += kNanosPerSecond;
-      seconds -= 1;
-    }
-  }
-  timestamp->set_seconds(seconds);
-  timestamp->set_nanos(nanos);
-}
-
 void ToDuration(const uint128& value, bool negative, Duration* duration) {
   int64 seconds = static_cast<int64>(Uint128Low64(value / kNanosPerSecond));
   int32 nanos = static_cast<int32>(Uint128Low64(value % kNanosPerSecond));
diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc
index bd5b248..d3d21c0 100644
--- a/src/google/protobuf/wire_format.cc
+++ b/src/google/protobuf/wire_format.cc
@@ -76,6 +76,8 @@
 bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag,
                            UnknownFieldSet* unknown_fields) {
   int number = WireFormatLite::GetTagFieldNumber(tag);
+  // Field number 0 is illegal.
+  if (number == 0) return false;
 
   switch (WireFormatLite::GetTagWireType(tag)) {
     case WireFormatLite::WIRETYPE_VARINT: {
diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc
index e46ac40..3b139e3 100644
--- a/src/google/protobuf/wire_format_lite.cc
+++ b/src/google/protobuf/wire_format_lite.cc
@@ -47,8 +47,8 @@
 #include <google/protobuf/io/zero_copy_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 
-
 namespace google {
+
 namespace protobuf {
 namespace internal {
 
@@ -123,6 +123,8 @@
 
 bool WireFormatLite::SkipField(
     io::CodedInputStream* input, uint32 tag) {
+  // Field number 0 is illegal.
+  if (WireFormatLite::GetTagFieldNumber(tag) == 0) return false;
   switch (WireFormatLite::GetTagWireType(tag)) {
     case WireFormatLite::WIRETYPE_VARINT: {
       uint64 value;
@@ -168,6 +170,8 @@
 
 bool WireFormatLite::SkipField(
     io::CodedInputStream* input, uint32 tag, io::CodedOutputStream* output) {
+  // Field number 0 is illegal.
+  if (WireFormatLite::GetTagFieldNumber(tag) == 0) return false;
   switch (WireFormatLite::GetTagWireType(tag)) {
     case WireFormatLite::WIRETYPE_VARINT: {
       uint64 value;
@@ -340,6 +344,8 @@
   return true;
 }
 
+#if !defined(PROTOBUF_LITTLE_ENDIAN)
+
 namespace {
 void EncodeFixedSizeValue(float v, uint8* dest) {
   WireFormatLite::WriteFloatNoTagToArray(v, dest);
@@ -370,6 +376,8 @@
 }
 }  // anonymous namespace
 
+#endif  // !defined(PROTOBUF_LITTLE_ENDIAN)
+
 template <typename CType>
 static void WriteArray(const CType* a, int n, io::CodedOutputStream* output) {
 #if defined(PROTOBUF_LITTLE_ENDIAN)
diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h
index 6035514..18b38ea 100644
--- a/src/google/protobuf/wire_format_lite.h
+++ b/src/google/protobuf/wire_format_lite.h
@@ -250,10 +250,6 @@
   // of these methods are defined in wire_format_lite_inl.h; you must #include
   // that file to use these.
 
-// Avoid ugly line wrapping
-#define input  io::CodedInputStream*  input_arg
-#define output io::CodedOutputStream* output_arg
-#define field_number int field_number_arg
 #ifdef NDEBUG
 #define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE
 #else
@@ -270,24 +266,22 @@
   // For primitive fields, we just use a templatized routine parameterized by
   // the represented type and the FieldType. These are specialized with the
   // appropriate definition for each declared type.
-  template <typename CType, enum FieldType DeclaredType> INL
-  static bool ReadPrimitive(input, CType* value);
+  template <typename CType, enum FieldType DeclaredType>
+  INL static bool ReadPrimitive(io::CodedInputStream* input, CType* value);
 
   // Reads repeated primitive values, with optimizations for repeats.
   // tag_size and tag should both be compile-time constants provided by the
   // protocol compiler.
-  template <typename CType, enum FieldType DeclaredType> INL
-  static bool ReadRepeatedPrimitive(int tag_size,
-                                    uint32 tag,
-                                    input,
-                                    RepeatedField<CType>* value);
+  template <typename CType, enum FieldType DeclaredType>
+  INL static bool ReadRepeatedPrimitive(int tag_size, uint32 tag,
+                                        io::CodedInputStream* input,
+                                        RepeatedField<CType>* value);
 
   // Identical to ReadRepeatedPrimitive, except will not inline the
   // implementation.
   template <typename CType, enum FieldType DeclaredType>
-  static bool ReadRepeatedPrimitiveNoInline(int tag_size,
-                                            uint32 tag,
-                                            input,
+  static bool ReadRepeatedPrimitiveNoInline(int tag_size, uint32 tag,
+                                            io::CodedInputStream* input,
                                             RepeatedField<CType>* value);
 
   // Reads a primitive value directly from the provided buffer. It returns a
@@ -301,39 +295,39 @@
   // Reads a primitive packed field.
   //
   // This is only implemented for packable types.
-  template <typename CType, enum FieldType DeclaredType> INL
-  static bool ReadPackedPrimitive(input, RepeatedField<CType>* value);
+  template <typename CType, enum FieldType DeclaredType>
+  INL static bool ReadPackedPrimitive(io::CodedInputStream* input,
+                                      RepeatedField<CType>* value);
 
   // Identical to ReadPackedPrimitive, except will not inline the
   // implementation.
   template <typename CType, enum FieldType DeclaredType>
-  static bool ReadPackedPrimitiveNoInline(input, RepeatedField<CType>* value);
+  static bool ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
+                                          RepeatedField<CType>* value);
 
   // 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,
+  static bool ReadPackedEnumNoInline(io::CodedInputStream* input,
                                      bool (*is_valid)(int),
                                      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);
+      io::CodedInputStream* input, int 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);
+  static inline bool ReadString(io::CodedInputStream* input, string* value);
   // ReadString(..., string** p) is internal-only, and should only be called
   // from generated code. It starts by setting *p to "new string"
   // if *p == &GetEmptyStringAlreadyInited().  It then invokes
-  // ReadString(input, *p).  This is useful for reducing code size.
-  static inline bool ReadString(input, string** p);
+  // ReadString(io::CodedInputStream* input, *p).  This is useful for reducing
+  // code size.
+  static inline bool ReadString(io::CodedInputStream* input, string** p);
   // Analogous to ReadString().
-  static bool ReadBytes(input, string* value);
-  static bool ReadBytes(input, string** p);
+  static bool ReadBytes(io::CodedInputStream* input, string* value);
+  static bool ReadBytes(io::CodedInputStream* input, string** p);
 
 
   enum Operation {
@@ -346,195 +340,322 @@
                                Operation op,
                                const char* field_name);
 
-  static inline bool ReadGroup  (field_number, input, MessageLite* value);
-  static inline bool ReadMessage(input, MessageLite* value);
+  static inline bool ReadGroup(int field_number, io::CodedInputStream* input,
+                               MessageLite* value);
+  static inline bool ReadMessage(io::CodedInputStream* input,
+                                 MessageLite* value);
 
   // Like above, but de-virtualize the call to MergePartialFromCodedStream().
   // The pointer must point at an instance of MessageType, *not* a subclass (or
   // the subclass must not override MergePartialFromCodedStream()).
-  template<typename MessageType>
-  static inline bool ReadGroupNoVirtual(field_number, input,
+  template <typename MessageType>
+  static inline bool ReadGroupNoVirtual(int field_number,
+                                        io::CodedInputStream* input,
                                         MessageType* value);
   template<typename MessageType>
-  static inline bool ReadMessageNoVirtual(input, MessageType* value);
+  static inline bool ReadMessageNoVirtual(io::CodedInputStream* input,
+                                          MessageType* value);
 
   // The same, but do not modify input's recursion depth.  This is useful
   // when reading a bunch of groups or messages in a loop, because then the
   // recursion depth can be incremented before the loop and decremented after.
   template<typename MessageType>
-  static inline bool ReadGroupNoVirtualNoRecursionDepth(field_number, input,
-                                                        MessageType* value);
+  static inline bool ReadGroupNoVirtualNoRecursionDepth(
+      int field_number, io::CodedInputStream* input, MessageType* value);
 
   template<typename MessageType>
-  static inline bool ReadMessageNoVirtualNoRecursionDepth(input,
-                                                          MessageType* value);
+  static inline bool ReadMessageNoVirtualNoRecursionDepth(
+      io::CodedInputStream* input, MessageType* value);
 
   // Write a tag.  The Write*() functions typically include the tag, so
   // normally there's no need to call this unless using the Write*NoTag()
   // variants.
-  INL static void WriteTag(field_number, WireType type, output);
+  INL static void WriteTag(int field_number, WireType type,
+                           io::CodedOutputStream* output);
 
   // Write fields, without tags.
-  INL static void WriteInt32NoTag   (int32 value, output);
-  INL static void WriteInt64NoTag   (int64 value, output);
-  INL static void WriteUInt32NoTag  (uint32 value, output);
-  INL static void WriteUInt64NoTag  (uint64 value, output);
-  INL static void WriteSInt32NoTag  (int32 value, output);
-  INL static void WriteSInt64NoTag  (int64 value, output);
-  INL static void WriteFixed32NoTag (uint32 value, output);
-  INL static void WriteFixed64NoTag (uint64 value, output);
-  INL static void WriteSFixed32NoTag(int32 value, output);
-  INL static void WriteSFixed64NoTag(int64 value, output);
-  INL static void WriteFloatNoTag   (float value, output);
-  INL static void WriteDoubleNoTag  (double value, output);
-  INL static void WriteBoolNoTag    (bool value, output);
-  INL static void WriteEnumNoTag    (int value, output);
+  INL static void WriteInt32NoTag(int32 value, io::CodedOutputStream* output);
+  INL static void WriteInt64NoTag(int64 value, io::CodedOutputStream* output);
+  INL static void WriteUInt32NoTag(uint32 value, io::CodedOutputStream* output);
+  INL static void WriteUInt64NoTag(uint64 value, io::CodedOutputStream* output);
+  INL static void WriteSInt32NoTag(int32 value, io::CodedOutputStream* output);
+  INL static void WriteSInt64NoTag(int64 value, io::CodedOutputStream* output);
+  INL static void WriteFixed32NoTag(uint32 value,
+                                    io::CodedOutputStream* output);
+  INL static void WriteFixed64NoTag(uint64 value,
+                                    io::CodedOutputStream* output);
+  INL static void WriteSFixed32NoTag(int32 value,
+                                     io::CodedOutputStream* output);
+  INL static void WriteSFixed64NoTag(int64 value,
+                                     io::CodedOutputStream* output);
+  INL static void WriteFloatNoTag(float value, io::CodedOutputStream* output);
+  INL static void WriteDoubleNoTag(double value, io::CodedOutputStream* output);
+  INL static void WriteBoolNoTag(bool value, io::CodedOutputStream* output);
+  INL static void WriteEnumNoTag(int value, io::CodedOutputStream* output);
 
   // Write array of primitive fields, without tags
-  static void WriteFloatArray   (const float* a, int n, output);
-  static void WriteDoubleArray  (const double* a, int n, output);
-  static void WriteFixed32Array (const uint32* a, int n, output);
-  static void WriteFixed64Array (const uint64* a, int n, output);
-  static void WriteSFixed32Array(const int32* a, int n, output);
-  static void WriteSFixed64Array(const int64* a, int n, output);
-  static void WriteBoolArray    (const bool* a, int n, output);
+  static void WriteFloatArray(const float* a, int n,
+                              io::CodedOutputStream* output);
+  static void WriteDoubleArray(const double* a, int n,
+                               io::CodedOutputStream* output);
+  static void WriteFixed32Array(const uint32* a, int n,
+                                io::CodedOutputStream* output);
+  static void WriteFixed64Array(const uint64* a, int n,
+                                io::CodedOutputStream* output);
+  static void WriteSFixed32Array(const int32* a, int n,
+                                 io::CodedOutputStream* output);
+  static void WriteSFixed64Array(const int64* a, int n,
+                                 io::CodedOutputStream* output);
+  static void WriteBoolArray(const bool* a, int n,
+                             io::CodedOutputStream* output);
 
   // Write fields, including tags.
-  static void WriteInt32   (field_number,  int32 value, output);
-  static void WriteInt64   (field_number,  int64 value, output);
-  static void WriteUInt32  (field_number, uint32 value, output);
-  static void WriteUInt64  (field_number, uint64 value, output);
-  static void WriteSInt32  (field_number,  int32 value, output);
-  static void WriteSInt64  (field_number,  int64 value, output);
-  static void WriteFixed32 (field_number, uint32 value, output);
-  static void WriteFixed64 (field_number, uint64 value, output);
-  static void WriteSFixed32(field_number,  int32 value, output);
-  static void WriteSFixed64(field_number,  int64 value, output);
-  static void WriteFloat   (field_number,  float value, output);
-  static void WriteDouble  (field_number, double value, output);
-  static void WriteBool    (field_number,   bool value, output);
-  static void WriteEnum    (field_number,    int value, output);
+  static void WriteInt32(int field_number, int32 value,
+                         io::CodedOutputStream* output);
+  static void WriteInt64(int field_number, int64 value,
+                         io::CodedOutputStream* output);
+  static void WriteUInt32(int field_number, uint32 value,
+                          io::CodedOutputStream* output);
+  static void WriteUInt64(int field_number, uint64 value,
+                          io::CodedOutputStream* output);
+  static void WriteSInt32(int field_number, int32 value,
+                          io::CodedOutputStream* output);
+  static void WriteSInt64(int field_number, int64 value,
+                          io::CodedOutputStream* output);
+  static void WriteFixed32(int field_number, uint32 value,
+                           io::CodedOutputStream* output);
+  static void WriteFixed64(int field_number, uint64 value,
+                           io::CodedOutputStream* output);
+  static void WriteSFixed32(int field_number, int32 value,
+                            io::CodedOutputStream* output);
+  static void WriteSFixed64(int field_number, int64 value,
+                            io::CodedOutputStream* output);
+  static void WriteFloat(int field_number, float value,
+                         io::CodedOutputStream* output);
+  static void WriteDouble(int field_number, double value,
+                          io::CodedOutputStream* output);
+  static void WriteBool(int field_number, bool value,
+                        io::CodedOutputStream* output);
+  static void WriteEnum(int field_number, int value,
+                        io::CodedOutputStream* output);
 
-  static void WriteString(field_number, const string& value, output);
-  static void WriteBytes (field_number, const string& value, output);
-  static void WriteStringMaybeAliased(
-      field_number, const string& value, output);
-  static void WriteBytesMaybeAliased(
-      field_number, const string& value, output);
+  static void WriteString(int field_number, const string& value,
+                          io::CodedOutputStream* output);
+  static void WriteBytes(int field_number, const string& value,
+                         io::CodedOutputStream* output);
+  static void WriteStringMaybeAliased(int field_number, const string& value,
+                                      io::CodedOutputStream* output);
+  static void WriteBytesMaybeAliased(int field_number, const string& value,
+                                     io::CodedOutputStream* output);
 
-  static void WriteGroup(
-    field_number, const MessageLite& value, output);
-  static void WriteMessage(
-    field_number, const MessageLite& value, output);
+  static void WriteGroup(int field_number, const MessageLite& value,
+                         io::CodedOutputStream* output);
+  static void WriteMessage(int field_number, const MessageLite& value,
+                           io::CodedOutputStream* output);
   // Like above, but these will check if the output stream has enough
   // space to write directly to a flat array.
-  static void WriteGroupMaybeToArray(
-    field_number, const MessageLite& value, output);
-  static void WriteMessageMaybeToArray(
-    field_number, const MessageLite& value, output);
+  static void WriteGroupMaybeToArray(int field_number, const MessageLite& value,
+                                     io::CodedOutputStream* output);
+  static void WriteMessageMaybeToArray(int field_number,
+                                       const MessageLite& value,
+                                       io::CodedOutputStream* output);
 
   // Like above, but de-virtualize the call to SerializeWithCachedSizes().  The
   // pointer must point at an instance of MessageType, *not* a subclass (or
   // the subclass must not override SerializeWithCachedSizes()).
-  template<typename MessageType>
-  static inline void WriteGroupNoVirtual(
-    field_number, const MessageType& value, output);
-  template<typename MessageType>
-  static inline void WriteMessageNoVirtual(
-    field_number, const MessageType& value, output);
-
-#undef output
-#define output uint8* target
+  template <typename MessageType>
+  static inline void WriteGroupNoVirtual(int field_number,
+                                         const MessageType& value,
+                                         io::CodedOutputStream* output);
+  template <typename MessageType>
+  static inline void WriteMessageNoVirtual(int field_number,
+                                           const MessageType& value,
+                                           io::CodedOutputStream* output);
 
   // Like above, but use only *ToArray methods of CodedOutputStream.
-  INL static uint8* WriteTagToArray(field_number, WireType type, output);
+  INL static uint8* WriteTagToArray(int field_number, WireType type,
+                                    uint8* target);
 
   // Write fields, without tags.
-  INL static uint8* WriteInt32NoTagToArray   (int32 value, output);
-  INL static uint8* WriteInt64NoTagToArray   (int64 value, output);
-  INL static uint8* WriteUInt32NoTagToArray  (uint32 value, output);
-  INL static uint8* WriteUInt64NoTagToArray  (uint64 value, output);
-  INL static uint8* WriteSInt32NoTagToArray  (int32 value, output);
-  INL static uint8* WriteSInt64NoTagToArray  (int64 value, output);
-  INL static uint8* WriteFixed32NoTagToArray (uint32 value, output);
-  INL static uint8* WriteFixed64NoTagToArray (uint64 value, output);
-  INL static uint8* WriteSFixed32NoTagToArray(int32 value, output);
-  INL static uint8* WriteSFixed64NoTagToArray(int64 value, output);
-  INL static uint8* WriteFloatNoTagToArray   (float value, output);
-  INL static uint8* WriteDoubleNoTagToArray  (double value, output);
-  INL static uint8* WriteBoolNoTagToArray    (bool value, output);
-  INL static uint8* WriteEnumNoTagToArray    (int value, output);
+  INL static uint8* WriteInt32NoTagToArray(int32 value, uint8* target);
+  INL static uint8* WriteInt64NoTagToArray(int64 value, uint8* target);
+  INL static uint8* WriteUInt32NoTagToArray(uint32 value, uint8* target);
+  INL static uint8* WriteUInt64NoTagToArray(uint64 value, uint8* target);
+  INL static uint8* WriteSInt32NoTagToArray(int32 value, uint8* target);
+  INL static uint8* WriteSInt64NoTagToArray(int64 value, uint8* target);
+  INL static uint8* WriteFixed32NoTagToArray(uint32 value, uint8* target);
+  INL static uint8* WriteFixed64NoTagToArray(uint64 value, uint8* target);
+  INL static uint8* WriteSFixed32NoTagToArray(int32 value, uint8* target);
+  INL static uint8* WriteSFixed64NoTagToArray(int64 value, uint8* target);
+  INL static uint8* WriteFloatNoTagToArray(float value, uint8* target);
+  INL static uint8* WriteDoubleNoTagToArray(double value, uint8* target);
+  INL static uint8* WriteBoolNoTagToArray(bool value, uint8* target);
+  INL static uint8* WriteEnumNoTagToArray(int value, uint8* target);
+
+  // Write fields, without tags.  These require that value.size() > 0.
+  template<typename T>
+  INL static uint8* WritePrimitiveNoTagToArray(
+      const RepeatedField<T>& value,
+      uint8* (*Writer)(T, uint8*), uint8* target);
+  template<typename T>
+  INL static uint8* WriteFixedNoTagToArray(
+      const RepeatedField<T>& value,
+      uint8* (*Writer)(T, uint8*), uint8* target);
+
+  INL static uint8* WriteInt32NoTagToArray(
+      const RepeatedField< int32>& value, uint8* output);
+  INL static uint8* WriteInt64NoTagToArray(
+      const RepeatedField< int64>& value, uint8* output);
+  INL static uint8* WriteUInt32NoTagToArray(
+      const RepeatedField<uint32>& value, uint8* output);
+  INL static uint8* WriteUInt64NoTagToArray(
+      const RepeatedField<uint64>& value, uint8* output);
+  INL static uint8* WriteSInt32NoTagToArray(
+      const RepeatedField< int32>& value, uint8* output);
+  INL static uint8* WriteSInt64NoTagToArray(
+      const RepeatedField< int64>& value, uint8* output);
+  INL static uint8* WriteFixed32NoTagToArray(
+      const RepeatedField<uint32>& value, uint8* output);
+  INL static uint8* WriteFixed64NoTagToArray(
+      const RepeatedField<uint64>& value, uint8* output);
+  INL static uint8* WriteSFixed32NoTagToArray(
+      const RepeatedField< int32>& value, uint8* output);
+  INL static uint8* WriteSFixed64NoTagToArray(
+      const RepeatedField< int64>& value, uint8* output);
+  INL static uint8* WriteFloatNoTagToArray(
+      const RepeatedField< float>& value, uint8* output);
+  INL static uint8* WriteDoubleNoTagToArray(
+      const RepeatedField<double>& value, uint8* output);
+  INL static uint8* WriteBoolNoTagToArray(
+      const RepeatedField<  bool>& value, uint8* output);
+  INL static uint8* WriteEnumNoTagToArray(
+      const RepeatedField<   int>& value, uint8* output);
 
   // Write fields, including tags.
-  INL static uint8* WriteInt32ToArray(field_number, int32 value, output);
-  INL static uint8* WriteInt64ToArray(field_number, int64 value, output);
-  INL static uint8* WriteUInt32ToArray(field_number, uint32 value, output);
-  INL static uint8* WriteUInt64ToArray(field_number, uint64 value, output);
-  INL static uint8* WriteSInt32ToArray(field_number, int32 value, output);
-  INL static uint8* WriteSInt64ToArray(field_number, int64 value, output);
-  INL static uint8* WriteFixed32ToArray(field_number, uint32 value, output);
-  INL static uint8* WriteFixed64ToArray(field_number, uint64 value, output);
-  INL static uint8* WriteSFixed32ToArray(field_number, int32 value, output);
-  INL static uint8* WriteSFixed64ToArray(field_number, int64 value, output);
-  INL static uint8* WriteFloatToArray(field_number, float value, output);
-  INL static uint8* WriteDoubleToArray(field_number, double value, output);
-  INL static uint8* WriteBoolToArray(field_number, bool value, output);
-  INL static uint8* WriteEnumToArray(field_number, int value, output);
+  INL static uint8* WriteInt32ToArray(int field_number, int32 value,
+                                      uint8* target);
+  INL static uint8* WriteInt64ToArray(int field_number, int64 value,
+                                      uint8* target);
+  INL static uint8* WriteUInt32ToArray(int field_number, uint32 value,
+                                       uint8* target);
+  INL static uint8* WriteUInt64ToArray(int field_number, uint64 value,
+                                       uint8* target);
+  INL static uint8* WriteSInt32ToArray(int field_number, int32 value,
+                                       uint8* target);
+  INL static uint8* WriteSInt64ToArray(int field_number, int64 value,
+                                       uint8* target);
+  INL static uint8* WriteFixed32ToArray(int field_number, uint32 value,
+                                        uint8* target);
+  INL static uint8* WriteFixed64ToArray(int field_number, uint64 value,
+                                        uint8* target);
+  INL static uint8* WriteSFixed32ToArray(int field_number, int32 value,
+                                         uint8* target);
+  INL static uint8* WriteSFixed64ToArray(int field_number, int64 value,
+                                         uint8* target);
+  INL static uint8* WriteFloatToArray(int field_number, float value,
+                                      uint8* target);
+  INL static uint8* WriteDoubleToArray(int field_number, double value,
+                                       uint8* target);
+  INL static uint8* WriteBoolToArray(int field_number, bool value,
+                                     uint8* target);
+  INL static uint8* WriteEnumToArray(int field_number, int value,
+                                     uint8* target);
 
-  INL static uint8* WriteStringToArray(
-    field_number, const string& value, output);
-  INL static uint8* WriteBytesToArray(
-    field_number, const string& value, output);
+  template<typename T>
+  INL static uint8* WritePrimitiveToArray(
+      int field_number,
+      const RepeatedField<T>& value,
+      uint8* (*Writer)(int, T, uint8*), uint8* target);
+
+  INL static uint8* WriteInt32ToArray(
+      int field_number, const RepeatedField< int32>& value, uint8* output);
+  INL static uint8* WriteInt64ToArray(
+      int field_number, const RepeatedField< int64>& value, uint8* output);
+  INL static uint8* WriteUInt32ToArray(
+      int field_number, const RepeatedField<uint32>& value, uint8* output);
+  INL static uint8* WriteUInt64ToArray(
+      int field_number, const RepeatedField<uint64>& value, uint8* output);
+  INL static uint8* WriteSInt32ToArray(
+      int field_number, const RepeatedField< int32>& value, uint8* output);
+  INL static uint8* WriteSInt64ToArray(
+      int field_number, const RepeatedField< int64>& value, uint8* output);
+  INL static uint8* WriteFixed32ToArray(
+      int field_number, const RepeatedField<uint32>& value, uint8* output);
+  INL static uint8* WriteFixed64ToArray(
+      int field_number, const RepeatedField<uint64>& value, uint8* output);
+  INL static uint8* WriteSFixed32ToArray(
+      int field_number, const RepeatedField< int32>& value, uint8* output);
+  INL static uint8* WriteSFixed64ToArray(
+      int field_number, const RepeatedField< int64>& value, uint8* output);
+  INL static uint8* WriteFloatToArray(
+      int field_number, const RepeatedField< float>& value, uint8* output);
+  INL static uint8* WriteDoubleToArray(
+      int field_number, const RepeatedField<double>& value, uint8* output);
+  INL static uint8* WriteBoolToArray(
+      int field_number, const RepeatedField<  bool>& value, uint8* output);
+  INL static uint8* WriteEnumToArray(
+      int field_number, const RepeatedField<   int>& value, uint8* output);
+
+  INL static uint8* WriteStringToArray(int field_number, const string& value,
+                                       uint8* target);
+  INL static uint8* WriteBytesToArray(int field_number, const string& value,
+                                      uint8* target);
 
   // Whether to serialize deterministically (e.g., map keys are
   // sorted) is a property of a CodedOutputStream, and in the process
   // of serialization, the "ToArray" variants may be invoked.  But they don't
   // have a CodedOutputStream available, so they get an additional parameter
   // telling them whether to serialize deterministically.
-  INL static uint8* InternalWriteGroupToArray(
-      field_number, const MessageLite& value, bool deterministic, output);
-  INL static uint8* InternalWriteMessageToArray(
-      field_number, const MessageLite& value, bool deterministic, output);
+  INL static uint8* InternalWriteGroupToArray(int field_number,
+                                              const MessageLite& value,
+                                              bool deterministic,
+                                              uint8* target);
+  INL static uint8* InternalWriteMessageToArray(int field_number,
+                                                const MessageLite& value,
+                                                bool deterministic,
+                                                uint8* target);
 
   // Like above, but de-virtualize the call to SerializeWithCachedSizes().  The
   // pointer must point at an instance of MessageType, *not* a subclass (or
   // the subclass must not override SerializeWithCachedSizes()).
-  template<typename MessageType>
-  INL static uint8* InternalWriteGroupNoVirtualToArray(
-    field_number, const MessageType& value, bool deterministic, output);
-  template<typename MessageType>
+  template <typename MessageType>
+  INL static uint8* InternalWriteGroupNoVirtualToArray(int field_number,
+                                                       const MessageType& value,
+                                                       bool deterministic,
+                                                       uint8* target);
+  template <typename MessageType>
   INL static uint8* InternalWriteMessageNoVirtualToArray(
-    field_number, const MessageType& value, bool deterministic, output);
+      int field_number, const MessageType& value, bool deterministic,
+      uint8* target);
 
   // For backward-compatibility, the last four methods also have versions
   // that are non-deterministic always.
-  INL static uint8* WriteGroupToArray(
-      field_number, const MessageLite& value, output) {
-    return InternalWriteGroupToArray(field_number_arg, value, false, target);
+  INL static uint8* WriteGroupToArray(int field_number,
+                                      const MessageLite& value, uint8* target) {
+    return InternalWriteGroupToArray(field_number, value, false, target);
   }
-  INL static uint8* WriteMessageToArray(
-      field_number, const MessageLite& value, output) {
-    return InternalWriteMessageToArray(field_number_arg, value, false, target);
+  INL static uint8* WriteMessageToArray(int field_number,
+                                        const MessageLite& value,
+                                        uint8* target) {
+    return InternalWriteMessageToArray(field_number, value, false, target);
   }
-  template<typename MessageType>
-  INL static uint8* WriteGroupNoVirtualToArray(
-      field_number, const MessageType& value, output) {
-    return InternalWriteGroupNoVirtualToArray(field_number_arg, value, false,
+  template <typename MessageType>
+  INL static uint8* WriteGroupNoVirtualToArray(int field_number,
+                                               const MessageType& value,
+                                               uint8* target) {
+    return InternalWriteGroupNoVirtualToArray(field_number, value, false,
                                               target);
   }
-  template<typename MessageType>
-  INL static uint8* WriteMessageNoVirtualToArray(
-      field_number, const MessageType& value, output) {
-    return InternalWriteMessageNoVirtualToArray(field_number_arg, value, false,
+  template <typename MessageType>
+  INL static uint8* WriteMessageNoVirtualToArray(int field_number,
+                                                 const MessageType& value,
+                                                 uint8* target) {
+    return InternalWriteMessageNoVirtualToArray(field_number, value, false,
                                                 target);
   }
 
-#undef output
-#undef input
 #undef INL
 
-#undef field_number
-
   // Compute the byte size of a field.  The XxSize() functions do NOT include
   // the tag, so you must also call TagSize().  (This is because, for repeated
   // fields, you should only call TagSize() once and multiply it by the element
@@ -594,9 +715,9 @@
       RepeatedField<CType>* value);
 
   // Like ReadRepeatedFixedSizePrimitive but for packed primitive fields.
-  template <typename CType, enum FieldType DeclaredType> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
-  static bool ReadPackedFixedSizePrimitive(google::protobuf::io::CodedInputStream* input,
-                                           RepeatedField<CType>* value);
+  template <typename CType, enum FieldType DeclaredType>
+  GOOGLE_ATTRIBUTE_ALWAYS_INLINE static bool ReadPackedFixedSizePrimitive(
+      google::protobuf::io::CodedInputStream* input, RepeatedField<CType>* value);
 
   static const CppType kFieldTypeToCppTypeMap[];
   static const WireFormatLite::WireType kWireTypeForFieldType[];
diff --git a/src/google/protobuf/wire_format_lite_inl.h b/src/google/protobuf/wire_format_lite_inl.h
index aa3bb3a..0504901 100644
--- a/src/google/protobuf/wire_format_lite_inl.h
+++ b/src/google/protobuf/wire_format_lite_inl.h
@@ -36,11 +36,7 @@
 #ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
 #define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
 
-#ifdef _MSC_VER
-// This is required for min/max on VS2013 only.
 #include <algorithm>
-#endif
-
 #include <string>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/logging.h>
@@ -452,7 +448,7 @@
   if (p.second < 0 || !value->MergePartialFromCodedStream(input)) return false;
   // Make sure that parsing stopped when the limit was hit, not at an endgroup
   // tag.
-  return input->DecrementRecursionDepthAndPopLimit(p.first);
+ return input->DecrementRecursionDepthAndPopLimit(p.first);
 }
 
 // We name the template parameter something long and extremely unlikely to occur
@@ -502,6 +498,7 @@
   // tag.
   return input->DecrementRecursionDepthAndPopLimit(p.first);
 }
+
 template<typename MessageType_WorkAroundCppLookupDefect>
 inline bool WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
     io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) {
@@ -671,6 +668,98 @@
   return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
 }
 
+template<typename T>
+inline uint8* WireFormatLite::WritePrimitiveNoTagToArray(
+      const RepeatedField<T>& value,
+      uint8* (*Writer)(T, uint8*), uint8* target) {
+  const int n = value.size();
+  GOOGLE_DCHECK_GT(n, 0);
+
+  const T* ii = value.unsafe_data();
+  int i = 0;
+  do {
+    target = Writer(ii[i], target);
+  } while (++i < n);
+
+  return target;
+}
+
+template<typename T>
+inline uint8* WireFormatLite::WriteFixedNoTagToArray(
+      const RepeatedField<T>& value,
+      uint8* (*Writer)(T, uint8*), uint8* target) {
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+  (void) Writer;
+
+  const int n = value.size();
+  GOOGLE_DCHECK_GT(n, 0);
+
+  const T* ii = value.unsafe_data();
+  const int bytes = n * sizeof(ii[0]);
+  memcpy(target, ii, bytes);
+  return target + bytes;
+#else
+  return WritePrimitiveNoTagToArray(value, Writer, target);
+#endif
+}
+
+inline uint8* WireFormatLite::WriteInt32NoTagToArray(
+    const RepeatedField< int32>& value, uint8* target) {
+  return WritePrimitiveNoTagToArray(value, WriteInt32NoTagToArray, target);
+}
+inline uint8* WireFormatLite::WriteInt64NoTagToArray(
+    const RepeatedField< int64>& value, uint8* target) {
+  return WritePrimitiveNoTagToArray(value, WriteInt64NoTagToArray, target);
+}
+inline uint8* WireFormatLite::WriteUInt32NoTagToArray(
+    const RepeatedField<uint32>& value, uint8* target) {
+  return WritePrimitiveNoTagToArray(value, WriteUInt32NoTagToArray, target);
+}
+inline uint8* WireFormatLite::WriteUInt64NoTagToArray(
+    const RepeatedField<uint64>& value, uint8* target) {
+  return WritePrimitiveNoTagToArray(value, WriteUInt64NoTagToArray, target);
+}
+inline uint8* WireFormatLite::WriteSInt32NoTagToArray(
+    const RepeatedField< int32>& value, uint8* target) {
+  return WritePrimitiveNoTagToArray(value, WriteSInt32NoTagToArray, target);
+}
+inline uint8* WireFormatLite::WriteSInt64NoTagToArray(
+    const RepeatedField< int64>& value, uint8* target) {
+  return WritePrimitiveNoTagToArray(value, WriteSInt64NoTagToArray, target);
+}
+inline uint8* WireFormatLite::WriteFixed32NoTagToArray(
+    const RepeatedField<uint32>& value, uint8* target) {
+  return WriteFixedNoTagToArray(value, WriteFixed32NoTagToArray, target);
+}
+inline uint8* WireFormatLite::WriteFixed64NoTagToArray(
+    const RepeatedField<uint64>& value, uint8* target) {
+  return WriteFixedNoTagToArray(value, WriteFixed64NoTagToArray, target);
+}
+inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(
+    const RepeatedField< int32>& value, uint8* target) {
+  return WriteFixedNoTagToArray(value, WriteSFixed32NoTagToArray, target);
+}
+inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(
+    const RepeatedField< int64>& value, uint8* target) {
+  return WriteFixedNoTagToArray(value, WriteSFixed64NoTagToArray, target);
+}
+inline uint8* WireFormatLite::WriteFloatNoTagToArray(
+    const RepeatedField< float>& value, uint8* target) {
+  return WriteFixedNoTagToArray(value, WriteFloatNoTagToArray, target);
+}
+inline uint8* WireFormatLite::WriteDoubleNoTagToArray(
+    const RepeatedField<double>& value, uint8* target) {
+  return WriteFixedNoTagToArray(value, WriteDoubleNoTagToArray, target);
+}
+inline uint8* WireFormatLite::WriteBoolNoTagToArray(
+    const RepeatedField<  bool>& value, uint8* target) {
+  return WritePrimitiveNoTagToArray(value, WriteBoolNoTagToArray, target);
+}
+inline uint8* WireFormatLite::WriteEnumNoTagToArray(
+    const RepeatedField<   int>& value, uint8* target) {
+  return WritePrimitiveNoTagToArray(value, WriteEnumNoTagToArray, target);
+}
+
 inline uint8* WireFormatLite::WriteInt32ToArray(int field_number,
                                                 int32 value,
                                                 uint8* target) {
@@ -756,6 +845,85 @@
   return WriteEnumNoTagToArray(value, target);
 }
 
+template<typename T>
+inline uint8* WireFormatLite::WritePrimitiveToArray(
+    int field_number,
+    const RepeatedField<T>& value,
+    uint8* (*Writer)(int, T, uint8*), uint8* target) {
+  const int n = value.size();
+  if (n == 0) {
+    return target;
+  }
+
+  const T* ii = value.unsafe_data();
+  int i = 0;
+  do {
+    target = Writer(field_number, ii[i], target);
+  } while (++i < n);
+
+  return target;
+}
+
+inline uint8* WireFormatLite::WriteInt32ToArray(
+    int field_number, const RepeatedField< int32>& value, uint8* target) {
+  return WritePrimitiveToArray(field_number, value, WriteInt32ToArray, target);
+}
+inline uint8* WireFormatLite::WriteInt64ToArray(
+    int field_number, const RepeatedField< int64>& value, uint8* target) {
+  return WritePrimitiveToArray(field_number, value, WriteInt64ToArray, target);
+}
+inline uint8* WireFormatLite::WriteUInt32ToArray(
+    int field_number, const RepeatedField<uint32>& value, uint8* target) {
+  return WritePrimitiveToArray(field_number, value, WriteUInt32ToArray, target);
+}
+inline uint8* WireFormatLite::WriteUInt64ToArray(
+    int field_number, const RepeatedField<uint64>& value, uint8* target) {
+  return WritePrimitiveToArray(field_number, value, WriteUInt64ToArray, target);
+}
+inline uint8* WireFormatLite::WriteSInt32ToArray(
+    int field_number, const RepeatedField< int32>& value, uint8* target) {
+  return WritePrimitiveToArray(field_number, value, WriteSInt32ToArray, target);
+}
+inline uint8* WireFormatLite::WriteSInt64ToArray(
+    int field_number, const RepeatedField< int64>& value, uint8* target) {
+  return WritePrimitiveToArray(field_number, value, WriteSInt64ToArray, target);
+}
+inline uint8* WireFormatLite::WriteFixed32ToArray(
+    int field_number, const RepeatedField<uint32>& value, uint8* target) {
+  return WritePrimitiveToArray(
+      field_number, value, WriteFixed32ToArray, target);
+}
+inline uint8* WireFormatLite::WriteFixed64ToArray(
+    int field_number, const RepeatedField<uint64>& value, uint8* target) {
+  return WritePrimitiveToArray(
+      field_number, value, WriteFixed64ToArray, target);
+}
+inline uint8* WireFormatLite::WriteSFixed32ToArray(
+    int field_number, const RepeatedField< int32>& value, uint8* target) {
+  return WritePrimitiveToArray(
+      field_number, value, WriteSFixed32ToArray, target);
+}
+inline uint8* WireFormatLite::WriteSFixed64ToArray(
+    int field_number, const RepeatedField< int64>& value, uint8* target) {
+  return WritePrimitiveToArray(
+      field_number, value, WriteSFixed64ToArray, target);
+}
+inline uint8* WireFormatLite::WriteFloatToArray(
+    int field_number, const RepeatedField< float>& value, uint8* target) {
+  return WritePrimitiveToArray(field_number, value, WriteFloatToArray, target);
+}
+inline uint8* WireFormatLite::WriteDoubleToArray(
+    int field_number, const RepeatedField<double>& value, uint8* target) {
+  return WritePrimitiveToArray(field_number, value, WriteDoubleToArray, target);
+}
+inline uint8* WireFormatLite::WriteBoolToArray(
+    int field_number, const RepeatedField<  bool>& value, uint8* target) {
+  return WritePrimitiveToArray(field_number, value, WriteBoolToArray, target);
+}
+inline uint8* WireFormatLite::WriteEnumToArray(
+    int field_number, const RepeatedField<   int>& value, uint8* target) {
+  return WritePrimitiveToArray(field_number, value, WriteEnumToArray, target);
+}
 inline uint8* WireFormatLite::WriteStringToArray(int field_number,
                                                  const string& value,
                                                  uint8* target) {
@@ -797,7 +965,8 @@
     int field_number, const MessageType_WorkAroundCppLookupDefect& value,
     bool deterministic, uint8* target) {
   target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
-  target = value.InternalSerializeWithCachedSizesToArray(deterministic, target);
+  target = value.MessageType_WorkAroundCppLookupDefect::
+      InternalSerializeWithCachedSizesToArray(deterministic, target);
   return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
 }
 template<typename MessageType_WorkAroundCppLookupDefect>
@@ -807,7 +976,8 @@
   target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
   target = io::CodedOutputStream::WriteVarint32ToArray(
     value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target);
-  return value.InternalSerializeWithCachedSizesToArray(deterministic, target);
+  return value.MessageType_WorkAroundCppLookupDefect::
+      InternalSerializeWithCachedSizesToArray(deterministic, target);
 }
 
 // ===================================================================
diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc
index 897fec0..cafe9a4 100644
--- a/src/google/protobuf/wire_format_unittest.cc
+++ b/src/google/protobuf/wire_format_unittest.cc
@@ -1029,6 +1029,29 @@
   EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\017", 1)));
 }
 
+TEST_F(WireFormatInvalidInputTest, InvalidMessageWithExtraZero) {
+  string data;
+  {
+    // Serialize a valid proto
+    unittest::TestAllTypes message;
+    message.set_optional_int32(1);
+    message.SerializeToString(&data);
+    data.push_back(0);  // Append invalid zero tag
+  }
+
+  // Control case.
+  {
+    io::ArrayInputStream ais(data.data(), data.size());
+    io::CodedInputStream is(&ais);
+    unittest::TestAllTypes message;
+    // It should fail but currently passes.
+    EXPECT_TRUE(message.MergePartialFromCodedStream(&is));
+    // Parsing from the string should fail.
+    EXPECT_FALSE(message.ParseFromString(data));
+  }
+}
+
+
 TEST_F(WireFormatInvalidInputTest, InvalidGroup) {
   unittest::TestAllTypes message;
 
diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc
index d614de9..12c04fd 100644
--- a/src/google/protobuf/wrappers.pb.cc
+++ b/src/google/protobuf/wrappers.pb.cc
@@ -47,64 +47,95 @@
 
 }  // namespace
 
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+    const TableStruct::entries[] = {
+  {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+    const TableStruct::aux[] = {
+  ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+    TableStruct::schema[] = {
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+  { NULL, NULL, 0, -1, -1, false },
+};
+
 const ::google::protobuf::uint32 TableStruct::offsets[] = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DoubleValue, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DoubleValue, value_),
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FloatValue, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FloatValue, value_),
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Int64Value, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Int64Value, value_),
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UInt64Value, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UInt64Value, value_),
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Int32Value, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Int32Value, value_),
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UInt32Value, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UInt32Value, value_),
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BoolValue, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BoolValue, value_),
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StringValue, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StringValue, value_),
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BytesValue, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BytesValue, value_),
 };
 
 static const ::google::protobuf::internal::MigrationSchema schemas[] = {
   { 0, -1, sizeof(DoubleValue)},
-  { 5, -1, sizeof(FloatValue)},
-  { 10, -1, sizeof(Int64Value)},
-  { 15, -1, sizeof(UInt64Value)},
-  { 20, -1, sizeof(Int32Value)},
-  { 25, -1, sizeof(UInt32Value)},
-  { 30, -1, sizeof(BoolValue)},
-  { 35, -1, sizeof(StringValue)},
-  { 40, -1, sizeof(BytesValue)},
+  { 6, -1, sizeof(FloatValue)},
+  { 12, -1, sizeof(Int64Value)},
+  { 18, -1, sizeof(UInt64Value)},
+  { 24, -1, sizeof(Int32Value)},
+  { 30, -1, sizeof(UInt32Value)},
+  { 36, -1, sizeof(BoolValue)},
+  { 42, -1, sizeof(StringValue)},
+  { 48, -1, sizeof(BytesValue)},
 };
 
 static ::google::protobuf::Message const * const file_default_instances[] = {
@@ -283,7 +314,7 @@
 }
 const ::google::protobuf::Descriptor* DoubleValue::descriptor() {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[0].descriptor;
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const DoubleValue& DoubleValue::default_instance() {
@@ -348,6 +379,9 @@
 void DoubleValue::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.DoubleValue)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // double value = 1;
   if (this->value() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->value(), output);
@@ -358,8 +392,10 @@
 
 ::google::protobuf::uint8* DoubleValue::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DoubleValue)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // double value = 1;
   if (this->value() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->value(), target);
@@ -404,6 +440,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DoubleValue)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.value() != 0) {
     set_value(from.value());
   }
@@ -453,7 +492,7 @@
 
 ::google::protobuf::Metadata DoubleValue::GetMetadata() const {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[0];
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -539,7 +578,7 @@
 }
 const ::google::protobuf::Descriptor* FloatValue::descriptor() {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[1].descriptor;
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const FloatValue& FloatValue::default_instance() {
@@ -604,6 +643,9 @@
 void FloatValue::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.FloatValue)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // float value = 1;
   if (this->value() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteFloat(1, this->value(), output);
@@ -614,8 +656,10 @@
 
 ::google::protobuf::uint8* FloatValue::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FloatValue)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // float value = 1;
   if (this->value() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(1, this->value(), target);
@@ -660,6 +704,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FloatValue)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.value() != 0) {
     set_value(from.value());
   }
@@ -709,7 +756,7 @@
 
 ::google::protobuf::Metadata FloatValue::GetMetadata() const {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[1];
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -795,7 +842,7 @@
 }
 const ::google::protobuf::Descriptor* Int64Value::descriptor() {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[2].descriptor;
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const Int64Value& Int64Value::default_instance() {
@@ -860,6 +907,9 @@
 void Int64Value::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Int64Value)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // int64 value = 1;
   if (this->value() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->value(), output);
@@ -870,8 +920,10 @@
 
 ::google::protobuf::uint8* Int64Value::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Int64Value)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // int64 value = 1;
   if (this->value() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(1, this->value(), target);
@@ -918,6 +970,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int64Value)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.value() != 0) {
     set_value(from.value());
   }
@@ -967,7 +1022,7 @@
 
 ::google::protobuf::Metadata Int64Value::GetMetadata() const {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[2];
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1053,7 +1108,7 @@
 }
 const ::google::protobuf::Descriptor* UInt64Value::descriptor() {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[3].descriptor;
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const UInt64Value& UInt64Value::default_instance() {
@@ -1118,6 +1173,9 @@
 void UInt64Value::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.UInt64Value)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // uint64 value = 1;
   if (this->value() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->value(), output);
@@ -1128,8 +1186,10 @@
 
 ::google::protobuf::uint8* UInt64Value::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UInt64Value)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // uint64 value = 1;
   if (this->value() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->value(), target);
@@ -1176,6 +1236,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt64Value)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.value() != 0) {
     set_value(from.value());
   }
@@ -1225,7 +1288,7 @@
 
 ::google::protobuf::Metadata UInt64Value::GetMetadata() const {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[3];
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1311,7 +1374,7 @@
 }
 const ::google::protobuf::Descriptor* Int32Value::descriptor() {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[4].descriptor;
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const Int32Value& Int32Value::default_instance() {
@@ -1376,6 +1439,9 @@
 void Int32Value::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Int32Value)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // int32 value = 1;
   if (this->value() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->value(), output);
@@ -1386,8 +1452,10 @@
 
 ::google::protobuf::uint8* Int32Value::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Int32Value)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // int32 value = 1;
   if (this->value() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->value(), target);
@@ -1434,6 +1502,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int32Value)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.value() != 0) {
     set_value(from.value());
   }
@@ -1483,7 +1554,7 @@
 
 ::google::protobuf::Metadata Int32Value::GetMetadata() const {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[4];
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1569,7 +1640,7 @@
 }
 const ::google::protobuf::Descriptor* UInt32Value::descriptor() {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[5].descriptor;
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const UInt32Value& UInt32Value::default_instance() {
@@ -1634,6 +1705,9 @@
 void UInt32Value::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.UInt32Value)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // uint32 value = 1;
   if (this->value() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->value(), output);
@@ -1644,8 +1718,10 @@
 
 ::google::protobuf::uint8* UInt32Value::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UInt32Value)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // uint32 value = 1;
   if (this->value() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->value(), target);
@@ -1692,6 +1768,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt32Value)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.value() != 0) {
     set_value(from.value());
   }
@@ -1741,7 +1820,7 @@
 
 ::google::protobuf::Metadata UInt32Value::GetMetadata() const {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[5];
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1827,7 +1906,7 @@
 }
 const ::google::protobuf::Descriptor* BoolValue::descriptor() {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[6].descriptor;
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const BoolValue& BoolValue::default_instance() {
@@ -1892,6 +1971,9 @@
 void BoolValue::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.BoolValue)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // bool value = 1;
   if (this->value() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->value(), output);
@@ -1902,8 +1984,10 @@
 
 ::google::protobuf::uint8* BoolValue::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.BoolValue)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // bool value = 1;
   if (this->value() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->value(), target);
@@ -1948,6 +2032,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BoolValue)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.value() != 0) {
     set_value(from.value());
   }
@@ -1997,7 +2084,7 @@
 
 ::google::protobuf::Metadata BoolValue::GetMetadata() const {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[6];
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -2088,7 +2175,7 @@
 }
 const ::google::protobuf::Descriptor* StringValue::descriptor() {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[7].descriptor;
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const StringValue& StringValue::default_instance() {
@@ -2155,6 +2242,9 @@
 void StringValue::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.StringValue)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string value = 1;
   if (this->value().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -2170,8 +2260,10 @@
 
 ::google::protobuf::uint8* StringValue::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.StringValue)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string value = 1;
   if (this->value().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -2224,6 +2316,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.StringValue)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.value().size() > 0) {
     set_value(from.value());
   }
@@ -2273,7 +2368,7 @@
 
 ::google::protobuf::Metadata StringValue::GetMetadata() const {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[7];
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -2293,6 +2388,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.StringValue.value)
 }
 void StringValue::set_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
@@ -2416,7 +2512,7 @@
 }
 const ::google::protobuf::Descriptor* BytesValue::descriptor() {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[8].descriptor;
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
 }
 
 const BytesValue& BytesValue::default_instance() {
@@ -2479,6 +2575,9 @@
 void BytesValue::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.BytesValue)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // bytes value = 1;
   if (this->value().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
@@ -2490,8 +2589,10 @@
 
 ::google::protobuf::uint8* BytesValue::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.BytesValue)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // bytes value = 1;
   if (this->value().size() > 0) {
     target =
@@ -2540,6 +2641,9 @@
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BytesValue)
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.value().size() > 0) {
     set_value(from.value());
   }
@@ -2589,7 +2693,7 @@
 
 ::google::protobuf::Metadata BytesValue::GetMetadata() const {
   protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[8];
+  return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -2609,6 +2713,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.BytesValue.value)
 }
 void BytesValue::set_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h
index 61b0510..78631a1 100644
--- a/src/google/protobuf/wrappers.pb.h
+++ b/src/google/protobuf/wrappers.pb.h
@@ -22,6 +22,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/message.h>
@@ -67,6 +68,9 @@
 namespace protobuf_google_2fprotobuf_2fwrappers_2eproto {
 // Internal implementation detail -- do not call these.
 struct LIBPROTOBUF_EXPORT TableStruct {
+  static const ::google::protobuf::internal::ParseTableField entries[];
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+  static const ::google::protobuf::internal::ParseTable schema[];
   static const ::google::protobuf::uint32 offsets[];
   static void InitDefaultsImpl();
   static void Shutdown();
@@ -102,6 +106,8 @@
     return reinterpret_cast<const DoubleValue*>(
                &_DoubleValue_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    0;
 
   void UnsafeArenaSwap(DoubleValue* other);
   void Swap(DoubleValue* other);
@@ -125,11 +131,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -171,7 +172,7 @@
   typedef void DestructorSkippable_;
   double value_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
 
@@ -200,6 +201,8 @@
     return reinterpret_cast<const FloatValue*>(
                &_FloatValue_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    1;
 
   void UnsafeArenaSwap(FloatValue* other);
   void Swap(FloatValue* other);
@@ -223,11 +226,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -269,7 +267,7 @@
   typedef void DestructorSkippable_;
   float value_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
 
@@ -298,6 +296,8 @@
     return reinterpret_cast<const Int64Value*>(
                &_Int64Value_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    2;
 
   void UnsafeArenaSwap(Int64Value* other);
   void Swap(Int64Value* other);
@@ -321,11 +321,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -367,7 +362,7 @@
   typedef void DestructorSkippable_;
   ::google::protobuf::int64 value_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
 
@@ -396,6 +391,8 @@
     return reinterpret_cast<const UInt64Value*>(
                &_UInt64Value_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    3;
 
   void UnsafeArenaSwap(UInt64Value* other);
   void Swap(UInt64Value* other);
@@ -419,11 +416,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -465,7 +457,7 @@
   typedef void DestructorSkippable_;
   ::google::protobuf::uint64 value_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
 
@@ -494,6 +486,8 @@
     return reinterpret_cast<const Int32Value*>(
                &_Int32Value_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    4;
 
   void UnsafeArenaSwap(Int32Value* other);
   void Swap(Int32Value* other);
@@ -517,11 +511,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -563,7 +552,7 @@
   typedef void DestructorSkippable_;
   ::google::protobuf::int32 value_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
 
@@ -592,6 +581,8 @@
     return reinterpret_cast<const UInt32Value*>(
                &_UInt32Value_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    5;
 
   void UnsafeArenaSwap(UInt32Value* other);
   void Swap(UInt32Value* other);
@@ -615,11 +606,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -661,7 +647,7 @@
   typedef void DestructorSkippable_;
   ::google::protobuf::uint32 value_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
 
@@ -690,6 +676,8 @@
     return reinterpret_cast<const BoolValue*>(
                &_BoolValue_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    6;
 
   void UnsafeArenaSwap(BoolValue* other);
   void Swap(BoolValue* other);
@@ -713,11 +701,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -759,7 +742,7 @@
   typedef void DestructorSkippable_;
   bool value_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
 
@@ -788,6 +771,8 @@
     return reinterpret_cast<const StringValue*>(
                &_StringValue_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    7;
 
   void UnsafeArenaSwap(StringValue* other);
   void Swap(StringValue* other);
@@ -811,11 +796,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -865,7 +845,7 @@
   typedef void DestructorSkippable_;
   ::google::protobuf::internal::ArenaStringPtr value_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
 };
 // -------------------------------------------------------------------
 
@@ -894,6 +874,8 @@
     return reinterpret_cast<const BytesValue*>(
                &_BytesValue_default_instance_);
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    8;
 
   void UnsafeArenaSwap(BytesValue* other);
   void Swap(BytesValue* other);
@@ -917,11 +899,6 @@
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
-      const PROTOBUF_FINAL {
-    return InternalSerializeWithCachedSizesToArray(
-        ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output);
-  }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   void SharedCtor();
@@ -971,7 +948,7 @@
   typedef void DestructorSkippable_;
   ::google::protobuf::internal::ArenaStringPtr value_;
   mutable int _cached_size_;
-  friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
 };
 // ===================================================================
 
@@ -1121,6 +1098,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.StringValue.value)
 }
 inline void StringValue::set_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
@@ -1191,6 +1169,7 @@
   // @@protoc_insertion_point(field_set:google.protobuf.BytesValue.value)
 }
 inline void BytesValue::set_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());