Browse Source

Down-integrate from google3.

Feng Xiao 8 years ago
parent
commit
d36c0c538a
100 changed files with 3223 additions and 588 deletions
  1. 3 1
      Makefile.am
  2. 1 0
      cmake/libprotoc.cmake
  3. 4 1
      cmake/tests.cmake
  4. 17 0
      conformance/conformance_test.cc
  5. 1 0
      conformance/conformance_test.h
  6. 0 2
      conformance/failure_list_cpp.txt
  7. 1 0
      conformance/failure_list_java.txt
  8. 602 0
      conformance/failure_list_python.txt
  9. 586 0
      conformance/failure_list_python_cpp.txt
  10. 8 13
      generate_descriptor_proto.sh
  11. 2 2
      java/core/src/main/java/com/google/protobuf/AbstractMessage.java
  12. 11 10
      java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java
  13. 25 1
      java/core/src/main/java/com/google/protobuf/AbstractParser.java
  14. 5 7
      java/core/src/main/java/com/google/protobuf/BooleanArrayList.java
  15. 2 2
      java/core/src/main/java/com/google/protobuf/CodedInputStream.java
  16. 2 2
      java/core/src/main/java/com/google/protobuf/CodedOutputStream.java
  17. 3 4
      java/core/src/main/java/com/google/protobuf/Descriptors.java
  18. 5 7
      java/core/src/main/java/com/google/protobuf/DoubleArrayList.java
  19. 3 4
      java/core/src/main/java/com/google/protobuf/DynamicMessage.java
  20. 3 4
      java/core/src/main/java/com/google/protobuf/FieldSet.java
  21. 5 7
      java/core/src/main/java/com/google/protobuf/FloatArrayList.java
  22. 20 2
      java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
  23. 1 1
      java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
  24. 5 7
      java/core/src/main/java/com/google/protobuf/IntArrayList.java
  25. 15 0
      java/core/src/main/java/com/google/protobuf/Internal.java
  26. 1 0
      java/core/src/main/java/com/google/protobuf/LazyFieldLite.java
  27. 5 7
      java/core/src/main/java/com/google/protobuf/LongArrayList.java
  28. 18 6
      java/core/src/main/java/com/google/protobuf/MapEntry.java
  29. 5 0
      java/core/src/main/java/com/google/protobuf/MapEntryLite.java
  30. 8 0
      java/core/src/main/java/com/google/protobuf/MapField.java
  31. 13 1
      java/core/src/main/java/com/google/protobuf/MapFieldLite.java
  32. 13 0
      java/core/src/main/java/com/google/protobuf/Parser.java
  33. 34 0
      java/core/src/main/java/com/google/protobuf/PrimitiveNonBoxingCollection.java
  34. 6 12
      java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java
  35. 4 8
      java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java
  36. 3 1
      java/core/src/main/java/com/google/protobuf/TextFormat.java
  37. 2 2
      java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
  38. 308 93
      java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
  39. 1 1
      java/core/src/main/java/com/google/protobuf/Utf8.java
  40. 1 1
      java/core/src/test/java/com/google/protobuf/LazyFieldTest.java
  41. 108 0
      java/core/src/test/java/com/google/protobuf/LiteTest.java
  42. 1 0
      java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
  43. 38 1
      java/core/src/test/java/com/google/protobuf/MapTest.java
  44. 23 4
      java/core/src/test/java/com/google/protobuf/ParserTest.java
  45. 2 0
      java/core/src/test/java/com/google/protobuf/TestUtil.java
  46. 92 0
      java/core/src/test/java/com/google/protobuf/TextFormatTest.java
  47. 8 0
      java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto
  48. 1 0
      java/lite/pom.xml
  49. 98 77
      java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
  50. 1 1
      java/util/src/main/java/com/google/protobuf/util/Timestamps.java
  51. 126 11
      java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
  52. 11 6
      js/binary/decoder.js
  53. 19 0
      js/binary/decoder_test.js
  54. 2 2
      js/binary/encoder.js
  55. 1 1
      js/binary/reader.js
  56. 1 1
      js/binary/utils.js
  57. 2 2
      js/binary/writer.js
  58. 1 1
      js/binary/writer_test.js
  59. 5 5
      js/map.js
  60. 25 6
      js/message.js
  61. 1 0
      js/message_test.js
  62. 7 4
      python/google/protobuf/descriptor_database.py
  63. 84 15
      python/google/protobuf/descriptor_pool.py
  64. 1 1
      python/google/protobuf/internal/containers.py
  65. 36 0
      python/google/protobuf/internal/descriptor_pool_test.py
  66. 5 2
      python/google/protobuf/internal/encoder.py
  67. 26 1
      python/google/protobuf/internal/message_test.py
  68. 3 2
      python/google/protobuf/internal/python_message.py
  69. 63 0
      python/google/protobuf/internal/python_protobuf.cc
  70. 8 1
      python/google/protobuf/internal/reflection_test.py
  71. 8 1
      python/google/protobuf/internal/symbol_database_test.py
  72. 51 0
      python/google/protobuf/internal/text_format_test.py
  73. 19 0
      python/google/protobuf/pyext/descriptor.cc
  74. 2 0
      python/google/protobuf/pyext/descriptor.h
  75. 19 1
      python/google/protobuf/pyext/descriptor_pool.cc
  76. 1 0
      python/google/protobuf/pyext/descriptor_pool.h
  77. 29 0
      python/google/protobuf/pyext/repeated_composite_container.cc
  78. 34 25
      python/google/protobuf/pyext/scoped_pyobject_ptr.h
  79. 0 0
      python/google/protobuf/python_protobuf.h
  80. 3 3
      python/google/protobuf/reflection.py
  81. 11 0
      python/google/protobuf/symbol_database.py
  82. 30 5
      python/google/protobuf/text_format.py
  83. 30 13
      src/Makefile.am
  84. 3 3
      src/google/protobuf/any.h
  85. 28 3
      src/google/protobuf/any.pb.cc
  86. 9 6
      src/google/protobuf/any.pb.h
  87. 74 32
      src/google/protobuf/api.pb.cc
  88. 20 18
      src/google/protobuf/api.pb.h
  89. 26 29
      src/google/protobuf/arena.h
  90. 52 0
      src/google/protobuf/arena_unittest.cc
  91. 0 10
      src/google/protobuf/arenastring.cc
  92. 16 0
      src/google/protobuf/arenastring.h
  93. 1 1
      src/google/protobuf/compiler/code_generator.h
  94. 31 26
      src/google/protobuf/compiler/command_line_interface.cc
  95. 6 1
      src/google/protobuf/compiler/command_line_interface.h
  96. 21 19
      src/google/protobuf/compiler/command_line_interface_unittest.cc
  97. 11 3
      src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
  98. 5 11
      src/google/protobuf/compiler/cpp/cpp_enum_field.cc
  99. 129 25
      src/google/protobuf/compiler/cpp/cpp_file.cc
  100. 3 0
      src/google/protobuf/compiler/cpp/cpp_file.h

+ 3 - 1
Makefile.am

@@ -247,6 +247,7 @@ java_EXTRA_DIST=
   java/core/src/main/java/com/google/protobuf/MutabilityOracle.java                \
   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/NioByteString.java                   \
   java/core/src/main/java/com/google/protobuf/Parser.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/ProtobufArrayList.java               \
   java/core/src/main/java/com/google/protobuf/ProtocolMessageEnum.java             \
   java/core/src/main/java/com/google/protobuf/ProtocolMessageEnum.java             \
   java/core/src/main/java/com/google/protobuf/ProtocolStringList.java              \
   java/core/src/main/java/com/google/protobuf/ProtocolStringList.java              \
@@ -710,6 +711,7 @@ python_EXTRA_DIST=                                                           \
   python/google/protobuf/internal/packed_field_test.proto                    \
   python/google/protobuf/internal/packed_field_test.proto                    \
   python/google/protobuf/internal/proto_builder_test.py                      \
   python/google/protobuf/internal/proto_builder_test.py                      \
   python/google/protobuf/internal/python_message.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/reflection_test.py                         \
   python/google/protobuf/internal/service_reflection_test.py                 \
   python/google/protobuf/internal/service_reflection_test.py                 \
   python/google/protobuf/internal/symbol_database_test.py                    \
   python/google/protobuf/internal/symbol_database_test.py                    \
@@ -752,13 +754,13 @@ python_EXTRA_DIST=                                                           \
   python/google/protobuf/pyext/message_module.cc                             \
   python/google/protobuf/pyext/message_module.cc                             \
   python/google/protobuf/pyext/proto2_api_test.proto                         \
   python/google/protobuf/pyext/proto2_api_test.proto                         \
   python/google/protobuf/pyext/python.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.cc               \
   python/google/protobuf/pyext/repeated_composite_container.h                \
   python/google/protobuf/pyext/repeated_composite_container.h                \
   python/google/protobuf/pyext/repeated_scalar_container.cc                  \
   python/google/protobuf/pyext/repeated_scalar_container.cc                  \
   python/google/protobuf/pyext/repeated_scalar_container.h                   \
   python/google/protobuf/pyext/repeated_scalar_container.h                   \
   python/google/protobuf/pyext/safe_numerics.h                               \
   python/google/protobuf/pyext/safe_numerics.h                               \
   python/google/protobuf/pyext/scoped_pyobject_ptr.h                         \
   python/google/protobuf/pyext/scoped_pyobject_ptr.h                         \
+  python/google/protobuf/python_protobuf.h                                   \
   python/google/protobuf/reflection.py                                       \
   python/google/protobuf/reflection.py                                       \
   python/google/protobuf/service.py                                          \
   python/google/protobuf/service.py                                          \
   python/google/protobuf/service_reflection.py                               \
   python/google/protobuf/service_reflection.py                               \

+ 1 - 0
cmake/libprotoc.cmake

@@ -88,6 +88,7 @@ set(libprotoc_files
   ${protobuf_source_dir}/src/google/protobuf/compiler/php/php_generator.cc
   ${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.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.pb.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/python/python_generator.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/ruby/ruby_generator.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/ruby/ruby_generator.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/subprocess.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/subprocess.cc

+ 4 - 1
cmake/tests.cmake

@@ -43,6 +43,9 @@ set(tests_protos
   google/protobuf/unittest_empty.proto
   google/protobuf/unittest_empty.proto
   google/protobuf/unittest_import.proto
   google/protobuf/unittest_import.proto
   google/protobuf/unittest_import_public.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_imports_nonlite.proto
   google/protobuf/unittest_mset.proto
   google/protobuf/unittest_mset.proto
   google/protobuf/unittest_mset_wire_format.proto
   google/protobuf/unittest_mset_wire_format.proto
@@ -207,7 +210,7 @@ set(lite_test_files
   ${protobuf_source_dir}/src/google/protobuf/lite_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/lite_unittest.cc
 )
 )
 add_executable(lite-test ${lite_test_files} ${common_lite_test_files} ${lite_test_proto_files})
 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
 set(lite_arena_test_files
   ${protobuf_source_dir}/src/google/protobuf/lite_arena_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/lite_arena_unittest.cc

+ 17 - 0
conformance/conformance_test.cc

@@ -708,6 +708,21 @@ bool ConformanceTestSuite::CheckSetEmpty(const set<string>& set_to_check,
   }
   }
 }
 }
 
 
+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,
 bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
                                     std::string* output) {
                                     std::string* output) {
   runner_ = runner;
   runner_ = runner;
@@ -728,6 +743,8 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
     TestPrematureEOFForType(static_cast<FieldDescriptor::Type>(i));
     TestPrematureEOFForType(static_cast<FieldDescriptor::Type>(i));
   }
   }
 
 
+  TestIllegalTags();
+
   int64 kInt64Min = -9223372036854775808ULL;
   int64 kInt64Min = -9223372036854775808ULL;
   int64 kInt64Max = 9223372036854775807ULL;
   int64 kInt64Max = 9223372036854775807ULL;
   uint64 kUint64Max = 18446744073709551615ULL;
   uint64 kUint64Max = 18446744073709551615ULL;

+ 1 - 0
conformance/conformance_test.h

@@ -201,6 +201,7 @@ class ConformanceTestSuite {
                                       const std::string& test_name,
                                       const std::string& test_name,
                                       ConformanceLevel level);
                                       ConformanceLevel level);
   void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type);
   void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type);
+  void TestIllegalTags();
   void TestValidDataForType(
   void TestValidDataForType(
       google::protobuf::FieldDescriptor::Type,
       google::protobuf::FieldDescriptor::Type,
       std::vector<std::pair<std::string, std::string>> values);
       std::vector<std::pair<std::string, std::string>> values);

+ 0 - 2
conformance/failure_list_cpp.txt

@@ -32,7 +32,6 @@ Recommended.JsonInput.TrailingCommaInAnObject
 Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines
 Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines
 Recommended.JsonInput.TrailingCommaInAnObjectWithSpace
 Recommended.JsonInput.TrailingCommaInAnObjectWithSpace
 Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
 Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
 Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
 Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
 Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
 Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
 Required.ProtobufInput.PrematureEofInPackedField.BOOL
 Required.ProtobufInput.PrematureEofInPackedField.BOOL
@@ -43,4 +42,3 @@ Required.ProtobufInput.PrematureEofInPackedField.SINT32
 Required.ProtobufInput.PrematureEofInPackedField.SINT64
 Required.ProtobufInput.PrematureEofInPackedField.SINT64
 Required.ProtobufInput.PrematureEofInPackedField.UINT32
 Required.ProtobufInput.PrematureEofInPackedField.UINT32
 Required.ProtobufInput.PrematureEofInPackedField.UINT64
 Required.ProtobufInput.PrematureEofInPackedField.UINT64
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE

+ 1 - 0
conformance/failure_list_java.txt

@@ -32,6 +32,7 @@ Recommended.JsonInput.StringFieldSingleQuoteValue
 Recommended.JsonInput.StringFieldSurrogateInWrongOrder
 Recommended.JsonInput.StringFieldSurrogateInWrongOrder
 Recommended.JsonInput.StringFieldUnpairedHighSurrogate
 Recommended.JsonInput.StringFieldUnpairedHighSurrogate
 Recommended.JsonInput.StringFieldUnpairedLowSurrogate
 Recommended.JsonInput.StringFieldUnpairedLowSurrogate
+Recommended.JsonInput.StringFieldUppercaseEscapeLetter
 Recommended.JsonInput.Uint32MapFieldKeyNotQuoted
 Recommended.JsonInput.Uint32MapFieldKeyNotQuoted
 Recommended.JsonInput.Uint64MapFieldKeyNotQuoted
 Recommended.JsonInput.Uint64MapFieldKeyNotQuoted
 Required.JsonInput.EnumFieldNotQuoted
 Required.JsonInput.EnumFieldNotQuoted

+ 602 - 0
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.DoubleFieldInfinityNotQuoted
 Recommended.JsonInput.DoubleFieldNanNotQuoted
 Recommended.JsonInput.DoubleFieldNanNotQuoted
 Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
 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.FloatFieldInfinityNotQuoted
 Recommended.JsonInput.FloatFieldNanNotQuoted
 Recommended.JsonInput.FloatFieldNanNotQuoted
 Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
 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.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.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.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.FloatFieldTooLarge
 Required.JsonInput.FloatFieldTooSmall
 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.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.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

+ 586 - 0
conformance/failure_list_python_cpp.txt

@@ -7,21 +7,461 @@
 # TODO(haberman): insert links to corresponding bugs tracking the issue.
 # TODO(haberman): insert links to corresponding bugs tracking the issue.
 # Should we use GitHub issues or the Google-internal bug tracker?
 # 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.DoubleFieldInfinityNotQuoted
 Recommended.JsonInput.DoubleFieldNanNotQuoted
 Recommended.JsonInput.DoubleFieldNanNotQuoted
 Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
 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.FloatFieldInfinityNotQuoted
 Recommended.JsonInput.FloatFieldNanNotQuoted
 Recommended.JsonInput.FloatFieldNanNotQuoted
 Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
 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.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.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.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.FloatFieldTooLarge
 Required.JsonInput.FloatFieldTooSmall
 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.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.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.MESSAGE
+Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.STRING
+Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.BYTES
 Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
 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.BOOL
 Required.ProtobufInput.PrematureEofInPackedField.DOUBLE
 Required.ProtobufInput.PrematureEofInPackedField.DOUBLE
 Required.ProtobufInput.PrematureEofInPackedField.ENUM
 Required.ProtobufInput.PrematureEofInPackedField.ENUM
@@ -36,3 +476,149 @@ Required.ProtobufInput.PrematureEofInPackedField.SINT32
 Required.ProtobufInput.PrematureEofInPackedField.SINT64
 Required.ProtobufInput.PrematureEofInPackedField.SINT64
 Required.ProtobufInput.PrematureEofInPackedField.UINT32
 Required.ProtobufInput.PrematureEofInPackedField.UINT32
 Required.ProtobufInput.PrematureEofInPackedField.UINT64
 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

+ 8 - 13
generate_descriptor_proto.sh

@@ -41,6 +41,11 @@ declare -a RUNTIME_PROTO_FILES=(\
   google/protobuf/type.proto \
   google/protobuf/type.proto \
   google/protobuf/wrappers.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
 CORE_PROTO_IS_CORRECT=0
 PROCESS_ROUND=1
 PROCESS_ROUND=1
 TMP=$(mktemp -d)
 TMP=$(mktemp -d)
@@ -57,9 +62,9 @@ do
   fi
   fi
 
 
   ./protoc --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:$TMP ${RUNTIME_PROTO_FILES[@]} && \
   ./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%.*}
     BASE_NAME=${PROTO_FILE%.*}
     diff ${BASE_NAME}.pb.h $TMP/${BASE_NAME}.pb.h > /dev/null
     diff ${BASE_NAME}.pb.h $TMP/${BASE_NAME}.pb.h > /dev/null
     if test $? -ne 0; then
     if test $? -ne 0; then
@@ -71,24 +76,14 @@ do
     fi
     fi
   done
   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
   # Only override the output if the files are different to avoid re-compilation
   # of the protoc.
   # of the protoc.
   if [ $CORE_PROTO_IS_CORRECT -ne 1 ]; then
   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%.*}
       BASE_NAME=${PROTO_FILE%.*}
       mv $TMP/${BASE_NAME}.pb.h ${BASE_NAME}.pb.h
       mv $TMP/${BASE_NAME}.pb.h ${BASE_NAME}.pb.h
       mv $TMP/${BASE_NAME}.pb.cc ${BASE_NAME}.pb.cc
       mv $TMP/${BASE_NAME}.pb.cc ${BASE_NAME}.pb.cc
     done
     done
-    mv $TMP/google/protobuf/compiler/plugin.pb.* google/protobuf/compiler/
   fi
   fi
 
 
   PROCESS_ROUND=$((PROCESS_ROUND + 1))
   PROCESS_ROUND=$((PROCESS_ROUND + 1))

+ 2 - 2
java/core/src/main/java/com/google/protobuf/AbstractMessage.java

@@ -34,7 +34,6 @@ import com.google.protobuf.Descriptors.EnumValueDescriptor;
 import com.google.protobuf.Descriptors.FieldDescriptor;
 import com.google.protobuf.Descriptors.FieldDescriptor;
 import com.google.protobuf.Descriptors.OneofDescriptor;
 import com.google.protobuf.Descriptors.OneofDescriptor;
 import com.google.protobuf.Internal.EnumLite;
 import com.google.protobuf.Internal.EnumLite;
-
 import java.io.IOException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStream;
 import java.util.Arrays;
 import java.util.Arrays;
@@ -328,7 +327,8 @@ public abstract class AbstractMessage
       extends AbstractMessageLite.Builder
       extends AbstractMessageLite.Builder
       implements Message.Builder {
       implements Message.Builder {
     // The compiler produces an error if this is not declared explicitly.
     // 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
     @Override
     public BuilderType clone() {
     public BuilderType clone() {
       throw new UnsupportedOperationException("clone() should be implemented in subclasses.");
       throw new UnsupportedOperationException("clone() should be implemented in subclasses.");

+ 11 - 10
java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java

@@ -30,6 +30,8 @@
 
 
 package com.google.protobuf;
 package com.google.protobuf;
 
 
+import static com.google.protobuf.Internal.checkNotNull;
+
 import java.io.FilterInputStream;
 import java.io.FilterInputStream;
 import java.io.IOException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStream;
@@ -351,22 +353,23 @@ public abstract class AbstractMessageLite<
      */
      */
     protected static <T> void addAll(final Iterable<T> values,
     protected static <T> void addAll(final Iterable<T> values,
                                      final Collection<? super T> list) {
                                      final Collection<? super T> list) {
-      if (values == null) {
-        throw new NullPointerException();
-      }
+      checkNotNull(values);
       if (values instanceof LazyStringList) {
       if (values instanceof LazyStringList) {
         // For StringOrByteStringLists, check the underlying elements to avoid
         // For StringOrByteStringLists, check the underlying elements to avoid
         // forcing conversions of ByteStrings to Strings.
         // 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());
         checkForNullValues(((LazyStringList) values).getUnderlyingElements());
         list.addAll((Collection<T>) values);
         list.addAll((Collection<T>) values);
       } else if (values instanceof Collection) {
       } else if (values instanceof Collection) {
-        checkForNullValues(values);
+        if (!(values instanceof PrimitiveNonBoxingCollection)) {
+          checkForNullValues(values);
+        }
         list.addAll((Collection<T>) values);
         list.addAll((Collection<T>) values);
       } else {
       } else {
         for (final T value : values) {
         for (final T value : values) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
+          checkNotNull(value);
           list.add(value);
           list.add(value);
         }
         }
       }
       }
@@ -374,9 +377,7 @@ public abstract class AbstractMessageLite<
 
 
     private static void checkForNullValues(final Iterable<?> values) {
     private static void checkForNullValues(final Iterable<?> values) {
       for (final Object value : values) {
       for (final Object value : values) {
-        if (value == null) {
-          throw new NullPointerException();
-        }
+        checkNotNull(value);
       }
       }
     }
     }
   }
   }

+ 25 - 1
java/core/src/main/java/com/google/protobuf/AbstractParser.java

@@ -31,9 +31,9 @@
 package com.google.protobuf;
 package com.google.protobuf;
 
 
 import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream;
 import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream;
-
 import java.io.IOException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStream;
+import java.nio.ByteBuffer;
 
 
 /**
 /**
  * A partial implementation of the {@link Parser} interface which implements
  * A partial implementation of the {@link Parser} interface which implements
@@ -130,6 +130,30 @@ public abstract class AbstractParser<MessageType extends MessageLite>
     return parseFrom(data, EMPTY_REGISTRY);
     return parseFrom(data, EMPTY_REGISTRY);
   }
   }
 
 
+  @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
   @Override
   public MessageType parsePartialFrom(
   public MessageType parsePartialFrom(
       byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
       byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)

+ 5 - 7
java/core/src/main/java/com/google/protobuf/BooleanArrayList.java

@@ -30,8 +30,9 @@
 
 
 package com.google.protobuf;
 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.Arrays;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.RandomAccess;
 import java.util.RandomAccess;
@@ -41,9 +42,8 @@ import java.util.RandomAccess;
  *
  *
  * @author dweis@google.com (Daniel Weis)
  * @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();
   private static final BooleanArrayList EMPTY_LIST = new BooleanArrayList();
   static {
   static {
@@ -198,9 +198,7 @@ final class BooleanArrayList
   public boolean addAll(Collection<? extends Boolean> collection) {
   public boolean addAll(Collection<? extends Boolean> collection) {
     ensureIsMutable();
     ensureIsMutable();
 
 
-    if (collection == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(collection);
 
 
     // We specialize when adding another BooleanArrayList to avoid boxing elements.
     // We specialize when adding another BooleanArrayList to avoid boxing elements.
     if (!(collection instanceof BooleanArrayList)) {
     if (!(collection instanceof BooleanArrayList)) {

+ 2 - 2
java/core/src/main/java/com/google/protobuf/CodedInputStream.java

@@ -355,8 +355,8 @@ public abstract class CodedInputStream {
    * <p>Set the maximum message size. In order to prevent malicious messages from exhausting memory
    * <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
    * 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
    * 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
    * <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.
    * #resetSizeCounter()} after each one to avoid hitting the size limit.

+ 2 - 2
java/core/src/main/java/com/google/protobuf/CodedOutputStream.java

@@ -184,7 +184,7 @@ public abstract class CodedOutputStream extends ByteOutput {
    *     maps are sorted on the lexicographical order of the UTF8 encoded keys.
    *     maps are sorted on the lexicographical order of the UTF8 encoded keys.
    * </ul>
    * </ul>
    */
    */
-  void useDeterministicSerialization() {
+  public void useDeterministicSerialization() {
     serializationDeterministic = true;
     serializationDeterministic = true;
   }
   }
 
 
@@ -1854,7 +1854,7 @@ public abstract class CodedOutputStream extends ByteOutput {
     }
     }
 
 
     static boolean isSupported() {
     static boolean isSupported() {
-      return UnsafeUtil.hasUnsafeByteBufferOperations();
+      return UnsafeUtil.hasUnsafeByteBufferOperations() && UnsafeUtil.hasUnsafeCopyMemory();
     }
     }
 
 
     @Override
     @Override

+ 3 - 4
java/core/src/main/java/com/google/protobuf/Descriptors.java

@@ -30,9 +30,10 @@
 
 
 package com.google.protobuf;
 package com.google.protobuf;
 
 
+import static com.google.protobuf.Internal.checkNotNull;
+
 import com.google.protobuf.DescriptorProtos.*;
 import com.google.protobuf.DescriptorProtos.*;
 import com.google.protobuf.Descriptors.FileDescriptor.Syntax;
 import com.google.protobuf.Descriptors.FileDescriptor.Syntax;
-
 import java.lang.ref.WeakReference;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Arrays;
@@ -682,9 +683,7 @@ public final class Descriptors {
 
 
     /** Determines if the given field name is reserved. */
     /** Determines if the given field name is reserved. */
     public boolean isReservedName(final String name) {
     public boolean isReservedName(final String name) {
-      if (name == null) {
-        throw new NullPointerException();
-      }
+      checkNotNull(name);
       for (final String reservedName : proto.getReservedNameList()) {
       for (final String reservedName : proto.getReservedNameList()) {
         if (reservedName.equals(name)) {
         if (reservedName.equals(name)) {
           return true;
           return true;

+ 5 - 7
java/core/src/main/java/com/google/protobuf/DoubleArrayList.java

@@ -30,8 +30,9 @@
 
 
 package com.google.protobuf;
 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.Arrays;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.RandomAccess;
 import java.util.RandomAccess;
@@ -41,9 +42,8 @@ import java.util.RandomAccess;
  *
  *
  * @author dweis@google.com (Daniel Weis)
  * @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();
   private static final DoubleArrayList EMPTY_LIST = new DoubleArrayList();
   static {
   static {
@@ -199,9 +199,7 @@ final class DoubleArrayList
   public boolean addAll(Collection<? extends Double> collection) {
   public boolean addAll(Collection<? extends Double> collection) {
     ensureIsMutable();
     ensureIsMutable();
 
 
-    if (collection == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(collection);
 
 
     // We specialize when adding another DoubleArrayList to avoid boxing elements.
     // We specialize when adding another DoubleArrayList to avoid boxing elements.
     if (!(collection instanceof DoubleArrayList)) {
     if (!(collection instanceof DoubleArrayList)) {

+ 3 - 4
java/core/src/main/java/com/google/protobuf/DynamicMessage.java

@@ -30,11 +30,12 @@
 
 
 package com.google.protobuf;
 package com.google.protobuf;
 
 
+import static com.google.protobuf.Internal.checkNotNull;
+
 import com.google.protobuf.Descriptors.Descriptor;
 import com.google.protobuf.Descriptors.Descriptor;
 import com.google.protobuf.Descriptors.EnumValueDescriptor;
 import com.google.protobuf.Descriptors.EnumValueDescriptor;
 import com.google.protobuf.Descriptors.FieldDescriptor;
 import com.google.protobuf.Descriptors.FieldDescriptor;
 import com.google.protobuf.Descriptors.OneofDescriptor;
 import com.google.protobuf.Descriptors.OneofDescriptor;
-
 import java.io.IOException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStream;
 import java.util.Collections;
 import java.util.Collections;
@@ -631,9 +632,7 @@ public final class DynamicMessage extends AbstractMessage {
     /** Verifies that the value is EnumValueDescriptor and matches Enum Type. */
     /** Verifies that the value is EnumValueDescriptor and matches Enum Type. */
     private void ensureSingularEnumValueDescriptor(
     private void ensureSingularEnumValueDescriptor(
         FieldDescriptor field, Object value) {
         FieldDescriptor field, Object value) {
-      if (value == null) {
-        throw new NullPointerException();
-      }
+      checkNotNull(value);
       if (!(value instanceof EnumValueDescriptor)) {
       if (!(value instanceof EnumValueDescriptor)) {
         throw new IllegalArgumentException(
         throw new IllegalArgumentException(
           "DynamicMessage should use EnumValueDescriptor to set Enum Value.");
           "DynamicMessage should use EnumValueDescriptor to set Enum Value.");

+ 3 - 4
java/core/src/main/java/com/google/protobuf/FieldSet.java

@@ -30,8 +30,9 @@
 
 
 package com.google.protobuf;
 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.io.IOException;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Collections;
@@ -385,9 +386,7 @@ final class FieldSet<FieldDescriptorType extends
    */
    */
   private static void verifyType(final WireFormat.FieldType type,
   private static void verifyType(final WireFormat.FieldType type,
                                  final Object value) {
                                  final Object value) {
-    if (value == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(value);
 
 
     boolean isValid = false;
     boolean isValid = false;
     switch (type.getJavaType()) {
     switch (type.getJavaType()) {

+ 5 - 7
java/core/src/main/java/com/google/protobuf/FloatArrayList.java

@@ -30,8 +30,9 @@
 
 
 package com.google.protobuf;
 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.Arrays;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.RandomAccess;
 import java.util.RandomAccess;
@@ -41,9 +42,8 @@ import java.util.RandomAccess;
  *
  *
  * @author dweis@google.com (Daniel Weis)
  * @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();
   private static final FloatArrayList EMPTY_LIST = new FloatArrayList();
   static {
   static {
@@ -198,9 +198,7 @@ final class FloatArrayList
   public boolean addAll(Collection<? extends Float> collection) {
   public boolean addAll(Collection<? extends Float> collection) {
     ensureIsMutable();
     ensureIsMutable();
 
 
-    if (collection == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(collection);
 
 
     // We specialize when adding another FloatArrayList to avoid boxing elements.
     // We specialize when adding another FloatArrayList to avoid boxing elements.
     if (!(collection instanceof FloatArrayList)) {
     if (!(collection instanceof FloatArrayList)) {

+ 20 - 2
java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java

@@ -34,6 +34,7 @@ import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream;
 import com.google.protobuf.GeneratedMessageLite.EqualsVisitor.NotEqualsException;
 import com.google.protobuf.GeneratedMessageLite.EqualsVisitor.NotEqualsException;
 import com.google.protobuf.Internal.BooleanList;
 import com.google.protobuf.Internal.BooleanList;
 import com.google.protobuf.Internal.DoubleList;
 import com.google.protobuf.Internal.DoubleList;
+import com.google.protobuf.Internal.EnumLiteMap;
 import com.google.protobuf.Internal.FloatList;
 import com.google.protobuf.Internal.FloatList;
 import com.google.protobuf.Internal.IntList;
 import com.google.protobuf.Internal.IntList;
 import com.google.protobuf.Internal.LongList;
 import com.google.protobuf.Internal.LongList;
@@ -45,6 +46,7 @@ import java.io.ObjectStreamException;
 import java.io.Serializable;
 import java.io.Serializable;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.Iterator;
@@ -136,6 +138,7 @@ public abstract class GeneratedMessageLite<
       return false;
       return false;
     }
     }
 
 
+
     try {
     try {
       visit(EqualsVisitor.INSTANCE, (MessageType) other);
       visit(EqualsVisitor.INSTANCE, (MessageType) other);
     } catch (NotEqualsException e) {
     } catch (NotEqualsException e) {
@@ -1154,6 +1157,7 @@ public abstract class GeneratedMessageLite<
     }
     }
   }
   }
 
 
+
   /**
   /**
    * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}.
    * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}.
    *
    *
@@ -1527,6 +1531,20 @@ public abstract class GeneratedMessageLite<
     return message;
     return message;
   }
   }
 
 
+  // 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.
   // Validates last tag.
   protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
   protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
       T defaultInstance, ByteString data)
       T defaultInstance, ByteString data)
@@ -1979,13 +1997,13 @@ public abstract class GeneratedMessageLite<
   /**
   /**
    * Implements hashCode by accumulating state.
    * 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
     // 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
     // other is this. This is required due to how oneof cases are handled. See the class comment
     // on Visitor for more information.
     // on Visitor for more information.
 
 
-    private int hashCode = 0;
+    int hashCode = 0;
 
 
     @Override
     @Override
     public boolean visitBoolean(
     public boolean visitBoolean(

+ 1 - 1
java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java

@@ -41,7 +41,7 @@ import com.google.protobuf.Descriptors.OneofDescriptor;
 // class without breaking binary compatibility with old generated code that still subclasses
 // class without breaking binary compatibility with old generated code that still subclasses
 // the old GeneratedMessageV3 class. To allow these different GeneratedMessageV3V? classes to
 // the old GeneratedMessageV3 class. To allow these different GeneratedMessageV3V? classes to
 // interoperate (e.g., a GeneratedMessageV3V3 object has a message extension field whose class
 // 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.
 // 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
 // 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
 // to be able to use GeneratedMessage.GeneratedExtension. The GeneratedExtension definition in

+ 5 - 7
java/core/src/main/java/com/google/protobuf/IntArrayList.java

@@ -30,8 +30,9 @@
 
 
 package com.google.protobuf;
 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.Arrays;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.RandomAccess;
 import java.util.RandomAccess;
@@ -41,9 +42,8 @@ import java.util.RandomAccess;
  *
  *
  * @author dweis@google.com (Daniel Weis)
  * @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();
   private static final IntArrayList EMPTY_LIST = new IntArrayList();
   static {
   static {
@@ -198,9 +198,7 @@ final class IntArrayList
   public boolean addAll(Collection<? extends Integer> collection) {
   public boolean addAll(Collection<? extends Integer> collection) {
     ensureIsMutable();
     ensureIsMutable();
 
 
-    if (collection == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(collection);
 
 
     // We specialize when adding another IntArrayList to avoid boxing elements.
     // We specialize when adding another IntArrayList to avoid boxing elements.
     if (!(collection instanceof IntArrayList)) {
     if (!(collection instanceof IntArrayList)) {

+ 15 - 0
java/core/src/main/java/com/google/protobuf/Internal.java

@@ -59,6 +59,16 @@ public final class Internal {
   static final Charset UTF_8 = Charset.forName("UTF-8");
   static final Charset UTF_8 = Charset.forName("UTF-8");
   static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
   static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
 
 
+  /**
+   * 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}.
    * Throws an appropriate {@link NullPointerException} if the given objects is {@code null}.
    */
    */
@@ -420,6 +430,11 @@ public final class Internal {
       CodedInputStream.newInstance(EMPTY_BYTE_ARRAY);
       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>}.
    * Provides an immutable view of {@code List<T>} around a {@code List<F>}.
    *
    *

+ 1 - 0
java/core/src/main/java/com/google/protobuf/LazyFieldLite.java

@@ -394,6 +394,7 @@ public class LazyFieldLite {
     }
     }
   }
   }
 
 
+
   /**
   /**
    * Might lazily parse the bytes that were previously passed in. Is thread-safe.
    * Might lazily parse the bytes that were previously passed in. Is thread-safe.
    */
    */

+ 5 - 7
java/core/src/main/java/com/google/protobuf/LongArrayList.java

@@ -30,8 +30,9 @@
 
 
 package com.google.protobuf;
 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.Arrays;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.RandomAccess;
 import java.util.RandomAccess;
@@ -41,9 +42,8 @@ import java.util.RandomAccess;
  *
  *
  * @author dweis@google.com (Daniel Weis)
  * @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();
   private static final LongArrayList EMPTY_LIST = new LongArrayList();
   static {
   static {
@@ -198,9 +198,7 @@ final class LongArrayList
   public boolean addAll(Collection<? extends Long> collection) {
   public boolean addAll(Collection<? extends Long> collection) {
     ensureIsMutable();
     ensureIsMutable();
 
 
-    if (collection == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(collection);
 
 
     // We specialize when adding another LongArrayList to avoid boxing elements.
     // We specialize when adding another LongArrayList to avoid boxing elements.
     if (!(collection instanceof LongArrayList)) {
     if (!(collection instanceof LongArrayList)) {

+ 18 - 6
java/core/src/main/java/com/google/protobuf/MapEntry.java

@@ -33,7 +33,6 @@ package com.google.protobuf;
 import com.google.protobuf.Descriptors.Descriptor;
 import com.google.protobuf.Descriptors.Descriptor;
 import com.google.protobuf.Descriptors.EnumValueDescriptor;
 import com.google.protobuf.Descriptors.EnumValueDescriptor;
 import com.google.protobuf.Descriptors.FieldDescriptor;
 import com.google.protobuf.Descriptors.FieldDescriptor;
-
 import java.io.IOException;
 import java.io.IOException;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.Map;
 import java.util.Map;
@@ -171,7 +170,7 @@ public final class MapEntry<K, V> extends AbstractMessage {
 
 
   @Override
   @Override
   public Builder<K, V> toBuilder() {
   public Builder<K, V> toBuilder() {
-    return new Builder<K, V>(metadata, key, value);
+    return new Builder<K, V>(metadata, key, value, true, true);
   }
   }
 
 
   @Override
   @Override
@@ -247,15 +246,19 @@ public final class MapEntry<K, V> extends AbstractMessage {
     private final Metadata<K, V> metadata;
     private final Metadata<K, V> metadata;
     private K key;
     private K key;
     private V value;
     private V value;
+    private boolean hasKey;
+    private boolean hasValue;
 
 
     private Builder(Metadata<K, V> metadata) {
     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.metadata = metadata;
       this.key = key;
       this.key = key;
       this.value = value;
       this.value = value;
+      this.hasKey = hasKey;
+      this.hasValue = hasValue;
     }
     }
 
 
     public K getKey() {
     public K getKey() {
@@ -268,21 +271,25 @@ public final class MapEntry<K, V> extends AbstractMessage {
 
 
     public Builder<K, V> setKey(K key) {
     public Builder<K, V> setKey(K key) {
       this.key = key;
       this.key = key;
+      this.hasKey = true;
       return this;
       return this;
     }
     }
 
 
     public Builder<K, V> clearKey() {
     public Builder<K, V> clearKey() {
       this.key = metadata.defaultKey;
       this.key = metadata.defaultKey;
+      this.hasKey = false;
       return this;
       return this;
     }
     }
 
 
     public Builder<K, V> setValue(V value) {
     public Builder<K, V> setValue(V value) {
       this.value = value;
       this.value = value;
+      this.hasValue = true;
       return this;
       return this;
     }
     }
 
 
     public Builder<K, V> clearValue() {
     public Builder<K, V> clearValue() {
       this.value = metadata.defaultValue;
       this.value = metadata.defaultValue;
+      this.hasValue = false;
       return this;
       return this;
     }
     }
 
 
@@ -404,7 +411,7 @@ public final class MapEntry<K, V> extends AbstractMessage {
     @Override
     @Override
     public boolean hasField(FieldDescriptor field) {
     public boolean hasField(FieldDescriptor field) {
       checkFieldDescriptor(field);
       checkFieldDescriptor(field);
-      return true;
+      return field.getNumber() == 1 ? hasKey : hasValue;
     }
     }
 
 
     @Override
     @Override
@@ -438,7 +445,7 @@ public final class MapEntry<K, V> extends AbstractMessage {
     @Override
     @Override
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
     public Builder<K, V> clone() {
     public Builder<K, V> clone() {
-      return new Builder(metadata, key, value);
+      return new Builder(metadata, key, value, hasKey, hasValue);
     }
     }
   }
   }
 
 
@@ -448,4 +455,9 @@ public final class MapEntry<K, V> extends AbstractMessage {
     }
     }
     return true;
     return true;
   }
   }
+  
+  /** Returns the metadata only for experimental runtime. */
+  final Metadata<K, V> getMetadata() {
+    return metadata;
+  }
 }
 }

+ 5 - 0
java/core/src/main/java/com/google/protobuf/MapEntryLite.java

@@ -223,4 +223,9 @@ public class MapEntryLite<K, V> {
     input.popLimit(oldLimit);
     input.popLimit(oldLimit);
     map.put(key, value);
     map.put(key, value);
   }
   }
+
+  /** For experimental runtime internal use only. */
+  Metadata<K, V> getMetadata() {
+    return metadata;
+  }
 }
 }

+ 8 - 0
java/core/src/main/java/com/google/protobuf/MapField.java

@@ -30,6 +30,8 @@
 
 
 package com.google.protobuf;
 package com.google.protobuf;
 
 
+import static com.google.protobuf.Internal.checkNotNull;
+
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Collections;
@@ -329,6 +331,8 @@ public class MapField<K, V> implements MutabilityOracle {
     @Override
     @Override
     public V put(K key, V value) {
     public V put(K key, V value) {
       mutabilityOracle.ensureMutable();
       mutabilityOracle.ensureMutable();
+      checkNotNull(key);
+      checkNotNull(value);
       return delegate.put(key, value);
       return delegate.put(key, value);
     }
     }
 
 
@@ -341,6 +345,10 @@ public class MapField<K, V> implements MutabilityOracle {
     @Override
     @Override
     public void putAll(Map<? extends K, ? extends V> m) {
     public void putAll(Map<? extends K, ? extends V> m) {
       mutabilityOracle.ensureMutable();
       mutabilityOracle.ensureMutable();
+      for (K key : m.keySet()) {
+        checkNotNull(key);
+        checkNotNull(m.get(key));
+      }
       delegate.putAll(m);
       delegate.putAll(m);
     }
     }
 
 

+ 13 - 1
java/core/src/main/java/com/google/protobuf/MapFieldLite.java

@@ -30,8 +30,9 @@
 
 
 package com.google.protobuf;
 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.Arrays;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashMap;
@@ -88,6 +89,9 @@ public final class MapFieldLite<K, V> extends LinkedHashMap<K, V> {
 
 
   @Override public V put(K key, V value) {
   @Override public V put(K key, V value) {
     ensureMutable();
     ensureMutable();
+    checkNotNull(key);
+
+    checkNotNull(value);
     return super.put(key, value);
     return super.put(key, value);
   }
   }
 
 
@@ -97,6 +101,7 @@ public final class MapFieldLite<K, V> extends LinkedHashMap<K, V> {
 
 
   @Override public void putAll(Map<? extends K, ? extends V> m) {
   @Override public void putAll(Map<? extends K, ? extends V> m) {
     ensureMutable();
     ensureMutable();
+    checkForNullKeysAndValues(m);
     super.putAll(m);
     super.putAll(m);
   }
   }
 
 
@@ -105,6 +110,13 @@ public final class MapFieldLite<K, V> extends LinkedHashMap<K, V> {
     return super.remove(key);
     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) {
   private static boolean equals(Object a, Object b) {
     if (a instanceof byte[] && b instanceof byte[]) {
     if (a instanceof byte[] && b instanceof byte[]) {
       return Arrays.equals((byte[]) a, (byte[]) b);
       return Arrays.equals((byte[]) a, (byte[]) b);

+ 13 - 0
java/core/src/main/java/com/google/protobuf/Parser.java

@@ -31,6 +31,7 @@
 package com.google.protobuf;
 package com.google.protobuf;
 
 
 import java.io.InputStream;
 import java.io.InputStream;
+import java.nio.ByteBuffer;
 
 
 /**
 /**
  * Abstract interface for parsing Protocol Messages.
  * Abstract interface for parsing Protocol Messages.
@@ -92,6 +93,18 @@ public interface Parser<MessageType> {
   // ---------------------------------------------------------------
   // ---------------------------------------------------------------
   // Convenience methods.
   // 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}.
    * Parses {@code data} as a message of {@code MessageType}.
    * This is just a small wrapper around {@link #parseFrom(CodedInputStream)}.
    * This is just a small wrapper around {@link #parseFrom(CodedInputStream)}.

+ 34 - 0
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 {}

+ 6 - 12
java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java

@@ -30,6 +30,8 @@
 
 
 package com.google.protobuf;
 package com.google.protobuf;
 
 
+import static com.google.protobuf.Internal.checkNotNull;
+
 import java.util.AbstractList;
 import java.util.AbstractList;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collection;
@@ -290,9 +292,7 @@ public class RepeatedFieldBuilderV3
    */
    */
   public RepeatedFieldBuilderV3<MType, BType, IType> setMessage(
   public RepeatedFieldBuilderV3<MType, BType, IType> setMessage(
       int index, MType message) {
       int index, MType message) {
-    if (message == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(message);
     ensureMutableMessageList();
     ensureMutableMessageList();
     messages.set(index, message);
     messages.set(index, message);
     if (builders != null) {
     if (builders != null) {
@@ -315,9 +315,7 @@ public class RepeatedFieldBuilderV3
    */
    */
   public RepeatedFieldBuilderV3<MType, BType, IType> addMessage(
   public RepeatedFieldBuilderV3<MType, BType, IType> addMessage(
       MType message) {
       MType message) {
-    if (message == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(message);
     ensureMutableMessageList();
     ensureMutableMessageList();
     messages.add(message);
     messages.add(message);
     if (builders != null) {
     if (builders != null) {
@@ -339,9 +337,7 @@ public class RepeatedFieldBuilderV3
    */
    */
   public RepeatedFieldBuilderV3<MType, BType, IType> addMessage(
   public RepeatedFieldBuilderV3<MType, BType, IType> addMessage(
       int index, MType message) {
       int index, MType message) {
-    if (message == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(message);
     ensureMutableMessageList();
     ensureMutableMessageList();
     messages.add(index, message);
     messages.add(index, message);
     if (builders != null) {
     if (builders != null) {
@@ -363,9 +359,7 @@ public class RepeatedFieldBuilderV3
   public RepeatedFieldBuilderV3<MType, BType, IType> addAllMessages(
   public RepeatedFieldBuilderV3<MType, BType, IType> addAllMessages(
       Iterable<? extends MType> values) {
       Iterable<? extends MType> values) {
     for (final MType value : 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.
     // If we can inspect the size, we can more efficiently add messages.

+ 4 - 8
java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java

@@ -30,6 +30,8 @@
 
 
 package com.google.protobuf;
 package com.google.protobuf;
 
 
+import static com.google.protobuf.Internal.checkNotNull;
+
 /**
 /**
  * {@code SingleFieldBuilderV3} implements a structure that a protocol
  * {@code SingleFieldBuilderV3} implements a structure that a protocol
  * message uses to hold a single field of another protocol message. It supports
  * message uses to hold a single field of another protocol message. It supports
@@ -84,10 +86,7 @@ public class SingleFieldBuilderV3
       MType message,
       MType message,
       AbstractMessage.BuilderParent parent,
       AbstractMessage.BuilderParent parent,
       boolean isClean) {
       boolean isClean) {
-    if (message == null) {
-      throw new NullPointerException();
-    }
-    this.message = message;
+    this.message = checkNotNull(message);
     this.parent = parent;
     this.parent = parent;
     this.isClean = isClean;
     this.isClean = isClean;
   }
   }
@@ -169,10 +168,7 @@ public class SingleFieldBuilderV3
    */
    */
   public SingleFieldBuilderV3<MType, BType, IType> setMessage(
   public SingleFieldBuilderV3<MType, BType, IType> setMessage(
       MType message) {
       MType message) {
-    if (message == null) {
-      throw new NullPointerException();
-    }
-    this.message = message;
+    this.message = checkNotNull(message);
     if (builder != null) {
     if (builder != null) {
       builder.dispose();
       builder.dispose();
       builder = null;
       builder = null;

+ 3 - 1
java/core/src/main/java/com/google/protobuf/TextFormat.java

@@ -1442,7 +1442,7 @@ public final class TextFormat {
 
 
     /**
     /**
      * Parse a single field from {@code tokenizer} and merge it into
      * Parse a single field from {@code tokenizer} and merge it into
-     * {@code builder}.
+     * {@code target}.
      */
      */
     private void mergeField(final Tokenizer tokenizer,
     private void mergeField(final Tokenizer tokenizer,
                             final ExtensionRegistry extensionRegistry,
                             final ExtensionRegistry extensionRegistry,
@@ -1712,6 +1712,8 @@ public final class TextFormat {
       }
       }
 
 
       if (field.isRepeated()) {
       if (field.isRepeated()) {
+        // TODO(b/29122459): If field.isMapField() and FORBID_SINGULAR_OVERWRITES mode,
+        //     check for duplicate map keys here.
         target.addRepeatedField(field, value);
         target.addRepeatedField(field, value);
       } else if ((singularOverwritePolicy
       } else if ((singularOverwritePolicy
               == SingularOverwritePolicy.FORBID_SINGULAR_OVERWRITES)
               == SingularOverwritePolicy.FORBID_SINGULAR_OVERWRITES)

+ 2 - 2
java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java

@@ -91,7 +91,7 @@ public final class UnknownFieldSet implements MessageLite {
    * Construct an {@code UnknownFieldSet} around the given map.  The map is
    * Construct an {@code UnknownFieldSet} around the given map.  The map is
    * expected to be immutable.
    * expected to be immutable.
    */
    */
-  private UnknownFieldSet(final Map<Integer, Field> fields,
+  UnknownFieldSet(final Map<Integer, Field> fields,
       final Map<Integer, Field> fieldsDescending) {
       final Map<Integer, Field> fieldsDescending) {
     this.fields = fields;
     this.fields = fields;
   }
   }
@@ -715,7 +715,7 @@ public final class UnknownFieldSet implements MessageLite {
    * @see UnknownFieldSet
    * @see UnknownFieldSet
    */
    */
   public static final class Field {
   public static final class Field {
-    private Field() {}
+    Field() {}
 
 
     /** Construct a new {@link Builder}. */
     /** Construct a new {@link Builder}. */
     public static Builder newBuilder() {
     public static Builder newBuilder() {

+ 308 - 93
java/core/src/main/java/com/google/protobuf/UnsafeUtil.java

@@ -33,19 +33,23 @@ package com.google.protobuf;
 import java.lang.reflect.Field;
 import java.lang.reflect.Field;
 import java.nio.Buffer;
 import java.nio.Buffer;
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.security.AccessController;
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
 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. */
 /** Utility class for working with unsafe operations. */
-// TODO(nathanmittler): Add support for Android Memory/MemoryBlock
 final class UnsafeUtil {
 final class UnsafeUtil {
+  private static final Logger logger = Logger.getLogger(UnsafeUtil.class.getName());
   private static final sun.misc.Unsafe UNSAFE = getUnsafe();
   private static final sun.misc.Unsafe UNSAFE = getUnsafe();
+  private static final MemoryAccessor MEMORY_ACCESSOR = getMemoryAccessor();
   private static final boolean HAS_UNSAFE_BYTEBUFFER_OPERATIONS =
   private static final boolean HAS_UNSAFE_BYTEBUFFER_OPERATIONS =
       supportsUnsafeByteBufferOperations();
       supportsUnsafeByteBufferOperations();
   private static final boolean HAS_UNSAFE_ARRAY_OPERATIONS = supportsUnsafeArrayOperations();
   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 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() {}
   private UnsafeUtil() {}
 
 
@@ -53,20 +57,16 @@ final class UnsafeUtil {
     return HAS_UNSAFE_ARRAY_OPERATIONS;
     return HAS_UNSAFE_ARRAY_OPERATIONS;
   }
   }
 
 
-  static boolean hasUnsafeByteBufferOperations() {
-    return HAS_UNSAFE_BYTEBUFFER_OPERATIONS;
+  static boolean hasUnsafeCopyMemory() {
+    return HAS_UNSAFE_COPY_MEMORY;
   }
   }
 
 
-  static Object allocateInstance(Class<?> clazz) {
-    try {
-      return UNSAFE.allocateInstance(clazz);
-    } catch (InstantiationException e) {
-      throw new RuntimeException(e);
-    }
+  static boolean hasUnsafeByteBufferOperations() {
+    return HAS_UNSAFE_BYTEBUFFER_OPERATIONS;
   }
   }
 
 
   static long objectFieldOffset(Field field) {
   static long objectFieldOffset(Field field) {
-    return UNSAFE.objectFieldOffset(field);
+    return MEMORY_ACCESSOR.objectFieldOffset(field);
   }
   }
 
 
   static long getArrayBaseOffset() {
   static long getArrayBaseOffset() {
@@ -74,103 +74,103 @@ final class UnsafeUtil {
   }
   }
 
 
   static byte getByte(Object target, long offset) {
   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) {
   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) {
   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) {
   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) {
   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) {
   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) {
   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) {
   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) {
   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) {
   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) {
   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) {
   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) {
   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) {
   static void putObject(Object target, long offset, Object value) {
-    UNSAFE.putObject(target, offset, value);
+    MEMORY_ACCESSOR.putObject(target, offset, value);
   }
   }
 
 
   static void copyMemory(
   static void copyMemory(
       Object src, long srcOffset, Object target, long targetOffset, long length) {
       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) {
   static byte getByte(long address) {
-    return UNSAFE.getByte(address);
+    return MEMORY_ACCESSOR.getByte(address);
   }
   }
 
 
   static void putByte(long address, byte value) {
   static void putByte(long address, byte value) {
-    UNSAFE.putByte(address, value);
+    MEMORY_ACCESSOR.putByte(address, value);
   }
   }
 
 
   static int getInt(long address) {
   static int getInt(long address) {
-    return UNSAFE.getInt(address);
+    return MEMORY_ACCESSOR.getInt(address);
   }
   }
 
 
   static void putInt(long address, int value) {
   static void putInt(long address, int value) {
-    UNSAFE.putInt(address, value);
+    MEMORY_ACCESSOR.putInt(address, value);
   }
   }
 
 
   static long getLong(long address) {
   static long getLong(long address) {
-    return UNSAFE.getLong(address);
+    return MEMORY_ACCESSOR.getLong(address);
   }
   }
 
 
   static void putLong(long address, long value) {
   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) {
   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}.
    * Gets the offset of the {@code address} field of the given direct {@link ByteBuffer}.
    */
    */
   static long addressOffset(ByteBuffer buffer) {
   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 @@ final class UnsafeUtil {
     try {
     try {
       unsafe =
       unsafe =
           AccessController.doPrivileged(
           AccessController.doPrivileged(
-              new PrivilegedExceptionAction<Unsafe>() {
+              new PrivilegedExceptionAction<sun.misc.Unsafe>() {
                 @Override
                 @Override
                 public sun.misc.Unsafe run() throws Exception {
                 public sun.misc.Unsafe run() throws Exception {
                   Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
                   Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
@@ -204,69 +204,114 @@ final class UnsafeUtil {
     return unsafe;
     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. */
   /** Indicates whether or not unsafe array operations are supported on this platform. */
   private static boolean supportsUnsafeArrayOperations() {
   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.
-      }
-    }
-    return supported;
+    if (UNSAFE == null) {
+      return false;
+    }
+    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() {
   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.
-      }
-    }
-    return supported;
+    if (UNSAFE == null) {
+      return false;
+    }
+    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.
    * Get the base offset for byte arrays, or {@code -1} if {@code sun.misc.Unsafe} is not available.
    */
    */
   private static int byteArrayBaseOffset() {
   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 @@ final class UnsafeUtil {
    * available.
    * available.
    */
    */
   private static long fieldOffset(Field field) {
   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 @@ final class UnsafeUtil {
     }
     }
     return field;
     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));
+    }
+  }
+
 }
 }

+ 1 - 1
java/core/src/main/java/com/google/protobuf/Utf8.java

@@ -1332,7 +1332,7 @@ final class Utf8 {
       // the index (relative to the start of the array) is also 8-byte aligned. We do this by
       // 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
       // ANDing the index with 7 to determine the number of bytes that need to be read before
       // we're 8-byte aligned.
       // 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--) {
       for (int j = unaligned; j > 0; j--) {
         if (UnsafeUtil.getByte(bytes, offset++) < 0) {
         if (UnsafeUtil.getByte(bytes, offset++) < 0) {
           return unaligned - j;
           return unaligned - j;

+ 1 - 1
java/core/src/test/java/com/google/protobuf/LazyFieldTest.java

@@ -32,7 +32,6 @@ package com.google.protobuf;
 
 
 import protobuf_unittest.UnittestProto.TestAllExtensions;
 import protobuf_unittest.UnittestProto.TestAllExtensions;
 import protobuf_unittest.UnittestProto.TestAllTypes;
 import protobuf_unittest.UnittestProto.TestAllTypes;
-import java.io.IOException;
 import junit.framework.TestCase;
 import junit.framework.TestCase;
 
 
 /**
 /**
@@ -89,6 +88,7 @@ public class LazyFieldTest extends TestCase {
     assertFalse(message.equals(lazyField.getValue()));
     assertFalse(message.equals(lazyField.getValue()));
   }
   }
 
 
+  @SuppressWarnings("EqualsIncompatibleType") // LazyField.equals() is not symmetric
   public void testEqualsObjectEx() throws Exception {
   public void testEqualsObjectEx() throws Exception {
     TestAllExtensions message = TestUtil.getAllExtensionsSet();
     TestAllExtensions message = TestUtil.getAllExtensionsSet();
     LazyField lazyField = createLazyFieldFromMessage(message);
     LazyField lazyField = createLazyFieldFromMessage(message);

+ 108 - 0
java/core/src/test/java/com/google/protobuf/LiteTest.java

@@ -52,6 +52,7 @@ import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.BarPrime;
 import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Foo;
 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.TestOneofEquals;
 import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestRecursiveOneof;
 import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestRecursiveOneof;
+import java.nio.ByteBuffer;
 import junit.framework.TestCase;
 import junit.framework.TestCase;
 
 
 /**
 /**
@@ -2174,6 +2175,24 @@ public class LiteTest extends TestCase {
     assertFalse(bar.equals(barPrime));
     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 {
   public void testOneofEquals() throws Exception {
     TestOneofEquals.Builder builder = TestOneofEquals.newBuilder();
     TestOneofEquals.Builder builder = TestOneofEquals.newBuilder();
     TestOneofEquals message1 = builder.build();
     TestOneofEquals message1 = builder.build();
@@ -2270,4 +2289,93 @@ public class LiteTest extends TestCase {
     // This tests that we don't infinite loop.
     // This tests that we don't infinite loop.
     TestRecursiveOneof.getDefaultInstance().hashCode();
     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());
+    }
+  }
 }
 }

+ 1 - 0
java/core/src/test/java/com/google/protobuf/MapForProto2Test.java

@@ -759,6 +759,7 @@ public class MapForProto2Test extends TestCase {
     assertEquals(55, message.getInt32ToInt32Field().get(55).intValue());
     assertEquals(55, message.getInt32ToInt32Field().get(55).intValue());
   }
   }
 
 
+  // See additional coverage in TextFormatTest.java.
   public void testTextFormat() throws Exception {
   public void testTextFormat() throws Exception {
     TestMap.Builder builder = TestMap.newBuilder();
     TestMap.Builder builder = TestMap.newBuilder();
     setMapValuesUsingAccessors(builder);
     setMapValuesUsingAccessors(builder);

+ 38 - 1
java/core/src/test/java/com/google/protobuf/MapTest.java

@@ -30,7 +30,7 @@
 
 
 package com.google.protobuf;
 package com.google.protobuf;
 
 
-
+import static org.junit.Assert.assertArrayEquals;
 import com.google.protobuf.Descriptors.Descriptor;
 import com.google.protobuf.Descriptors.Descriptor;
 import com.google.protobuf.Descriptors.EnumDescriptor;
 import com.google.protobuf.Descriptors.EnumDescriptor;
 import com.google.protobuf.Descriptors.EnumValueDescriptor;
 import com.google.protobuf.Descriptors.EnumValueDescriptor;
@@ -870,6 +870,7 @@ public class MapTest extends TestCase {
     assertEquals(55, message.getInt32ToInt32Field().get(55).intValue());
     assertEquals(55, message.getInt32ToInt32Field().get(55).intValue());
   }
   }
 
 
+  // See additional coverage in TextFormatTest.java.
   public void testTextFormat() throws Exception {
   public void testTextFormat() throws Exception {
     TestMap.Builder builder = TestMap.newBuilder();
     TestMap.Builder builder = TestMap.newBuilder();
     setMapValuesUsingAccessors(builder);
     setMapValuesUsingAccessors(builder);
@@ -1492,4 +1493,40 @@ public class MapTest extends TestCase {
     map.put(key3, value3);
     map.put(key3, value3);
     return map;
     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());
+  }
 }
 }

+ 23 - 4
java/core/src/test/java/com/google/protobuf/ParserTest.java

@@ -79,6 +79,8 @@ public class ParserTest extends TestCase {
         new ByteArrayInputStream(data), registry));
         new ByteArrayInputStream(data), registry));
     assertMessageEquals(message, parser.parseFrom(
     assertMessageEquals(message, parser.parseFrom(
         CodedInputStream.newInstance(data), registry));
         CodedInputStream.newInstance(data), registry));
+    assertMessageEquals(
+        message, parser.parseFrom(message.toByteString().asReadOnlyByteBuffer(), registry));
   }
   }
 
 
   @SuppressWarnings("unchecked")
   @SuppressWarnings("unchecked")
@@ -99,6 +101,7 @@ public class ParserTest extends TestCase {
         new ByteArrayInputStream(data)));
         new ByteArrayInputStream(data)));
     assertMessageEquals(message, parser.parseFrom(
     assertMessageEquals(message, parser.parseFrom(
         CodedInputStream.newInstance(data)));
         CodedInputStream.newInstance(data)));
+    assertMessageEquals(message, parser.parseFrom(message.toByteString().asReadOnlyByteBuffer()));
   }
   }
 
 
   private void assertMessageEquals(
   private void assertMessageEquals(
@@ -178,6 +181,9 @@ public class ParserTest extends TestCase {
   public void testParseExtensions() throws Exception {
   public void testParseExtensions() throws Exception {
     assertRoundTripEquals(TestUtil.getAllExtensionsSet(),
     assertRoundTripEquals(TestUtil.getAllExtensionsSet(),
                           TestUtil.getExtensionRegistry());
                           TestUtil.getExtensionRegistry());
+  }
+
+  public void testParseExtensionsLite() throws Exception {
     assertRoundTripEquals(
     assertRoundTripEquals(
         TestUtilLite.getAllLiteExtensionsSet(), TestUtilLite.getExtensionRegistryLite());
         TestUtilLite.getAllLiteExtensionsSet(), TestUtilLite.getExtensionRegistryLite());
   }
   }
@@ -186,6 +192,9 @@ public class ParserTest extends TestCase {
     assertRoundTripEquals(TestUtil.getPackedSet());
     assertRoundTripEquals(TestUtil.getPackedSet());
     assertRoundTripEquals(TestUtil.getPackedExtensionsSet(),
     assertRoundTripEquals(TestUtil.getPackedExtensionsSet(),
                           TestUtil.getExtensionRegistry());
                           TestUtil.getExtensionRegistry());
+  }
+
+  public void testParsePackedLite() throws Exception {
     assertRoundTripEquals(
     assertRoundTripEquals(
         TestUtilLite.getLitePackedExtensionsSet(), TestUtilLite.getExtensionRegistryLite());
         TestUtilLite.getLitePackedExtensionsSet(), TestUtilLite.getExtensionRegistryLite());
   }
   }
@@ -195,15 +204,26 @@ public class ParserTest extends TestCase {
     TestAllTypes normalMessage = TestUtil.getAllSet();
     TestAllTypes normalMessage = TestUtil.getAllSet();
     ByteArrayOutputStream output = new ByteArrayOutputStream();
     ByteArrayOutputStream output = new ByteArrayOutputStream();
     normalMessage.writeDelimitedTo(output);
     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.
     // Write MessageLite with packed extension fields.
     TestPackedExtensionsLite packedMessage = TestUtilLite.getLitePackedExtensionsSet();
     TestPackedExtensionsLite packedMessage = TestUtilLite.getLitePackedExtensionsSet();
+    ByteArrayOutputStream output = new ByteArrayOutputStream();
+    packedMessage.writeDelimitedTo(output);
     packedMessage.writeDelimitedTo(output);
     packedMessage.writeDelimitedTo(output);
 
 
     InputStream input = new ByteArrayInputStream(output.toByteArray());
     InputStream input = new ByteArrayInputStream(output.toByteArray());
     assertMessageEquals(
     assertMessageEquals(
-        normalMessage,
-        normalMessage.getParserForType().parseDelimitedFrom(input));
+        packedMessage,
+        packedMessage
+            .getParserForType()
+            .parseDelimitedFrom(input, TestUtilLite.getExtensionRegistryLite()));
     assertMessageEquals(
     assertMessageEquals(
         packedMessage,
         packedMessage,
         packedMessage
         packedMessage
@@ -314,8 +334,7 @@ public class ParserTest extends TestCase {
 
 
   public void testParsingMergeLite() throws Exception {
   public void testParsingMergeLite() throws Exception {
     // Build messages.
     // Build messages.
-    TestAllTypesLite.Builder builder =
-        TestAllTypesLite.newBuilder();
+    TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder();
     TestAllTypesLite msg1 = builder.setOptionalInt32(1).build();
     TestAllTypesLite msg1 = builder.setOptionalInt32(1).build();
     builder.clear();
     builder.clear();
     TestAllTypesLite msg2 = builder.setOptionalInt64(2).build();
     TestAllTypesLite msg2 = builder.setOptionalInt64(2).build();

+ 2 - 0
java/core/src/test/java/com/google/protobuf/TestUtil.java

@@ -2622,6 +2622,8 @@ public final class TestUtil {
         break;
         break;
       case FOO_NOT_SET:
       case FOO_NOT_SET:
         break;
         break;
+      default:
+        // TODO(b/18683919): go/enum-switch-lsc
     }
     }
   }
   }
 
 

+ 92 - 0
java/core/src/test/java/com/google/protobuf/TextFormatTest.java

@@ -30,9 +30,12 @@
 
 
 package com.google.protobuf;
 package com.google.protobuf;
 
 
+import static com.google.common.truth.Truth.assertThat;
+
 import com.google.protobuf.Descriptors.Descriptor;
 import com.google.protobuf.Descriptors.Descriptor;
 import com.google.protobuf.Descriptors.FieldDescriptor;
 import com.google.protobuf.Descriptors.FieldDescriptor;
 import com.google.protobuf.TextFormat.Parser.SingularOverwritePolicy;
 import com.google.protobuf.TextFormat.Parser.SingularOverwritePolicy;
+import map_test.MapTestProto.TestMap;
 import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
 import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
 import protobuf_unittest.UnittestMset.TestMessageSetExtension2;
 import protobuf_unittest.UnittestMset.TestMessageSetExtension2;
 import protobuf_unittest.UnittestProto.OneString;
 import protobuf_unittest.UnittestProto.OneString;
@@ -940,6 +943,7 @@ public class TextFormatTest extends TestCase {
   }
   }
 
 
 
 
+  // See additional coverage in testOneofOverwriteForbidden and testMapOverwriteForbidden.
   public void testParseNonRepeatedFields() throws Exception {
   public void testParseNonRepeatedFields() throws Exception {
     assertParseSuccessWithOverwriteForbidden(
     assertParseSuccessWithOverwriteForbidden(
         "repeated_int32: 1\n" +
         "repeated_int32: 1\n" +
@@ -950,6 +954,7 @@ public class TextFormatTest extends TestCase {
     assertParseSuccessWithOverwriteForbidden(
     assertParseSuccessWithOverwriteForbidden(
         "repeated_nested_message { bb: 1 }\n" +
         "repeated_nested_message { bb: 1 }\n" +
         "repeated_nested_message { bb: 2 }\n");
         "repeated_nested_message { bb: 2 }\n");
+
     assertParseErrorWithOverwriteForbidden(
     assertParseErrorWithOverwriteForbidden(
         "3:17: Non-repeated field " +
         "3:17: Non-repeated field " +
         "\"protobuf_unittest.TestAllTypes.optional_int32\" " +
         "\"protobuf_unittest.TestAllTypes.optional_int32\" " +
@@ -988,6 +993,7 @@ public class TextFormatTest extends TestCase {
     assertParseSuccessWithOverwriteForbidden("repeated_int32: [ 1, 2 ]\n");
     assertParseSuccessWithOverwriteForbidden("repeated_int32: [ 1, 2 ]\n");
     assertParseSuccessWithOverwriteForbidden("RepeatedGroup [{ a: 1 },{ a: 2 }]\n");
     assertParseSuccessWithOverwriteForbidden("RepeatedGroup [{ a: 1 },{ a: 2 }]\n");
     assertParseSuccessWithOverwriteForbidden("repeated_nested_message [{ bb: 1 }, { bb: 2 }]\n");
     assertParseSuccessWithOverwriteForbidden("repeated_nested_message [{ bb: 1 }, { bb: 2 }]\n");
+    // See also testMapShortForm.
   }
   }
 
 
   public void testParseShortRepeatedFormOfEmptyRepeatedFields() throws Exception {
   public void testParseShortRepeatedFormOfEmptyRepeatedFields() throws Exception {
@@ -995,6 +1001,7 @@ public class TextFormatTest extends TestCase {
     assertParseSuccessWithOverwriteForbidden("repeated_int32: []\n");
     assertParseSuccessWithOverwriteForbidden("repeated_int32: []\n");
     assertParseSuccessWithOverwriteForbidden("RepeatedGroup []\n");
     assertParseSuccessWithOverwriteForbidden("RepeatedGroup []\n");
     assertParseSuccessWithOverwriteForbidden("repeated_nested_message []\n");
     assertParseSuccessWithOverwriteForbidden("repeated_nested_message []\n");
+    // See also testMapShortFormEmpty.
   }
   }
 
 
   public void testParseShortRepeatedFormWithTrailingComma() throws Exception {
   public void testParseShortRepeatedFormWithTrailingComma() throws Exception {
@@ -1010,6 +1017,7 @@ public class TextFormatTest extends TestCase {
     assertParseErrorWithOverwriteForbidden(
     assertParseErrorWithOverwriteForbidden(
         "1:37: Expected \"{\".",
         "1:37: Expected \"{\".",
         "repeated_nested_message [{ bb: 1 }, ]\n");
         "repeated_nested_message [{ bb: 1 }, ]\n");
+    // See also testMapShortFormTrailingComma.
   }
   }
 
 
   public void testParseShortRepeatedFormOfNonRepeatedFields() throws Exception {
   public void testParseShortRepeatedFormOfNonRepeatedFields() throws Exception {
@@ -1057,6 +1065,90 @@ public class TextFormatTest extends TestCase {
     assertTrue(oneof.hasFooInt());
     assertTrue(oneof.hasFooInt());
   }
   }
 
 
+  // =======================================================================
+  // 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
   // test location information
 
 

+ 8 - 0
java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto

@@ -46,6 +46,14 @@ message TestOneofEquals {
 message Foo {
 message Foo {
   optional int32 value = 1;
   optional int32 value = 1;
   repeated Bar bar = 2;
   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;
   extensions 100 to max;
 }
 }

+ 1 - 0
java/lite/pom.xml

@@ -137,6 +137,7 @@
             <include>**/MutabilityOracle.java</include>
             <include>**/MutabilityOracle.java</include>
             <include>**/NioByteString.java</include>
             <include>**/NioByteString.java</include>
             <include>**/Parser.java</include>
             <include>**/Parser.java</include>
+            <include>**/PrimitiveNonBoxingCollection.java</include>
             <include>**/ProtobufArrayList.java</include>
             <include>**/ProtobufArrayList.java</include>
             <include>**/ProtocolStringList.java</include>
             <include>**/ProtocolStringList.java</include>
             <include>**/RopeByteString.java</include>
             <include>**/RopeByteString.java</include>

+ 98 - 77
java/util/src/main/java/com/google/protobuf/util/JsonFormat.java

@@ -30,6 +30,7 @@
 
 
 package com.google.protobuf.util;
 package com.google.protobuf.util;
 
 
+import com.google.common.base.Preconditions;
 import com.google.common.io.BaseEncoding;
 import com.google.common.io.BaseEncoding;
 import com.google.gson.Gson;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.GsonBuilder;
@@ -102,7 +103,8 @@ public class JsonFormat {
    * Creates a {@link Printer} with default configurations.
    * Creates a {@link Printer} with default configurations.
    */
    */
   public static Printer printer() {
   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 class JsonFormat {
    */
    */
   public static class Printer {
   public static class Printer {
     private final TypeRegistry registry;
     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 preservingProtoFieldNames;
     private final boolean omittingInsignificantWhitespace;
     private final boolean omittingInsignificantWhitespace;
 
 
     private Printer(
     private Printer(
         TypeRegistry registry,
         TypeRegistry registry,
-        boolean includingDefaultValueFields,
+        boolean alwaysOutputDefaultValueFields,
+        Set<FieldDescriptor> includingDefaultValueFields,
         boolean preservingProtoFieldNames,
         boolean preservingProtoFieldNames,
         boolean omittingInsignificantWhitespace) {
         boolean omittingInsignificantWhitespace) {
       this.registry = registry;
       this.registry = registry;
+      this.alwaysOutputDefaultValueFields = alwaysOutputDefaultValueFields;
       this.includingDefaultValueFields = includingDefaultValueFields;
       this.includingDefaultValueFields = includingDefaultValueFields;
       this.preservingProtoFieldNames = preservingProtoFieldNames;
       this.preservingProtoFieldNames = preservingProtoFieldNames;
       this.omittingInsignificantWhitespace = omittingInsignificantWhitespace;
       this.omittingInsignificantWhitespace = omittingInsignificantWhitespace;
@@ -137,6 +150,7 @@ public class JsonFormat {
       }
       }
       return new Printer(
       return new Printer(
           registry,
           registry,
+          alwaysOutputDefaultValueFields,
           includingDefaultValueFields,
           includingDefaultValueFields,
           preservingProtoFieldNames,
           preservingProtoFieldNames,
           omittingInsignificantWhitespace);
           omittingInsignificantWhitespace);
@@ -149,8 +163,41 @@ public class JsonFormat {
      * {@link Printer}.
      * {@link Printer}.
      */
      */
     public Printer includingDefaultValueFields() {
     public Printer includingDefaultValueFields() {
+      checkUnsetIncludingDefaultValueFields();
       return new Printer(
       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 class JsonFormat {
      */
      */
     public Printer preservingProtoFieldNames() {
     public Printer preservingProtoFieldNames() {
       return new Printer(
       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>
      * <pre>
      * ws = *(
      * ws = *(
      * %x20 /              ; Space
      * %x20 /              ; Space
@@ -177,18 +229,24 @@ public class JsonFormat {
      * %x0A /              ; Line feed or New line
      * %x0A /              ; Line feed or New line
      * %x0D )              ; Carriage return
      * %x0D )              ; Carriage return
      * </pre>
      * </pre>
+     *
      * See <a href="https://tools.ietf.org/html/rfc7159">https://tools.ietf.org/html/rfc7159</a>
      * See <a href="https://tools.ietf.org/html/rfc7159">https://tools.ietf.org/html/rfc7159</a>
      * current {@link Printer}.
      * current {@link Printer}.
      */
      */
     public Printer omittingInsignificantWhitespace() {
     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.
      * 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.
      * @throws IOException if writing to the output fails.
      */
      */
     public void appendTo(MessageOrBuilder message, Appendable output) throws IOException {
     public void appendTo(MessageOrBuilder message, Appendable output) throws IOException {
@@ -196,6 +254,7 @@ public class JsonFormat {
       // mobile.
       // mobile.
       new PrinterImpl(
       new PrinterImpl(
               registry,
               registry,
+              alwaysOutputDefaultValueFields,
               includingDefaultValueFields,
               includingDefaultValueFields,
               preservingProtoFieldNames,
               preservingProtoFieldNames,
               output,
               output,
@@ -428,19 +487,16 @@ public class JsonFormat {
       this.output = output;
       this.output = output;
     }
     }
 
 
-    /**
-     * ignored by compact printer
-     */
+    /** ignored by compact printer */
+    @Override
     public void indent() {}
     public void indent() {}
 
 
-    /**
-     * ignored by compact printer
-     */
+    /** ignored by compact printer */
+    @Override
     public void outdent() {}
     public void outdent() {}
 
 
-    /**
-     * Print text to the output stream.
-     */
+    /** Print text to the output stream. */
+    @Override
     public void print(final CharSequence text) throws IOException {
     public void print(final CharSequence text) throws IOException {
       output.append(text);
       output.append(text);
     }
     }
@@ -458,18 +514,17 @@ public class JsonFormat {
     }
     }
 
 
     /**
     /**
-     * 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() {
     public void indent() {
       indent.append("  ");
       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() {
     public void outdent() {
       final int length = indent.length();
       final int length = indent.length();
       if (length < 2) {
       if (length < 2) {
@@ -478,9 +533,8 @@ public class JsonFormat {
       indent.delete(length - 2, length);
       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 {
     public void print(final CharSequence text) throws IOException {
       final int size = text.length();
       final int size = text.length();
       int pos = 0;
       int pos = 0;
@@ -512,7 +566,8 @@ public class JsonFormat {
    */
    */
   private static final class PrinterImpl {
   private static final class PrinterImpl {
     private final TypeRegistry registry;
     private final TypeRegistry registry;
-    private final boolean includingDefaultValueFields;
+    private final boolean alwaysOutputDefaultValueFields;
+    private final Set<FieldDescriptor> includingDefaultValueFields;
     private final boolean preservingProtoFieldNames;
     private final boolean preservingProtoFieldNames;
     private final TextGenerator generator;
     private final TextGenerator generator;
     // We use Gson to help handle string escapes.
     // We use Gson to help handle string escapes.
@@ -526,11 +581,13 @@ public class JsonFormat {
 
 
     PrinterImpl(
     PrinterImpl(
         TypeRegistry registry,
         TypeRegistry registry,
-        boolean includingDefaultValueFields,
+        boolean alwaysOutputDefaultValueFields,
+        Set<FieldDescriptor> includingDefaultValueFields,
         boolean preservingProtoFieldNames,
         boolean preservingProtoFieldNames,
         Appendable jsonOutput,
         Appendable jsonOutput,
         boolean omittingInsignificantWhitespace) {
         boolean omittingInsignificantWhitespace) {
       this.registry = registry;
       this.registry = registry;
+      this.alwaysOutputDefaultValueFields = alwaysOutputDefaultValueFields;
       this.includingDefaultValueFields = includingDefaultValueFields;
       this.includingDefaultValueFields = includingDefaultValueFields;
       this.preservingProtoFieldNames = preservingProtoFieldNames;
       this.preservingProtoFieldNames = preservingProtoFieldNames;
       this.gson = GsonHolder.DEFAULT_GSON;
       this.gson = GsonHolder.DEFAULT_GSON;
@@ -781,23 +838,26 @@ public class JsonFormat {
         printedField = true;
         printedField = true;
       }
       }
       Map<FieldDescriptor, Object> fieldsToPrint = null;
       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()) {
         for (FieldDescriptor field : message.getDescriptorForType().getFields()) {
           if (field.isOptional()) {
           if (field.isOptional()) {
             if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE
             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
               // Always skip empty optional message fields. If not we will recurse indefinitely if
               // a message has itself as a sub-field.
               // a message has itself as a sub-field.
               continue;
               continue;
             }
             }
             OneofDescriptor oneof = field.getContainingOneof();
             OneofDescriptor oneof = field.getContainingOneof();
             if (oneof != null && !message.hasField(field)) {
             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;
               continue;
             }
             }
           }
           }
-          fieldsToPrint.put(field, message.getField(field));
+          if (!fieldsToPrint.containsKey(field)
+              && (alwaysOutputDefaultValueFields || includingDefaultValueFields.contains(field))) {
+            fieldsToPrint.put(field, message.getField(field));
+          }
         }
         }
       } else {
       } else {
         fieldsToPrint = message.getAllFields();
         fieldsToPrint = message.getAllFields();
@@ -1451,45 +1511,6 @@ public class JsonFormat {
       }
       }
     }
     }
 
 
-    /**
-     * 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(
     private void mergeRepeatedField(
         FieldDescriptor field, JsonElement json, Message.Builder builder)
         FieldDescriptor field, JsonElement json, Message.Builder builder)
         throws InvalidProtocolBufferException {
         throws InvalidProtocolBufferException {

+ 1 - 1
java/util/src/main/java/com/google/protobuf/util/Timestamps.java

@@ -297,7 +297,7 @@ public final class Timestamps {
    * Convert a Timestamp to the number of microseconds elapsed from the epoch.
    * 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
    * <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) {
   public static long toMicros(Timestamp timestamp) {
     checkValid(timestamp);
     checkValid(timestamp);

+ 126 - 11
java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java

@@ -34,6 +34,7 @@ import com.google.protobuf.Any;
 import com.google.protobuf.BoolValue;
 import com.google.protobuf.BoolValue;
 import com.google.protobuf.ByteString;
 import com.google.protobuf.ByteString;
 import com.google.protobuf.BytesValue;
 import com.google.protobuf.BytesValue;
+import com.google.protobuf.Descriptors.FieldDescriptor;
 import com.google.protobuf.DoubleValue;
 import com.google.protobuf.DoubleValue;
 import com.google.protobuf.FloatValue;
 import com.google.protobuf.FloatValue;
 import com.google.protobuf.Int32Value;
 import com.google.protobuf.Int32Value;
@@ -68,9 +69,12 @@ import java.io.Reader;
 import java.io.StringReader;
 import java.io.StringReader;
 import java.math.BigDecimal;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.math.BigInteger;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Locale;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Map;
+import java.util.Set;
 import junit.framework.TestCase;
 import junit.framework.TestCase;
 
 
 public class JsonFormatTest extends TestCase {
 public class JsonFormatTest extends TestCase {
@@ -284,8 +288,8 @@ public class JsonFormatTest extends TestCase {
     assertEquals(9012, message.getOptionalSint32());
     assertEquals(9012, message.getOptionalSint32());
     assertEquals(3456, message.getOptionalFixed32());
     assertEquals(3456, message.getOptionalFixed32());
     assertEquals(7890, message.getOptionalSfixed32());
     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());
     assertEquals(true, message.getOptionalBool());
   }
   }
 
 
@@ -1215,6 +1219,115 @@ public class JsonFormatTest extends TestCase {
             + "}",
             + "}",
         JsonFormat.printer().includingDefaultValueFields().print(message));
         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();
     TestMap mapMessage = TestMap.getDefaultInstance();
     assertEquals("{\n}", JsonFormat.printer().print(mapMessage));
     assertEquals("{\n}", JsonFormat.printer().print(mapMessage));
     assertEquals(
     assertEquals(
@@ -1283,16 +1396,17 @@ public class JsonFormatTest extends TestCase {
     assertEquals("{\n}", JsonFormat.printer().includingDefaultValueFields().print(oneofMessage));
     assertEquals("{\n}", JsonFormat.printer().includingDefaultValueFields().print(oneofMessage));
 
 
     oneofMessage = TestOneof.newBuilder().setOneofInt32(42).build();
     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));
         JsonFormat.printer().includingDefaultValueFields().print(oneofMessage));
 
 
     TestOneof.Builder oneofBuilder = TestOneof.newBuilder();
     TestOneof.Builder oneofBuilder = TestOneof.newBuilder();
     mergeFromJson("{\n" + "  \"oneofNullValue\": null \n" + "}", oneofBuilder);
     mergeFromJson("{\n" + "  \"oneofNullValue\": null \n" + "}", oneofBuilder);
     oneofMessage = oneofBuilder.build();
     oneofMessage = oneofBuilder.build();
     assertEquals("{\n  \"oneofNullValue\": null\n}", JsonFormat.printer().print(oneofMessage));
     assertEquals("{\n  \"oneofNullValue\": null\n}", JsonFormat.printer().print(oneofMessage));
-    assertEquals("{\n  \"oneofNullValue\": null\n}",
+    assertEquals(
+        "{\n  \"oneofNullValue\": null\n}",
         JsonFormat.printer().includingDefaultValueFields().print(oneofMessage));
         JsonFormat.printer().includingDefaultValueFields().print(oneofMessage));
   }
   }
 
 
@@ -1424,11 +1538,12 @@ public class JsonFormatTest extends TestCase {
 
 
   // Test that we are not leaking out JSON exceptions.
   // Test that we are not leaking out JSON exceptions.
   public void testJsonException() throws Exception {
   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);
     InputStreamReader throwingReader = new InputStreamReader(throwingInputStream);
     // When the underlying reader throws IOException, JsonFormat should forward
     // When the underlying reader throws IOException, JsonFormat should forward
     // through this IOException.
     // through this IOException.

+ 11 - 6
js/binary/decoder.js

@@ -71,7 +71,7 @@ jspb.BinaryIterator = function(opt_decoder, opt_next, opt_elements) {
    */
    */
   this.nextMethod_ = null;
   this.nextMethod_ = null;
 
 
-  /** @private {Array.<number>} */
+  /** @private {?Array<number|boolean|string>} */
   this.elements_ = null;
   this.elements_ = null;
 
 
   /** @private {number} */
   /** @private {number} */
@@ -100,7 +100,7 @@ jspb.BinaryIterator.prototype.init_ =
     this.decoder_ = opt_decoder;
     this.decoder_ = opt_decoder;
     this.nextMethod_ = opt_next;
     this.nextMethod_ = opt_next;
   }
   }
-  this.elements_ = opt_elements ? opt_elements : null;
+  this.elements_ = opt_elements || null;
   this.cursor_ = 0;
   this.cursor_ = 0;
   this.nextValue_ = null;
   this.nextValue_ = null;
   this.atEnd_ = !this.decoder_ && !this.elements_;
   this.atEnd_ = !this.decoder_ && !this.elements_;
@@ -953,6 +953,7 @@ jspb.BinaryDecoder.prototype.readString = function(length) {
   var end = cursor + length;
   var end = cursor + length;
   var codeUnits = [];
   var codeUnits = [];
 
 
+  var result = '';
   while (cursor < end) {
   while (cursor < end) {
     var c = bytes[cursor++];
     var c = bytes[cursor++];
     if (c < 128) { // Regular 7-bit ASCII.
     if (c < 128) { // Regular 7-bit ASCII.
@@ -973,7 +974,7 @@ jspb.BinaryDecoder.prototype.readString = function(length) {
       var c2 = bytes[cursor++];
       var c2 = bytes[cursor++];
       var c3 = bytes[cursor++];
       var c3 = bytes[cursor++];
       var c4 = 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.
       // 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);
       var codepoint = ((c & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63);
       // Surrogates formula from wikipedia.
       // Surrogates formula from wikipedia.
@@ -986,10 +987,14 @@ jspb.BinaryDecoder.prototype.readString = function(length) {
       var high = ((codepoint >> 10) & 1023) + 0xD800;
       var high = ((codepoint >> 10) & 1023) + 0xD800;
       codeUnits.push(high, low);
       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;
   this.cursor_ = cursor;
   return result;
   return result;
 };
 };

+ 19 - 0
js/binary/decoder_test.js

@@ -210,6 +210,25 @@ describe('binaryDecoderTest', function() {
     assertEquals(hashD, decoder.readFixedHash64());
     assertEquals(hashD, decoder.readFixedHash64());
   });
   });
 
 
+  /**
+   * 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.
    * Test encoding and decoding utf-8.
    */
    */

+ 2 - 2
js/binary/encoder.js

@@ -355,8 +355,8 @@ jspb.BinaryEncoder.prototype.writeInt64 = function(value) {
  */
  */
 jspb.BinaryEncoder.prototype.writeInt64String = function(value) {
 jspb.BinaryEncoder.prototype.writeInt64String = function(value) {
   goog.asserts.assert(value == Math.floor(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));
   jspb.utils.splitHash64(jspb.utils.decimalStringToHash64(value));
   this.writeSplitFixed64(jspb.utils.split64Low, jspb.utils.split64High);
   this.writeSplitFixed64(jspb.utils.split64Low, jspb.utils.split64High);
 };
 };

+ 1 - 1
js/binary/reader.js

@@ -971,7 +971,7 @@ jspb.BinaryReader.prototype.readFixedHash64 = function() {
 
 
 /**
 /**
  * Reads a packed scalar field using the supplied raw reader function.
  * Reads a packed scalar field using the supplied raw reader function.
- * @param {function()} decodeMethod
+ * @param {function(this:jspb.BinaryDecoder)} decodeMethod
  * @return {!Array}
  * @return {!Array}
  * @private
  * @private
  */
  */

+ 1 - 1
js/binary/utils.js

@@ -430,7 +430,7 @@ jspb.utils.joinHash64 = function(bitsLow, bitsHigh) {
 
 
 /**
 /**
  * Individual digits for number->string conversion.
  * Individual digits for number->string conversion.
- * @const {!Array.<number>}
+ * @const {!Array.<string>}
  */
  */
 jspb.utils.DIGITS = [
 jspb.utils.DIGITS = [
   '0', '1', '2', '3', '4', '5', '6', '7',
   '0', '1', '2', '3', '4', '5', '6', '7',

+ 2 - 2
js/binary/writer.js

@@ -596,8 +596,8 @@ jspb.BinaryWriter.prototype.writeSint64 = function(field, value) {
  */
  */
 jspb.BinaryWriter.prototype.writeSint64String = function(field, value) {
 jspb.BinaryWriter.prototype.writeSint64String = function(field, value) {
   if (value == null) return;
   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);
   this.writeZigzagVarint64String_(field, value);
 };
 };
 
 

+ 1 - 1
js/binary/writer_test.js

@@ -47,7 +47,7 @@ goog.require('jspb.BinaryWriter');
  * @param {function()} func This function should throw an error when run.
  * @param {function()} func This function should throw an error when run.
  */
  */
 function assertFails(func) {
 function assertFails(func) {
-  var e = assertThrows(func);
+  assertThrows(func);
 }
 }
 
 
 
 

+ 5 - 5
js/map.js

@@ -136,7 +136,7 @@ jspb.Map.prototype.toArray = function() {
  *
  *
  * @param {boolean=} includeInstance Whether to include the JSPB instance for
  * @param {boolean=} includeInstance Whether to include the JSPB instance for
  *    transitional soy proto support: http://goto/soy-param-migration
  *    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.
  *    The static toObject() method, if V is a message type.
  * @return {!Array<!Array<!Object>>}
  * @return {!Array<!Array<!Object>>}
  */
  */
@@ -146,7 +146,7 @@ jspb.Map.prototype.toObject = function(includeInstance, valueToObject) {
   for (var i = 0; i < rawArray.length; i++) {
   for (var i = 0; i < rawArray.length; i++) {
     var entry = this.map_[rawArray[i][0].toString()];
     var entry = this.map_[rawArray[i][0].toString()];
     this.wrapEntry_(entry);
     this.wrapEntry_(entry);
-    var valueWrapper = /** @type {!V|undefined} */ (entry.valueWrapper);
+    var valueWrapper = /** @type {V|undefined} */ (entry.valueWrapper);
     if (valueWrapper) {
     if (valueWrapper) {
       goog.asserts.assert(valueToObject);
       goog.asserts.assert(valueToObject);
       entries.push([entry.key, valueToObject(includeInstance, valueWrapper)]);
       entries.push([entry.key, valueToObject(includeInstance, valueWrapper)]);
@@ -412,8 +412,8 @@ jspb.Map.prototype.has = function(key) {
  * @param {!jspb.BinaryWriter} writer
  * @param {!jspb.BinaryWriter} writer
  * @param {!function(this:jspb.BinaryWriter,number,K)} keyWriterFn
  * @param {!function(this:jspb.BinaryWriter,number,K)} keyWriterFn
  *     The method on BinaryWriter that writes type K to the stream.
  *     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
  *     The method on BinaryWriter that writes type V to the stream.  May be
  *     writeMessage, in which case the second callback arg form is used.
  *     writeMessage, in which case the second callback arg form is used.
  * @param {function(V,!jspb.BinaryWriter)=} opt_valueWriterCallback
  * @param {function(V,!jspb.BinaryWriter)=} opt_valueWriterCallback
@@ -509,7 +509,7 @@ jspb.Map.prototype.stringKeys_ = function() {
 
 
 
 
 /**
 /**
- * @param {!K} key The entry's key.
+ * @param {K} key The entry's key.
  * @param {V=} opt_value The entry's value wrapper.
  * @param {V=} opt_value The entry's value wrapper.
  * @constructor
  * @constructor
  * @struct
  * @struct

+ 25 - 6
js/message.js

@@ -106,8 +106,9 @@ jspb.ExtensionFieldInfo = function(fieldNumber, fieldName, ctor, toObjectFn,
 /**
 /**
  * Stores binary-related information for a single extension field.
  * Stores binary-related information for a single extension field.
  * @param {!jspb.ExtensionFieldInfo<T>} fieldInfo
  * @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_binaryMessageSerializeFn
  * @param {function(?,?)=} opt_binaryMessageDeserializeFn
  * @param {function(?,?)=} opt_binaryMessageDeserializeFn
  * @param {boolean=} opt_isPacked
  * @param {boolean=} opt_isPacked
@@ -141,6 +142,21 @@ jspb.ExtensionFieldInfo.prototype.isMessageType = function() {
 
 
 /**
 /**
  * Base class for all JsPb messages.
  * 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
  * @constructor
  * @struct
  * @struct
  */
  */
@@ -524,7 +540,7 @@ jspb.Message.toObjectExtension = function(proto, obj, extensions,
  * @param {!jspb.Message} proto The proto whose extensions to convert.
  * @param {!jspb.Message} proto The proto whose extensions to convert.
  * @param {*} writer The binary-format writer to write to.
  * @param {*} writer The binary-format writer to write to.
  * @param {!Object} extensions The proto class' registered extensions.
  * @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.
  *     class' getExtension function. Passed for effective dead code removal.
  */
  */
 jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions,
 jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions,
@@ -570,10 +586,13 @@ jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions,
  * Reads an extension field from the given reader and, if a valid extension,
  * Reads an extension field from the given reader and, if a valid extension,
  * sets the extension value.
  * sets the extension value.
  * @param {!jspb.Message} msg A jspb proto.
  * @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 {!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,
 jspb.Message.readBinaryExtension = function(msg, reader, extensions,
     getExtensionFn, setExtensionFn) {
     getExtensionFn, setExtensionFn) {

+ 1 - 0
js/message_test.js

@@ -40,6 +40,7 @@ goog.require('goog.userAgent');
 goog.require('jspb.Message');
 goog.require('jspb.Message');
 
 
 // CommonJS-LoadFromFile: test8_pb proto.jspb.exttest.nested
 // CommonJS-LoadFromFile: test8_pb proto.jspb.exttest.nested
+goog.require('proto.jspb.exttest.nested.TestNestedExtensionsMessage');
 goog.require('proto.jspb.exttest.nested.TestOuterMessage');
 goog.require('proto.jspb.exttest.nested.TestOuterMessage');
 
 
 // CommonJS-LoadFromFile: test5_pb proto.jspb.exttest.beta
 // CommonJS-LoadFromFile: test5_pb proto.jspb.exttest.beta

+ 7 - 4
python/google/protobuf/descriptor_database.py

@@ -54,9 +54,9 @@ class DescriptorDatabase(object):
     Args:
     Args:
       file_desc_proto: The FileDescriptorProto to add.
       file_desc_proto: The FileDescriptorProto to add.
     Raises:
     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
     proto_name = file_desc_proto.name
     if proto_name not in self._file_desc_protos_by_file:
     if proto_name not in self._file_desc_protos_by_file:
@@ -65,7 +65,7 @@ class DescriptorDatabase(object):
       raise DescriptorDatabaseConflictingDefinitionError(
       raise DescriptorDatabaseConflictingDefinitionError(
           '%s already added, but with different descriptor.' % proto_name)
           '%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
     package = file_desc_proto.package
     for message in file_desc_proto.message_type:
     for message in file_desc_proto.message_type:
       self._file_desc_protos_by_symbol.update(
       self._file_desc_protos_by_symbol.update(
@@ -76,6 +76,9 @@ class DescriptorDatabase(object):
     for extension in file_desc_proto.extension:
     for extension in file_desc_proto.extension:
       self._file_desc_protos_by_symbol[
       self._file_desc_protos_by_symbol[
           '.'.join((package, extension.name))] = file_desc_proto
           '.'.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):
   def FindFileByName(self, name):
     """Finds the file descriptor proto by file name.
     """Finds the file descriptor proto by file name.

+ 84 - 15
python/google/protobuf/descriptor_pool.py

@@ -124,6 +124,7 @@ class DescriptorPool(object):
     self._descriptor_db = descriptor_db
     self._descriptor_db = descriptor_db
     self._descriptors = {}
     self._descriptors = {}
     self._enum_descriptors = {}
     self._enum_descriptors = {}
+    self._service_descriptors = {}
     self._file_descriptors = {}
     self._file_descriptors = {}
     self._toplevel_extensions = {}
     self._toplevel_extensions = {}
     # We store extensions in two two-level mappings: The first key is the
     # We store extensions in two two-level mappings: The first key is the
@@ -174,7 +175,7 @@ class DescriptorPool(object):
   def AddEnumDescriptor(self, enum_desc):
   def AddEnumDescriptor(self, enum_desc):
     """Adds an EnumDescriptor to the pool.
     """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:
     Args:
       enum_desc: An EnumDescriptor.
       enum_desc: An EnumDescriptor.
@@ -186,6 +187,18 @@ class DescriptorPool(object):
     self._enum_descriptors[enum_desc.full_name] = enum_desc
     self._enum_descriptors[enum_desc.full_name] = enum_desc
     self.AddFileDescriptor(enum_desc.file)
     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):
   def AddExtensionDescriptor(self, extension):
     """Adds a FieldDescriptor describing an extension to the pool.
     """Adds a FieldDescriptor describing an extension to the pool.
 
 
@@ -252,7 +265,7 @@ class DescriptorPool(object):
       A FileDescriptor for the named file.
       A FileDescriptor for the named file.
 
 
     Raises:
     Raises:
-      KeyError: if the file can not be found in the pool.
+      KeyError: if the file cannot be found in the pool.
     """
     """
 
 
     try:
     try:
@@ -281,7 +294,7 @@ class DescriptorPool(object):
       A FileDescriptor that contains the specified symbol.
       A FileDescriptor that contains the specified symbol.
 
 
     Raises:
     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)
     symbol = _NormalizeFullyQualifiedName(symbol)
@@ -296,15 +309,18 @@ class DescriptorPool(object):
       pass
       pass
 
 
     try:
     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)
       raise KeyError('Cannot find a file containing %s' % symbol)
-    return self._ConvertFileProtoToFileDescriptor(file_proto)
 
 
   def FindMessageTypeByName(self, full_name):
   def FindMessageTypeByName(self, full_name):
     """Loads the named descriptor from the pool.
     """Loads the named descriptor from the pool.
@@ -314,11 +330,14 @@ class DescriptorPool(object):
 
 
     Returns:
     Returns:
       The descriptor for the named type.
       The descriptor for the named type.
+
+    Raises:
+      KeyError: if the message cannot be found in the pool.
     """
     """
 
 
     full_name = _NormalizeFullyQualifiedName(full_name)
     full_name = _NormalizeFullyQualifiedName(full_name)
     if full_name not in self._descriptors:
     if full_name not in self._descriptors:
-      self.FindFileContainingSymbol(full_name)
+      self._FindFileContainingSymbolInDb(full_name)
     return self._descriptors[full_name]
     return self._descriptors[full_name]
 
 
   def FindEnumTypeByName(self, full_name):
   def FindEnumTypeByName(self, full_name):
@@ -329,11 +348,14 @@ class DescriptorPool(object):
 
 
     Returns:
     Returns:
       The enum descriptor for the named type.
       The enum descriptor for the named type.
+
+    Raises:
+      KeyError: if the enum cannot be found in the pool.
     """
     """
 
 
     full_name = _NormalizeFullyQualifiedName(full_name)
     full_name = _NormalizeFullyQualifiedName(full_name)
     if full_name not in self._enum_descriptors:
     if full_name not in self._enum_descriptors:
-      self.FindFileContainingSymbol(full_name)
+      self._FindFileContainingSymbolInDb(full_name)
     return self._enum_descriptors[full_name]
     return self._enum_descriptors[full_name]
 
 
   def FindFieldByName(self, full_name):
   def FindFieldByName(self, full_name):
@@ -344,6 +366,9 @@ class DescriptorPool(object):
 
 
     Returns:
     Returns:
       The field descriptor for the named field.
       The field descriptor for the named field.
+
+    Raises:
+      KeyError: if the field cannot be found in the pool.
     """
     """
     full_name = _NormalizeFullyQualifiedName(full_name)
     full_name = _NormalizeFullyQualifiedName(full_name)
     message_name, _, field_name = full_name.rpartition('.')
     message_name, _, field_name = full_name.rpartition('.')
@@ -358,6 +383,9 @@ class DescriptorPool(object):
 
 
     Returns:
     Returns:
       A FieldDescriptor, describing the named extension.
       A FieldDescriptor, describing the named extension.
+
+    Raises:
+      KeyError: if the extension cannot be found in the pool.
     """
     """
     full_name = _NormalizeFullyQualifiedName(full_name)
     full_name = _NormalizeFullyQualifiedName(full_name)
     try:
     try:
@@ -374,7 +402,7 @@ class DescriptorPool(object):
       scope = self.FindMessageTypeByName(message_name)
       scope = self.FindMessageTypeByName(message_name)
     except KeyError:
     except KeyError:
       # Some extensions are defined at file scope.
       # Some extensions are defined at file scope.
-      scope = self.FindFileContainingSymbol(full_name)
+      scope = self._FindFileContainingSymbolInDb(full_name)
     return scope.extensions_by_name[extension_name]
     return scope.extensions_by_name[extension_name]
 
 
   def FindExtensionByNumber(self, message_descriptor, number):
   def FindExtensionByNumber(self, message_descriptor, number):
@@ -390,7 +418,7 @@ class DescriptorPool(object):
     Returns:
     Returns:
       A FieldDescriptor describing the extension.
       A FieldDescriptor describing the extension.
 
 
-    Raise:
+    Raises:
       KeyError: when no extension with the given number is known for the
       KeyError: when no extension with the given number is known for the
         specified message.
         specified message.
     """
     """
@@ -410,6 +438,46 @@ class DescriptorPool(object):
     """
     """
     return list(self._extensions_by_number[message_descriptor].values())
     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):
   def _ConvertFileProtoToFileDescriptor(self, file_proto):
     """Creates a FileDescriptor from a proto or returns a cached copy.
     """Creates a FileDescriptor from a proto or returns a cached copy.
 
 
@@ -804,6 +872,7 @@ class DescriptorPool(object):
                                         methods=methods,
                                         methods=methods,
                                         options=_OptionsOrNone(service_proto),
                                         options=_OptionsOrNone(service_proto),
                                         file=file_desc)
                                         file=file_desc)
+    self._service_descriptors[service_name] = desc
     return desc
     return desc
 
 
   def _MakeMethodDescriptor(self, method_proto, service_name, package, scope,
   def _MakeMethodDescriptor(self, method_proto, service_name, package, scope,

+ 1 - 1
python/google/protobuf/internal/containers.py

@@ -275,7 +275,7 @@ class RepeatedScalarFieldContainer(BaseContainer):
     new_values = [self._type_checker.CheckValue(elem) for elem in elem_seq_iter]
     new_values = [self._type_checker.CheckValue(elem) for elem in elem_seq_iter]
     if new_values:
     if new_values:
       self._values.extend(new_values)
       self._values.extend(new_values)
-      self._message_listener.Modified()
+    self._message_listener.Modified()
 
 
   def MergeFrom(self, other):
   def MergeFrom(self, other):
     """Appends the contents of another repeated field of the same type to this
     """Appends the contents of another repeated field of the same type to this

+ 36 - 0
python/google/protobuf/internal/descriptor_pool_test.py

@@ -71,6 +71,13 @@ class DescriptorPoolTest(unittest.TestCase):
     self.pool.Add(self.factory_test1_fd)
     self.pool.Add(self.factory_test1_fd)
     self.pool.Add(self.factory_test2_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):
   def testFindFileByName(self):
     name1 = 'google/protobuf/internal/factory_test1.proto'
     name1 = 'google/protobuf/internal/factory_test1.proto'
     file_desc1 = self.pool.FindFileByName(name1)
     file_desc1 = self.pool.FindFileByName(name1)
@@ -107,6 +114,20 @@ class DescriptorPoolTest(unittest.TestCase):
     self.assertEqual('google.protobuf.python.internal', file_desc2.package)
     self.assertEqual('google.protobuf.python.internal', file_desc2.package)
     self.assertIn('Factory2Message', file_desc2.message_types_by_name)
     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):
   def testFindFileContainingSymbolFailure(self):
     with self.assertRaises(KeyError):
     with self.assertRaises(KeyError):
       self.pool.FindFileContainingSymbol('Does not exist')
       self.pool.FindFileContainingSymbol('Does not exist')
@@ -311,6 +332,10 @@ class DescriptorPoolTest(unittest.TestCase):
       self.pool.FindExtensionByName(
       self.pool.FindExtensionByName(
           'google.protobuf.python.internal.Factory1Message.list_value')
           '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):
   def testUserDefinedDB(self):
     db = descriptor_database.DescriptorDatabase()
     db = descriptor_database.DescriptorDatabase()
     self.pool = descriptor_pool.DescriptorPool(db)
     self.pool = descriptor_pool.DescriptorPool(db)
@@ -643,6 +668,17 @@ class AddDescriptorTest(unittest.TestCase):
     self._TestEnum('')
     self._TestEnum('')
     self._TestEnum('.')
     self._TestEnum('.')
 
 
+  @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',
   @unittest.skipIf(api_implementation.Type() == 'cpp',
                    'With the cpp implementation, Add() must be called first')
                    'With the cpp implementation, Add() must be called first')
   def testFile(self):
   def testFile(self):

+ 5 - 2
python/google/protobuf/internal/encoder.py

@@ -340,7 +340,7 @@ def MessageSetItemSizer(field_number):
 # Map is special: it needs custom logic to compute its size properly.
 # 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."""
   """Returns a sizer for a map field."""
 
 
   # Can't look at field_descriptor.message_type._concrete_class because it may
   # Can't look at field_descriptor.message_type._concrete_class because it may
@@ -355,9 +355,12 @@ def MapSizer(field_descriptor):
       # It's wasteful to create the messages and throw them away one second
       # 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
       # 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
       # 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)
       entry_msg = message_type._concrete_class(key=key, value=value)
       total += message_sizer(entry_msg)
       total += message_sizer(entry_msg)
+      if is_message_map:
+        value.ByteSize()
     return total
     return total
 
 
   return FieldSize
   return FieldSize

+ 26 - 1
python/google/protobuf/internal/message_test.py

@@ -564,6 +564,11 @@ class MessageTest(BaseTestCase):
     self.assertIsInstance(m.repeated_nested_message,
     self.assertIsInstance(m.repeated_nested_message,
                           collections.MutableSequence)
                           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):
   def ensureNestedMessageExists(self, msg, attribute):
     """Make sure that a nested message object exists.
     """Make sure that a nested message object exists.
 
 
@@ -1432,6 +1437,18 @@ class Proto3Test(BaseTestCase):
     self.assertIn(-456, msg2.map_int32_foreign_message)
     self.assertIn(-456, msg2.map_int32_foreign_message)
     self.assertEqual(2, len(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):
   def testMergeFrom(self):
     msg = map_unittest_pb2.TestMap()
     msg = map_unittest_pb2.TestMap()
     msg.map_int32_int32[12] = 34
     msg.map_int32_int32[12] = 34
@@ -1456,7 +1473,15 @@ class Proto3Test(BaseTestCase):
     self.assertEqual(5, msg2.map_int32_foreign_message[111].c)
     self.assertEqual(5, msg2.map_int32_foreign_message[111].c)
     self.assertEqual(10, msg2.map_int32_foreign_message[222].c)
     self.assertEqual(10, msg2.map_int32_foreign_message[222].c)
     self.assertFalse(msg2.map_int32_foreign_message[222].HasField('d'))
     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
     # 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
     # may have internally created multiple entries for a single key in the

+ 3 - 2
python/google/protobuf/internal/python_message.py

@@ -288,7 +288,8 @@ def _AttachFieldHelpers(cls, field_descriptor):
 
 
   if is_map_entry:
   if is_map_entry:
     field_encoder = encoder.MapEncoder(field_descriptor)
     field_encoder = encoder.MapEncoder(field_descriptor)
-    sizer = encoder.MapSizer(field_descriptor)
+    sizer = encoder.MapSizer(field_descriptor,
+                             _IsMessageMapField(field_descriptor))
   elif _IsMessageSetExtension(field_descriptor):
   elif _IsMessageSetExtension(field_descriptor):
     field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number)
     field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number)
     sizer = encoder.MessageSetItemSizer(field_descriptor.number)
     sizer = encoder.MessageSetItemSizer(field_descriptor.number)
@@ -891,7 +892,7 @@ def _AddHasExtensionMethod(cls):
 def _InternalUnpackAny(msg):
 def _InternalUnpackAny(msg):
   """Unpacks Any message and returns the unpacked message.
   """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
   the target message as argument. _InternalUnpackAny method does not have
   target message type and need to find the message type in descriptor pool.
   target message type and need to find the message type in descriptor pool.
 
 

+ 63 - 0
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

+ 8 - 1
python/google/protobuf/internal/reflection_test.py

@@ -1551,7 +1551,14 @@ class ReflectionTest(BaseTestCase):
     container = copy.deepcopy(proto1.repeated_int32)
     container = copy.deepcopy(proto1.repeated_int32)
     self.assertEqual([2, 3], container)
     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):
   def testClear(self):
     proto = unittest_pb2.TestAllTypes()
     proto = unittest_pb2.TestAllTypes()

+ 8 - 1
python/google/protobuf/internal/symbol_database_test.py

@@ -60,6 +60,7 @@ class SymbolDatabaseTest(unittest.TestCase):
     db.RegisterMessage(unittest_pb2.TestAllTypes.RepeatedGroup)
     db.RegisterMessage(unittest_pb2.TestAllTypes.RepeatedGroup)
     db.RegisterEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR)
     db.RegisterEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR)
     db.RegisterEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR)
     db.RegisterEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR)
+    db.RegisterServiceDescriptor(unittest_pb2._TESTSERVICE)
     return db
     return db
 
 
   def testGetPrototype(self):
   def testGetPrototype(self):
@@ -109,7 +110,13 @@ class SymbolDatabaseTest(unittest.TestCase):
         self._Database().pool.FindMessageTypeByName(
         self._Database().pool.FindMessageTypeByName(
             'protobuf_unittest.TestAllTypes.NestedMessage').full_name)
             '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.
     # Lookup based on either enum or message.
     self.assertEqual(
     self.assertEqual(
         'google/protobuf/unittest.proto',
         'google/protobuf/unittest.proto',

+ 51 - 0
python/google/protobuf/internal/text_format_test.py

@@ -1119,6 +1119,11 @@ class Proto3Tests(unittest.TestCase):
     packed_message = unittest_pb2.OneString()
     packed_message = unittest_pb2.OneString()
     message.any_value.Unpack(packed_message)
     message.any_value.Unpack(packed_message)
     self.assertEqual('string', packed_message.data)
     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):
   def testMergeExpandedAnyRepeated(self):
     message = any_test_pb2.TestAny()
     message = any_test_pb2.TestAny()
@@ -1373,6 +1378,52 @@ class TokenizerTest(unittest.TestCase):
     self.assertEqual('# some comment', tokenizer.ConsumeComment())
     self.assertEqual('# some comment', tokenizer.ConsumeComment())
     self.assertTrue(tokenizer.AtEnd())
     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__':
 if __name__ == '__main__':
   unittest.main()
   unittest.main()

+ 19 - 0
python/google/protobuf/pyext/descriptor.cc

@@ -32,6 +32,7 @@
 
 
 #include <Python.h>
 #include <Python.h>
 #include <frameobject.h>
 #include <frameobject.h>
+#include <google/protobuf/stubs/hash.h>
 #include <string>
 #include <string>
 
 
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/coded_stream.h>
@@ -1666,6 +1667,15 @@ PyObject* PyServiceDescriptor_FromDescriptor(
       &PyServiceDescriptor_Type, service_descriptor, NULL);
       &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 {
 namespace method_descriptor {
 
 
 // Unchecked accessor to the C++ pointer.
 // Unchecked accessor to the C++ pointer.
@@ -1769,6 +1779,15 @@ PyObject* PyMethodDescriptor_FromDescriptor(
       &PyMethodDescriptor_Type, method_descriptor, NULL);
       &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.
 // Add a enum values to a type dictionary.
 static bool AddEnumValues(PyTypeObject *type,
 static bool AddEnumValues(PyTypeObject *type,
                           const EnumDescriptor* enum_descriptor) {
                           const EnumDescriptor* enum_descriptor) {

+ 2 - 0
python/google/protobuf/pyext/descriptor.h

@@ -80,6 +80,8 @@ const Descriptor* PyMessageDescriptor_AsDescriptor(PyObject* obj);
 const FieldDescriptor* PyFieldDescriptor_AsDescriptor(PyObject* obj);
 const FieldDescriptor* PyFieldDescriptor_AsDescriptor(PyObject* obj);
 const EnumDescriptor* PyEnumDescriptor_AsDescriptor(PyObject* obj);
 const EnumDescriptor* PyEnumDescriptor_AsDescriptor(PyObject* obj);
 const FileDescriptor* PyFileDescriptor_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.
 // Returns the raw C++ pointer.
 const void* PyDescriptor_AsVoidPtr(PyObject* obj);
 const void* PyDescriptor_AsVoidPtr(PyObject* obj);

+ 19 - 1
python/google/protobuf/pyext/descriptor_pool.cc

@@ -39,6 +39,7 @@
 #include <google/protobuf/pyext/message.h>
 #include <google/protobuf/pyext/message.h>
 #include <google/protobuf/pyext/message_factory.h>
 #include <google/protobuf/pyext/message_factory.h>
 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+#include <google/protobuf/stubs/hash.h>
 
 
 #if PY_MAJOR_VERSION >= 3
 #if PY_MAJOR_VERSION >= 3
   #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
   #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
@@ -437,8 +438,23 @@ PyObject* AddExtensionDescriptor(PyDescriptorPool* self, PyObject* descriptor) {
   Py_RETURN_NONE;
   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
 // 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.
 // propagated in the python exception instead of only living in ERROR logs.
@@ -538,6 +554,8 @@ static PyMethodDef Methods[] = {
     "No-op. Add() must have been called before." },
     "No-op. Add() must have been called before." },
   { "AddExtensionDescriptor", (PyCFunction)AddExtensionDescriptor, METH_O,
   { "AddExtensionDescriptor", (PyCFunction)AddExtensionDescriptor, METH_O,
     "No-op. Add() must have been called before." },
     "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,
   { "FindFileByName", (PyCFunction)FindFileByName, METH_O,
     "Searches for a file descriptor by its .proto name." },
     "Searches for a file descriptor by its .proto name." },

+ 1 - 0
python/google/protobuf/pyext/descriptor_pool.h

@@ -85,6 +85,7 @@ extern PyTypeObject PyDescriptorPool_Type;
 
 
 namespace cdescriptor_pool {
 namespace cdescriptor_pool {
 
 
+
 // Looks up a message by name.
 // Looks up a message by name.
 // Returns a message Descriptor, or NULL if not found.
 // Returns a message Descriptor, or NULL if not found.
 const Descriptor* FindMessageTypeByName(PyDescriptorPool* self,
 const Descriptor* FindMessageTypeByName(PyDescriptorPool* self,

+ 29 - 0
python/google/protobuf/pyext/repeated_composite_container.cc

@@ -47,6 +47,7 @@
 #include <google/protobuf/pyext/descriptor_pool.h>
 #include <google/protobuf/pyext/descriptor_pool.h>
 #include <google/protobuf/pyext/message.h>
 #include <google/protobuf/pyext/message.h>
 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+#include <google/protobuf/reflection.h>
 
 
 #if PY_MAJOR_VERSION >= 3
 #if PY_MAJOR_VERSION >= 3
   #define PyInt_Check PyLong_Check
   #define PyInt_Check PyLong_Check
@@ -485,6 +486,32 @@ int Release(RepeatedCompositeContainer* self) {
   return 0;
   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,
 int SetOwner(RepeatedCompositeContainer* self,
              const shared_ptr<Message>& new_owner) {
              const shared_ptr<Message>& new_owner) {
   GOOGLE_CHECK_ATTACHED(self);
   GOOGLE_CHECK_ATTACHED(self);
@@ -551,6 +578,8 @@ static PyMappingMethods MpMethods = {
 };
 };
 
 
 static PyMethodDef Methods[] = {
 static PyMethodDef Methods[] = {
+  { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
+    "Makes a deep copy of the class." },
   { "add", (PyCFunction) Add, METH_VARARGS | METH_KEYWORDS,
   { "add", (PyCFunction) Add, METH_VARARGS | METH_KEYWORDS,
     "Adds an object to the repeated container." },
     "Adds an object to the repeated container." },
   { "extend", (PyCFunction) Extend, METH_O,
   { "extend", (PyCFunction) Extend, METH_O,

+ 34 - 25
python/google/protobuf/pyext/scoped_pyobject_ptr.h

@@ -36,61 +36,70 @@
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/common.h>
 
 
 #include <Python.h>
 #include <Python.h>
-
 namespace google {
 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:
  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 function must be called with a reference that you own.
   //   this->reset(this->get()) is wrong!
   //   this->reset(this->get()) is wrong!
   //   this->reset(this->release()) is OK.
   //   this->reset(this->release()) is OK.
-  PyObject* reset(PyObject* p = NULL) {
+  PyObjectStruct* reset(PyObjectStruct* p = NULL) {
     Py_XDECREF(ptr_);
     Py_XDECREF(ptr_);
     ptr_ = p;
     ptr_ = p;
     return ptr_;
     return ptr_;
   }
   }
 
 
-  // Releases ownership of the object.
+  // Releases ownership of the object without decrementing the reference count.
   // The caller now owns the returned reference.
   // The caller now owns the returned reference.
-  PyObject* release() {
+  PyObjectStruct* release() {
     PyObject* p = ptr_;
     PyObject* p = ptr_;
     ptr_ = NULL;
     ptr_ = NULL;
     return p;
     return p;
   }
   }
 
 
-  PyObject* operator->() const  {
+  PyObjectStruct* operator->() const {
     assert(ptr_ != NULL);
     assert(ptr_ != NULL);
     return ptr_;
     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_); }
   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:
  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
 }  // namespace google
 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_SCOPED_PYOBJECT_PTR_H__
 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_SCOPED_PYOBJECT_PTR_H__

+ 0 - 0
python/google/protobuf/pyext/python_protobuf.h → python/google/protobuf/python_protobuf.h


+ 3 - 3
python/google/protobuf/reflection.py

@@ -107,7 +107,7 @@ def MakeClass(descriptor):
     The Message class object described by the descriptor.
     The Message class object described by the descriptor.
   """
   """
   if descriptor in MESSAGE_CLASS_CACHE:
   if descriptor in MESSAGE_CLASS_CACHE:
-      return MESSAGE_CLASS_CACHE[descriptor]
+    return MESSAGE_CLASS_CACHE[descriptor]
 
 
   attributes = {}
   attributes = {}
   for name, nested_type in descriptor.nested_types_by_name.items():
   for name, nested_type in descriptor.nested_types_by_name.items():
@@ -115,7 +115,7 @@ def MakeClass(descriptor):
 
 
   attributes[GeneratedProtocolMessageType._DESCRIPTOR_KEY] = descriptor
   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
   MESSAGE_CLASS_CACHE[descriptor] = result
   return result
   return result

+ 11 - 0
python/google/protobuf/symbol_database.py

@@ -94,6 +94,17 @@ class SymbolDatabase(message_factory.MessageFactory):
     self.pool.AddEnumDescriptor(enum_descriptor)
     self.pool.AddEnumDescriptor(enum_descriptor)
     return 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):
   def RegisterFileDescriptor(self, file_descriptor):
     """Registers the given file descriptor in the local database.
     """Registers the given file descriptor in the local database.
 
 

+ 30 - 5
python/google/protobuf/text_format.py

@@ -422,7 +422,8 @@ class _Printer(object):
 def Parse(text,
 def Parse(text,
           message,
           message,
           allow_unknown_extension=False,
           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.
   """Parses a text representation of a protocol message into a message.
 
 
   Args:
   Args:
@@ -431,6 +432,7 @@ def Parse(text,
     allow_unknown_extension: if True, skip over missing extensions and keep
     allow_unknown_extension: if True, skip over missing extensions and keep
       parsing
       parsing
     allow_field_number: if True, both field number and field name are allowed.
     allow_field_number: if True, both field number and field name are allowed.
+    descriptor_pool: A DescriptorPool used to resolve Any types.
 
 
   Returns:
   Returns:
     The same message passed as argument.
     The same message passed as argument.
@@ -440,8 +442,11 @@ def Parse(text,
   """
   """
   if not isinstance(text, str):
   if not isinstance(text, str):
     text = text.decode('utf-8')
     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,
 def Merge(text,
@@ -479,7 +484,8 @@ def Merge(text,
 def ParseLines(lines,
 def ParseLines(lines,
                message,
                message,
                allow_unknown_extension=False,
                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.
   """Parses a text representation of a protocol message into a message.
 
 
   Args:
   Args:
@@ -496,7 +502,9 @@ def ParseLines(lines,
   Raises:
   Raises:
     ParseError: On text parsing problems.
     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)
   return parser.ParseLines(lines, message)
 
 
 
 
@@ -513,6 +521,7 @@ def MergeLines(lines,
     allow_unknown_extension: if True, skip over missing extensions and keep
     allow_unknown_extension: if True, skip over missing extensions and keep
       parsing
       parsing
     allow_field_number: if True, both field number and field name are allowed.
     allow_field_number: if True, both field number and field name are allowed.
+    descriptor_pool: A DescriptorPool used to resolve Any types.
 
 
   Returns:
   Returns:
     The same message passed as argument.
     The same message passed as argument.
@@ -1023,6 +1032,22 @@ class Tokenizer(object):
     self.NextToken()
     self.NextToken()
     return result
     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):
   def TryConsumeIdentifier(self):
     try:
     try:
       self.ConsumeIdentifier()
       self.ConsumeIdentifier()

+ 30 - 13
src/Makefile.am

@@ -37,18 +37,19 @@ protodir = $(includedir)
 # If you are adding new files here, also remember to change the build files for
 # 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
 # all other languages, //protoc-artifacts/build-zip.sh and run
 # //update_file_list.sh for bazel.
 # //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.
 # Not sure why these don't get cleaned automatically.
 clean-local:
 clean-local:
@@ -155,6 +156,7 @@ nobase_include_HEADERS =                                         \
   google/protobuf/compiler/parser.h                              \
   google/protobuf/compiler/parser.h                              \
   google/protobuf/compiler/plugin.h                              \
   google/protobuf/compiler/plugin.h                              \
   google/protobuf/compiler/plugin.pb.h                           \
   google/protobuf/compiler/plugin.pb.h                           \
+  google/protobuf/compiler/profile.pb.h                          \
   google/protobuf/compiler/cpp/cpp_generator.h                   \
   google/protobuf/compiler/cpp/cpp_generator.h                   \
   google/protobuf/compiler/csharp/csharp_generator.h             \
   google/protobuf/compiler/csharp/csharp_generator.h             \
   google/protobuf/compiler/csharp/csharp_names.h                 \
   google/protobuf/compiler/csharp/csharp_names.h                 \
@@ -324,6 +326,7 @@ libprotoc_la_SOURCES =                                         \
   google/protobuf/compiler/command_line_interface.cc           \
   google/protobuf/compiler/command_line_interface.cc           \
   google/protobuf/compiler/plugin.cc                           \
   google/protobuf/compiler/plugin.cc                           \
   google/protobuf/compiler/plugin.pb.cc                        \
   google/protobuf/compiler/plugin.pb.cc                        \
+  google/protobuf/compiler/profile.pb.cc                       \
   google/protobuf/compiler/subprocess.cc                       \
   google/protobuf/compiler/subprocess.cc                       \
   google/protobuf/compiler/subprocess.h                        \
   google/protobuf/compiler/subprocess.h                        \
   google/protobuf/compiler/zip_writer.cc                       \
   google/protobuf/compiler/zip_writer.cc                       \
@@ -535,6 +538,9 @@ protoc_inputs =                                                   \
   google/protobuf/unittest_import.proto                           \
   google/protobuf/unittest_import.proto                           \
   google/protobuf/unittest_import_public_lite.proto               \
   google/protobuf/unittest_import_public_lite.proto               \
   google/protobuf/unittest_import_public.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_imports_nonlite.proto             \
   google/protobuf/unittest_lite.proto                             \
   google/protobuf/unittest_lite.proto                             \
   google/protobuf/unittest_mset.proto                             \
   google/protobuf/unittest_mset.proto                             \
@@ -639,6 +645,12 @@ protoc_outputs =                                                  \
   google/protobuf/unittest_import.pb.h                            \
   google/protobuf/unittest_import.pb.h                            \
   google/protobuf/unittest_import_public.pb.cc                    \
   google/protobuf/unittest_import_public.pb.cc                    \
   google/protobuf/unittest_import_public.pb.h                     \
   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.cc             \
   google/protobuf/unittest_lite_imports_nonlite.pb.h              \
   google/protobuf/unittest_lite_imports_nonlite.pb.h              \
   google/protobuf/unittest_mset.pb.cc                             \
   google/protobuf/unittest_mset.pb.cc                             \
@@ -847,7 +859,12 @@ COMMON_LITE_TEST_SOURCES =                                             \
 # depend on gtest because our internal version of gtest depend on proto
 # 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
 # full runtime and we want to make sure this test builds without full
 # runtime.
 # 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_CXXFLAGS = $(NO_OPT_CXXFLAGS)
 protobuf_lite_test_SOURCES =                                           \
 protobuf_lite_test_SOURCES =                                           \
   google/protobuf/lite_unittest.cc                                     \
   google/protobuf/lite_unittest.cc                                     \

+ 3 - 3
src/google/protobuf/any.h

@@ -63,7 +63,7 @@ class LIBPROTOBUF_EXPORT AnyMetadata {
 
 
   // Unpacks the payload into the given message. Returns false if the message's
   // 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
   // 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.
   // full name) or parsing the payload has failed.
   bool UnpackTo(Message* message) const;
   bool UnpackTo(Message* message) const;
 
 
@@ -90,8 +90,8 @@ extern const char kTypeGoogleProdComPrefix[];  // "type.googleprod.com/".
 
 
 // Get the proto type name from Any::type_url value. For example, passing
 // Get the proto type name from Any::type_url value. For example, passing
 // "type.googleapis.com/rpc.QueryOrigin" will return "rpc.QueryOrigin" in
 // "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);
 bool ParseAnyTypeUrl(const string& type_url, string* full_type_name);
 
 
 // See if message is of type google.protobuf.Any, if so, return the descriptors
 // See if message is of type google.protobuf.Any, if so, return the descriptors

+ 28 - 3
src/google/protobuf/any.pb.cc

@@ -31,11 +31,26 @@ namespace {
 
 
 }  // namespace
 }  // 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[] = {
 const ::google::protobuf::uint32 TableStruct::offsets[] = {
   ~0u,  // no _has_bits_
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, _internal_metadata_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
   ~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, type_url_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, value_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, value_),
 };
 };
@@ -186,7 +201,7 @@ void Any::SetCachedSize(int size) const {
 }
 }
 const ::google::protobuf::Descriptor* Any::descriptor() {
 const ::google::protobuf::Descriptor* Any::descriptor() {
   protobuf_google_2fprotobuf_2fany_2eproto::protobuf_AssignDescriptorsOnce();
   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() {
 const Any& Any::default_instance() {
@@ -270,6 +285,9 @@ failure:
 void Any::SerializeWithCachedSizes(
 void Any::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Any)
   // @@protoc_insertion_point(serialize_start:google.protobuf.Any)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string type_url = 1;
   // string type_url = 1;
   if (this->type_url().size() > 0) {
   if (this->type_url().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -291,8 +309,10 @@ void Any::SerializeWithCachedSizes(
 
 
 ::google::protobuf::uint8* Any::InternalSerializeWithCachedSizesToArray(
 ::google::protobuf::uint8* Any::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Any)
   // @@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;
   // string type_url = 1;
   if (this->type_url().size() > 0) {
   if (this->type_url().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -359,6 +379,9 @@ void Any::MergeFrom(const Any& from) {
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Any)
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Any)
   GOOGLE_DCHECK_NE(&from, this);
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.type_url().size() > 0) {
   if (from.type_url().size() > 0) {
 
 
     type_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_url_);
     type_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_url_);
@@ -399,7 +422,7 @@ void Any::InternalSwap(Any* other) {
 
 
 ::google::protobuf::Metadata Any::GetMetadata() const {
 ::google::protobuf::Metadata Any::GetMetadata() const {
   protobuf_google_2fprotobuf_2fany_2eproto::protobuf_AssignDescriptorsOnce();
   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
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -427,6 +450,7 @@ void Any::set_type_url(::std::string&& value) {
 }
 }
 #endif
 #endif
 void Any::set_type_url(const char* value) {
 void Any::set_type_url(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   
   type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Any.type_url)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Any.type_url)
@@ -479,6 +503,7 @@ void Any::set_value(::std::string&& value) {
 }
 }
 #endif
 #endif
 void Any::set_value(const char* value) {
 void Any::set_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   
   value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Any.value)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Any.value)

+ 9 - 6
src/google/protobuf/any.pb.h

@@ -22,6 +22,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arenastring.h>
 #include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/message.h>
 #include <google/protobuf/message.h>
@@ -44,6 +45,9 @@ namespace protobuf {
 namespace protobuf_google_2fprotobuf_2fany_2eproto {
 namespace protobuf_google_2fprotobuf_2fany_2eproto {
 // Internal implementation detail -- do not call these.
 // Internal implementation detail -- do not call these.
 struct LIBPROTOBUF_EXPORT TableStruct {
 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 const ::google::protobuf::uint32 offsets[];
   static void InitDefaultsImpl();
   static void InitDefaultsImpl();
   static void Shutdown();
   static void Shutdown();
@@ -73,6 +77,8 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in
     return reinterpret_cast<const Any*>(
     return reinterpret_cast<const Any*>(
                &_Any_default_instance_);
                &_Any_default_instance_);
   }
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    0;
 
 
   // implements Any -----------------------------------------------
   // implements Any -----------------------------------------------
 
 
@@ -105,11 +111,6 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
       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_; }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   private:
   void SharedCtor();
   void SharedCtor();
@@ -167,7 +168,7 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in
   ::google::protobuf::internal::ArenaStringPtr value_;
   ::google::protobuf::internal::ArenaStringPtr value_;
   mutable int _cached_size_;
   mutable int _cached_size_;
   ::google::protobuf::internal::AnyMetadata _any_metadata_;
   ::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 @@ inline void Any::set_type_url(::std::string&& value) {
 }
 }
 #endif
 #endif
 inline void Any::set_type_url(const char* value) {
 inline void Any::set_type_url(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   
   type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Any.type_url)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Any.type_url)
@@ -251,6 +253,7 @@ inline void Any::set_value(::std::string&& value) {
 }
 }
 #endif
 #endif
 inline void Any::set_value(const char* value) {
 inline void Any::set_value(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   
   value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Any.value)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Any.value)

+ 74 - 32
src/google/protobuf/api.pb.cc

@@ -35,11 +35,28 @@ namespace {
 
 
 }  // namespace
 }  // 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[] = {
 const ::google::protobuf::uint32 TableStruct::offsets[] = {
   ~0u,  // no _has_bits_
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, _internal_metadata_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, methods_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, methods_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, options_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, options_),
@@ -51,6 +68,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = {
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, _internal_metadata_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, name_),
   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_type_url_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, request_streaming_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, request_streaming_),
@@ -62,14 +80,15 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = {
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, _internal_metadata_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
   ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, name_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, root_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, root_),
 };
 };
 
 
 static const ::google::protobuf::internal::MigrationSchema schemas[] = {
 static const ::google::protobuf::internal::MigrationSchema schemas[] = {
   { 0, -1, sizeof(Api)},
   { 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[] = {
 static ::google::protobuf::Message const * const file_default_instances[] = {
@@ -246,7 +265,7 @@ void Api::SetCachedSize(int size) const {
 }
 }
 const ::google::protobuf::Descriptor* Api::descriptor() {
 const ::google::protobuf::Descriptor* Api::descriptor() {
   protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
   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() {
 const Api& Api::default_instance() {
@@ -306,13 +325,11 @@ bool Api::MergePartialFromCodedStream(
       case 2: {
       case 2: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(18u)) {
             static_cast< ::google::protobuf::uint8>(18u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_methods()));
                 input, add_methods()));
         } else {
         } else {
           goto handle_unusual;
           goto handle_unusual;
         }
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
         break;
       }
       }
 
 
@@ -320,13 +337,11 @@ bool Api::MergePartialFromCodedStream(
       case 3: {
       case 3: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(26u)) {
             static_cast< ::google::protobuf::uint8>(26u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_options()));
                 input, add_options()));
         } else {
         } else {
           goto handle_unusual;
           goto handle_unusual;
         }
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
         break;
       }
       }
 
 
@@ -362,13 +377,11 @@ bool Api::MergePartialFromCodedStream(
       case 6: {
       case 6: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(50u)) {
             static_cast< ::google::protobuf::uint8>(50u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_mixins()));
                 input, add_mixins()));
         } else {
         } else {
           goto handle_unusual;
           goto handle_unusual;
         }
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
         break;
       }
       }
 
 
@@ -411,6 +424,9 @@ failure:
 void Api::SerializeWithCachedSizes(
 void Api::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Api)
   // @@protoc_insertion_point(serialize_start:google.protobuf.Api)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   // string name = 1;
   if (this->name().size() > 0) {
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -466,8 +482,10 @@ void Api::SerializeWithCachedSizes(
 
 
 ::google::protobuf::uint8* Api::InternalSerializeWithCachedSizesToArray(
 ::google::protobuf::uint8* Api::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Api)
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Api)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   // string name = 1;
   if (this->name().size() > 0) {
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -483,14 +501,14 @@ void Api::SerializeWithCachedSizes(
   for (unsigned int i = 0, n = this->methods_size(); i < n; i++) {
   for (unsigned int i = 0, n = this->methods_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
       InternalWriteMessageNoVirtualToArray(
-        2, this->methods(i), false, target);
+        2, this->methods(i), deterministic, target);
   }
   }
 
 
   // repeated .google.protobuf.Option options = 3;
   // repeated .google.protobuf.Option options = 3;
   for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
   for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
       InternalWriteMessageNoVirtualToArray(
-        3, this->options(i), false, target);
+        3, this->options(i), deterministic, target);
   }
   }
 
 
   // string version = 4;
   // string version = 4;
@@ -508,14 +526,14 @@ void Api::SerializeWithCachedSizes(
   if (this->has_source_context()) {
   if (this->has_source_context()) {
     target = ::google::protobuf::internal::WireFormatLite::
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
       InternalWriteMessageNoVirtualToArray(
-        5, *this->source_context_, false, target);
+        5, *this->source_context_, deterministic, target);
   }
   }
 
 
   // repeated .google.protobuf.Mixin mixins = 6;
   // repeated .google.protobuf.Mixin mixins = 6;
   for (unsigned int i = 0, n = this->mixins_size(); i < n; i++) {
   for (unsigned int i = 0, n = this->mixins_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
       InternalWriteMessageNoVirtualToArray(
-        6, this->mixins(i), false, target);
+        6, this->mixins(i), deterministic, target);
   }
   }
 
 
   // .google.protobuf.Syntax syntax = 7;
   // .google.protobuf.Syntax syntax = 7;
@@ -618,6 +636,9 @@ void Api::MergeFrom(const Api& from) {
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Api)
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Api)
   GOOGLE_DCHECK_NE(&from, this);
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   methods_.MergeFrom(from.methods_);
   methods_.MergeFrom(from.methods_);
   options_.MergeFrom(from.options_);
   options_.MergeFrom(from.options_);
   mixins_.MergeFrom(from.mixins_);
   mixins_.MergeFrom(from.mixins_);
@@ -660,9 +681,9 @@ void Api::Swap(Api* other) {
   InternalSwap(other);
   InternalSwap(other);
 }
 }
 void Api::InternalSwap(Api* 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_);
   name_.Swap(&other->name_);
   version_.Swap(&other->version_);
   version_.Swap(&other->version_);
   std::swap(source_context_, other->source_context_);
   std::swap(source_context_, other->source_context_);
@@ -672,7 +693,7 @@ void Api::InternalSwap(Api* other) {
 
 
 ::google::protobuf::Metadata Api::GetMetadata() const {
 ::google::protobuf::Metadata Api::GetMetadata() const {
   protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
   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
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -700,6 +721,7 @@ void Api::set_name(::std::string&& value) {
 }
 }
 #endif
 #endif
 void Api::set_name(const char* value) {
 void Api::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Api.name)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Api.name)
@@ -812,6 +834,7 @@ void Api::set_version(::std::string&& value) {
 }
 }
 #endif
 #endif
 void Api::set_version(const char* value) {
 void Api::set_version(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   
   version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Api.version)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Api.version)
@@ -998,7 +1021,7 @@ void Method::SetCachedSize(int size) const {
 }
 }
 const ::google::protobuf::Descriptor* Method::descriptor() {
 const ::google::protobuf::Descriptor* Method::descriptor() {
   protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
   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() {
 const Method& Method::default_instance() {
@@ -1114,13 +1137,11 @@ bool Method::MergePartialFromCodedStream(
       case 6: {
       case 6: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(50u)) {
             static_cast< ::google::protobuf::uint8>(50u)) {
-          DO_(input->IncrementRecursionDepth());
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_options()));
                 input, add_options()));
         } else {
         } else {
           goto handle_unusual;
           goto handle_unusual;
         }
         }
-        input->UnsafeDecrementRecursionDepth();
         break;
         break;
       }
       }
 
 
@@ -1163,6 +1184,9 @@ failure:
 void Method::SerializeWithCachedSizes(
 void Method::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Method)
   // @@protoc_insertion_point(serialize_start:google.protobuf.Method)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   // string name = 1;
   if (this->name().size() > 0) {
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -1220,8 +1244,10 @@ void Method::SerializeWithCachedSizes(
 
 
 ::google::protobuf::uint8* Method::InternalSerializeWithCachedSizesToArray(
 ::google::protobuf::uint8* Method::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Method)
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Method)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   // string name = 1;
   if (this->name().size() > 0) {
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -1269,7 +1295,7 @@ void Method::SerializeWithCachedSizes(
   for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
   for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageNoVirtualToArray(
       InternalWriteMessageNoVirtualToArray(
-        6, this->options(i), false, target);
+        6, this->options(i), deterministic, target);
   }
   }
 
 
   // .google.protobuf.Syntax syntax = 7;
   // .google.protobuf.Syntax syntax = 7;
@@ -1360,6 +1386,9 @@ void Method::MergeFrom(const Method& from) {
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Method)
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Method)
   GOOGLE_DCHECK_NE(&from, this);
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   options_.MergeFrom(from.options_);
   options_.MergeFrom(from.options_);
   if (from.name().size() > 0) {
   if (from.name().size() > 0) {
 
 
@@ -1407,7 +1436,7 @@ void Method::Swap(Method* other) {
   InternalSwap(other);
   InternalSwap(other);
 }
 }
 void Method::InternalSwap(Method* other) {
 void Method::InternalSwap(Method* other) {
-  options_.UnsafeArenaSwap(&other->options_);
+  options_.InternalSwap(&other->options_);
   name_.Swap(&other->name_);
   name_.Swap(&other->name_);
   request_type_url_.Swap(&other->request_type_url_);
   request_type_url_.Swap(&other->request_type_url_);
   response_type_url_.Swap(&other->response_type_url_);
   response_type_url_.Swap(&other->response_type_url_);
@@ -1419,7 +1448,7 @@ void Method::InternalSwap(Method* other) {
 
 
 ::google::protobuf::Metadata Method::GetMetadata() const {
 ::google::protobuf::Metadata Method::GetMetadata() const {
   protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
   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
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1447,6 +1476,7 @@ void Method::set_name(::std::string&& value) {
 }
 }
 #endif
 #endif
 void Method::set_name(const char* value) {
 void Method::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.name)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.name)
@@ -1499,6 +1529,7 @@ void Method::set_request_type_url(::std::string&& value) {
 }
 }
 #endif
 #endif
 void Method::set_request_type_url(const char* value) {
 void Method::set_request_type_url(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   
   request_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   request_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.request_type_url)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.request_type_url)
@@ -1565,6 +1596,7 @@ void Method::set_response_type_url(::std::string&& value) {
 }
 }
 #endif
 #endif
 void Method::set_response_type_url(const char* value) {
 void Method::set_response_type_url(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   
   response_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   response_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.response_type_url)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.response_type_url)
@@ -1709,7 +1741,7 @@ void Mixin::SetCachedSize(int size) const {
 }
 }
 const ::google::protobuf::Descriptor* Mixin::descriptor() {
 const ::google::protobuf::Descriptor* Mixin::descriptor() {
   protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
   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() {
 const Mixin& Mixin::default_instance() {
@@ -1797,6 +1829,9 @@ failure:
 void Mixin::SerializeWithCachedSizes(
 void Mixin::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:google.protobuf.Mixin)
   // @@protoc_insertion_point(serialize_start:google.protobuf.Mixin)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   // string name = 1;
   if (this->name().size() > 0) {
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -1822,8 +1857,10 @@ void Mixin::SerializeWithCachedSizes(
 
 
 ::google::protobuf::uint8* Mixin::InternalSerializeWithCachedSizesToArray(
 ::google::protobuf::uint8* Mixin::InternalSerializeWithCachedSizesToArray(
     bool deterministic, ::google::protobuf::uint8* target) const {
     bool deterministic, ::google::protobuf::uint8* target) const {
-  (void)deterministic;  // Unused
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Mixin)
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Mixin)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   // string name = 1;
   // string name = 1;
   if (this->name().size() > 0) {
   if (this->name().size() > 0) {
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
     ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -1894,6 +1931,9 @@ void Mixin::MergeFrom(const Mixin& from) {
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Mixin)
 // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Mixin)
   GOOGLE_DCHECK_NE(&from, this);
   GOOGLE_DCHECK_NE(&from, this);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
   if (from.name().size() > 0) {
   if (from.name().size() > 0) {
 
 
     name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
     name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
@@ -1934,7 +1974,7 @@ void Mixin::InternalSwap(Mixin* other) {
 
 
 ::google::protobuf::Metadata Mixin::GetMetadata() const {
 ::google::protobuf::Metadata Mixin::GetMetadata() const {
   protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
   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
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1962,6 +2002,7 @@ void Mixin::set_name(::std::string&& value) {
 }
 }
 #endif
 #endif
 void Mixin::set_name(const char* value) {
 void Mixin::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name)
@@ -2014,6 +2055,7 @@ void Mixin::set_root(::std::string&& value) {
 }
 }
 #endif
 #endif
 void Mixin::set_root(const char* value) {
 void Mixin::set_root(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   
   root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root)

+ 20 - 18
src/google/protobuf/api.pb.h

@@ -22,6 +22,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arenastring.h>
 #include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/message.h>
 #include <google/protobuf/message.h>
@@ -69,6 +70,9 @@ namespace protobuf {
 namespace protobuf_google_2fprotobuf_2fapi_2eproto {
 namespace protobuf_google_2fprotobuf_2fapi_2eproto {
 // Internal implementation detail -- do not call these.
 // Internal implementation detail -- do not call these.
 struct LIBPROTOBUF_EXPORT TableStruct {
 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 const ::google::protobuf::uint32 offsets[];
   static void InitDefaultsImpl();
   static void InitDefaultsImpl();
   static void Shutdown();
   static void Shutdown();
@@ -98,6 +102,8 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in
     return reinterpret_cast<const Api*>(
     return reinterpret_cast<const Api*>(
                &_Api_default_instance_);
                &_Api_default_instance_);
   }
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    0;
 
 
   void Swap(Api* other);
   void Swap(Api* other);
 
 
@@ -120,11 +126,6 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
       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_; }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   private:
   void SharedCtor();
   void SharedCtor();
@@ -237,7 +238,7 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in
   ::google::protobuf::SourceContext* source_context_;
   ::google::protobuf::SourceContext* source_context_;
   int syntax_;
   int syntax_;
   mutable int _cached_size_;
   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 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc
     return reinterpret_cast<const Method*>(
     return reinterpret_cast<const Method*>(
                &_Method_default_instance_);
                &_Method_default_instance_);
   }
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    1;
 
 
   void Swap(Method* other);
   void Swap(Method* other);
 
 
@@ -282,11 +285,6 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
       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_; }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   private:
   void SharedCtor();
   void SharedCtor();
@@ -392,7 +390,7 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc
   bool response_streaming_;
   bool response_streaming_;
   int syntax_;
   int syntax_;
   mutable int _cached_size_;
   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 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_
     return reinterpret_cast<const Mixin*>(
     return reinterpret_cast<const Mixin*>(
                &_Mixin_default_instance_);
                &_Mixin_default_instance_);
   }
   }
+  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+    2;
 
 
   void Swap(Mixin* other);
   void Swap(Mixin* other);
 
 
@@ -437,11 +437,6 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
       ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
       bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
       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_; }
   int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
   private:
   private:
   void SharedCtor();
   void SharedCtor();
@@ -498,7 +493,7 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::internal::ArenaStringPtr root_;
   ::google::protobuf::internal::ArenaStringPtr root_;
   mutable int _cached_size_;
   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 @@ inline void Api::set_name(::std::string&& value) {
 }
 }
 #endif
 #endif
 inline void Api::set_name(const char* value) {
 inline void Api::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Api.name)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Api.name)
@@ -642,6 +638,7 @@ inline void Api::set_version(::std::string&& value) {
 }
 }
 #endif
 #endif
 inline void Api::set_version(const char* value) {
 inline void Api::set_version(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   
   version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Api.version)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Api.version)
@@ -781,6 +778,7 @@ inline void Method::set_name(::std::string&& value) {
 }
 }
 #endif
 #endif
 inline void Method::set_name(const char* value) {
 inline void Method::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.name)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.name)
@@ -833,6 +831,7 @@ inline void Method::set_request_type_url(::std::string&& value) {
 }
 }
 #endif
 #endif
 inline void Method::set_request_type_url(const char* value) {
 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));
   request_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.request_type_url)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.request_type_url)
@@ -899,6 +898,7 @@ inline void Method::set_response_type_url(::std::string&& value) {
 }
 }
 #endif
 #endif
 inline void Method::set_response_type_url(const char* value) {
 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));
   response_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.response_type_url)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Method.response_type_url)
@@ -1013,6 +1013,7 @@ inline void Mixin::set_name(::std::string&& value) {
 }
 }
 #endif
 #endif
 inline void Mixin::set_name(const char* value) {
 inline void Mixin::set_name(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name)
@@ -1065,6 +1066,7 @@ inline void Mixin::set_root(::std::string&& value) {
 }
 }
 #endif
 #endif
 inline void Mixin::set_root(const char* value) {
 inline void Mixin::set_root(const char* value) {
+  GOOGLE_DCHECK(value != NULL);
   
   
   root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root)
   // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root)

+ 26 - 29
src/google/protobuf/arena.h

@@ -303,6 +303,17 @@ class LIBPROTOBUF_EXPORT Arena {
   // (unless the destructor is trivial). Hence, from T's point of view, it is as
   // (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
   // if the object were allocated on the heap (except that the underlying memory
   // is obtained from the arena).
   // 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
   template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   static T* Create(::google::protobuf::Arena* arena) {
   static T* Create(::google::protobuf::Arena* arena) {
     if (arena == NULL) {
     if (arena == NULL) {
@@ -322,17 +333,6 @@ class LIBPROTOBUF_EXPORT Arena {
                                       arg);
                                       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.
   // Version of the above with two constructor arguments for the created object.
   template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
@@ -655,35 +655,34 @@ class LIBPROTOBUF_EXPORT Arena {
         AllocateAligned(RTTI_TYPE_ID(T), sizeof(T) * num_elements));
         AllocateAligned(RTTI_TYPE_ID(T), sizeof(T) * num_elements));
   }
   }
 
 
-  template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
-  T* CreateInternal(bool skip_explicit_ownership) {
-    T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T();
+#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) {
     if (!skip_explicit_ownership) {
       AddListNode(t, &internal::arena_destruct_object<T>);
       AddListNode(t, &internal::arena_destruct_object<T>);
     }
     }
     return t;
     return t;
   }
   }
-
-  template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
-  T* CreateInternal(bool skip_explicit_ownership, const Arg& arg) {
-    T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(arg);
+#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();
     if (!skip_explicit_ownership) {
     if (!skip_explicit_ownership) {
       AddListNode(t, &internal::arena_destruct_object<T>);
       AddListNode(t, &internal::arena_destruct_object<T>);
     }
     }
     return t;
     return t;
   }
   }
 
 
-#if LANG_CXX11
   template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   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));
+  T* CreateInternal(bool skip_explicit_ownership, const Arg& arg) {
+    T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(arg);
     if (!skip_explicit_ownership) {
     if (!skip_explicit_ownership) {
       AddListNode(t, &internal::arena_destruct_object<T>);
       AddListNode(t, &internal::arena_destruct_object<T>);
     }
     }
     return t;
     return t;
   }
   }
-#endif
 
 
   template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   T* CreateInternal(
   T* CreateInternal(
@@ -796,22 +795,20 @@ class LIBPROTOBUF_EXPORT Arena {
 
 
   template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   T* CreateMessageInternal(typename T::InternalArenaConstructable_*) {
   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
   template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   T* CreateMessageInternal(typename T::InternalArenaConstructable_*,
   T* CreateMessageInternal(typename T::InternalArenaConstructable_*,
                            const Arg& arg) {
                            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
   template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   T* CreateMessageInternal(typename T::InternalArenaConstructable_*,
   T* CreateMessageInternal(typename T::InternalArenaConstructable_*,
                            const Arg1& arg1, const Arg2& arg2) {
                            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,
   // CreateInArenaStorage is used to implement map field. Without it,

+ 52 - 0
src/google/protobuf/arena_unittest.cc

@@ -180,6 +180,35 @@ TEST(ArenaTest, BasicCreate) {
   EXPECT_EQ(2, notifier.GetCount());
   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) {
 TEST(ArenaTest, CreateWithFourConstructorArguments) {
   Arena arena;
   Arena arena;
   const string three("3");
   const string three("3");
@@ -214,6 +243,29 @@ TEST(ArenaTest, CreateWithEightConstructorArguments) {
   ASSERT_EQ("8", new_object->eight_);
   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) {
 TEST(ArenaTest, InitialBlockTooSmall) {
   // Construct a small (64 byte) initial block of memory to be used by the
   // 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
   // arena allocator; then, allocate an object which will not fit in the

+ 0 - 10
src/google/protobuf/arenastring.cc

@@ -38,16 +38,6 @@ namespace protobuf {
 namespace internal {
 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 internal
 }  // namespace protobuf
 }  // namespace protobuf
 }  // namespace google
 }  // namespace google

+ 16 - 0
src/google/protobuf/arenastring.h

@@ -310,5 +310,21 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
 
 
 
 
 
 
+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
 }  // namespace google
 #endif  // GOOGLE_PROTOBUF_ARENASTRING_H__
 #endif  // GOOGLE_PROTOBUF_ARENASTRING_H__

+ 1 - 1
src/google/protobuf/compiler/code_generator.h

@@ -162,7 +162,7 @@ typedef GeneratorContext OutputDirectory;
 //   "foo=bar,baz,qux=corge"
 //   "foo=bar,baz,qux=corge"
 // parses to the pairs:
 // parses to the pairs:
 //   ("foo", "bar"), ("baz", ""), ("qux", "corge")
 //   ("foo", "bar"), ("baz", ""), ("qux", "corge")
-extern void LIBPROTOC_EXPORT ParseGeneratorParameter(const string&,
+extern void ParseGeneratorParameter(const string&,
             std::vector<std::pair<string, string> >*);
             std::vector<std::pair<string, string> >*);
 
 
 }  // namespace compiler
 }  // namespace compiler

+ 31 - 26
src/google/protobuf/compiler/command_line_interface.cc

@@ -816,11 +816,11 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
         if (direct_dependencies_.find(parsed_file->dependency(i)->name()) ==
         if (direct_dependencies_.find(parsed_file->dependency(i)->name()) ==
             direct_dependencies_.end()) {
             direct_dependencies_.end()) {
           indirect_imports = true;
           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) {
       if (indirect_imports) {
@@ -1038,7 +1038,7 @@ CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
 
 
   // Make sure each plugin option has a matching plugin output.
   // Make sure each plugin option has a matching plugin output.
   bool foundUnknownPluginOption = false;
   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) {
        i != plugin_parameters_.end(); ++i) {
     if (plugins_.find(i->first) != plugins_.end()) {
     if (plugins_.find(i->first) != plugins_.end()) {
       continue;
       continue;
@@ -1221,7 +1221,8 @@ CommandLineInterface::InterpretArgument(const string& name,
       if (access(disk_path.c_str(), F_OK) < 0) {
       if (access(disk_path.c_str(), F_OK) < 0) {
         // Try the original path; it may have just happed to have a '=' in it.
         // Try the original path; it may have just happed to have a '=' in it.
         if (access(parts[i].c_str(), F_OK) < 0) {
         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 {
         } else {
           virtual_path = "";
           virtual_path = "";
           disk_path = parts[i];
           disk_path = parts[i];
@@ -1391,6 +1392,7 @@ CommandLineInterface::InterpretArgument(const string& name,
     }
     }
     mode_ = MODE_PRINT;
     mode_ = MODE_PRINT;
     print_mode_ = PRINT_FREE_FIELDS;
     print_mode_ = PRINT_FREE_FIELDS;
+  } else if (name == "--profile_path") {
   } else {
   } else {
     // Some other flag.  Look it up in the generators list.
     // Some other flag.  Look it up in the generators list.
     const GeneratorInfo* generator_info =
     const GeneratorInfo* generator_info =
@@ -1790,31 +1792,34 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) {
 }
 }
 
 
 bool CommandLineInterface::WriteDescriptorSet(
 bool CommandLineInterface::WriteDescriptorSet(
-    const std::vector<const FileDescriptor*> parsed_files) {
+    const std::vector<const FileDescriptor*>& parsed_files) {
   FileDescriptorSet file_set;
   FileDescriptorSet file_set;
 
 
-  if (imports_in_descriptor_set_) {
-    std::set<const FileDescriptor*> already_seen;
-    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;
+  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++) {
     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;
   int fd;
   do {
   do {

+ 6 - 1
src/google/protobuf/compiler/command_line_interface.h

@@ -258,7 +258,7 @@ class LIBPROTOC_EXPORT CommandLineInterface {
 
 
   // Implements the --descriptor_set_out option.
   // Implements the --descriptor_set_out option.
   bool WriteDescriptorSet(
   bool WriteDescriptorSet(
-      const std::vector<const FileDescriptor*> parsed_files);
+      const std::vector<const FileDescriptor*>& parsed_files);
 
 
   // Implements the --dependency_out option
   // Implements the --dependency_out option
   bool GenerateDependencyManifestFile(
   bool GenerateDependencyManifestFile(
@@ -391,6 +391,11 @@ class LIBPROTOC_EXPORT CommandLineInterface {
   // dependency file will be written. Otherwise, empty.
   // dependency file will be written. Otherwise, empty.
   string dependency_out_name_;
   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
   // True if --include_imports was given, meaning that we should
   // write all transitive dependencies to the DescriptorSet.  Otherwise, only
   // write all transitive dependencies to the DescriptorSet.  Otherwise, only
   // the .proto files listed on the command-line are added.
   // the .proto files listed on the command-line are added.

+ 21 - 19
src/google/protobuf/compiler/command_line_interface_unittest.cc

@@ -32,9 +32,9 @@
 //  Based on original Protocol Buffers design by
 //  Based on original Protocol Buffers design by
 //  Sanjay Ghemawat, Jeff Dean, and others.
 //  Sanjay Ghemawat, Jeff Dean, and others.
 
 
-#include <sys/types.h>
-#include <sys/stat.h>
 #include <fcntl.h>
 #include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 #ifdef _MSC_VER
 #ifdef _MSC_VER
 #include <io.h>
 #include <io.h>
 #else
 #else
@@ -46,25 +46,25 @@
 #endif
 #endif
 #include <vector>
 #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/testing/file.h>
 #include <google/protobuf/compiler/mock_code_generator.h>
 #include <google/protobuf/compiler/mock_code_generator.h>
 #include <google/protobuf/compiler/subprocess.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/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/stubs/substitute.h>
 
 
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/testing/googletest.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
 #include <gtest/gtest.h>
 
 
+#include <google/protobuf/stubs/strutil.h>
 
 
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
@@ -101,7 +101,7 @@ class CommandLineInterfaceTest : public testing::Test {
   // command is automatically split on spaces, and the string "$tmpdir"
   // command is automatically split on spaces, and the string "$tmpdir"
   // is replaced with TestTempDir().
   // is replaced with TestTempDir().
   void Run(const string& command);
   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()).
   // Methods to set up the test (called before Run()).
@@ -301,7 +301,7 @@ void CommandLineInterfaceTest::Run(const string& command) {
   RunWithArgs(Split(command, " ", true));
   RunWithArgs(Split(command, " ", true));
 }
 }
 
 
-void CommandLineInterfaceTest::RunWithArgs(vector<string> args) {
+void CommandLineInterfaceTest::RunWithArgs(std::vector<string> args) {
   if (!disallow_plugins_) {
   if (!disallow_plugins_) {
     cli_.AllowPlugins("prefix-");
     cli_.AllowPlugins("prefix-");
 #ifndef GOOGLE_THIRD_PARTY_PROTOBUF
 #ifndef GOOGLE_THIRD_PARTY_PROTOBUF
@@ -1044,7 +1044,7 @@ TEST_F(CommandLineInterfaceTest, DirectDependencies_CustomErrorMessage) {
                  "syntax = \"proto2\";\n"
                  "syntax = \"proto2\";\n"
                  "message Bar { optional string text = 1; }");
                  "message Bar { optional string text = 1; }");
 
 
-  vector<string> commands;
+  std::vector<string> commands;
   commands.push_back("protocol_compiler");
   commands.push_back("protocol_compiler");
   commands.push_back("--test_out=$tmpdir");
   commands.push_back("--test_out=$tmpdir");
   commands.push_back("--proto_path=$tmpdir");
   commands.push_back("--proto_path=$tmpdir");
@@ -1127,15 +1127,17 @@ TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithDuplicates) {
   ReadDescriptorSet("descriptor_set", &descriptor_set);
   ReadDescriptorSet("descriptor_set", &descriptor_set);
   if (HasFatalFailure()) return;
   if (HasFatalFailure()) return;
   EXPECT_EQ(3, descriptor_set.file_size());
   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());
   EXPECT_EQ("baz.proto", descriptor_set.file(2).name());
   // Descriptor set should not have source code info.
   // Descriptor set should not have source code info.
   EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
   EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
   // Descriptor set should have json_name.
   // 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) {
 TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithSourceInfo) {

+ 11 - 3
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/cpp/cpp_generator.h>
 #include <google/protobuf/compiler/importer.h>
 #include <google/protobuf/compiler/importer.h>
-#include <google/protobuf/descriptor.h>
 #include <google/protobuf/io/zero_copy_stream_impl.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/map_util.h>
 #include <google/protobuf/stubs/stl_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>
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/testing/file.h>
@@ -126,9 +125,12 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) {
     importer.Import("google/protobuf/descriptor.proto");
     importer.Import("google/protobuf/descriptor.proto");
   const FileDescriptor* plugin_proto_file =
   const FileDescriptor* plugin_proto_file =
     importer.Import("google/protobuf/compiler/plugin.proto");
     importer.Import("google/protobuf/compiler/plugin.proto");
+  const FileDescriptor* profile_proto_file =
+    importer.Import("google/protobuf/compiler/profile.proto");
   EXPECT_EQ("", error_collector.text_);
   EXPECT_EQ("", error_collector.text_);
   ASSERT_TRUE(proto_file != NULL);
   ASSERT_TRUE(proto_file != NULL);
   ASSERT_TRUE(plugin_proto_file != NULL);
   ASSERT_TRUE(plugin_proto_file != NULL);
+  ASSERT_TRUE(profile_proto_file != NULL);
 
 
   CppGenerator generator;
   CppGenerator generator;
   MockGeneratorContext context;
   MockGeneratorContext context;
@@ -139,6 +141,8 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) {
   parameter = "dllexport_decl=LIBPROTOC_EXPORT";
   parameter = "dllexport_decl=LIBPROTOC_EXPORT";
   ASSERT_TRUE(generator.Generate(plugin_proto_file, parameter,
   ASSERT_TRUE(generator.Generate(plugin_proto_file, parameter,
                                  &context, &error));
                                  &context, &error));
+  ASSERT_TRUE(generator.Generate(profile_proto_file, parameter,
+                                 &context, &error));
 
 
   context.ExpectFileMatches("google/protobuf/descriptor.pb.h",
   context.ExpectFileMatches("google/protobuf/descriptor.pb.h",
                             "google/protobuf/descriptor.pb.h");
                             "google/protobuf/descriptor.pb.h");
@@ -148,6 +152,10 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) {
                             "google/protobuf/compiler/plugin.pb.h");
                             "google/protobuf/compiler/plugin.pb.h");
   context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc",
   context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc",
                             "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
 }  // namespace

+ 5 - 11
src/google/protobuf/compiler/cpp/cpp_enum_field.cc

@@ -318,7 +318,7 @@ GenerateMergingCode(io::Printer* printer) const {
 
 
 void RepeatedEnumFieldGenerator::
 void RepeatedEnumFieldGenerator::
 GenerateSwappingCode(io::Printer* printer) const {
 GenerateSwappingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.UnsafeArenaSwap(&other->$name$_);\n");
+  printer->Print(variables_, "$name$_.InternalSwap(&other->$name$_);\n");
 }
 }
 
 
 void RepeatedEnumFieldGenerator::
 void RepeatedEnumFieldGenerator::
@@ -461,20 +461,14 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
       "    target);\n"
       "    target);\n"
       "  target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray("
       "  target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray("
       "    _$name$_cached_byte_size_, target);\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::WriteEnumNoTagToArray(\n"
       "  target = ::google::protobuf::internal::WireFormatLite::WriteEnumNoTagToArray(\n"
-      "    this->$name$(i), target);\n");
+      "    this->$name$_, target);\n"
+      "}\n");
   } else {
   } else {
     printer->Print(variables_,
     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::
 void RepeatedEnumFieldGenerator::

+ 129 - 25
src/google/protobuf/compiler/cpp/cpp_file.cc

@@ -39,6 +39,7 @@
 #include <google/protobuf/stubs/shared_ptr.h>
 #include <google/protobuf/stubs/shared_ptr.h>
 #endif
 #endif
 #include <set>
 #include <set>
+#include <vector>
 
 
 #include <google/protobuf/compiler/cpp/cpp_enum.h>
 #include <google/protobuf/compiler/cpp/cpp_enum.h>
 #include <google/protobuf/compiler/cpp/cpp_service.h>
 #include <google/protobuf/compiler/cpp/cpp_service.h>
@@ -67,7 +68,7 @@ bool IsMacroName(const string& name) {
   return false;
   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) {
   for (int i = 0; i < message->field_count(); ++i) {
     const FieldDescriptor* field = message->field(i);
     const FieldDescriptor* field = message->field(i);
     if (IsMacroName(field->name())) {
     if (IsMacroName(field->name())) {
@@ -79,7 +80,13 @@ void CollectMacroNames(const Descriptor* message, vector<string>* names) {
   }
   }
 }
 }
 
 
-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) {
   for (int i = 0; i < file->message_type_count(); ++i) {
     CollectMacroNames(file->message_type(i), names);
     CollectMacroNames(file->message_type(i), names);
   }
   }
@@ -93,18 +100,19 @@ void CollectMacroNames(const FileDescriptor* file, vector<string>* names) {
 FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
 FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
     : file_(file),
     : file_(file),
       options_(options),
       options_(options),
+      scc_analyzer_(options),
       message_generators_owner_(
       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_(
       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_(
       service_generators_owner_(
-          new google::protobuf::scoped_ptr<ServiceGenerator>[ file->service_count() ]),
+          new google::protobuf::scoped_ptr<ServiceGenerator>[file->service_count()]),
       extension_generators_owner_(
       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++) {
   for (int i = 0; i < file->message_type_count(); i++) {
     message_generators_owner_[i].reset(
     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_);
     message_generators_owner_[i]->Flatten(&message_generators_);
   }
   }
 
 
@@ -137,7 +145,7 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
 FileGenerator::~FileGenerator() {}
 FileGenerator::~FileGenerator() {}
 
 
 void FileGenerator::GenerateMacroUndefs(io::Printer* printer) {
 void FileGenerator::GenerateMacroUndefs(io::Printer* printer) {
-  vector<string> names_to_undef;
+  std::vector<string> names_to_undef;
   CollectMacroNames(file_, &names_to_undef);
   CollectMacroNames(file_, &names_to_undef);
   for (int i = 0; i < names_to_undef.size(); ++i) {
   for (int i = 0; i < names_to_undef.size(); ++i) {
     printer->Print(
     printer->Print(
@@ -241,6 +249,7 @@ void FileGenerator::GeneratePBHeader(io::Printer* printer,
   } else {
   } else {
     GenerateLibraryIncludes(printer);
     GenerateLibraryIncludes(printer);
   }
   }
+
   GenerateDependencyIncludes(printer);
   GenerateDependencyIncludes(printer);
   GenerateMetadataPragma(printer, info_path);
   GenerateMetadataPragma(printer, info_path);
 
 
@@ -327,11 +336,17 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
   GenerateNamespaceOpeners(printer);
   GenerateNamespaceOpeners(printer);
 
 
   for (int i = 0; i < message_generators_.size(); i++) {
   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(
     printer->Print(
         "class $classname$DefaultTypeInternal : "
         "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();
     printer->Indent();
     message_generators_[i]->GenerateExtraDefaultFields(printer);
     message_generators_[i]->GenerateExtraDefaultFields(printer);
     printer->Outdent();
     printer->Outdent();
@@ -340,9 +355,6 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
         "classname", message_generators_[i]->classname_);
         "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++) {
   for (int i = 0; i < enum_generators_.size(); i++) {
     enum_generators_[i]->index_in_metadata_ = i;
     enum_generators_[i]->index_in_metadata_ = i;
   }
   }
@@ -530,6 +542,70 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
   // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors()
   // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors()
   // and we only use AddDescriptors() to allocate default instances.
   // 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 (HasDescriptorMethods(file_, options_)) {
     if (!message_generators_.empty()) {
     if (!message_generators_.empty()) {
       printer->Print("const ::google::protobuf::uint32 TableStruct::offsets[] = {\n");
       printer->Print("const ::google::protobuf::uint32 TableStruct::offsets[] = {\n");
@@ -560,8 +636,6 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
       printer->Indent();
       printer->Indent();
       for (int i = 0; i < message_generators_.size(); i++) {
       for (int i = 0; i < message_generators_.size(); i++) {
         const Descriptor* descriptor = message_generators_[i]->descriptor_;
         const Descriptor* descriptor = message_generators_[i]->descriptor_;
-        if (IsMapEntryMessage(descriptor)) continue;
-
         printer->Print(
         printer->Print(
             "reinterpret_cast<const "
             "reinterpret_cast<const "
             "::google::protobuf::Message*>(&_$classname$_default_instance_),\n",
             "::google::protobuf::Message*>(&_$classname$_default_instance_),\n",
@@ -600,7 +674,31 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
         "  AssignDescriptors(\n"
         "  AssignDescriptors(\n"
         "      \"$filename$\", schemas, file_default_instances, "
         "      \"$filename$\", schemas, file_default_instances, "
         "TableStruct::offsets, factory,\n"
         "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"
         "\n"
         "\n"
         "void protobuf_AssignDescriptorsOnce() {\n"
         "void protobuf_AssignDescriptorsOnce() {\n"
@@ -634,12 +732,6 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
         "size", SimpleItoa(message_generators_.size()));
         "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->Outdent();
     printer->Print(
     printer->Print(
       "}\n"
       "}\n"
@@ -902,8 +994,16 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
       "#include <google/protobuf/io/coded_stream.h>\n"
       "#include <google/protobuf/io/coded_stream.h>\n"
       "#include <google/protobuf/arena.h>\n"
       "#include <google/protobuf/arena.h>\n"
       "#include <google/protobuf/arenastring.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");
       "#include <google/protobuf/metadata.h>\n");
+  } else {
+    printer->Print(
+      "#include <google/protobuf/metadata_lite.h>\n");
+  }
 
 
   if (!message_generators_.empty()) {
   if (!message_generators_.empty()) {
     if (HasDescriptorMethods(file_, options_)) {
     if (HasDescriptorMethods(file_, options_)) {
@@ -921,7 +1021,8 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
     "  // IWYU pragma: export\n");
     "  // IWYU pragma: export\n");
   if (HasMapFields(file_)) {
   if (HasMapFields(file_)) {
     printer->Print(
     printer->Print(
-        "#include <google/protobuf/map.h>\n");
+        "#include <google/protobuf/map.h>"
+        "  // IWYU pragma: export\n");
     if (HasDescriptorMethods(file_, options_)) {
     if (HasDescriptorMethods(file_, options_)) {
       printer->Print(
       printer->Print(
           "#include <google/protobuf/map_field_inl.h>\n");
           "#include <google/protobuf/map_field_inl.h>\n");
@@ -1001,6 +1102,9 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations(
       "namespace $file_namespace$ {\n"
       "namespace $file_namespace$ {\n"
       "// Internal implementation detail -- do not call these.\n"
       "// Internal implementation detail -- do not call these.\n"
       "struct $dllexport_decl$TableStruct {\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"
       "  static const ::google::protobuf::uint32 offsets[];\n"
       // The following function(s) need to be able to access private members of
       // 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.
       // the messages defined in the file. So we make them static members.

+ 3 - 0
src/google/protobuf/compiler/cpp/cpp_file.h

@@ -43,6 +43,7 @@
 #include <vector>
 #include <vector>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/compiler/cpp/cpp_field.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>
 #include <google/protobuf/compiler/cpp/cpp_options.h>
 
 
 namespace google {
 namespace google {
@@ -145,6 +146,8 @@ class FileGenerator {
   const FileDescriptor* file_;
   const FileDescriptor* file_;
   const Options options_;
   const Options options_;
 
 
+  SCCAnalyzer scc_analyzer_;
+
   // Contains the post-order walk of all the messages (and child messages) in
   // 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.
   // this file. If you need a pre-order walk just reverse iterate.
   std::vector<MessageGenerator*> message_generators_;
   std::vector<MessageGenerator*> message_generators_;

Some files were not shown because too many files changed in this diff