Переглянути джерело

Down Integrate Internal Changes

Rafi Kamal 5 роки тому
батько
коміт
58d4420e2d
100 змінених файлів з 2227 додано та 1463 видалено
  1. 0 1
      BUILD
  2. 0 2
      cmake/libprotobuf.cmake
  3. 30 0
      conformance/ConformanceJava.java
  4. 29 0
      conformance/ConformanceJavaLite.java
  5. 282 257
      conformance/binary_json_conformance_suite.cc
  6. 12 3
      conformance/binary_json_conformance_suite.h
  7. 2 2
      conformance/conformance.proto
  8. 20 14
      conformance/conformance_cpp.cc
  9. 0 3
      conformance/conformance_python.py
  10. 27 34
      conformance/conformance_test.cc
  11. 4 6
      conformance/conformance_test.h
  12. 19 24
      conformance/conformance_test_runner.cc
  13. 1 0
      conformance/failure_list_js.txt
  14. 22 20
      conformance/text_format_conformance_suite.cc
  15. 1 1
      csharp/src/Google.Protobuf.Conformance/Conformance.cs
  16. BIN
      csharp/src/Google.Protobuf.Test/testprotos.pb
  17. 1 1
      csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
  18. 7 3
      java/core/src/main/java/com/google/protobuf/ByteString.java
  19. 1 1
      java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
  20. 1 2
      java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
  21. 1 1
      java/core/src/main/java/com/google/protobuf/MessageLiteToString.java
  22. 3 5
      java/core/src/main/java/com/google/protobuf/MessageSchema.java
  23. 22 6
      java/core/src/main/java/com/google/protobuf/RopeByteString.java
  24. 5 4
      java/core/src/test/java/com/google/protobuf/RopeByteStringTest.java
  25. 25 0
      java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
  26. 3 0
      java/lite/proguard.pgcfg
  27. 3 3
      js/binary/decoder.js
  28. 1 1
      js/binary/encoder.js
  29. 3 3
      js/binary/proto_test.js
  30. 4 4
      js/binary/reader.js
  31. 1 1
      js/binary/utils.js
  32. 3 3
      js/binary/utils_test.js
  33. 1 1
      js/binary/writer.js
  34. 5 5
      js/map.js
  35. 5 5
      js/message.js
  36. 1 1
      js/message_test.js
  37. 1 1
      js/proto3_test.js
  38. 1 1
      objectivec/google/protobuf/FieldMask.pbobjc.h
  39. 1 5
      python/google/protobuf/descriptor.py
  40. 10 2
      python/google/protobuf/internal/enum_type_wrapper.py
  41. 8 0
      python/google/protobuf/internal/json_format_test.py
  42. 751 451
      python/google/protobuf/internal/reflection_test.py
  43. 25 1
      python/google/protobuf/internal/text_format_test.py
  44. 20 5
      python/google/protobuf/json_format.py
  45. 0 4
      python/google/protobuf/pyext/message.cc
  46. 13 3
      python/google/protobuf/text_format.py
  47. 0 2
      src/Makefile.am
  48. 6 3
      src/google/protobuf/any.pb.cc
  49. 1 2
      src/google/protobuf/any.pb.h
  50. 29 15
      src/google/protobuf/api.pb.cc
  51. 3 3
      src/google/protobuf/api.pb.h
  52. 5 32
      src/google/protobuf/arena.cc
  53. 7 3
      src/google/protobuf/arena.h
  54. 64 3
      src/google/protobuf/arena_impl.h
  55. 1 0
      src/google/protobuf/arenastring.h
  56. 1 1
      src/google/protobuf/arenastring_unittest.cc
  57. 9 5
      src/google/protobuf/compiler/command_line_interface.cc
  58. 2 0
      src/google/protobuf/compiler/command_line_interface.h
  59. 17 5
      src/google/protobuf/compiler/command_line_interface_unittest.cc
  60. 4 6
      src/google/protobuf/compiler/cpp/cpp_enum.cc
  61. 1 2
      src/google/protobuf/compiler/cpp/cpp_field.cc
  62. 0 4
      src/google/protobuf/compiler/cpp/cpp_file.cc
  63. 55 59
      src/google/protobuf/compiler/cpp/cpp_helpers.cc
  64. 16 3
      src/google/protobuf/compiler/cpp/cpp_helpers.h
  65. 21 19
      src/google/protobuf/compiler/cpp/cpp_message.cc
  66. 6 8
      src/google/protobuf/compiler/cpp/cpp_message_field.cc
  67. 2 2
      src/google/protobuf/compiler/cpp/cpp_string_field.cc
  68. 1 0
      src/google/protobuf/compiler/csharp/csharp_helpers.h
  69. 1 0
      src/google/protobuf/compiler/csharp/csharp_names.h
  70. 1 2
      src/google/protobuf/compiler/main.cc
  71. 1 0
      src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
  72. 43 15
      src/google/protobuf/compiler/plugin.pb.cc
  73. 10 10
      src/google/protobuf/compiler/plugin.pb.h
  74. 1 0
      src/google/protobuf/descriptor.cc
  75. 236 120
      src/google/protobuf/descriptor.pb.cc
  76. 60 60
      src/google/protobuf/descriptor.pb.h
  77. 6 6
      src/google/protobuf/descriptor_unittest.cc
  78. 1 1
      src/google/protobuf/duration.pb.cc
  79. 1 1
      src/google/protobuf/duration.pb.h
  80. 0 1
      src/google/protobuf/dynamic_message.h
  81. 1 5
      src/google/protobuf/empty.pb.cc
  82. 1 1
      src/google/protobuf/empty.pb.h
  83. 9 9
      src/google/protobuf/extension_set.cc
  84. 5 6
      src/google/protobuf/extension_set.h
  85. 4 2
      src/google/protobuf/field_mask.pb.cc
  86. 1 1
      src/google/protobuf/field_mask.pb.h
  87. 1 1
      src/google/protobuf/field_mask.proto
  88. 13 13
      src/google/protobuf/generated_message_reflection.cc
  89. 5 2
      src/google/protobuf/generated_message_util.h
  90. 2 2
      src/google/protobuf/implicit_weak_message.h
  91. 6 67
      src/google/protobuf/io/strtod.cc
  92. 4 3
      src/google/protobuf/map_entry_lite.h
  93. 15 0
      src/google/protobuf/map_field.h
  94. 7 2
      src/google/protobuf/map_field_lite.h
  95. 1 1
      src/google/protobuf/map_type_handler.h
  96. 19 21
      src/google/protobuf/message.cc
  97. 56 28
      src/google/protobuf/message.h
  98. 52 3
      src/google/protobuf/message_lite.cc
  99. 38 5
      src/google/protobuf/message_lite.h
  100. 0 8
      src/google/protobuf/parse_context.cc

+ 0 - 1
BUILD

@@ -190,7 +190,6 @@ cc_library(
         "src/google/protobuf/service.cc",
         "src/google/protobuf/source_context.pb.cc",
         "src/google/protobuf/struct.pb.cc",
-        "src/google/protobuf/stubs/mathlimits.cc",
         "src/google/protobuf/stubs/substitute.cc",
         "src/google/protobuf/text_format.cc",
         "src/google/protobuf/timestamp.pb.cc",

+ 0 - 2
cmake/libprotobuf.cmake

@@ -23,7 +23,6 @@ set(libprotobuf_files
   ${protobuf_source_dir}/src/google/protobuf/service.cc
   ${protobuf_source_dir}/src/google/protobuf/source_context.pb.cc
   ${protobuf_source_dir}/src/google/protobuf/struct.pb.cc
-  ${protobuf_source_dir}/src/google/protobuf/stubs/mathlimits.cc
   ${protobuf_source_dir}/src/google/protobuf/stubs/substitute.cc
   ${protobuf_source_dir}/src/google/protobuf/text_format.cc
   ${protobuf_source_dir}/src/google/protobuf/timestamp.pb.cc
@@ -77,7 +76,6 @@ set(libprotobuf_includes
   ${protobuf_source_dir}/src/google/protobuf/service.h
   ${protobuf_source_dir}/src/google/protobuf/source_context.pb.h
   ${protobuf_source_dir}/src/google/protobuf/struct.pb.h
-  ${protobuf_source_dir}/src/google/protobuf/stubs/mathlimits.h
   ${protobuf_source_dir}/src/google/protobuf/stubs/substitute.h
   ${protobuf_source_dir}/src/google/protobuf/text_format.h
   ${protobuf_source_dir}/src/google/protobuf/timestamp.pb.h

+ 30 - 0
conformance/ConformanceJava.java

@@ -1,3 +1,33 @@
+// 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.
+
 import com.google.protobuf.AbstractMessage;
 import com.google.protobuf.ByteString;
 import com.google.protobuf.CodedInputStream;

+ 29 - 0
conformance/ConformanceJavaLite.java

@@ -1,3 +1,32 @@
+// 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.
 
 import com.google.protobuf.conformance.Conformance;
 import com.google.protobuf.InvalidProtocolBufferException;

+ 282 - 257
conformance/binary_json_conformance_suite.cc

@@ -29,18 +29,18 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "binary_json_conformance_suite.h"
-#include "conformance_test.h"
-#include "third_party/jsoncpp/json.h"
-
-#include <google/protobuf/test_messages_proto3.pb.h>
-#include <google/protobuf/test_messages_proto2.pb.h>
 
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/text_format.h>
+#include <google/protobuf/wire_format_lite.h>
 #include <google/protobuf/util/json_util.h>
 #include <google/protobuf/util/type_resolver_util.h>
-#include <google/protobuf/wire_format_lite.h>
+#include "third_party/jsoncpp/json.h"
+#include "conformance_test.h"
+#include <google/protobuf/test_messages_proto2.pb.h>
+#include <google/protobuf/test_messages_proto3.pb.h>
+#include <google/protobuf/stubs/status.h>
+
+namespace proto2_messages = protobuf_test_messages::proto2;
 
 using conformance::ConformanceRequest;
 using conformance::ConformanceResponse;
@@ -48,11 +48,11 @@ using conformance::WireFormat;
 using google::protobuf::Descriptor;
 using google::protobuf::FieldDescriptor;
 using google::protobuf::Message;
-using google::protobuf::internal::WireFormatLite;
 using google::protobuf::TextFormat;
+using google::protobuf::internal::WireFormatLite;
 using google::protobuf::util::NewTypeResolverForDescriptorPool;
+using proto2_messages::TestAllTypesProto2;
 using protobuf_test_messages::proto3::TestAllTypesProto3;
-using protobuf_test_messages::proto2::TestAllTypesProto2;
 using std::string;
 
 namespace {
@@ -249,10 +249,9 @@ const FieldDescriptor* GetFieldForType(FieldDescriptor::Type type,
   if (packed == Packed::FALSE) {
     packed_string = "Unpacked ";
   }
-  GOOGLE_LOG(FATAL) << "Couldn't find field with type: "
-                    << repeated_string.c_str() << packed_string.c_str()
-                    << FieldDescriptor::TypeName(type) << " for "
-                    << proto_string.c_str();
+  GOOGLE_LOG(FATAL) << "Couldn't find field with type: " << repeated_string.c_str()
+             << packed_string.c_str() << FieldDescriptor::TypeName(type)
+             << " for " << proto_string.c_str();
   return nullptr;
 }
 
@@ -275,9 +274,9 @@ const FieldDescriptor* GetFieldForMapType(FieldDescriptor::Type key_type,
 
   const string proto_string = is_proto3 ? "Proto3" : "Proto2";
   GOOGLE_LOG(FATAL) << "Couldn't find map field with type: "
-                    << FieldDescriptor::TypeName(key_type) << " and "
-                    << FieldDescriptor::TypeName(key_type) << " for "
-                    << proto_string.c_str();
+             << FieldDescriptor::TypeName(key_type) << " and "
+             << FieldDescriptor::TypeName(key_type) << " for "
+             << proto_string.c_str();
   return nullptr;
 }
 
@@ -295,8 +294,8 @@ const FieldDescriptor* GetFieldForOneofType(FieldDescriptor::Type type,
 
   const string proto_string = is_proto3 ? "Proto3" : "Proto2";
   GOOGLE_LOG(FATAL) << "Couldn't find oneof field with type: "
-                    << FieldDescriptor::TypeName(type) << " for "
-                    << proto_string.c_str();
+             << FieldDescriptor::TypeName(type) << " for "
+             << proto_string.c_str();
   return nullptr;
 }
 
@@ -364,9 +363,8 @@ bool BinaryAndJsonConformanceSuite::ParseJsonResponse(
   }
 
   if (!test_message->ParseFromString(binary_protobuf)) {
-    GOOGLE_LOG(FATAL)
-        << "INTERNAL ERROR: internal JSON->protobuf transcode "
-        << "yielded unparseable proto.";
+    GOOGLE_LOG(FATAL) << "INTERNAL ERROR: internal JSON->protobuf transcode "
+               << "yielded unparseable proto.";
     return false;
   }
 
@@ -385,10 +383,11 @@ bool BinaryAndJsonConformanceSuite::ParseResponse(
   switch (response.result_case()) {
     case ConformanceResponse::kProtobufPayload: {
       if (requested_output != conformance::PROTOBUF) {
-        ReportFailure(
-            test_name, level, request, response,
-            StrCat("Test was asked for ", WireFormatToString(requested_output),
-                   " output but provided PROTOBUF instead.").c_str());
+        ReportFailure(test_name, level, request, response,
+                      StrCat("Test was asked for ",
+                                   WireFormatToString(requested_output),
+                                   " output but provided PROTOBUF instead.")
+                          .c_str());
         return false;
       }
 
@@ -403,10 +402,11 @@ bool BinaryAndJsonConformanceSuite::ParseResponse(
 
     case ConformanceResponse::kJsonPayload: {
       if (requested_output != conformance::JSON) {
-        ReportFailure(
-            test_name, level, request, response,
-            StrCat("Test was asked for ", WireFormatToString(requested_output),
-                   " output but provided JSON instead.").c_str());
+        ReportFailure(test_name, level, request, response,
+                      StrCat("Test was asked for ",
+                                   WireFormatToString(requested_output),
+                                   " output but provided JSON instead.")
+                          .c_str());
         return false;
       }
 
@@ -420,8 +420,8 @@ bool BinaryAndJsonConformanceSuite::ParseResponse(
     }
 
     default:
-      GOOGLE_LOG(FATAL) << test_name << ": unknown payload type: "
-                        << response.result_case();
+      GOOGLE_LOG(FATAL) << test_name
+                 << ": unknown payload type: " << response.result_case();
   }
 
   return true;
@@ -440,10 +440,9 @@ void BinaryAndJsonConformanceSuite::ExpectParseFailureForProtoWithProtoVersion (
 
   const ConformanceRequest& request = setting.GetRequest();
   ConformanceResponse response;
-  string effective_test_name =
-      StrCat(setting.ConformanceLevelToString(level),
-             (is_proto3 ? ".Proto3" : ".Proto2"),
-             ".ProtobufInput.", test_name);
+  string effective_test_name = StrCat(
+      setting.ConformanceLevelToString(level),
+      (is_proto3 ? ".Proto3" : ".Proto2"), ".ProtobufInput.", test_name);
 
   RunTest(effective_test_name, request, &response);
   if (response.result_case() == ConformanceResponse::kParseError) {
@@ -574,8 +573,7 @@ void BinaryAndJsonConformanceSuite::RunValidJsonTestWithValidator(
   ConformanceResponse response;
   string effective_test_name =
       StrCat(setting.ConformanceLevelToString(level),
-             ".Proto3.JsonInput.",
-             test_name, ".Validator");
+                   ".Proto3.JsonInput.", test_name, ".Validator");
 
   RunTest(effective_test_name, request, &response);
 
@@ -617,9 +615,8 @@ void BinaryAndJsonConformanceSuite::ExpectParseFailureForJson(
       prototype, test_name, input_json);
   const ConformanceRequest& request = setting.GetRequest();
   ConformanceResponse response;
-  string effective_test_name =
-      StrCat(setting.ConformanceLevelToString(level),
-             ".Proto3.JsonInput.", test_name);
+  string effective_test_name = StrCat(
+      setting.ConformanceLevelToString(level), ".Proto3.JsonInput.", test_name);
 
   RunTest(effective_test_name, request, &response);
   if (response.result_case() == ConformanceResponse::kParseError) {
@@ -635,9 +632,8 @@ void BinaryAndJsonConformanceSuite::ExpectParseFailureForJson(
 void BinaryAndJsonConformanceSuite::ExpectSerializeFailureForJson(
     const string& test_name, ConformanceLevel level, const string& text_format) {
   TestAllTypesProto3 payload_message;
-  GOOGLE_CHECK(
-      TextFormat::ParseFromString(text_format, &payload_message))
-          << "Failed to parse: " << text_format;
+  GOOGLE_CHECK(TextFormat::ParseFromString(text_format, &payload_message))
+      << "Failed to parse: " << text_format;
 
   TestAllTypesProto3 prototype;
   ConformanceRequestSetting setting(
@@ -646,9 +642,8 @@ void BinaryAndJsonConformanceSuite::ExpectSerializeFailureForJson(
       prototype, test_name, payload_message.SerializeAsString());
   const ConformanceRequest& request = setting.GetRequest();
   ConformanceResponse response;
-  string effective_test_name =
-      StrCat(setting.ConformanceLevelToString(level),
-             ".", test_name, ".JsonOutput");
+  string effective_test_name = StrCat(
+      setting.ConformanceLevelToString(level), ".", test_name, ".JsonOutput");
 
   RunTest(effective_test_name, request, &response);
   if (response.result_case() == ConformanceResponse::kSerializeError) {
@@ -772,11 +767,12 @@ void BinaryAndJsonConformanceSuite::TestValidDataForType(
       test_message->MergeFromString(expected_proto);
       string text = test_message->DebugString();
 
-      RunValidProtobufTest(StrCat("ValidDataScalar", type_name, "[", i, "]"),
-                           REQUIRED, proto, text, is_proto3);
+      RunValidProtobufTest(
+          StrCat("ValidDataScalar", type_name, "[", i, "]"), REQUIRED,
+          proto, text, is_proto3);
       RunValidBinaryProtobufTest(
-          StrCat("ValidDataScalarBinary", type_name, "[", i, "]"), RECOMMENDED,
-          proto, expected_proto, is_proto3);
+          StrCat("ValidDataScalarBinary", type_name, "[", i, "]"),
+          RECOMMENDED, proto, expected_proto, is_proto3);
     }
 
     // Test repeated data for singular fields.
@@ -856,11 +852,11 @@ void BinaryAndJsonConformanceSuite::TestValidDataForType(
 
       // Ensures both packed and unpacked data can be parsed.
       RunValidProtobufTest(
-          StrCat("ValidDataRepeated", type_name, ".UnpackedInput"), REQUIRED,
-          default_proto_unpacked, text, is_proto3);
+          StrCat("ValidDataRepeated", type_name, ".UnpackedInput"),
+          REQUIRED, default_proto_unpacked, text, is_proto3);
       RunValidProtobufTest(
-          StrCat("ValidDataRepeated", type_name, ".PackedInput"), REQUIRED,
-          default_proto_packed, text, is_proto3);
+          StrCat("ValidDataRepeated", type_name, ".PackedInput"),
+          REQUIRED, default_proto_packed, text, is_proto3);
 
       // proto2 should encode as unpacked by default and proto3 should encode as
       // packed by default.
@@ -868,26 +864,29 @@ void BinaryAndJsonConformanceSuite::TestValidDataForType(
                                   ? default_proto_packed_expected
                                   : default_proto_unpacked_expected;
       RunValidBinaryProtobufTest(StrCat("ValidDataRepeated", type_name,
-                                        ".UnpackedInput.DefaultOutput"),
+                                              ".UnpackedInput.DefaultOutput"),
                                  RECOMMENDED, default_proto_unpacked,
                                  expected_proto, is_proto3);
-      RunValidBinaryProtobufTest(
-          StrCat("ValidDataRepeated", type_name, ".PackedInput.DefaultOutput"),
-          RECOMMENDED, default_proto_packed, expected_proto, is_proto3);
-      RunValidBinaryProtobufTest(
-          StrCat("ValidDataRepeated", type_name, ".UnpackedInput.PackedOutput"),
-          RECOMMENDED, packed_proto_unpacked, packed_proto_expected, is_proto3);
-      RunValidBinaryProtobufTest(
-          StrCat("ValidDataRepeated", type_name, ".PackedInput.PackedOutput"),
-          RECOMMENDED, packed_proto_packed, packed_proto_expected, is_proto3);
       RunValidBinaryProtobufTest(StrCat("ValidDataRepeated", type_name,
-                                        ".UnpackedInput.UnpackedOutput"),
+                                              ".PackedInput.DefaultOutput"),
+                                 RECOMMENDED, default_proto_packed,
+                                 expected_proto, is_proto3);
+      RunValidBinaryProtobufTest(StrCat("ValidDataRepeated", type_name,
+                                              ".UnpackedInput.PackedOutput"),
+                                 RECOMMENDED, packed_proto_unpacked,
+                                 packed_proto_expected, is_proto3);
+      RunValidBinaryProtobufTest(StrCat("ValidDataRepeated", type_name,
+                                              ".PackedInput.PackedOutput"),
+                                 RECOMMENDED, packed_proto_packed,
+                                 packed_proto_expected, is_proto3);
+      RunValidBinaryProtobufTest(StrCat("ValidDataRepeated", type_name,
+                                              ".UnpackedInput.UnpackedOutput"),
                                  RECOMMENDED, unpacked_proto_unpacked,
                                  unpacked_proto_expected, is_proto3);
-      RunValidBinaryProtobufTest(
-          StrCat("ValidDataRepeated", type_name, ".PackedInput.UnpackedOutput"),
-          RECOMMENDED, unpacked_proto_packed, unpacked_proto_expected,
-          is_proto3);
+      RunValidBinaryProtobufTest(StrCat("ValidDataRepeated", type_name,
+                                              ".PackedInput.UnpackedOutput"),
+                                 RECOMMENDED, unpacked_proto_packed,
+                                 unpacked_proto_expected, is_proto3);
     } else {
       string proto;
       string expected_proto;
@@ -900,8 +899,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForType(
       test_message->MergeFromString(expected_proto);
       string text = test_message->DebugString();
 
-      RunValidProtobufTest(StrCat("ValidDataRepeated", type_name), REQUIRED,
-                           proto, text, is_proto3);
+      RunValidProtobufTest(StrCat("ValidDataRepeated", type_name),
+                           REQUIRED, proto, text, is_proto3);
     }
   }
 }
@@ -976,9 +975,9 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
       std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
       test_message->MergeFromString(proto);
       string text = test_message->DebugString();
-      RunValidProtobufTest(
-          StrCat("ValidDataMap", key_type_name, value_type_name, ".Default"),
-          REQUIRED, proto, text, is_proto3);
+      RunValidProtobufTest(StrCat("ValidDataMap", key_type_name,
+                                        value_type_name, ".Default"),
+                           REQUIRED, proto, text, is_proto3);
     }
 
     {
@@ -990,7 +989,7 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
       test_message->MergeFromString(proto);
       string text = test_message->DebugString();
       RunValidProtobufTest(StrCat("ValidDataMap", key_type_name,
-                                  value_type_name, ".MissingDefault"),
+                                        value_type_name, ".MissingDefault"),
                            REQUIRED, proto, text, is_proto3);
     }
 
@@ -1002,9 +1001,9 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
       std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
       test_message->MergeFromString(proto);
       string text = test_message->DebugString();
-      RunValidProtobufTest(
-          StrCat("ValidDataMap", key_type_name, value_type_name, ".NonDefault"),
-          REQUIRED, proto, text, is_proto3);
+      RunValidProtobufTest(StrCat("ValidDataMap", key_type_name,
+                                        value_type_name, ".NonDefault"),
+                           REQUIRED, proto, text, is_proto3);
     }
 
     {
@@ -1015,9 +1014,9 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
       std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
       test_message->MergeFromString(proto);
       string text = test_message->DebugString();
-      RunValidProtobufTest(
-          StrCat("ValidDataMap", key_type_name, value_type_name, ".Unordered"),
-          REQUIRED, proto, text, is_proto3);
+      RunValidProtobufTest(StrCat("ValidDataMap", key_type_name,
+                                        value_type_name, ".Unordered"),
+                           REQUIRED, proto, text, is_proto3);
     }
 
     {
@@ -1033,7 +1032,7 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
       test_message->MergeFromString(proto2);
       string text = test_message->DebugString();
       RunValidProtobufTest(StrCat("ValidDataMap", key_type_name,
-                                  value_type_name, ".DuplicateKey"),
+                                        value_type_name, ".DuplicateKey"),
                            REQUIRED, proto, text, is_proto3);
     }
 
@@ -1045,9 +1044,10 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
       std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
       test_message->MergeFromString(proto);
       string text = test_message->DebugString();
-      RunValidProtobufTest(StrCat("ValidDataMap", key_type_name,
-                                  value_type_name, ".DuplicateKeyInMapEntry"),
-                           REQUIRED, proto, text, is_proto3);
+      RunValidProtobufTest(
+          StrCat("ValidDataMap", key_type_name, value_type_name,
+                       ".DuplicateKeyInMapEntry"),
+          REQUIRED, proto, text, is_proto3);
     }
 
     {
@@ -1058,9 +1058,10 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
       std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
       test_message->MergeFromString(proto);
       string text = test_message->DebugString();
-      RunValidProtobufTest(StrCat("ValidDataMap", key_type_name,
-                                  value_type_name, ".DuplicateValueInMapEntry"),
-                           REQUIRED, proto, text, is_proto3);
+      RunValidProtobufTest(
+          StrCat("ValidDataMap", key_type_name, value_type_name,
+                       ".DuplicateValueInMapEntry"),
+          REQUIRED, proto, text, is_proto3);
     }
   }
 }
@@ -1123,8 +1124,9 @@ void BinaryAndJsonConformanceSuite::TestValidDataForOneofType(
       test_message->MergeFromString(proto);
       string text = test_message->DebugString();
 
-      RunValidProtobufTest(StrCat("ValidDataOneof", type_name, ".DefaultValue"),
-                           REQUIRED, proto, text, is_proto3);
+      RunValidProtobufTest(
+          StrCat("ValidDataOneof", type_name, ".DefaultValue"), REQUIRED,
+          proto, text, is_proto3);
       RunValidBinaryProtobufTest(
           StrCat("ValidDataOneofBinary", type_name, ".DefaultValue"),
           RECOMMENDED, proto, proto, is_proto3);
@@ -1138,8 +1140,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForOneofType(
       string text = test_message->DebugString();
 
       RunValidProtobufTest(
-          StrCat("ValidDataOneof", type_name, ".NonDefaultValue"), REQUIRED,
-          proto, text, is_proto3);
+          StrCat("ValidDataOneof", type_name, ".NonDefaultValue"),
+          REQUIRED, proto, text, is_proto3);
       RunValidBinaryProtobufTest(
           StrCat("ValidDataOneofBinary", type_name, ".NonDefaultValue"),
           RECOMMENDED, proto, proto, is_proto3);
@@ -1153,11 +1155,11 @@ void BinaryAndJsonConformanceSuite::TestValidDataForOneofType(
       test_message->MergeFromString(expected_proto);
       string text = test_message->DebugString();
 
-      RunValidProtobufTest(
-          StrCat("ValidDataOneof", type_name, ".MultipleValuesForSameField"),
-          REQUIRED, proto, text, is_proto3);
-      RunValidBinaryProtobufTest(StrCat("ValidDataOneofBinary", type_name,
+      RunValidProtobufTest(StrCat("ValidDataOneof", type_name,
                                         ".MultipleValuesForSameField"),
+                           REQUIRED, proto, text, is_proto3);
+      RunValidBinaryProtobufTest(StrCat("ValidDataOneofBinary", type_name,
+                                              ".MultipleValuesForSameField"),
                                  RECOMMENDED, proto, expected_proto, is_proto3);
     }
 
@@ -1180,11 +1182,12 @@ void BinaryAndJsonConformanceSuite::TestValidDataForOneofType(
       string text = test_message->DebugString();
 
       RunValidProtobufTest(StrCat("ValidDataOneof", type_name,
-                                  ".MultipleValuesForDifferentField"),
-                           REQUIRED, proto, text, is_proto3);
-      RunValidBinaryProtobufTest(StrCat("ValidDataOneofBinary", type_name,
                                         ".MultipleValuesForDifferentField"),
-                                 RECOMMENDED, proto, expected_proto, is_proto3);
+                           REQUIRED, proto, text, is_proto3);
+      RunValidBinaryProtobufTest(
+          StrCat("ValidDataOneofBinary", type_name,
+                       ".MultipleValuesForDifferentField"),
+          RECOMMENDED, proto, expected_proto, is_proto3);
     }
   }
 }
@@ -1292,7 +1295,7 @@ void BinaryAndJsonConformanceSuite::TestUnknownMessage(
 
 void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
   // Hack to get the list of test failures based on whether
-  // GOOGLE3_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER is enabled or not.
+  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER is enabled or not.
   conformance::FailureSet failure_set;
   ConformanceRequest req;
   ConformanceResponse res;
@@ -1363,6 +1366,8 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
                            {varint(kInt32Min), varint(kInt32Min)},
                            {varint(1LL << 33), varint(0)},
                            {varint((1LL << 33) - 1), varint(-1)},
+                           {varint(kInt64Max), varint(-1)},
+                           {varint(kInt64Min + 1), varint(1)},
                        });
   TestValidDataForType(
       FieldDescriptor::TYPE_UINT32,
@@ -1373,7 +1378,10 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
           {longvarint(12345, 7), varint(12345)},
           {varint(kUint32Max), varint(kUint32Max)},  // UINT32_MAX
           {varint(1LL << 33), varint(0)},
+          {varint((1LL << 33) + 1), varint(1)},
           {varint((1LL << 33) - 1), varint((1LL << 32) - 1)},
+          {varint(kInt64Max), varint((1LL << 32) - 1)},
+          {varint(kInt64Min + 1), varint(1)},
       });
   TestValidDataForType(FieldDescriptor::TYPE_FIXED64,
                        {
@@ -1407,7 +1415,11 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
                        {
                            {varint(0), varint(0)},
                            {varint(1), varint(1)},
+                           {varint(-1), varint(1)},
                            {varint(12345678), varint(1)},
+                           {varint(1LL << 33), varint(1)},
+                           {varint(kInt64Max), varint(1)},
+                           {varint(kInt64Min), varint(1)},
                        });
   TestValidDataForType(FieldDescriptor::TYPE_SINT32,
                        {
@@ -1415,6 +1427,7 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
                            {zz32(12345), zz32(12345)},
                            {zz32(kInt32Max), zz32(kInt32Max)},
                            {zz32(kInt32Min), zz32(kInt32Min)},
+                           {zz64(kInt32Max + 2LL), zz32(1)},
                        });
   TestValidDataForType(FieldDescriptor::TYPE_SINT64,
                        {
@@ -1438,15 +1451,19 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
   TestValidDataForType(FieldDescriptor::TYPE_BYTES,
                        {
                            {delim(""), delim("")},
+                           {delim("Hello world!"), delim("Hello world!")},
                            {delim("\x01\x02"), delim("\x01\x02")},
                            {delim("\xfb"), delim("\xfb")},
                        });
-  TestValidDataForType(FieldDescriptor::TYPE_ENUM, {
-                                                       {varint(0), varint(0)},
-                                                       {varint(1), varint(1)},
-                                                       {varint(2), varint(2)},
-                                                       {varint(-1), varint(-1)},
-                                                   });
+  TestValidDataForType(FieldDescriptor::TYPE_ENUM,
+                       {
+                           {varint(0), varint(0)},
+                           {varint(1), varint(1)},
+                           {varint(2), varint(2)},
+                           {varint(-1), varint(-1)},
+                           {varint(kInt64Max), varint(-1)},
+                           {varint(kInt64Min + 1), varint(1)},
+                       });
   TestValidDataForRepeatedScalarMessage();
   TestValidDataForType(
       FieldDescriptor::TYPE_MESSAGE,
@@ -1508,13 +1525,74 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
   // TODO(haberman):
   // TestValidDataForType(FieldDescriptor::TYPE_GROUP
 
+  // Unknown fields.
+  {
+    TestAllTypesProto3 messageProto3;
+    TestAllTypesProto2 messageProto2;
+    // TODO(yilunchong): update this behavior when unknown field's behavior
+    // changed in open source. Also delete
+    // Required.Proto3.ProtobufInput.UnknownVarint.ProtobufOutput
+    // from failure list of python_cpp python java
+    TestUnknownMessage(messageProto3, true);
+    TestUnknownMessage(messageProto2, false);
+  }
+
+  RunJsonTests();
+}
+
+void BinaryAndJsonConformanceSuite::RunJsonTests() {
   RunValidJsonTest("HelloWorld", REQUIRED,
                    "{\"optionalString\":\"Hello, World!\"}",
                    "optional_string: 'Hello, World!'");
 
   // NOTE: The spec for JSON support is still being sorted out, these may not
   // all be correct.
-  // Test field name conventions.
+
+  RunJsonTestsForFieldNameConvention();
+  RunJsonTestsForNonRepeatedTypes();
+  RunJsonTestsForRepeatedTypes();
+  RunJsonTestsForNullTypes();
+  RunJsonTestsForWrapperTypes();
+  RunJsonTestsForFieldMask();
+  RunJsonTestsForStruct();
+  RunJsonTestsForValue();
+  RunJsonTestsForAny();
+
+  RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonNumber", REQUIRED,
+                                R"({
+        "unknown": 1
+      })",
+                                "");
+  RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonString", REQUIRED,
+                                R"({
+        "unknown": "a"
+      })",
+                                "");
+  RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonTrue", REQUIRED,
+                                R"({
+        "unknown": true
+      })",
+                                "");
+  RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonFalse", REQUIRED,
+                                R"({
+        "unknown": false
+      })",
+                                "");
+  RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonNull", REQUIRED,
+                                R"({
+        "unknown": null
+      })",
+                                "");
+  RunValidJsonIgnoreUnknownTest("IgnoreUnknownJsonObject", REQUIRED,
+                                R"({
+        "unknown": {"a": 1}
+      })",
+                                "");
+
+  ExpectParseFailureForJson("RejectTopLevelNull", REQUIRED, "null");
+}
+
+void BinaryAndJsonConformanceSuite::RunJsonTestsForFieldNameConvention() {
   RunValidJsonTest(
       "FieldNameInSnakeCase", REQUIRED,
       R"({
@@ -1769,7 +1847,9 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
             value.isMember("fieldName17") &&
             value.isMember("FieldName18");
       });
+}
 
+void BinaryAndJsonConformanceSuite::RunJsonTestsForNonRepeatedTypes() {
   // Integer fields.
   RunValidJsonTest(
       "Int32FieldMaxValue", REQUIRED,
@@ -2254,71 +2334,6 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
       "OneofZeroEnum", RECOMMENDED,
       R"({"oneofEnum":"FOO"})", "oneof_enum: FOO");
 
-  // Repeated fields.
-  RunValidJsonTest(
-      "PrimitiveRepeatedField", REQUIRED,
-      R"({"repeatedInt32": [1, 2, 3, 4]})",
-      "repeated_int32: [1, 2, 3, 4]");
-  RunValidJsonTest(
-      "EnumRepeatedField", REQUIRED,
-      R"({"repeatedNestedEnum": ["FOO", "BAR", "BAZ"]})",
-      "repeated_nested_enum: [FOO, BAR, BAZ]");
-  RunValidJsonTest(
-      "StringRepeatedField", REQUIRED,
-      R"({"repeatedString": ["Hello", "world"]})",
-      R"(repeated_string: ["Hello", "world"])");
-  RunValidJsonTest(
-      "BytesRepeatedField", REQUIRED,
-      R"({"repeatedBytes": ["AAEC", "AQI="]})",
-      R"(repeated_bytes: ["\x00\x01\x02", "\x01\x02"])");
-  RunValidJsonTest(
-      "MessageRepeatedField", REQUIRED,
-      R"({"repeatedNestedMessage": [{"a": 1234}, {"a": 5678}]})",
-      "repeated_nested_message: {a: 1234}"
-      "repeated_nested_message: {a: 5678}");
-
-  // Repeated field elements are of incorrect type.
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingIntegersGotBool", REQUIRED,
-      R"({"repeatedInt32": [1, false, 3, 4]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingIntegersGotString", REQUIRED,
-      R"({"repeatedInt32": [1, 2, "name", 4]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingIntegersGotMessage", REQUIRED,
-      R"({"repeatedInt32": [1, 2, 3, {"a": 4}]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingStringsGotInt", REQUIRED,
-      R"({"repeatedString": ["1", 2, "3", "4"]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingStringsGotBool", REQUIRED,
-      R"({"repeatedString": ["1", "2", false, "4"]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingStringsGotMessage", REQUIRED,
-      R"({"repeatedString": ["1", 2, "3", {"a": 4}]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingMessagesGotInt", REQUIRED,
-      R"({"repeatedNestedMessage": [{"a": 1}, 2]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingMessagesGotBool", REQUIRED,
-      R"({"repeatedNestedMessage": [{"a": 1}, false]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingMessagesGotString", REQUIRED,
-      R"({"repeatedNestedMessage": [{"a": 1}, "2"]})");
-  // Trailing comma in the repeated field is not allowed.
-  ExpectParseFailureForJson(
-      "RepeatedFieldTrailingComma", RECOMMENDED,
-      R"({"repeatedInt32": [1, 2, 3, 4,]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldTrailingCommaWithSpace", RECOMMENDED,
-      "{\"repeatedInt32\": [1, 2, 3, 4 ,]}");
-  ExpectParseFailureForJson(
-      "RepeatedFieldTrailingCommaWithSpaceCommaSpace", RECOMMENDED,
-      "{\"repeatedInt32\": [1, 2, 3, 4 , ]}");
-  ExpectParseFailureForJson(
-      "RepeatedFieldTrailingCommaWithNewlines", RECOMMENDED,
-      "{\"repeatedInt32\": [\n  1,\n  2,\n  3,\n  4,\n]}");
-
   // Map fields.
   RunValidJsonTest(
       "Int32MapField", REQUIRED,
@@ -2392,6 +2407,77 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
       R"({"mapBoolBool": {"tr\u0075e": true}})",
       "map_bool_bool: {key: true value: true}");
 
+  // http://www.rfc-editor.org/rfc/rfc7159.txt says strings have to use double
+  // quotes.
+  ExpectParseFailureForJson("StringFieldSingleQuoteKey", RECOMMENDED,
+                            R"({'optionalString': "Hello world!"})");
+  ExpectParseFailureForJson("StringFieldSingleQuoteValue", RECOMMENDED,
+                            R"({"optionalString": 'Hello world!'})");
+  ExpectParseFailureForJson("StringFieldSingleQuoteBoth", RECOMMENDED,
+                            R"({'optionalString': 'Hello world!'})");
+}
+
+void BinaryAndJsonConformanceSuite::RunJsonTestsForRepeatedTypes() {
+  // Repeated fields.
+  RunValidJsonTest("PrimitiveRepeatedField", REQUIRED,
+                   R"({"repeatedInt32": [1, 2, 3, 4]})",
+                   "repeated_int32: [1, 2, 3, 4]");
+  RunValidJsonTest("EnumRepeatedField", REQUIRED,
+                   R"({"repeatedNestedEnum": ["FOO", "BAR", "BAZ"]})",
+                   "repeated_nested_enum: [FOO, BAR, BAZ]");
+  RunValidJsonTest("StringRepeatedField", REQUIRED,
+                   R"({"repeatedString": ["Hello", "world"]})",
+                   R"(repeated_string: ["Hello", "world"])");
+  RunValidJsonTest("BytesRepeatedField", REQUIRED,
+                   R"({"repeatedBytes": ["AAEC", "AQI="]})",
+                   R"(repeated_bytes: ["\x00\x01\x02", "\x01\x02"])");
+  RunValidJsonTest("MessageRepeatedField", REQUIRED,
+                   R"({"repeatedNestedMessage": [{"a": 1234}, {"a": 5678}]})",
+                   "repeated_nested_message: {a: 1234}"
+                   "repeated_nested_message: {a: 5678}");
+
+  // Repeated field elements are of incorrect type.
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingIntegersGotBool", REQUIRED,
+      R"({"repeatedInt32": [1, false, 3, 4]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingIntegersGotString", REQUIRED,
+      R"({"repeatedInt32": [1, 2, "name", 4]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingIntegersGotMessage", REQUIRED,
+      R"({"repeatedInt32": [1, 2, 3, {"a": 4}]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingStringsGotInt", REQUIRED,
+      R"({"repeatedString": ["1", 2, "3", "4"]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingStringsGotBool", REQUIRED,
+      R"({"repeatedString": ["1", "2", false, "4"]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingStringsGotMessage", REQUIRED,
+      R"({"repeatedString": ["1", 2, "3", {"a": 4}]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingMessagesGotInt", REQUIRED,
+      R"({"repeatedNestedMessage": [{"a": 1}, 2]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingMessagesGotBool", REQUIRED,
+      R"({"repeatedNestedMessage": [{"a": 1}, false]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingMessagesGotString", REQUIRED,
+      R"({"repeatedNestedMessage": [{"a": 1}, "2"]})");
+  // Trailing comma in the repeated field is not allowed.
+  ExpectParseFailureForJson("RepeatedFieldTrailingComma", RECOMMENDED,
+                            R"({"repeatedInt32": [1, 2, 3, 4,]})");
+  ExpectParseFailureForJson("RepeatedFieldTrailingCommaWithSpace", RECOMMENDED,
+                            "{\"repeatedInt32\": [1, 2, 3, 4 ,]}");
+  ExpectParseFailureForJson("RepeatedFieldTrailingCommaWithSpaceCommaSpace",
+                            RECOMMENDED,
+                            "{\"repeatedInt32\": [1, 2, 3, 4 , ]}");
+  ExpectParseFailureForJson(
+      "RepeatedFieldTrailingCommaWithNewlines", RECOMMENDED,
+      "{\"repeatedInt32\": [\n  1,\n  2,\n  3,\n  4,\n]}");
+}
+
+void BinaryAndJsonConformanceSuite::RunJsonTestsForNullTypes() {
   // "null" is accepted for all fields types.
   RunValidJsonTest(
       "AllFieldAcceptNull", REQUIRED,
@@ -2451,36 +2537,12 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
   ExpectParseFailureForJson(
       "MapFieldValueIsNull", RECOMMENDED,
       R"({"mapInt32Int32": {"0": null}})");
+}
 
-  // http://www.rfc-editor.org/rfc/rfc7159.txt says strings have to use double
-  // quotes.
-  ExpectParseFailureForJson(
-      "StringFieldSingleQuoteKey", RECOMMENDED,
-      R"({'optionalString': "Hello world!"})");
-  ExpectParseFailureForJson(
-      "StringFieldSingleQuoteValue", RECOMMENDED,
-      R"({"optionalString": 'Hello world!'})");
-  ExpectParseFailureForJson(
-      "StringFieldSingleQuoteBoth", RECOMMENDED,
-      R"({'optionalString': 'Hello world!'})");
-
-  // Unknown fields.
-  {
-    TestAllTypesProto3 messageProto3;
-    TestAllTypesProto2 messageProto2;
-    //TODO(yilunchong): update this behavior when unknown field's behavior
-    // changed in open source. Also delete
-    // Required.Proto3.ProtobufInput.UnknownVarint.ProtobufOutput
-    // from failure list of python_cpp python java
-    TestUnknownMessage(messageProto3, true);
-    TestUnknownMessage(messageProto2, false);
-  }
-
-  // Wrapper types.
-  RunValidJsonTest(
-      "OptionalBoolWrapper", REQUIRED,
-      R"({"optionalBoolWrapper": false})",
-      "optional_bool_wrapper: {value: false}");
+void BinaryAndJsonConformanceSuite::RunJsonTestsForWrapperTypes() {
+  RunValidJsonTest("OptionalBoolWrapper", REQUIRED,
+                   R"({"optionalBoolWrapper": false})",
+                   "optional_bool_wrapper: {value: false}");
   RunValidJsonTest(
       "OptionalInt32Wrapper", REQUIRED,
       R"({"optionalInt32Wrapper": 0})",
@@ -2689,10 +2751,9 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
       })",
       "repeated_timestamp: {seconds: -62135596800}"
       "repeated_timestamp: {seconds: 253402300799 nanos: 999999999}");
-  RunValidJsonTest(
-      "TimestampLeap", REQUIRED,
-      R"({"optionalTimestamp": "1993-02-10T00:00:00.000Z"})",
-      "optional_timestamp: {seconds: 729302400}");
+  RunValidJsonTest("TimestampLeap", REQUIRED,
+                   R"({"optionalTimestamp": "1993-02-10T00:00:00.000Z"})",
+                   "optional_timestamp: {seconds: 729302400}");
   RunValidJsonTest("TimestampWithPositiveOffset", REQUIRED,
                    R"({"optionalTimestamp": "1970-01-01T08:00:01+08:00"})",
                    "optional_timestamp: {seconds: 1}");
@@ -2732,39 +2793,38 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
       "TimestampZeroNormalized", RECOMMENDED,
       R"({"optionalTimestamp": "1969-12-31T16:00:00-08:00"})",
       [](const Json::Value& value) {
-        return value["optionalTimestamp"].asString() ==
-            "1970-01-01T00:00:00Z";
+        return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00Z";
       });
   RunValidJsonTestWithValidator(
       "TimestampHasZeroFractionalDigit", RECOMMENDED,
       R"({"optionalTimestamp": "1970-01-01T00:00:00.000000000Z"})",
       [](const Json::Value& value) {
-        return value["optionalTimestamp"].asString() ==
-            "1970-01-01T00:00:00Z";
+        return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00Z";
       });
   RunValidJsonTestWithValidator(
       "TimestampHas3FractionalDigits", RECOMMENDED,
       R"({"optionalTimestamp": "1970-01-01T00:00:00.010000000Z"})",
       [](const Json::Value& value) {
         return value["optionalTimestamp"].asString() ==
-            "1970-01-01T00:00:00.010Z";
+               "1970-01-01T00:00:00.010Z";
       });
   RunValidJsonTestWithValidator(
       "TimestampHas6FractionalDigits", RECOMMENDED,
       R"({"optionalTimestamp": "1970-01-01T00:00:00.000010000Z"})",
       [](const Json::Value& value) {
         return value["optionalTimestamp"].asString() ==
-            "1970-01-01T00:00:00.000010Z";
+               "1970-01-01T00:00:00.000010Z";
       });
   RunValidJsonTestWithValidator(
       "TimestampHas9FractionalDigits", RECOMMENDED,
       R"({"optionalTimestamp": "1970-01-01T00:00:00.000000010Z"})",
       [](const Json::Value& value) {
         return value["optionalTimestamp"].asString() ==
-            "1970-01-01T00:00:00.000000010Z";
+               "1970-01-01T00:00:00.000000010Z";
       });
+}
 
-  // FieldMask
+void BinaryAndJsonConformanceSuite::RunJsonTestsForFieldMask() {
   RunValidJsonTest(
       "FieldMask", REQUIRED,
       R"({"optionalFieldMask": "foo,barBaz"})",
@@ -2785,8 +2845,9 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
   ExpectSerializeFailureForJson(
       "FieldMaskTooManyUnderscore", RECOMMENDED,
       R"(optional_field_mask: {paths: "foo__bar"})");
+}
 
-  // Struct
+void BinaryAndJsonConformanceSuite::RunJsonTestsForStruct() {
   RunValidJsonTest(
       "Struct", REQUIRED,
       R"({
@@ -2870,7 +2931,9 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
           }
         }
       )");
-  // Value
+}
+
+void BinaryAndJsonConformanceSuite::RunJsonTestsForValue() {
   RunValidJsonTest(
       "ValueAcceptInteger", REQUIRED,
       R"({"optionalValue": 1})",
@@ -2951,8 +3014,9 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
           }
         ]
       )");
+}
 
-  // Any
+void BinaryAndJsonConformanceSuite::RunJsonTestsForAny() {
   RunValidJsonTest(
       "Any", REQUIRED,
       R"({
@@ -3128,45 +3192,6 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
           }
         }
       )");
-
-  RunValidJsonIgnoreUnknownTest(
-      "IgnoreUnknownJsonNumber", REQUIRED,
-      R"({
-        "unknown": 1
-      })",
-      "");
-  RunValidJsonIgnoreUnknownTest(
-      "IgnoreUnknownJsonString", REQUIRED,
-      R"({
-        "unknown": "a"
-      })",
-      "");
-  RunValidJsonIgnoreUnknownTest(
-      "IgnoreUnknownJsonTrue", REQUIRED,
-      R"({
-        "unknown": true
-      })",
-      "");
-  RunValidJsonIgnoreUnknownTest(
-      "IgnoreUnknownJsonFalse", REQUIRED,
-      R"({
-        "unknown": false
-      })",
-      "");
-  RunValidJsonIgnoreUnknownTest(
-      "IgnoreUnknownJsonNull", REQUIRED,
-      R"({
-        "unknown": null
-      })",
-      "");
-  RunValidJsonIgnoreUnknownTest(
-      "IgnoreUnknownJsonObject", REQUIRED,
-      R"({
-        "unknown": {"a": 1}
-      })",
-      "");
-
-  ExpectParseFailureForJson("RejectTopLevelNull", REQUIRED, "null");
 }
 
 }  // namespace protobuf

+ 12 - 3
conformance/binary_json_conformance_suite.h

@@ -31,8 +31,8 @@
 #ifndef CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H
 #define CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H
 
-#include "conformance_test.h"
 #include "third_party/jsoncpp/json.h"
+#include "conformance_test.h"
 
 namespace google {
 namespace protobuf {
@@ -43,6 +43,16 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite {
 
  private:
   void RunSuiteImpl();
+  void RunJsonTests();
+  void RunJsonTestsForFieldNameConvention();
+  void RunJsonTestsForNonRepeatedTypes();
+  void RunJsonTestsForRepeatedTypes();
+  void RunJsonTestsForNullTypes();
+  void RunJsonTestsForWrapperTypes();
+  void RunJsonTestsForFieldMask();
+  void RunJsonTestsForStruct();
+  void RunJsonTestsForValue();
+  void RunJsonTestsForAny();
   void RunValidJsonTest(const string& test_name,
                         ConformanceLevel level,
                         const string& input_json,
@@ -121,8 +131,7 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite {
   void TestMergeOneofMessage();
   void TestOverwriteMessageValueMap();
 
-  std::unique_ptr<google::protobuf::util::TypeResolver>
-      type_resolver_;
+  std::unique_ptr<google::protobuf::util::TypeResolver> type_resolver_;
   std::string type_url_;
 };
 

+ 2 - 2
conformance/conformance.proto

@@ -95,7 +95,7 @@ message ConformanceRequest {
   //
   // TODO(haberman): if/when we expand the conformance tests to support proto2,
   // we will want to include a field that lets the payload/response be a
-  // protobuf_test_messages.proto2.TestAllTypes message instead.
+  // protobuf_test_messages.google.protobuf.TestAllTypes message instead.
   oneof payload {
     bytes protobuf_payload = 1;
     string json_payload = 2;
@@ -109,7 +109,7 @@ message ConformanceRequest {
 
   // The full name for the test message to use; for the moment, either:
   // protobuf_test_messages.proto3.TestAllTypesProto3 or
-  // protobuf_test_messages.proto2.TestAllTypesProto2.
+  // protobuf_test_messages.google.protobuf.TestAllTypesProto2.
   string message_type = 4;
 
   // Each test is given a specific test category. Some category may need

+ 20 - 14
conformance/conformance_cpp.cc

@@ -32,13 +32,14 @@
 #include <stdarg.h>
 #include <unistd.h>
 
-#include "conformance.pb.h"
-#include <google/protobuf/test_messages_proto3.pb.h>
-#include <google/protobuf/test_messages_proto2.pb.h>
 #include <google/protobuf/message.h>
 #include <google/protobuf/text_format.h>
 #include <google/protobuf/util/json_util.h>
 #include <google/protobuf/util/type_resolver_util.h>
+#include "conformance.pb.h"
+#include <google/protobuf/test_messages_proto2.pb.h>
+#include <google/protobuf/test_messages_proto3.pb.h>
+#include <google/protobuf/stubs/status.h>
 
 using conformance::ConformanceRequest;
 using conformance::ConformanceResponse;
@@ -51,9 +52,7 @@ using google::protobuf::util::BinaryToJsonString;
 using google::protobuf::util::JsonParseOptions;
 using google::protobuf::util::JsonToBinaryString;
 using google::protobuf::util::NewTypeResolverForDescriptorPool;
-using google::protobuf::util::Status;
 using google::protobuf::util::TypeResolver;
-using protobuf_test_messages::proto2::TestAllTypesProto2;
 using protobuf_test_messages::proto3::TestAllTypesProto3;
 using std::string;
 
@@ -71,6 +70,10 @@ bool verbose = false;
 TypeResolver* type_resolver;
 string* type_url;
 
+namespace google {
+namespace protobuf {
+
+using util::Status;
 
 bool CheckedRead(int fd, void *buf, size_t len) {
   size_t ofs = 0;
@@ -80,7 +83,7 @@ bool CheckedRead(int fd, void *buf, size_t len) {
     if (bytes_read == 0) return false;
 
     if (bytes_read < 0) {
-      GOOGLE_LOG(FATAL) << "Error reading from test runner: " <<  strerror(errno);
+      GOOGLE_LOG(FATAL) << "Error reading from test runner: " << strerror(errno);
     }
 
     len -= bytes_read;
@@ -127,7 +130,7 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
                                          options);
       if (!status.ok()) {
         response->set_parse_error(string("Parse error: ") +
-                                  status.error_message().as_string());
+                                  std::string(status.error_message()));
         return;
       }
 
@@ -152,8 +155,7 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
       break;
 
     default:
-      GOOGLE_LOG(FATAL) << "unknown payload type: "
-                        << request.payload_case();
+      GOOGLE_LOG(FATAL) << "unknown payload type: " << request.payload_case();
       break;
   }
 
@@ -169,7 +171,8 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
       break;
 
     case conformance::PROTOBUF: {
-      GOOGLE_CHECK(test_message->SerializeToString(response->mutable_protobuf_payload()));
+      GOOGLE_CHECK(test_message->SerializeToString(
+          response->mutable_protobuf_payload()));
       break;
     }
 
@@ -181,7 +184,7 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
       if (!status.ok()) {
         response->set_serialize_error(
             string("Failed to serialize JSON output: ") +
-            status.error_message().as_string());
+            std::string(status.error_message()));
         return;
       }
       break;
@@ -191,13 +194,13 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
       TextFormat::Printer printer;
       printer.SetHideUnknownFields(!request.print_unknown_fields());
       GOOGLE_CHECK(printer.PrintToString(*test_message,
-                                         response->mutable_text_payload()));
+                                  response->mutable_text_payload()));
       break;
     }
 
     default:
       GOOGLE_LOG(FATAL) << "Unknown output format: "
-                        << request.requested_output_format();
+                 << request.requested_output_format();
   }
 }
 
@@ -243,12 +246,15 @@ bool DoTestIo() {
   return true;
 }
 
+}  // namespace protobuf
+}  // namespace google
+
 int main() {
   type_resolver = NewTypeResolverForDescriptorPool(
       kTypeUrlPrefix, DescriptorPool::generated_pool());
   type_url = new string(GetTypeUrl(TestAllTypesProto3::descriptor()));
   while (1) {
-    if (!DoTestIo()) {
+    if (!google::protobuf::DoTestIo()) {
       fprintf(stderr, "conformance-cpp: received EOF from test runner "
                       "after %d tests, exiting\n", test_count);
       return 0;

+ 0 - 3
conformance/conformance_python.py

@@ -1,5 +1,4 @@
 #!/usr/bin/env python
-#
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
 # https://developers.google.com/protocol-buffers/
@@ -38,8 +37,6 @@ See conformance.proto for more information.
 import struct
 import sys
 import os
-from google.protobuf import descriptor
-from google.protobuf import descriptor_pool
 from google.protobuf import json_format
 from google.protobuf import message
 from google.protobuf import test_messages_proto3_pb2

+ 27 - 34
conformance/conformance_test.cc

@@ -28,30 +28,28 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include <set>
+#include "conformance_test.h"
+
 #include <stdarg.h>
-#include <string>
-#include <fstream>
 
-#include "conformance.pb.h"
-#include "conformance_test.h"
+#include <fstream>
+#include <set>
+#include <string>
 
 #include <google/protobuf/stubs/stringprintf.h>
-#include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/message.h>
 #include <google/protobuf/text_format.h>
 #include <google/protobuf/util/field_comparator.h>
 #include <google/protobuf/util/json_util.h>
 #include <google/protobuf/util/message_differencer.h>
+#include "conformance.pb.h"
 
 using conformance::ConformanceRequest;
 using conformance::ConformanceResponse;
 using conformance::WireFormat;
 using google::protobuf::TextFormat;
 using google::protobuf::util::DefaultFieldComparator;
-using google::protobuf::util::JsonToBinaryString;
 using google::protobuf::util::MessageDifferencer;
-using google::protobuf::util::Status;
 using std::string;
 
 namespace {
@@ -120,9 +118,9 @@ ConformanceTestSuite::ConformanceRequestSetting::ConformanceRequestSetting(
   request_.set_requested_output_format(output_format);
 }
 
-Message* ConformanceTestSuite::ConformanceRequestSetting::
-    GetTestMessage() const {
-  return prototype_message_for_compare_->New();
+std::unique_ptr<Message>
+ConformanceTestSuite::ConformanceRequestSetting::NewTestMessage() const {
+  return std::unique_ptr<Message>(prototype_message_for_compare_->New());
 }
 
 string ConformanceTestSuite::ConformanceRequestSetting::
@@ -131,11 +129,9 @@ string ConformanceTestSuite::ConformanceRequestSetting::
       prototype_message_.GetDescriptor()->file()->syntax() ==
         FileDescriptor::SYNTAX_PROTO3 ? "Proto3" : "Proto2";
 
-  return StrCat(ConformanceLevelToString(level_), ".",
-                rname, ".",
-                InputFormatString(input_format_),
-                ".", test_name_, ".",
-                OutputFormatString(output_format_));
+  return StrCat(ConformanceLevelToString(level_), ".", rname, ".",
+                      InputFormatString(input_format_), ".", test_name_, ".",
+                      OutputFormatString(output_format_));
 }
 
 string ConformanceTestSuite::ConformanceRequestSetting::
@@ -228,11 +224,11 @@ void ConformanceTestSuite::ReportSkip(const string& test_name,
 void ConformanceTestSuite::RunValidInputTest(
     const ConformanceRequestSetting& setting,
     const string& equivalent_text_format) {
-  Message* reference_message = setting.GetTestMessage();
-  GOOGLE_CHECK(
-      TextFormat::ParseFromString(equivalent_text_format, reference_message))
-          << "Failed to parse data for test case: " << setting.GetTestName()
-          << ", data: " << equivalent_text_format;
+  std::unique_ptr<Message> reference_message(setting.NewTestMessage());
+  GOOGLE_CHECK(TextFormat::ParseFromString(equivalent_text_format,
+                                    reference_message.get()))
+      << "Failed to parse data for test case: " << setting.GetTestName()
+      << ", data: " << equivalent_text_format;
   const string equivalent_wire_format = reference_message->SerializeAsString();
   RunValidBinaryInputTest(setting, equivalent_wire_format);
 }
@@ -251,15 +247,14 @@ void ConformanceTestSuite::VerifyResponse(
     const ConformanceRequestSetting& setting,
     const string& equivalent_wire_format, const ConformanceResponse& response,
     bool need_report_success, bool require_same_wire_format) {
-  Message* test_message = setting.GetTestMessage();
+  std::unique_ptr<Message> test_message(setting.NewTestMessage());
   const ConformanceRequest& request = setting.GetRequest();
   const string& test_name = setting.GetTestName();
   ConformanceLevel level = setting.GetLevel();
-  Message* reference_message = setting.GetTestMessage();
+  std::unique_ptr<Message> reference_message = setting.NewTestMessage();
 
-  GOOGLE_CHECK(
-      reference_message->ParseFromString(equivalent_wire_format))
-          << "Failed to parse wire data for test case: " << test_name;
+  GOOGLE_CHECK(reference_message->ParseFromString(equivalent_wire_format))
+      << "Failed to parse wire data for test case: " << test_name;
 
   switch (response.result_case()) {
     case ConformanceResponse::RESULT_NOT_SET:
@@ -279,7 +274,7 @@ void ConformanceTestSuite::VerifyResponse(
       return;
 
     default:
-      if (!ParseResponse(response, setting, test_message)) return;
+      if (!ParseResponse(response, setting, test_message.get())) return;
   }
 
   MessageDifferencer differencer;
@@ -292,12 +287,11 @@ void ConformanceTestSuite::VerifyResponse(
   bool check = false;
 
   if (require_same_wire_format) {
-    GOOGLE_DCHECK_EQ(response.result_case(),
-                     ConformanceResponse::kProtobufPayload);
+    GOOGLE_DCHECK_EQ(response.result_case(), ConformanceResponse::kProtobufPayload);
     const string& protobuf_payload = response.protobuf_payload();
     check = equivalent_wire_format == protobuf_payload;
     differences = StrCat("Expect: ", ToOctString(equivalent_wire_format),
-                         ", but got: ", ToOctString(protobuf_payload));
+                               ", but got: ", ToOctString(protobuf_payload));
   } else {
     check = differencer.Compare(*reference_message, *test_message);
   }
@@ -386,8 +380,7 @@ string ConformanceTestSuite::WireFormatToString(
     case conformance::UNSPECIFIED:
       return "UNSPECIFIED";
     default:
-      GOOGLE_LOG(FATAL) << "unknown wire type: "
-                        << wire_format;
+      GOOGLE_LOG(FATAL) << "unknown wire type: " << wire_format;
   }
   return "";
 }
@@ -450,8 +443,8 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
   }
 
   StringAppendF(&output_,
-                "CONFORMANCE SUITE %s: %d successes, %d skipped, "
-                "%d expected failures, %d unexpected failures.\n",
+                "CONFORMANCE SUITE %s: %d successes, %zu skipped, "
+                "%d expected failures, %zu unexpected failures.\n",
                 ok ? "PASSED" : "FAILED", successes_, skipped_.size(),
                 expected_failures_, unexpected_failing_tests_.size());
   StringAppendF(&output_, "\n");

+ 4 - 6
conformance/conformance_test.h

@@ -38,15 +38,13 @@
 #ifndef CONFORMANCE_CONFORMANCE_TEST_H
 #define CONFORMANCE_CONFORMANCE_TEST_H
 
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/util/type_resolver.h>
-#include <google/protobuf/wire_format_lite.h>
-
 #include <functional>
 #include <string>
 #include <vector>
 
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/wire_format_lite.h>
+#include <google/protobuf/util/type_resolver.h>
 #include "conformance.pb.h"
 
 namespace conformance {
@@ -218,7 +216,7 @@ class ConformanceTestSuite {
         const string& test_name, const string& input);
     virtual ~ConformanceRequestSetting() {}
 
-    Message* GetTestMessage() const;
+    std::unique_ptr<Message> NewTestMessage() const;
 
     string GetTestName() const;
 

+ 19 - 24
conformance/conformance_test_runner.cc

@@ -53,28 +53,27 @@
 //   3. testee sends 4-byte length M (little endian)
 //   4. testee sends M bytes representing a ConformanceResponse proto
 
-#include <algorithm>
 #include <errno.h>
-#include <fstream>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
+
+#include <algorithm>
+#include <fstream>
 #include <vector>
 
 #include <google/protobuf/stubs/stringprintf.h>
-
 #include "conformance.pb.h"
 #include "conformance_test.h"
 
 using conformance::ConformanceResponse;
-using google::protobuf::StringAppendF;
 using google::protobuf::ConformanceTestSuite;
 using std::string;
 using std::vector;
 
 #define STRINGIFY(x) #x
 #define TOSTRING(x) STRINGIFY(x)
-#define CHECK_SYSCALL(call) \
+#define GOOGLE_CHECK_SYSCALL(call) \
   if (call < 0) { \
     perror(#call " " __FILE__ ":" TOSTRING(__LINE__)); \
     exit(1); \
@@ -275,22 +274,22 @@ void ForkPipeRunner::SpawnTestProgram() {
 
   if (pid) {
     // Parent.
-    CHECK_SYSCALL(close(toproc_pipe_fd[0]));
-    CHECK_SYSCALL(close(fromproc_pipe_fd[1]));
+    GOOGLE_CHECK_SYSCALL(close(toproc_pipe_fd[0]));
+    GOOGLE_CHECK_SYSCALL(close(fromproc_pipe_fd[1]));
     write_fd_ = toproc_pipe_fd[1];
     read_fd_ = fromproc_pipe_fd[0];
     child_pid_ = pid;
   } else {
     // Child.
-    CHECK_SYSCALL(close(STDIN_FILENO));
-    CHECK_SYSCALL(close(STDOUT_FILENO));
-    CHECK_SYSCALL(dup2(toproc_pipe_fd[0], STDIN_FILENO));
-    CHECK_SYSCALL(dup2(fromproc_pipe_fd[1], STDOUT_FILENO));
+    GOOGLE_CHECK_SYSCALL(close(STDIN_FILENO));
+    GOOGLE_CHECK_SYSCALL(close(STDOUT_FILENO));
+    GOOGLE_CHECK_SYSCALL(dup2(toproc_pipe_fd[0], STDIN_FILENO));
+    GOOGLE_CHECK_SYSCALL(dup2(fromproc_pipe_fd[1], STDOUT_FILENO));
 
-    CHECK_SYSCALL(close(toproc_pipe_fd[0]));
-    CHECK_SYSCALL(close(fromproc_pipe_fd[1]));
-    CHECK_SYSCALL(close(toproc_pipe_fd[1]));
-    CHECK_SYSCALL(close(fromproc_pipe_fd[0]));
+    GOOGLE_CHECK_SYSCALL(close(toproc_pipe_fd[0]));
+    GOOGLE_CHECK_SYSCALL(close(fromproc_pipe_fd[1]));
+    GOOGLE_CHECK_SYSCALL(close(toproc_pipe_fd[1]));
+    GOOGLE_CHECK_SYSCALL(close(fromproc_pipe_fd[0]));
 
     std::unique_ptr<char[]> executable(new char[executable_.size() + 1]);
     memcpy(executable.get(), executable_.c_str(), executable_.size());
@@ -303,15 +302,14 @@ void ForkPipeRunner::SpawnTestProgram() {
     }
     argv.push_back(nullptr);
     // Never returns.
-    CHECK_SYSCALL(execv(executable.get(), const_cast<char **>(argv.data())));
+    GOOGLE_CHECK_SYSCALL(execv(executable.get(), const_cast<char **>(argv.data())));
   }
 }
 
 void ForkPipeRunner::CheckedWrite(int fd, const void *buf, size_t len) {
   if (write(fd, buf, len) != len) {
     GOOGLE_LOG(FATAL) << current_test_name_
-                      << ": error writing to test program: "
-                      << strerror(errno);
+               << ": error writing to test program: " << strerror(errno);
   }
 }
 
@@ -321,13 +319,11 @@ bool ForkPipeRunner::TryRead(int fd, void *buf, size_t len) {
     ssize_t bytes_read = read(fd, (char*)buf + ofs, len);
 
     if (bytes_read == 0) {
-      GOOGLE_LOG(ERROR) << current_test_name_
-                        << ": unexpected EOF from test program";
+      GOOGLE_LOG(ERROR) << current_test_name_ << ": unexpected EOF from test program";
       return false;
     } else if (bytes_read < 0) {
       GOOGLE_LOG(ERROR) << current_test_name_
-                        << ": error reading from test program: "
-                        << strerror(errno);
+                 << ": error reading from test program: " << strerror(errno);
       return false;
     }
 
@@ -341,8 +337,7 @@ bool ForkPipeRunner::TryRead(int fd, void *buf, size_t len) {
 void ForkPipeRunner::CheckedRead(int fd, void *buf, size_t len) {
   if (!TryRead(fd, buf, len)) {
     GOOGLE_LOG(FATAL) << current_test_name_
-                      << ": error reading from test program: "
-                      << strerror(errno);
+               << ": error reading from test program: " << strerror(errno);
   }
 }
 

+ 1 - 0
conformance/failure_list_js.txt

@@ -1,3 +1,4 @@
+
 Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput
 Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.UnpackedOutput.ProtobufOutput
 Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput

+ 22 - 20
conformance/text_format_conformance_suite.cc

@@ -30,20 +30,21 @@
 
 #include "text_format_conformance_suite.h"
 
-#include "conformance_test.h"
-
 #include <google/protobuf/any.pb.h>
+#include <google/protobuf/text_format.h>
+#include "conformance_test.h"
 #include <google/protobuf/test_messages_proto2.pb.h>
 #include <google/protobuf/test_messages_proto3.pb.h>
-#include <google/protobuf/text_format.h>
+
+namespace proto2_messages = protobuf_test_messages::proto2;
 
 using conformance::ConformanceRequest;
 using conformance::ConformanceResponse;
 using conformance::WireFormat;
 using google::protobuf::Message;
 using google::protobuf::TextFormat;
-using protobuf_test_messages::proto2::TestAllTypesProto2;
-using protobuf_test_messages::proto2::UnknownToTestAllTypes;
+using proto2_messages::TestAllTypesProto2;
+using proto2_messages::UnknownToTestAllTypes;
 using protobuf_test_messages::proto3::TestAllTypesProto3;
 using std::string;
 
@@ -64,8 +65,8 @@ bool TextFormatConformanceTestSuite::ParseTextFormatResponse(
   }
   if (!parser.ParseFromString(response.text_payload(), test_message)) {
     GOOGLE_LOG(ERROR) << "INTERNAL ERROR: internal text->protobuf transcode "
-                      << "yielded unparseable proto. Text payload: "
-                      << response.text_payload();
+               << "yielded unparseable proto. Text payload: "
+               << response.text_payload();
     return false;
   }
 
@@ -83,11 +84,11 @@ bool TextFormatConformanceTestSuite::ParseResponse(
   switch (response.result_case()) {
     case ConformanceResponse::kProtobufPayload: {
       if (requested_output != conformance::PROTOBUF) {
-        ReportFailure(
-            test_name, level, request, response,
-            StrCat("Test was asked for ", WireFormatToString(requested_output),
-                   " output but provided PROTOBUF instead.")
-                .c_str());
+        ReportFailure(test_name, level, request, response,
+                      StrCat("Test was asked for ",
+                                   WireFormatToString(requested_output),
+                                   " output but provided PROTOBUF instead.")
+                          .c_str());
         return false;
       }
 
@@ -102,11 +103,11 @@ bool TextFormatConformanceTestSuite::ParseResponse(
 
     case ConformanceResponse::kTextPayload: {
       if (requested_output != conformance::TEXT_FORMAT) {
-        ReportFailure(
-            test_name, level, request, response,
-            StrCat("Test was asked for ", WireFormatToString(requested_output),
-                   " output but provided TEXT_FORMAT instead.")
-                .c_str());
+        ReportFailure(test_name, level, request, response,
+                      StrCat("Test was asked for ",
+                                   WireFormatToString(requested_output),
+                                   " output but provided TEXT_FORMAT instead.")
+                          .c_str());
         return false;
       }
 
@@ -122,7 +123,7 @@ bool TextFormatConformanceTestSuite::ParseResponse(
 
     default:
       GOOGLE_LOG(FATAL) << test_name
-                        << ": unknown payload type: " << response.result_case();
+                 << ": unknown payload type: " << response.result_case();
   }
 
   return true;
@@ -139,8 +140,9 @@ void TextFormatConformanceTestSuite::ExpectParseFailure(const string& test_name,
       conformance::TEXT_FORMAT_TEST, prototype, test_name, input);
   const ConformanceRequest& request = setting.GetRequest();
   ConformanceResponse response;
-  string effective_test_name = StrCat(setting.ConformanceLevelToString(level),
-                                      ".Proto3.TextFormatInput.", test_name);
+  string effective_test_name =
+      StrCat(setting.ConformanceLevelToString(level),
+                   ".Proto3.TextFormatInput.", test_name);
 
   RunTest(effective_test_name, request, &response);
   if (response.result_case() == ConformanceResponse::kParseError) {

+ 1 - 1
csharp/src/Google.Protobuf.Conformance/Conformance.cs

@@ -355,7 +355,7 @@ namespace Conformance {
     /// <summary>
     /// The full name for the test message to use; for the moment, either:
     /// protobuf_test_messages.proto3.TestAllTypesProto3 or
-    /// protobuf_test_messages.proto2.TestAllTypesProto2.
+    /// protobuf_test_messages.google.protobuf.TestAllTypesProto2.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string MessageType {

BIN
csharp/src/Google.Protobuf.Test/testprotos.pb


+ 1 - 1
csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs

@@ -238,7 +238,7 @@ namespace Google.Protobuf.WellKnownTypes {
   ///
   /// The implementation of any API method which has a FieldMask type field in the
   /// request should verify the included field paths, and return an
-  /// `INVALID_ARGUMENT` error if any path is duplicated or unmappable.
+  /// `INVALID_ARGUMENT` error if any path is unmappable.
   /// </summary>
   public sealed partial class FieldMask : pb::IMessage<FieldMask> {
     private static readonly pb::MessageParser<FieldMask> _parser = new pb::MessageParser<FieldMask>(() => new FieldMask());

+ 7 - 3
java/core/src/main/java/com/google/protobuf/ByteString.java

@@ -57,13 +57,17 @@ import java.util.Locale;
 import java.util.NoSuchElementException;
 
 /**
- * Immutable sequence of bytes. Substring is supported by sharing the reference to the immutable
- * underlying bytes. Concatenation is likewise supported without copying (long strings) by building
- * a tree of pieces in {@link RopeByteString}.
+ * Immutable sequence of bytes. Provides conversions to and from {@code byte[]}, {@link
+ * java.lang.String}, {@link ByteBuffer}, {@link InputStream}, {@link OutputStream}. Also provides a
+ * conversion to {@link CodedInputStream}.
  *
  * <p>Like {@link String}, the contents of a {@link ByteString} can never be observed to change, not
  * even in the presence of a data race or incorrect API usage in the client code.
  *
+ * <p>Substring is supported by sharing the reference to the immutable underlying bytes.
+ * Concatenation is likewise supported without copying (long strings) by building a tree of pieces
+ * in {@link RopeByteString}.
+ *
  * @author crazybob@google.com Bob Lee
  * @author kenton@google.com Kenton Varda
  * @author carlanton@google.com Carl Haverl

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

@@ -1023,7 +1023,7 @@ public abstract class GeneratedMessageLite<
     }
 
     /** Clear an extension. */
-    public final <Type> BuilderType clearExtension(final ExtensionLite<MessageType, ?> extension) {
+    public final BuilderType clearExtension(final ExtensionLite<MessageType, ?> extension) {
       GeneratedExtension<MessageType, ?> extensionLite = checkIsLite(extension);
 
       verifyExtensionContainingType(extensionLite);

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

@@ -1498,8 +1498,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
     }
 
     /** Clear an extension. */
-    public final <Type> BuilderType clearExtension(
-        final ExtensionLite<MessageType, ?> extensionLite) {
+    public final BuilderType clearExtension(final ExtensionLite<MessageType, ?> extensionLite) {
       Extension<MessageType, ?> extension = checkNotLite(extensionLite);
 
       verifyExtensionContainingType(extension);

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

@@ -88,7 +88,7 @@ final class MessageLiteToString {
     }
 
     for (String getter : getters) {
-      String suffix = getter.replaceFirst("get", "");
+      String suffix = getter.startsWith("get") ? getter.substring(3) : getter;
       if (suffix.endsWith(LIST_SUFFIX)
           && !suffix.endsWith(BUILDER_LIST_SUFFIX)
           // Sometimes people have fields named 'list' that aren't repeated.

+ 3 - 5
java/core/src/main/java/com/google/protobuf/MessageSchema.java

@@ -1173,12 +1173,10 @@ final class MessageSchema<T> implements Schema<T> {
       mergeSingleField(message, other, i);
     }
 
-    if (!proto3) {
-      SchemaUtil.mergeUnknownFields(unknownFieldSchema, message, other);
+    SchemaUtil.mergeUnknownFields(unknownFieldSchema, message, other);
 
-      if (hasExtensions) {
-        SchemaUtil.mergeExtensions(extensionSchema, message, other);
-      }
+    if (hasExtensions) {
+      SchemaUtil.mergeExtensions(extensionSchema, message, other);
     }
   }
 

+ 22 - 6
java/core/src/main/java/com/google/protobuf/RopeByteString.java

@@ -211,7 +211,7 @@ final class RopeByteString extends ByteString {
 
     // Fine, we'll add a node and increase the tree depth--unless we rebalance ;^)
     int newDepth = Math.max(left.getTreeDepth(), right.getTreeDepth()) + 1;
-    if (newLength >= minLengthByDepth[newDepth]) {
+    if (newLength >= minLength(newDepth)) {
       // The tree is shallow enough, so don't rebalance
       return new RopeByteString(left, right);
     }
@@ -250,6 +250,22 @@ final class RopeByteString extends ByteString {
     return new RopeByteString(left, right);
   }
 
+  /**
+   * Returns the minimum length for which a tree of the given depth is considered balanced according
+   * to BAP95, which means the tree is flat-enough with respect to the bounds. Defaults to {@code
+   * Integer.MAX_VALUE} if {@code depth >= minLengthByDepth.length} in order to avoid an {@code
+   * ArrayIndexOutOfBoundsException}.
+   *
+   * @param depth tree depth
+   * @return minimum balanced length
+   */
+  static int minLength(int depth) {
+    if (depth >= minLengthByDepth.length) {
+      return Integer.MAX_VALUE;
+    }
+    return minLengthByDepth[depth];
+  }
+
   /**
    * Gets the byte at the given index. Throws {@link ArrayIndexOutOfBoundsException} for
    * backwards-compatibility reasons although it would more properly be {@link
@@ -328,7 +344,7 @@ final class RopeByteString extends ByteString {
    */
   @Override
   protected boolean isBalanced() {
-    return totalLength >= minLengthByDepth[treeDepth];
+    return totalLength >= minLength(treeDepth);
   }
 
   /**
@@ -656,7 +672,7 @@ final class RopeByteString extends ByteString {
      */
     private void insert(ByteString byteString) {
       int depthBin = getDepthBinForLength(byteString.size());
-      int binEnd = minLengthByDepth[depthBin + 1];
+      int binEnd = minLength(depthBin + 1);
 
       // BAP95: Concatenate all trees occupying bins representing the length of
       // our new piece or of shorter pieces, to the extent that is possible.
@@ -665,7 +681,7 @@ final class RopeByteString extends ByteString {
       if (prefixesStack.isEmpty() || prefixesStack.peek().size() >= binEnd) {
         prefixesStack.push(byteString);
       } else {
-        int binStart = minLengthByDepth[depthBin];
+        int binStart = minLength(depthBin);
 
         // Concatenate the subtrees of shorter length
         ByteString newTree = prefixesStack.pop();
@@ -680,7 +696,7 @@ final class RopeByteString extends ByteString {
         // Continue concatenating until we land in an empty bin
         while (!prefixesStack.isEmpty()) {
           depthBin = getDepthBinForLength(newTree.size());
-          binEnd = minLengthByDepth[depthBin + 1];
+          binEnd = minLength(depthBin + 1);
           if (prefixesStack.peek().size() < binEnd) {
             ByteString left = prefixesStack.pop();
             newTree = new RopeByteString(left, newTree);
@@ -816,7 +832,7 @@ final class RopeByteString extends ByteString {
      *
      * <p>Note that {@link InputStream#read(byte[], int, int)} and {@link
      * ByteArrayInputStream#read(byte[], int, int)} behave inconsistently when reading 0 bytes at
-     * EOF; the interface defines the return value to be 0 and the latter returns -1.  We use the
+     * EOF; the interface defines the return value to be 0 and the latter returns -1. We use the
      * latter behavior so that all ByteString streams are consistent.
      *
      * @return -1 if at EOF, otherwise the actual number of bytes read.

+ 5 - 4
java/core/src/test/java/com/google/protobuf/RopeByteStringTest.java

@@ -62,18 +62,19 @@ public class RopeByteStringTest extends LiteralByteStringTest {
     expectedHashCode = -1214197238;
   }
 
-  public void testMinLengthByDepth() {
-    // minLengthByDepth should match the Fibonacci sequence
+  public void testMinLength() {
+    // minLength should match the Fibonacci sequence
     int a = 1;
     int b = 1;
     int i;
     for (i = 0; a > 0; i++) {
-      assertEquals(a, RopeByteString.minLengthByDepth[i]);
+      assertEquals(a, RopeByteString.minLength(i));
       int c = a + b;
       a = b;
       b = c;
     }
-    assertEquals(Integer.MAX_VALUE, RopeByteString.minLengthByDepth[i]);
+    assertEquals(Integer.MAX_VALUE, RopeByteString.minLength(i));
+    assertEquals(Integer.MAX_VALUE, RopeByteString.minLength(i + 1));
     assertEquals(i + 1, RopeByteString.minLengthByDepth.length);
   }
 

+ 25 - 0
java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java

@@ -38,6 +38,7 @@ import protobuf_unittest.UnittestProto.TestEmptyMessage;
 import protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions;
 import protobuf_unittest.UnittestProto.TestPackedExtensions;
 import protobuf_unittest.UnittestProto.TestPackedTypes;
+import proto3_unittest.UnittestProto3;
 import java.util.Arrays;
 import java.util.Map;
 import junit.framework.TestCase;
@@ -379,4 +380,28 @@ public class UnknownFieldSetTest extends TestCase {
   }
 
   // =================================================================
+
+  public void testProto3RoundTrip() throws Exception {
+    ByteString data = getBizarroData();
+
+    UnittestProto3.TestEmptyMessage message =
+        UnittestProto3.TestEmptyMessage.parseFrom(data, ExtensionRegistryLite.getEmptyRegistry());
+    assertEquals(data, message.toByteString());
+
+    message = UnittestProto3.TestEmptyMessage.newBuilder().mergeFrom(message).build();
+    assertEquals(data, message.toByteString());
+
+    assertEquals(
+        data,
+        UnittestProto3.TestMessageWithDummy.parseFrom(
+                data, ExtensionRegistryLite.getEmptyRegistry())
+            .toBuilder()
+            // force copy-on-write
+            .setDummy(true)
+            .build()
+            .toBuilder()
+            .clearDummy()
+            .build()
+            .toByteString());
+  }
 }

+ 3 - 0
java/lite/proguard.pgcfg

@@ -0,0 +1,3 @@
+-keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite {
+  <fields>;
+}

+ 3 - 3
js/binary/decoder.js

@@ -180,9 +180,9 @@ jspb.BinaryDecoder.prototype.getBuffer = function() {
 jspb.BinaryDecoder.prototype.setBlock =
     function(data, opt_start, opt_length) {
   this.bytes_ = jspb.utils.byteSourceToUint8Array(data);
-  this.start_ = goog.isDef(opt_start) ? opt_start : 0;
-  this.end_ =
-      goog.isDef(opt_length) ? this.start_ + opt_length : this.bytes_.length;
+  this.start_ = (opt_start !== undefined) ? opt_start : 0;
+  this.end_ = (opt_length !== undefined) ? this.start_ + opt_length :
+                                           this.bytes_.length;
   this.cursor_ = this.start_;
 };
 

+ 1 - 1
js/binary/encoder.js

@@ -414,7 +414,7 @@ jspb.BinaryEncoder.prototype.writeDouble = function(value) {
  * @param {boolean|number} value The value to write.
  */
 jspb.BinaryEncoder.prototype.writeBool = function(value) {
-  goog.asserts.assert(goog.isBoolean(value) || goog.isNumber(value));
+  goog.asserts.assert(typeof value === 'boolean' || typeof value === 'number');
   this.buffer_.push(value ? 1 : 0);
 };
 

+ 3 - 3
js/binary/proto_test.js

@@ -176,7 +176,7 @@ function fillAllFields(msg) {
  * @return {boolean}
  */
 function bytesCompare(arr, expected) {
-  if (goog.isString(arr)) {
+  if (typeof arr === 'string') {
     arr = goog.crypt.base64.decodeStringToUint8Array(arr);
   }
   if (arr.length != expected.length) {
@@ -481,8 +481,8 @@ describe('protoBinaryTest', function() {
     var msg = new proto.jspb.test.TestAllTypes();
 
     function assertGetters() {
-      assertTrue(goog.isString(msg.getRepeatedBytesList_asB64()[0]));
-      assertTrue(goog.isString(msg.getRepeatedBytesList_asB64()[1]));
+      assertTrue(typeof msg.getRepeatedBytesList_asB64()[0] === 'string');
+      assertTrue(typeof msg.getRepeatedBytesList_asB64()[1] === 'string');
       assertTrue(msg.getRepeatedBytesList_asU8()[0] instanceof Uint8Array);
       assertTrue(msg.getRepeatedBytesList_asU8()[1] instanceof Uint8Array);
 

+ 4 - 4
js/binary/reader.js

@@ -445,9 +445,9 @@ jspb.BinaryReader.prototype.skipField = function() {
  * @param {string} callbackName
  * @param {function(!jspb.BinaryReader):*} callback
  */
-jspb.BinaryReader.prototype.registerReadCallback =
-    function(callbackName, callback) {
-  if (goog.isNull(this.readCallbacks_)) {
+jspb.BinaryReader.prototype.registerReadCallback = function(
+    callbackName, callback) {
+  if (this.readCallbacks_ === null) {
     this.readCallbacks_ = {};
   }
   goog.asserts.assert(!this.readCallbacks_[callbackName]);
@@ -461,7 +461,7 @@ jspb.BinaryReader.prototype.registerReadCallback =
  * @return {*} The value returned by the callback.
  */
 jspb.BinaryReader.prototype.runReadCallback = function(callbackName) {
-  goog.asserts.assert(!goog.isNull(this.readCallbacks_));
+  goog.asserts.assert(this.readCallbacks_ !== null);
   var callback = this.readCallbacks_[callbackName];
   goog.asserts.assert(callback);
   return callback(this);

+ 1 - 1
js/binary/utils.js

@@ -1001,7 +1001,7 @@ jspb.utils.debugBytesToTextFormat = function(byteSource) {
  * @return {string} Stringified scalar for text format.
  */
 jspb.utils.debugScalarToTextFormat = function(scalar) {
-  if (goog.isString(scalar)) {
+  if (typeof scalar === 'string') {
     return goog.string.quote(scalar);
   } else {
     return scalar.toString();

+ 3 - 3
js/binary/utils_test.js

@@ -356,7 +356,7 @@ describe('binaryUtilsTest', function() {
      */
     function test(x, opt_bits) {
       jspb.utils.splitFloat32(x);
-      if (goog.isDef(opt_bits)) {
+      if (opt_bits !== undefined) {
         if (opt_bits != jspb.utils.split64Low) throw 'fail!';
       }
       expect(truncate(x))
@@ -428,11 +428,11 @@ describe('binaryUtilsTest', function() {
      */
     function test(x, opt_highBits, opt_lowBits) {
       jspb.utils.splitFloat64(x);
-      if (goog.isDef(opt_highBits)) {
+      if (opt_highBits !== undefined) {
         var split64High = jspb.utils.split64High;
         expect(opt_highBits.toString(16)).toEqual(split64High.toString(16));
       }
-      if (goog.isDef(opt_lowBits)) {
+      if (opt_lowBits !== undefined) {
         var split64Low = jspb.utils.split64Low;
         expect(opt_lowBits.toString(16)).toEqual(split64Low.toString(16));
       }

+ 1 - 1
js/binary/writer.js

@@ -748,7 +748,7 @@ jspb.BinaryWriter.prototype.writeDouble = function(field, value) {
  */
 jspb.BinaryWriter.prototype.writeBool = function(field, value) {
   if (value == null) return;
-  goog.asserts.assert(goog.isBoolean(value) || goog.isNumber(value));
+  goog.asserts.assert(typeof value === 'boolean' || typeof value === 'number');
   this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
   this.encoder_.writeBool(value);
 };

+ 5 - 5
js/map.js

@@ -208,14 +208,14 @@ jspb.Map.ArrayIteratorIterable_.prototype.next = function() {
   }
 };
 
+
 if (typeof(Symbol) != 'undefined') {
-  /** @override */
-  jspb.Map.ArrayIteratorIterable_.prototype[Symbol.iterator] = function() {
-    return this;
-  };
+/** @override */
+jspb.Map.ArrayIteratorIterable_.prototype[Symbol.iterator] = function() {
+  return this;
+};
 }
 
-
 /**
  * Returns the map's length (number of key/value pairs).
  * @return {number}

+ 5 - 5
js/message.js

@@ -778,7 +778,7 @@ jspb.Message.getRepeatedBooleanField = function(msg, fieldNumber) {
  * @return {?string} The field's coerced value.
  */
 jspb.Message.bytesAsB64 = function(value) {
-  if (value == null || goog.isString(value)) {
+  if (value == null || typeof value === 'string') {
     return value;
   }
   if (jspb.Message.SUPPORTS_UINT8ARRAY_ && value instanceof Uint8Array) {
@@ -800,7 +800,7 @@ jspb.Message.bytesAsU8 = function(value) {
   if (value == null || value instanceof Uint8Array) {
     return value;
   }
-  if (goog.isString(value)) {
+  if (typeof value === 'string') {
     return goog.crypt.base64.decodeStringToUint8Array(value);
   }
   goog.asserts.fail('Cannot coerce to Uint8Array: ' + goog.typeOf(value));
@@ -816,7 +816,7 @@ jspb.Message.bytesAsU8 = function(value) {
  */
 jspb.Message.bytesListAsB64 = function(value) {
   jspb.Message.assertConsistentTypes_(value);
-  if (!value.length || goog.isString(value[0])) {
+  if (!value.length || typeof value[0] === 'string') {
     return /** @type {!Array<string>} */ (value);
   }
   return goog.array.map(value, jspb.Message.bytesAsB64);
@@ -1654,8 +1654,8 @@ jspb.Message.compareFields = function(field1, field2) {
 
   if (!goog.isObject(field1) || !goog.isObject(field2)) {
     // NaN != NaN so we cover this case.
-    if ((goog.isNumber(field1) && isNaN(field1)) ||
-        (goog.isNumber(field2) && isNaN(field2))) {
+    if ((typeof field1 === 'number' && isNaN(field1)) ||
+        (typeof field2 === 'number' && isNaN(field2))) {
       // One of the fields might be a string 'NaN'.
       return String(field1) == String(field2);
     }

+ 1 - 1
js/message_test.js

@@ -855,7 +855,7 @@ describe('Message test suite', function() {
     var assertNan = function(x) {
       assertTrue(
           'Expected ' + x + ' (' + goog.typeOf(x) + ') to be NaN.',
-          goog.isNumber(x) && isNaN(x));
+          typeof x === 'number' && isNaN(x));
     };
 
     var message = new proto.jspb.test.FloatingPointFields([

+ 1 - 1
js/proto3_test.js

@@ -54,7 +54,7 @@ var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES);
  * @return {boolean}
  */
 function bytesCompare(arr, expected) {
-  if (goog.isString(arr)) {
+  if (typeof arr === 'string') {
     arr = goog.crypt.base64.decodeStringToUint8Array(arr);
   }
   if (arr.length != expected.length) {

+ 1 - 1
objectivec/google/protobuf/FieldMask.pbobjc.h

@@ -253,7 +253,7 @@ typedef GPB_ENUM(GPBFieldMask_FieldNumber) {
  *
  * The implementation of any API method which has a FieldMask type field in the
  * request should verify the included field paths, and return an
- * `INVALID_ARGUMENT` error if any path is duplicated or unmappable.
+ * `INVALID_ARGUMENT` error if any path is unmappable.
  **/
 @interface GPBFieldMask : GPBMessage
 

+ 1 - 5
python/google/protobuf/descriptor.py

@@ -45,7 +45,7 @@ if api_implementation.Type() == 'cpp':
   import binascii
   import os
   from google.protobuf.pyext import _message
-  _USE_C_DESCRIPTORS = getattr(_message, '_USE_C_DESCRIPTORS', False)
+  _USE_C_DESCRIPTORS = True
 
 
 class Error(Exception):
@@ -904,10 +904,6 @@ class FileDescriptor(DescriptorBase):
     self.dependencies = (dependencies or [])
     self.public_dependencies = (public_dependencies or [])
 
-    if (api_implementation.Type() == 'cpp' and
-        self.serialized_pb is not None):
-      _message.default_pool.AddSerializedFile(self.serialized_pb)
-
   def CopyToProto(self, proto):
     """Copies this to a descriptor_pb2.FileDescriptorProto.
 

+ 10 - 2
python/google/protobuf/internal/enum_type_wrapper.py

@@ -37,6 +37,8 @@ on proto classes.  For usage, see:
 
 __author__ = 'rabsatt@google.com (Kevin Rabsatt)'
 
+import six
+
 
 class EnumTypeWrapper(object):
   """A utility for finding the names of enum values."""
@@ -52,8 +54,14 @@ class EnumTypeWrapper(object):
     """Returns a string containing the name of an enum value."""
     if number in self._enum_type.values_by_number:
       return self._enum_type.values_by_number[number].name
-    raise ValueError('Enum %s has no name defined for value %d' % (
-        self._enum_type.name, number))
+
+    if not isinstance(number, six.integer_types):
+      raise TypeError('Enum value for %s must be an int, but got %r.' % (
+          self._enum_type.name, number))
+    else:
+      # %r here to handle the odd case when you pass in a boolean.
+      raise ValueError('Enum %s has no name defined for value %r' % (
+          self._enum_type.name, number))
 
   def Value(self, name):
     """Returns the value corresponding to the given enum name."""

+ 8 - 0
python/google/protobuf/internal/json_format_test.py

@@ -818,6 +818,14 @@ class JsonFormatTest(JsonFormatBase):
     self.assertEqual(message.repeated_float_value[0], float('inf'))
     self.assertAlmostEqual(message.repeated_float_value[1], 1.4028235e-39)
 
+  def testFloatPrecision(self):
+    message = json_format_proto3_pb2.TestMessage()
+    message.float_value = 1.123456789
+    # Set to 7 valid digits.
+    text = '{\n  "floatValue": 1.123457\n}'
+    self.assertEqual(
+        json_format.MessageToJson(message, float_precision=7), text)
+
   def testParseEmptyText(self):
     self.CheckError('',
                     r'Failed to load JSON: (Expecting value)|(No JSON).')

Різницю між файлами не показано, бо вона завелика
+ 751 - 451
python/google/protobuf/internal/reflection_test.py


+ 25 - 1
python/google/protobuf/internal/text_format_test.py

@@ -817,11 +817,19 @@ class TextFormatParserTests(TextFormatBase):
         r'have multiple "optional_int32" fields.'), text_format.Parse, text,
                           message)
 
+  def testParseExistingScalarInMessage(self, message_module):
+    message = message_module.TestAllTypes(optional_int32=42)
+    text = 'optional_int32: 67'
+    six.assertRaisesRegex(self, text_format.ParseError,
+                          (r'Message type "\w+.TestAllTypes" should not '
+                           r'have multiple "optional_int32" fields.'),
+                          text_format.Parse, text, message)
+
 
 @_parameterized.parameters(unittest_pb2, unittest_proto3_arena_pb2)
 class TextFormatMergeTests(TextFormatBase):
 
-  def testMergeDuplicateScalars(self, message_module):
+  def testMergeDuplicateScalarsInText(self, message_module):
     message = message_module.TestAllTypes()
     text = ('optional_int32: 42 ' 'optional_int32: 67')
     r = text_format.Merge(text, message)
@@ -836,6 +844,22 @@ class TextFormatMergeTests(TextFormatBase):
     self.assertTrue(r is message)
     self.assertEqual(2, message.optional_nested_message.bb)
 
+  def testReplaceScalarInMessage(self, message_module):
+    message = message_module.TestAllTypes(optional_int32=42)
+    text = 'optional_int32: 67'
+    r = text_format.Merge(text, message)
+    self.assertIs(r, message)
+    self.assertEqual(67, message.optional_int32)
+
+  def testReplaceMessageInMessage(self, message_module):
+    message = message_module.TestAllTypes(
+        optional_int32=42, optional_nested_message=dict())
+    self.assertTrue(message.HasField('optional_nested_message'))
+    text = 'optional_nested_message{ bb: 3 }'
+    r = text_format.Merge(text, message)
+    self.assertIs(r, message)
+    self.assertEqual(3, message.optional_nested_message.bb)
+
   def testMergeMultipleOneof(self, message_module):
     m_string = '\n'.join(['oneof_uint32: 11', 'oneof_string: "foo"'])
     m2 = message_module.TestAllTypes()

+ 20 - 5
python/google/protobuf/json_format.py

@@ -103,7 +103,8 @@ def MessageToJson(
     indent=2,
     sort_keys=False,
     use_integers_for_enums=False,
-    descriptor_pool=None):
+    descriptor_pool=None,
+    float_precision=None):
   """Converts protobuf message to JSON format.
 
   Args:
@@ -121,6 +122,7 @@ def MessageToJson(
     use_integers_for_enums: If true, print integers instead of enum names.
     descriptor_pool: A Descriptor Pool for resolving types. If None use the
         default.
+    float_precision: If set, use this to specify float field valid digits.
 
   Returns:
     A string containing the JSON formatted protocol buffer message.
@@ -129,7 +131,8 @@ def MessageToJson(
       including_default_value_fields,
       preserving_proto_field_name,
       use_integers_for_enums,
-      descriptor_pool)
+      descriptor_pool,
+      float_precision=float_precision)
   return printer.ToJsonString(message, indent, sort_keys)
 
 
@@ -138,7 +141,8 @@ def MessageToDict(
     including_default_value_fields=False,
     preserving_proto_field_name=False,
     use_integers_for_enums=False,
-    descriptor_pool=None):
+    descriptor_pool=None,
+    float_precision=None):
   """Converts protobuf message to a dictionary.
 
   When the dictionary is encoded to JSON, it conforms to proto3 JSON spec.
@@ -155,6 +159,7 @@ def MessageToDict(
     use_integers_for_enums: If true, print integers instead of enum names.
     descriptor_pool: A Descriptor Pool for resolving types. If None use the
         default.
+    float_precision: If set, use this to specify float field valid digits.
 
   Returns:
     A dict representation of the protocol buffer message.
@@ -163,7 +168,8 @@ def MessageToDict(
       including_default_value_fields,
       preserving_proto_field_name,
       use_integers_for_enums,
-      descriptor_pool)
+      descriptor_pool,
+      float_precision=float_precision)
   # pylint: disable=protected-access
   return printer._MessageToJsonObject(message)
 
@@ -182,11 +188,17 @@ class _Printer(object):
       including_default_value_fields=False,
       preserving_proto_field_name=False,
       use_integers_for_enums=False,
-      descriptor_pool=None):
+      descriptor_pool=None,
+      float_precision=None):
     self.including_default_value_fields = including_default_value_fields
     self.preserving_proto_field_name = preserving_proto_field_name
     self.use_integers_for_enums = use_integers_for_enums
     self.descriptor_pool = descriptor_pool
+    # TODO(jieluo): change the float precision default to 8 valid digits.
+    if float_precision:
+      self.float_format = '.{}g'.format(float_precision)
+    else:
+      self.float_format = None
 
   def ToJsonString(self, message, indent, sort_keys):
     js = self._MessageToJsonObject(message)
@@ -301,6 +313,9 @@ class _Printer(object):
           return _INFINITY
       if math.isnan(value):
         return _NAN
+      if (self.float_format and
+          field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_FLOAT):
+        return float(format(value, self.float_format))
     return value
 
   def _AnyMessageToJsonObject(self, message):

+ 0 - 4
python/google/protobuf/pyext/message.cc

@@ -3029,10 +3029,6 @@ bool InitProto2MessageModule(PyObject *m) {
   PyModule_AddObject(m, "DescriptorPool", reinterpret_cast<PyObject*>(
       &PyDescriptorPool_Type));
 
-  // This implementation provides full Descriptor types, we advertise it so that
-  // descriptor.py can use them in replacement of the Python classes.
-  PyModule_AddIntConstant(m, "_USE_C_DESCRIPTORS", 1);
-
   PyModule_AddObject(m, "Descriptor", reinterpret_cast<PyObject*>(
       &PyMessageDescriptor_Type));
   PyModule_AddObject(m, "FieldDescriptor", reinterpret_cast<PyObject*>(

+ 13 - 3
python/google/protobuf/text_format.py

@@ -617,15 +617,23 @@ def Parse(text,
 
   NOTE: for historical reasons this function does not clear the input
   message. This is different from what the binary msg.ParseFrom(...) does.
+  If text contains a field already set in message, the value is appended if the
+  field is repeated. Otherwise, an error is raised.
 
   Example
     a = MyProto()
     a.repeated_field.append('test')
     b = MyProto()
 
+    # Repeated fields are combined
     text_format.Parse(repr(a), b)
     text_format.Parse(repr(a), b) # repeated_field contains ["test", "test"]
 
+    # Non-repeated fields cannot be overwritten
+    a.singular_field = 1
+    b.singular_field = 2
+    text_format.Parse(repr(a), b) # ParseError
+
     # Binary version:
     b.ParseFromString(a.SerializeToString()) # repeated_field is now "test"
 
@@ -665,7 +673,8 @@ def Merge(text,
   """Parses a text representation of a protocol message into a message.
 
   Like Parse(), but allows repeated values for a non-repeated field, and uses
-  the last one.
+  the last one. This means any non-repeated, top-level fields specified in text
+  replace those in the message.
 
   Args:
     text: Message text representation.
@@ -701,6 +710,8 @@ def ParseLines(lines,
                allow_unknown_field=False):
   """Parses a text representation of a protocol message into a message.
 
+  See Parse() for caveats.
+
   Args:
     lines: An iterable of lines of a message's text representation.
     message: A protocol buffer message to merge into.
@@ -733,8 +744,7 @@ def MergeLines(lines,
                allow_unknown_field=False):
   """Parses a text representation of a protocol message into a message.
 
-  Like ParseLines(), but allows repeated values for a non-repeated field, and
-  uses the last one.
+  See Merge() for more details.
 
   Args:
     lines: An iterable of lines of a message's text representation.

+ 0 - 2
src/Makefile.am

@@ -228,8 +228,6 @@ libprotobuf_la_SOURCES =                                       \
   $(libprotobuf_lite_la_SOURCES)                               \
   google/protobuf/any.pb.cc                                    \
   google/protobuf/api.pb.cc                                    \
-  google/protobuf/stubs/mathlimits.cc                          \
-  google/protobuf/stubs/mathlimits.h                           \
   google/protobuf/any.cc                                       \
   google/protobuf/descriptor.cc                                \
   google/protobuf/descriptor_database.cc                       \

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

@@ -169,14 +169,17 @@ const char* Any::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::intern
       // string type_url = 1;
       case 1:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) {
-          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8(_internal_mutable_type_url(), ptr, ctx, "google.protobuf.Any.type_url");
+          auto str = _internal_mutable_type_url();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+          CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Any.type_url"));
           CHK_(ptr);
         } else goto handle_unusual;
         continue;
       // bytes value = 2;
       case 2:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 18)) {
-          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(_internal_mutable_value(), ptr, ctx);
+          auto str = _internal_mutable_value();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
           CHK_(ptr);
         } else goto handle_unusual;
         continue;
@@ -200,7 +203,7 @@ failure:
 #undef CHK_
 }
 
-::PROTOBUF_NAMESPACE_ID::uint8* Any::InternalSerializeWithCachedSizesToArray(
+::PROTOBUF_NAMESPACE_ID::uint8* Any::_InternalSerialize(
     ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Any)
   ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;

+ 1 - 2
src/google/protobuf/any.pb.h

@@ -32,7 +32,6 @@
 #include <google/protobuf/repeated_field.h>  // IWYU pragma: export
 #include <google/protobuf/extension_set.h>  // IWYU pragma: export
 #include <google/protobuf/unknown_field_set.h>
-#include <google/protobuf/any.h>
 // @@protoc_insertion_point(includes)
 #include <google/protobuf/port_def.inc>
 #define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fany_2eproto PROTOBUF_EXPORT
@@ -170,7 +169,7 @@ class PROTOBUF_EXPORT Any :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 

+ 29 - 15
src/google/protobuf/api.pb.cc

@@ -282,7 +282,9 @@ const char* Api::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::intern
       // string name = 1;
       case 1:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) {
-          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8(_internal_mutable_name(), ptr, ctx, "google.protobuf.Api.name");
+          auto str = _internal_mutable_name();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+          CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Api.name"));
           CHK_(ptr);
         } else goto handle_unusual;
         continue;
@@ -313,7 +315,9 @@ const char* Api::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::intern
       // string version = 4;
       case 4:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 34)) {
-          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8(_internal_mutable_version(), ptr, ctx, "google.protobuf.Api.version");
+          auto str = _internal_mutable_version();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+          CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Api.version"));
           CHK_(ptr);
         } else goto handle_unusual;
         continue;
@@ -364,7 +368,7 @@ failure:
 #undef CHK_
 }
 
-::PROTOBUF_NAMESPACE_ID::uint8* Api::InternalSerializeWithCachedSizesToArray(
+::PROTOBUF_NAMESPACE_ID::uint8* Api::_InternalSerialize(
     ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Api)
   ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
@@ -385,7 +389,7 @@ failure:
       n = static_cast<unsigned int>(this->_internal_methods_size()); i < n; i++) {
     target = stream->EnsureSpace(target);
     target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
-      InternalWriteMessageToArray(2, this->_internal_methods(i), target, stream);
+      InternalWriteMessage(2, this->_internal_methods(i), target, stream);
   }
 
   // repeated .google.protobuf.Option options = 3;
@@ -393,7 +397,7 @@ failure:
       n = static_cast<unsigned int>(this->_internal_options_size()); i < n; i++) {
     target = stream->EnsureSpace(target);
     target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
-      InternalWriteMessageToArray(3, this->_internal_options(i), target, stream);
+      InternalWriteMessage(3, this->_internal_options(i), target, stream);
   }
 
   // string version = 4;
@@ -410,7 +414,7 @@ failure:
   if (this->has_source_context()) {
     target = stream->EnsureSpace(target);
     target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
-      InternalWriteMessageToArray(
+      InternalWriteMessage(
         5, _Internal::source_context(this), target, stream);
   }
 
@@ -419,7 +423,7 @@ failure:
       n = static_cast<unsigned int>(this->_internal_mixins_size()); i < n; i++) {
     target = stream->EnsureSpace(target);
     target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
-      InternalWriteMessageToArray(6, this->_internal_mixins(i), target, stream);
+      InternalWriteMessage(6, this->_internal_mixins(i), target, stream);
   }
 
   // .google.protobuf.Syntax syntax = 7;
@@ -675,14 +679,18 @@ const char* Method::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::int
       // string name = 1;
       case 1:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) {
-          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8(_internal_mutable_name(), ptr, ctx, "google.protobuf.Method.name");
+          auto str = _internal_mutable_name();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+          CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.name"));
           CHK_(ptr);
         } else goto handle_unusual;
         continue;
       // string request_type_url = 2;
       case 2:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 18)) {
-          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8(_internal_mutable_request_type_url(), ptr, ctx, "google.protobuf.Method.request_type_url");
+          auto str = _internal_mutable_request_type_url();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+          CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.request_type_url"));
           CHK_(ptr);
         } else goto handle_unusual;
         continue;
@@ -696,7 +704,9 @@ const char* Method::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::int
       // string response_type_url = 4;
       case 4:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 34)) {
-          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8(_internal_mutable_response_type_url(), ptr, ctx, "google.protobuf.Method.response_type_url");
+          auto str = _internal_mutable_response_type_url();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+          CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.response_type_url"));
           CHK_(ptr);
         } else goto handle_unusual;
         continue;
@@ -747,7 +757,7 @@ failure:
 #undef CHK_
 }
 
-::PROTOBUF_NAMESPACE_ID::uint8* Method::InternalSerializeWithCachedSizesToArray(
+::PROTOBUF_NAMESPACE_ID::uint8* Method::_InternalSerialize(
     ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Method)
   ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
@@ -800,7 +810,7 @@ failure:
       n = static_cast<unsigned int>(this->_internal_options_size()); i < n; i++) {
     target = stream->EnsureSpace(target);
     target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
-      InternalWriteMessageToArray(6, this->_internal_options(i), target, stream);
+      InternalWriteMessage(6, this->_internal_options(i), target, stream);
   }
 
   // .google.protobuf.Syntax syntax = 7;
@@ -1037,14 +1047,18 @@ const char* Mixin::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::inte
       // string name = 1;
       case 1:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) {
-          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8(_internal_mutable_name(), ptr, ctx, "google.protobuf.Mixin.name");
+          auto str = _internal_mutable_name();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+          CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Mixin.name"));
           CHK_(ptr);
         } else goto handle_unusual;
         continue;
       // string root = 2;
       case 2:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 18)) {
-          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8(_internal_mutable_root(), ptr, ctx, "google.protobuf.Mixin.root");
+          auto str = _internal_mutable_root();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+          CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Mixin.root"));
           CHK_(ptr);
         } else goto handle_unusual;
         continue;
@@ -1068,7 +1082,7 @@ failure:
 #undef CHK_
 }
 
-::PROTOBUF_NAMESPACE_ID::uint8* Mixin::InternalSerializeWithCachedSizesToArray(
+::PROTOBUF_NAMESPACE_ID::uint8* Mixin::_InternalSerialize(
     ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Mixin)
   ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;

+ 3 - 3
src/google/protobuf/api.pb.h

@@ -146,7 +146,7 @@ class PROTOBUF_EXPORT Api :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -387,7 +387,7 @@ class PROTOBUF_EXPORT Method :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -611,7 +611,7 @@ class PROTOBUF_EXPORT Mixin :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 

+ 5 - 32
src/google/protobuf/arena.cc

@@ -144,16 +144,6 @@ void ArenaImpl::SerialArena::AddCleanupFallback(void* elem,
   AddCleanup(elem, cleanup);
 }
 
-PROTOBUF_FUNC_ALIGN(32)
-void* ArenaImpl::AllocateAligned(size_t n) {
-  SerialArena* arena;
-  if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) {
-    return arena->AllocateAligned(n);
-  } else {
-    return AllocateAlignedFallback(n);
-  }
-}
-
 void* ArenaImpl::AllocateAlignedAndAddCleanup(size_t n,
                                               void (*cleanup)(void*)) {
   SerialArena* arena;
@@ -189,28 +179,6 @@ void ArenaImpl::AddCleanupFallback(void* elem, void (*cleanup)(void*)) {
   GetSerialArena()->AddCleanup(elem, cleanup);
 }
 
-inline PROTOBUF_ALWAYS_INLINE bool ArenaImpl::GetSerialArenaFast(
-    ArenaImpl::SerialArena** arena) {
-  // If this thread already owns a block in this arena then try to use that.
-  // This fast path optimizes the case where multiple threads allocate from the
-  // same arena.
-  ThreadCache* tc = &thread_cache();
-  if (PROTOBUF_PREDICT_TRUE(tc->last_lifecycle_id_seen == lifecycle_id_)) {
-    *arena = tc->last_serial_arena;
-    return true;
-  }
-
-  // Check whether we own the last accessed SerialArena on this arena.  This
-  // fast path optimizes the case where a single thread uses multiple arenas.
-  SerialArena* serial = hint_.load(std::memory_order_acquire);
-  if (PROTOBUF_PREDICT_TRUE(serial != NULL && serial->owner() == tc)) {
-    *arena = serial;
-    return true;
-  }
-
-  return false;
-}
-
 ArenaImpl::SerialArena* ArenaImpl::GetSerialArena() {
   SerialArena* arena;
   if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) {
@@ -391,6 +359,11 @@ ArenaImpl::SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) {
 
 }  // namespace internal
 
+PROTOBUF_FUNC_ALIGN(32)
+void* Arena::AllocateAlignedNoHook(size_t n) {
+  return impl_.AllocateAligned(n);
+}
+
 void Arena::CallDestructorHooks() {
   uint64 space_allocated = impl_.SpaceAllocated();
   // Call the reset hook

+ 7 - 3
src/google/protobuf/arena.h

@@ -88,6 +88,7 @@ namespace internal {
 
 struct ArenaStringPtr;  // defined in arenastring.h
 class LazyField;        // defined in lazy_field.h
+class EpsCopyInputStream;  // defined in parse_context.h
 
 template <typename Type>
 class GenericTypeHandler;  // defined in repeated_field.h
@@ -535,7 +536,7 @@ class PROTOBUF_EXPORT alignas(8) Arena final {
     AllocHook(RTTI_TYPE_ID(T), n);
     // Monitor allocation if needed.
     if (skip_explicit_ownership) {
-      return impl_.AllocateAligned(n);
+      return AllocateAlignedNoHook(n);
     } else {
       return impl_.AllocateAlignedAndAddCleanup(
           n, &internal::arena_destruct_object<T>);
@@ -596,7 +597,7 @@ class PROTOBUF_EXPORT alignas(8) Arena final {
     const size_t n = internal::AlignUpTo8(sizeof(T) * num_elements);
     // Monitor allocation if needed.
     AllocHook(RTTI_TYPE_ID(T), n);
-    return static_cast<T*>(impl_.AllocateAligned(n));
+    return static_cast<T*>(AllocateAlignedNoHook(n));
   }
 
   template <typename T, typename... Args>
@@ -689,9 +690,11 @@ class PROTOBUF_EXPORT alignas(8) Arena final {
   // For friends of arena.
   void* AllocateAligned(size_t n) {
     AllocHook(NULL, n);
-    return impl_.AllocateAligned(internal::AlignUpTo8(n));
+    return AllocateAlignedNoHook(internal::AlignUpTo8(n));
   }
 
+  void* AllocateAlignedNoHook(size_t n);
+
   internal::ArenaImpl impl_;
 
   void (*on_arena_allocation_)(const std::type_info* allocated_type,
@@ -707,6 +710,7 @@ class PROTOBUF_EXPORT alignas(8) Arena final {
   friend class internal::GenericTypeHandler;
   friend struct internal::ArenaStringPtr;  // For AllocateAligned.
   friend class internal::LazyField;        // For CreateMaybeMessage.
+  friend class internal::EpsCopyInputStream;  // For parser performance
   friend class MessageLite;
   template <typename Key, typename T>
   friend class Map;

+ 64 - 3
src/google/protobuf/arena_impl.h

@@ -107,7 +107,27 @@ class PROTOBUF_EXPORT ArenaImpl {
   uint64 SpaceAllocated() const;
   uint64 SpaceUsed() const;
 
-  void* AllocateAligned(size_t n);
+  void* AllocateAligned(size_t n) {
+    SerialArena* arena;
+    if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) {
+      return arena->AllocateAligned(n);
+    } else {
+      return AllocateAlignedFallback(n);
+    }
+  }
+
+  // This function allocates n bytes if the common happy case is true and
+  // returns true. Otherwise does nothing and returns false. This strange
+  // semantics is necessary to allow callers to program functions that only
+  // have fallback function calls in tail position. This substantially improves
+  // code for the happy path.
+  PROTOBUF_ALWAYS_INLINE bool MaybeAllocateAligned(size_t n, void** out) {
+    SerialArena* a;
+    if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFromThreadCache(&a))) {
+      return a->MaybeAllocateAligned(n, out);
+    }
+    return false;
+  }
 
   void* AllocateAlignedAndAddCleanup(size_t n, void (*cleanup)(void*));
 
@@ -156,10 +176,12 @@ class PROTOBUF_EXPORT ArenaImpl {
     void CleanupList();
     uint64 SpaceUsed() const;
 
+    bool HasSpace(size_t n) { return n <= static_cast<size_t>(limit_ - ptr_); }
+
     void* AllocateAligned(size_t n) {
       GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n);  // Must be already aligned.
       GOOGLE_DCHECK_GE(limit_, ptr_);
-      if (PROTOBUF_PREDICT_FALSE(static_cast<size_t>(limit_ - ptr_) < n)) {
+      if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) {
         return AllocateAlignedFallback(n);
       }
       void* ret = ptr_;
@@ -170,6 +192,20 @@ class PROTOBUF_EXPORT ArenaImpl {
       return ret;
     }
 
+    // Allocate space if the current region provides enough space.
+    bool MaybeAllocateAligned(size_t n, void** out) {
+      GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n);  // Must be already aligned.
+      GOOGLE_DCHECK_GE(limit_, ptr_);
+      if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) return false;
+      void* ret = ptr_;
+      ptr_ += n;
+#ifdef ADDRESS_SANITIZER
+      ASAN_UNPOISON_MEMORY_REGION(ret, n);
+#endif  // ADDRESS_SANITIZER
+      *out = ret;
+      return true;
+    }
+
     void AddCleanup(void* elem, void (*cleanup)(void*)) {
       if (PROTOBUF_PREDICT_FALSE(cleanup_ptr_ == cleanup_limit_)) {
         AddCleanupFallback(elem, cleanup);
@@ -292,7 +328,32 @@ class PROTOBUF_EXPORT ArenaImpl {
   Block* NewBlock(Block* last_block, size_t min_bytes);
 
   SerialArena* GetSerialArena();
-  bool GetSerialArenaFast(SerialArena** arena);
+  PROTOBUF_ALWAYS_INLINE bool GetSerialArenaFast(SerialArena** arena) {
+    if (GetSerialArenaFromThreadCache(arena)) return true;
+
+    // Check whether we own the last accessed SerialArena on this arena.  This
+    // fast path optimizes the case where a single thread uses multiple arenas.
+    ThreadCache* tc = &thread_cache();
+    SerialArena* serial = hint_.load(std::memory_order_acquire);
+    if (PROTOBUF_PREDICT_TRUE(serial != NULL && serial->owner() == tc)) {
+      *arena = serial;
+      return true;
+    }
+    return false;
+  }
+
+  PROTOBUF_ALWAYS_INLINE bool GetSerialArenaFromThreadCache(
+      SerialArena** arena) {
+    // If this thread already owns a block in this arena then try to use that.
+    // This fast path optimizes the case where multiple threads allocate from
+    // the same arena.
+    ThreadCache* tc = &thread_cache();
+    if (PROTOBUF_PREDICT_TRUE(tc->last_lifecycle_id_seen == lifecycle_id_)) {
+      *arena = tc->last_serial_arena;
+      return true;
+    }
+    return false;
+  }
   SerialArena* GetSerialArenaFallback(void* me);
   LifecycleId lifecycle_id_;  // Unique for each arena. Changes on Reset().
 

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

@@ -32,6 +32,7 @@
 #define GOOGLE_PROTOBUF_ARENASTRING_H__
 
 #include <string>
+#include <type_traits>
 #include <utility>
 
 #include <google/protobuf/stubs/logging.h>

+ 1 - 1
src/google/protobuf/arenastring_unittest.cc

@@ -43,6 +43,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <gtest/gtest.h>
+#include <google/protobuf/stubs/strutil.h>
 
 
 namespace google {
@@ -50,7 +51,6 @@ namespace protobuf {
 
 using internal::ArenaStringPtr;
 
-
 static std::string WrapString(const char* value) { return value; }
 
 // Test ArenaStringPtr with arena == NULL.

+ 9 - 5
src/google/protobuf/compiler/command_line_interface.cc

@@ -869,7 +869,8 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
   }
 
   descriptor_pool->EnforceWeakDependencies(true);
-  if (!ParseInputFiles(descriptor_pool.get(), &parsed_files)) {
+  if (!ParseInputFiles(descriptor_pool.get(), disk_source_tree.get(),
+                       &parsed_files)) {
     return 1;
   }
 
@@ -1044,7 +1045,8 @@ bool CommandLineInterface::VerifyInputFilesInDescriptors(
   for (const auto& input_file : input_files_) {
     FileDescriptorProto file_descriptor;
     if (!database->FindFileByName(input_file, &file_descriptor)) {
-      std::cerr << input_file << ": " << strerror(ENOENT) << std::endl;
+      std::cerr << "Could not find file in descriptor database: " << input_file
+                << ": " << strerror(ENOENT) << std::endl;
       return false;
     }
 
@@ -1061,7 +1063,7 @@ bool CommandLineInterface::VerifyInputFilesInDescriptors(
 }
 
 bool CommandLineInterface::ParseInputFiles(
-    DescriptorPool* descriptor_pool,
+    DescriptorPool* descriptor_pool, DiskSourceTree* source_tree,
     std::vector<const FileDescriptor*>* parsed_files) {
 
   // Track unused imports in all source files
@@ -1154,7 +1156,8 @@ bool CommandLineInterface::MakeProtoProtoPathRelative(
         in_fallback_database) {
       return true;
     } else {
-      std::cerr << *proto << ": " << strerror(ENOENT) << std::endl;
+      std::cerr << "Could not make proto path relative: " << *proto << ": "
+                << strerror(ENOENT) << std::endl;
       return false;
     }
   }
@@ -1177,7 +1180,8 @@ bool CommandLineInterface::MakeProtoProtoPathRelative(
       if (in_fallback_database) {
         return true;
       }
-      std::cerr << *proto << ": " << strerror(errno) << std::endl;
+      std::cerr << "Could not map to virtual file: " << *proto << ": "
+                << strerror(errno) << std::endl;
       return false;
     case DiskSourceTree::NO_MAPPING: {
       // Try to interpret the path as a virtual path.

+ 2 - 0
src/google/protobuf/compiler/command_line_interface.h

@@ -43,6 +43,7 @@
 #include <set>
 #include <string>
 #include <unordered_map>
+#include <unordered_set>
 #include <utility>
 #include <vector>
 
@@ -273,6 +274,7 @@ class PROTOC_EXPORT CommandLineInterface {
 
   // Parses input_files_ into parsed_files
   bool ParseInputFiles(DescriptorPool* descriptor_pool,
+                       DiskSourceTree* source_tree,
                        std::vector<const FileDescriptor*>* parsed_files);
 
   // Generate the given output file from the given input.

+ 17 - 5
src/google/protobuf/compiler/command_line_interface_unittest.cc

@@ -1778,7 +1778,9 @@ TEST_F(CommandLineInterfaceTest, InputNotFoundError) {
   Run("protocol_compiler --test_out=$tmpdir "
       "--proto_path=$tmpdir foo.proto");
 
-  ExpectErrorText("foo.proto: No such file or directory\n");
+  ExpectErrorText(
+      "Could not make proto path relative: foo.proto: No such file or "
+      "directory\n");
 }
 
 TEST_F(CommandLineInterfaceTest, InputNotFoundError_DescriptorSetIn) {
@@ -1797,7 +1799,9 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundError) {
   Run("protocol_compiler --test_out=$tmpdir "
       "--proto_path=$tmpdir $tmpdir/foo.proto");
 
-  ExpectErrorText("$tmpdir/foo.proto: No such file or directory\n");
+  ExpectErrorText(
+      "Could not make proto path relative: $tmpdir/foo.proto: No such file or "
+      "directory\n");
 }
 
 TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotMappedError) {
@@ -1834,7 +1838,9 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundAndNotMappedError) {
   Run("protocol_compiler --test_out=$tmpdir "
       "--proto_path=$tmpdir/bar $tmpdir/foo.proto");
 
-  ExpectErrorText("$tmpdir/foo.proto: No such file or directory\n");
+  ExpectErrorText(
+      "Could not make proto path relative: $tmpdir/foo.proto: No such file or "
+      "directory\n");
 }
 
 TEST_F(CommandLineInterfaceTest, CwdRelativeInputShadowedError) {
@@ -1867,7 +1873,8 @@ TEST_F(CommandLineInterfaceTest, ProtoPathNotFoundError) {
 
   ExpectErrorText(
       "$tmpdir/foo: warning: directory does not exist.\n"
-      "foo.proto: No such file or directory\n");
+      "Could not make proto path relative: foo.proto: No such file or "
+      "directory\n");
 }
 
 TEST_F(CommandLineInterfaceTest, ProtoPathAndDescriptorSetIn) {
@@ -2479,6 +2486,11 @@ class EncodeDecodeTest : public testing::TestWithParam<EncodeDecodeTestMode> {
     EXPECT_EQ(StripCR(expected_text), StripCR(captured_stderr_));
   }
 
+  void ExpectStderrContainsText(const std::string& expected_text) {
+    EXPECT_NE(StripCR(captured_stderr_).find(StripCR(expected_text)),
+              std::string::npos);
+  }
+
  private:
   void WriteUnittestProtoDescriptorSet() {
     unittest_proto_descriptor_set_filename_ =
@@ -2569,7 +2581,7 @@ TEST_P(EncodeDecodeTest, ProtoParseError) {
       Run("net/proto2/internal/no_such_file.proto "
           "--encode=NoSuchType"));
   ExpectStdoutMatchesText("");
-  ExpectStderrMatchesText(
+  ExpectStderrContainsText(
       "net/proto2/internal/no_such_file.proto: No such file or directory\n");
 }
 

+ 4 - 6
src/google/protobuf/compiler/cpp/cpp_enum.cc

@@ -104,10 +104,8 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
     // 2147483648, and since 2147483648 can't fit in an integer, this produces a
     // compiler warning.  This works around that issue.
     format_value.Set("number", Int32ToString(descriptor_->value(i)->number()));
-    format_value.Set(
-        "deprecation",
-        DeprecatedAttribute(options_,
-                            descriptor_->value(i)->options().deprecated()));
+    format_value.Set("deprecation",
+                     DeprecatedAttribute(options_, descriptor_->value(i)));
 
     if (i > 0) format_value(",\n");
     format_value("${1$$prefix$$name$$}$ $deprecation$= $number$",
@@ -213,8 +211,8 @@ void EnumGenerator::GenerateSymbolImports(io::Printer* printer) const {
   format("typedef $classname$ $resolved_name$;\n");
 
   for (int j = 0; j < descriptor_->value_count(); j++) {
-    std::string deprecated_attr = DeprecatedAttribute(
-        options_, descriptor_->value(j)->options().deprecated());
+    std::string deprecated_attr =
+        DeprecatedAttribute(options_, descriptor_->value(j));
     format(
         "$1$static constexpr $resolved_name$ ${2$$3$$}$ =\n"
         "  $classname$_$3$;\n",

+ 1 - 2
src/google/protobuf/compiler/cpp/cpp_field.cc

@@ -69,8 +69,7 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
 
   (*variables)["tag_size"] = StrCat(
       WireFormat::TagSize(descriptor->number(), descriptor->type()));
-  (*variables)["deprecated_attr"] =
-      DeprecatedAttribute(options, descriptor->options().deprecated());
+  (*variables)["deprecated_attr"] = DeprecatedAttribute(options, descriptor);
 
   (*variables)["set_hasbit"] = "";
   (*variables)["clear_hasbit"] = "";

+ 0 - 4
src/google/protobuf/compiler/cpp/cpp_file.cc

@@ -1357,10 +1357,6 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
   if (UseUnknownFieldSet(file_, options_) && !message_generators_.empty()) {
     IncludeFile("net/proto2/public/unknown_field_set.h", printer);
   }
-
-  if (IsAnyMessage(file_, options_)) {
-    IncludeFile("net/proto2/internal/any.h", printer);
-  }
 }
 
 void FileGenerator::GenerateMetadataPragma(io::Printer* printer,

+ 55 - 59
src/google/protobuf/compiler/cpp/cpp_helpers.cc

@@ -983,12 +983,6 @@ bool IsWellKnownMessage(const FileDescriptor* file) {
   return well_known_files.find(file->name()) != well_known_files.end();
 }
 
-enum Utf8CheckMode {
-  STRICT = 0,  // Parsing will fail if non UTF-8 data is in string fields.
-  VERIFY = 1,  // Only log an error but parsing will succeed.
-  NONE = 2,    // No UTF-8 check.
-};
-
 static bool FieldEnforceUtf8(const FieldDescriptor* field,
                              const Options& options) {
   return true;
@@ -1000,8 +994,8 @@ static bool FileUtf8Verification(const FileDescriptor* file,
 }
 
 // Which level of UTF-8 enforcemant is placed on this file.
-static Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field,
-                                      const Options& options) {
+Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field,
+                               const Options& options) {
   if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
       FieldEnforceUtf8(field, options)) {
     return STRICT;
@@ -1014,19 +1008,6 @@ static Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field,
   }
 }
 
-std::string GetUtf8Suffix(const FieldDescriptor* field,
-                          const Options& options) {
-  switch (GetUtf8CheckMode(field, options)) {
-    case STRICT:
-      return "UTF8";
-    case VERIFY:
-      return "UTF8Verify";
-    case NONE:
-    default:  // Some build configs warn on missing return without default.
-      return "";
-  }
-}
-
 static void GenerateUtf8CheckCode(const FieldDescriptor* field,
                                   const Options& options, bool for_parse,
                                   const char* parameters,
@@ -1418,13 +1399,7 @@ class ParseLoopGenerator {
   using WireFormat = internal::WireFormat;
   using WireFormatLite = internal::WireFormatLite;
 
-  void GenerateArenaString(const FieldDescriptor* field,
-                           const std::string& utf8, std::string field_name) {
-    if (!field_name.empty()) {
-      format_("static const char kFieldName[] = $1$;\n",
-              field_name.substr(2));  // remove ", "
-      field_name = ", kFieldName";
-    }
+  void GenerateArenaString(const FieldDescriptor* field) {
     if (HasFieldPresence(field->file())) {
       format_("_Internal::set_has_$1$(&$has_bits$);\n", FieldName(field));
     }
@@ -1436,28 +1411,17 @@ class ParseLoopGenerator {
                   "::" + MakeDefaultName(field) + ".get()";
     format_(
         "if (arena != nullptr) {\n"
-        "  ptr = $pi_ns$::InlineCopyIntoArenaString$1$(&$2$_, ptr, ctx, "
-        "  arena$3$);\n"
+        "  ptr = ctx->ReadArenaString(ptr, &$1$_, arena);\n"
         "} else {\n"
         "  ptr = "
-        "$pi_ns$::InlineGreedyStringParser$1$($2$_.MutableNoArenaNoDefault(&$4$"
-        "), ptr, ctx$3$);"
-        "\n}\n",
-        utf8, FieldName(field), field_name, default_string);
+        "$pi_ns$::InlineGreedyStringParser($1$_.MutableNoArenaNoDefault(&$2$"
+        "), ptr, ctx);"
+        "\n}\n"
+        "const std::string* str = &$1$_.Get(); (void)str;\n",
+        FieldName(field), default_string);
   }
 
   void GenerateStrings(const FieldDescriptor* field, bool check_utf8) {
-    std::string utf8;
-    std::string field_name;
-    if (check_utf8) {
-      utf8 = GetUtf8Suffix(field, options_);
-      if (!utf8.empty()) {
-        field_name = ", nullptr";
-        if (HasDescriptorMethods(field->file(), options_)) {
-          field_name = StrCat(", \"", field->full_name(), "\"");
-        }
-      }
-    }
     FieldOptions::CType ctype = FieldOptions::STRING;
     if (!options_.opensource_runtime) {
       // Open source doesn't support other ctypes;
@@ -1470,25 +1434,57 @@ class ParseLoopGenerator {
         field->default_value_string().empty() &&
         !IsStringInlined(field, options_) &&
         field->containing_oneof() == nullptr && ctype == FieldOptions::STRING) {
-      GenerateArenaString(field, utf8, field_name);
-      return;
+      GenerateArenaString(field);
+    } else {
+      std::string name;
+      switch (ctype) {
+        case FieldOptions::STRING:
+          name = "GreedyStringParser";
+          break;
+        case FieldOptions::CORD:
+          name = "CordParser";
+          break;
+        case FieldOptions::STRING_PIECE:
+          name = "StringPieceParser";
+          break;
+      }
+      format_(
+          "auto str = $1$$2$_$3$();\n"
+          "ptr = $pi_ns$::Inline$4$(str, ptr, ctx);\n",
+          HasInternalAccessors(ctype) ? "_internal_" : "",
+          field->is_repeated() && !field->is_packable() ? "add" : "mutable",
+          FieldName(field), name);
     }
-    std::string name;
-    switch (ctype) {
-      case FieldOptions::STRING:
-        name = "GreedyStringParser" + utf8;
+    if (!check_utf8) return;  // return if this is a bytes field
+    auto level = GetUtf8CheckMode(field, options_);
+    switch (level) {
+      case NONE:
+        return;
+      case VERIFY:
+        format_("#ifndef NDEBUG\n");
+        break;
+      case STRICT:
+        format_("CHK_(");
         break;
-      case FieldOptions::CORD:
-        name = "CordParser" + utf8;
+    }
+    std::string field_name;
+    field_name = "nullptr";
+    if (HasDescriptorMethods(field->file(), options_)) {
+      field_name = StrCat("\"", field->full_name(), "\"");
+    }
+    format_("$pi_ns$::VerifyUTF8(str, $1$)", field_name);
+    switch (level) {
+      case NONE:
+        return;
+      case VERIFY:
+        format_(
+            ";\n"
+            "#endif  // !NDEBUG\n");
         break;
-      case FieldOptions::STRING_PIECE:
-        name = "StringPieceParser" + utf8;
+      case STRICT:
+        format_(");\n");
         break;
     }
-    format_("ptr = $pi_ns$::Inline$1$($2$$3$_$4$(), ptr, ctx$5$);\n", name,
-            HasInternalAccessors(ctype) ? "_internal_" : "",
-            field->is_repeated() && !field->is_packable() ? "add" : "mutable",
-            FieldName(field), field_name);
   }
 
   void GenerateLengthDelim(const FieldDescriptor* field) {

+ 16 - 3
src/google/protobuf/compiler/cpp/cpp_helpers.h

@@ -66,8 +66,13 @@ inline std::string MacroPrefix(const Options& options) {
 }
 
 inline std::string DeprecatedAttribute(const Options& options,
-                                       bool deprecated) {
-  return deprecated ? "PROTOBUF_DEPRECATED " : "";
+                                       const FieldDescriptor* d) {
+  return d->options().deprecated() ? "PROTOBUF_DEPRECATED " : "";
+}
+
+inline std::string DeprecatedAttribute(const Options& options,
+                                       const EnumValueDescriptor* d) {
+  return d->options().deprecated() ? "PROTOBUF_DEPRECATED_ENUM " : "";
 }
 
 // Commonly-used separator comments.  Thick is a line of '=', thin is a line
@@ -756,7 +761,15 @@ class PROTOC_EXPORT NamespaceOpener {
   std::vector<std::string> name_stack_;
 };
 
-std::string GetUtf8Suffix(const FieldDescriptor* field, const Options& options);
+enum Utf8CheckMode {
+  STRICT = 0,  // Parsing will fail if non UTF-8 data is in string fields.
+  VERIFY = 1,  // Only log an error but parsing will succeed.
+  NONE = 2,    // No UTF-8 check.
+};
+
+Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field,
+                               const Options& options);
+
 void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
                                     const Options& options, bool for_parse,
                                     const char* parameters,

+ 21 - 19
src/google/protobuf/compiler/cpp/cpp_message.cc

@@ -1011,10 +1011,10 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
         "  static const $classname$* internal_default_instance() { return "
         "reinterpret_cast<const "
         "$classname$*>(&_$classname$_default_instance_); }\n");
-    std::string suffix = GetUtf8Suffix(descriptor_->field(0), options_);
+    auto utf8_check = GetUtf8CheckMode(descriptor_->field(0), options_);
     if (descriptor_->field(0)->type() == FieldDescriptor::TYPE_STRING &&
-        !suffix.empty()) {
-      if (suffix == "UTF8") {
+        utf8_check != NONE) {
+      if (utf8_check == STRICT) {
         format(
             "  static bool ValidateKey(std::string* s) {\n"
             "    return ::$proto_ns$::internal::WireFormatLite::"
@@ -1023,12 +1023,13 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
             " }\n",
             descriptor_->field(0)->full_name());
       } else {
-        GOOGLE_CHECK(suffix == "UTF8Verify");
+        GOOGLE_CHECK(utf8_check == VERIFY);
         format(
             "  static bool ValidateKey(std::string* s) {\n"
             "#ifndef NDEBUG\n"
             "    ::$proto_ns$::internal::WireFormatLite::VerifyUtf8String(\n"
-            "       s->data(), static_cast<int>(s->size()), ::$proto_ns$::internal::"
+            "       s->data(), static_cast<int>(s->size()), "
+            "::$proto_ns$::internal::"
             "WireFormatLite::PARSE, \"$1$\");\n"
             "#endif\n"
             "    return true;\n"
@@ -1039,8 +1040,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
       format("  static bool ValidateKey(void*) { return true; }\n");
     }
     if (descriptor_->field(1)->type() == FieldDescriptor::TYPE_STRING &&
-        !suffix.empty()) {
-      if (suffix == "UTF8") {
+        utf8_check != NONE) {
+      if (utf8_check == STRICT) {
         format(
             "  static bool ValidateValue(std::string* s) {\n"
             "    return ::$proto_ns$::internal::WireFormatLite::"
@@ -1049,12 +1050,13 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
             " }\n",
             descriptor_->field(1)->full_name());
       } else {
-        GOOGLE_CHECK(suffix == "UTF8Verify");
+        GOOGLE_CHECK(utf8_check = VERIFY);
         format(
             "  static bool ValidateValue(std::string* s) {\n"
             "#ifndef NDEBUG\n"
             "    ::$proto_ns$::internal::WireFormatLite::VerifyUtf8String(\n"
-            "       s->data(), static_cast<int>(s->size()), ::$proto_ns$::internal::"
+            "       s->data(), static_cast<int>(s->size()), "
+            "::$proto_ns$::internal::"
             "WireFormatLite::PARSE, \"$1$\");\n"
             "#endif\n"
             "    return true;\n"
@@ -1351,7 +1353,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
         "size_t ByteSizeLong() const final;\n"
         "const char* _InternalParse(const char* ptr, "
         "::$proto_ns$::internal::ParseContext* ctx) final;\n"
-        "$uint8$* InternalSerializeWithCachedSizesToArray(\n"
+        "$uint8$* _InternalSerialize(\n"
         "    $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) "
         "const final;\n");
 
@@ -3488,7 +3490,7 @@ void MessageGenerator::GenerateSerializeOneExtensionRange(
   Formatter format(printer, vars);
   format("// Extension range [$start$, $end$)\n");
   format(
-      "target = _extensions_.InternalSerializeWithCachedSizesToArray(\n"
+      "target = _extensions_._InternalSerialize(\n"
       "    $start$, $end$, target, stream);\n\n");
 }
 
@@ -3498,7 +3500,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesToArray(
   if (descriptor_->options().message_set_wire_format()) {
     // Special-case MessageSet.
     format(
-        "$uint8$* $classname$::InternalSerializeWithCachedSizesToArray(\n"
+        "$uint8$* $classname$::_InternalSerialize(\n"
         "    $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) "
         "const {\n"
         "  target = _extensions_."
@@ -3517,7 +3519,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesToArray(
   }
 
   format(
-      "$uint8$* $classname$::InternalSerializeWithCachedSizesToArray(\n"
+      "$uint8$* $classname$::_InternalSerialize(\n"
       "    $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) "
       "const {\n");
   format.Indent();
@@ -3759,7 +3761,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) {
       if (field->is_required()) {
         format(
             "\n"
-            "if (has_$1$()) {\n",
+            "if (_internal_has_$1$()) {\n",
             FieldName(field));
         format.Indent();
         PrintFieldComment(format, field);
@@ -3820,7 +3822,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) {
     for (auto field : optimized_order_) {
       if (!field->is_required()) continue;
       PrintFieldComment(format, field);
-      format("if (has_$1$()) {\n", FieldName(field));
+      format("if (_internal_has_$1$()) {\n", FieldName(field));
       format.Indent();
       field_generators_.get(field).GenerateByteSize(printer);
       format.Outdent();
@@ -4042,13 +4044,13 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
         if (IsImplicitWeakField(field, options_, scc_analyzer_)) {
           format(
               "if "
-              "(!::$proto_ns$::internal::AllAreInitializedWeak(this->$1$_.weak)"
+              "(!::$proto_ns$::internal::AllAreInitializedWeak($1$_.weak)"
               ")"
               " return false;\n",
               FieldName(field));
         } else {
           format(
-              "if (!::$proto_ns$::internal::AllAreInitialized(this->$1$()))"
+              "if (!::$proto_ns$::internal::AllAreInitialized($1$_))"
               " return false;\n",
               FieldName(field));
         }
@@ -4057,8 +4059,8 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
       } else {
         GOOGLE_CHECK(!field->containing_oneof());
         format(
-            "if (has_$1$()) {\n"
-            "  if (!this->$1$_->IsInitialized()) return false;\n"
+            "if (_internal_has_$1$()) {\n"
+            "  if (!$1$_->IsInitialized()) return false;\n"
             "}\n",
             FieldName(field));
       }

+ 6 - 8
src/google/protobuf/compiler/cpp/cpp_message_field.cc

@@ -439,7 +439,7 @@ void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
   format(
       "target = stream->EnsureSpace(target);\n"
       "target = ::$proto_ns$::internal::WireFormatLite::\n"
-      "  InternalWrite$declared_type$ToArray(\n"
+      "  InternalWrite$declared_type$(\n"
       "    $number$, _Internal::$name$(this), target, stream);\n");
 }
 
@@ -505,7 +505,7 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
       "inline $type$* $classname$::$release_name$() {\n"
       "$annotate_accessor$"
       "  // @@protoc_insertion_point(field_release:$full_name$)\n"
-      "  if (has_$name$()) {\n"
+      "  if (_internal_has_$name$()) {\n"
       "    clear_has_$oneof_name$();\n"
       "      $type$* temp = $field_member$;\n");
   if (SupportsArenas(descriptor_)) {
@@ -540,7 +540,7 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
         "$annotate_accessor$"
         "  // @@protoc_insertion_point(field_unsafe_arena_release"
         ":$full_name$)\n"
-        "  if (has_$name$()) {\n"
+        "  if (_internal_has_$name$()) {\n"
         "    clear_has_$oneof_name$();\n"
         "    $type$* temp = $field_member$;\n"
         "    $field_member$ = nullptr;\n"
@@ -752,8 +752,7 @@ void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
         "          end = this->$name$_.pointer_end(); it < end; ++it) {\n"
         "  target = stream->EnsureSpace(target);\n"
         "  target = ::$proto_ns$::internal::WireFormatLite::\n"
-        "    InternalWrite$declared_type$ToArray($number$, **it, target, "
-        "stream);\n"
+        "    InternalWrite$declared_type$($number$, **it, target, stream);\n"
         "}\n");
   } else {
     format(
@@ -763,9 +762,8 @@ void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
         "{\n"
         "  target = stream->EnsureSpace(target);\n"
         "  target = ::$proto_ns$::internal::WireFormatLite::\n"
-        "    InternalWrite$declared_type$ToArray($number$, "
-        "this->_internal_$name$(i), target, "
-        "stream);\n"
+        "    InternalWrite$declared_type$($number$, "
+        "this->_internal_$name$(i), target, stream);\n"
         "}\n");
   }
 }

+ 2 - 2
src/google/protobuf/compiler/cpp/cpp_string_field.cc

@@ -285,7 +285,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
 
     if (HasFieldPresence(descriptor_->file())) {
       format(
-          "  if (!has_$name$()) {\n"
+          "  if (!_internal_has_$name$()) {\n"
           "    return nullptr;\n"
           "  }\n"
           "  $clear_hasbit$\n"
@@ -391,7 +391,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
 
     if (HasFieldPresence(descriptor_->file())) {
       format(
-          "  if (!has_$name$()) {\n"
+          "  if (!_internal_has_$name$()) {\n"
           "    return nullptr;\n"
           "  }\n"
           "  $clear_hasbit$\n"

+ 1 - 0
src/google/protobuf/compiler/csharp/csharp_helpers.h

@@ -36,6 +36,7 @@
 #define GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__
 
 #include <string>
+#include <google/protobuf/port.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/descriptor.h>

+ 1 - 0
src/google/protobuf/compiler/csharp/csharp_names.h

@@ -39,6 +39,7 @@
 #define GOOGLE_PROTOBUF_COMPILER_CSHARP_NAMES_H__
 
 #include <string>
+#include <google/protobuf/port.h>
 #include <google/protobuf/stubs/common.h>
 
 #include <google/protobuf/port_def.inc>

+ 1 - 2
src/google/protobuf/compiler/main.cc

@@ -32,11 +32,10 @@
 
 #include <google/protobuf/compiler/cpp/cpp_generator.h>
 #include <google/protobuf/compiler/java/java_generator.h>
+#include <google/protobuf/compiler/js/js_generator.h>
 #include <google/protobuf/compiler/command_line_interface.h>
 #include <google/protobuf/compiler/python/python_generator.h>
-
 #include <google/protobuf/compiler/csharp/csharp_generator.h>
-#include <google/protobuf/compiler/js/js_generator.h>
 #include <google/protobuf/compiler/objectivec/objectivec_generator.h>
 #include <google/protobuf/compiler/php/php_generator.h>
 #include <google/protobuf/compiler/ruby/ruby_generator.h>

+ 1 - 0
src/google/protobuf/compiler/objectivec/objectivec_helpers.cc

@@ -48,6 +48,7 @@
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <google/protobuf/io/io_win32.h>
+#include <google/protobuf/port.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/strutil.h>
 

+ 43 - 15
src/google/protobuf/compiler/plugin.pb.cc

@@ -324,7 +324,11 @@ const char* Version::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::in
       // optional string suffix = 4;
       case 4:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 34)) {
-          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8Verify(_internal_mutable_suffix(), ptr, ctx, "google.protobuf.compiler.Version.suffix");
+          auto str = _internal_mutable_suffix();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+          #ifndef NDEBUG
+          ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.Version.suffix");
+          #endif  // !NDEBUG
           CHK_(ptr);
         } else goto handle_unusual;
         continue;
@@ -349,7 +353,7 @@ failure:
 #undef CHK_
 }
 
-::PROTOBUF_NAMESPACE_ID::uint8* Version::InternalSerializeWithCachedSizesToArray(
+::PROTOBUF_NAMESPACE_ID::uint8* Version::_InternalSerialize(
     ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.Version)
   ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
@@ -625,7 +629,11 @@ const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAM
           ptr -= 1;
           do {
             ptr += 1;
-            ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8Verify(_internal_add_file_to_generate(), ptr, ctx, "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate");
+            auto str = _internal_add_file_to_generate();
+            ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+            #ifndef NDEBUG
+            ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate");
+            #endif  // !NDEBUG
             CHK_(ptr);
             if (!ctx->DataAvailable(ptr)) break;
           } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr));
@@ -634,7 +642,11 @@ const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAM
       // optional string parameter = 2;
       case 2:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 18)) {
-          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8Verify(_internal_mutable_parameter(), ptr, ctx, "google.protobuf.compiler.CodeGeneratorRequest.parameter");
+          auto str = _internal_mutable_parameter();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+          #ifndef NDEBUG
+          ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.parameter");
+          #endif  // !NDEBUG
           CHK_(ptr);
         } else goto handle_unusual;
         continue;
@@ -678,7 +690,7 @@ failure:
 #undef CHK_
 }
 
-::PROTOBUF_NAMESPACE_ID::uint8* CodeGeneratorRequest::InternalSerializeWithCachedSizesToArray(
+::PROTOBUF_NAMESPACE_ID::uint8* CodeGeneratorRequest::_InternalSerialize(
     ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorRequest)
   ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
@@ -709,7 +721,7 @@ failure:
   if (cached_has_bits & 0x00000002u) {
     target = stream->EnsureSpace(target);
     target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
-      InternalWriteMessageToArray(
+      InternalWriteMessage(
         3, _Internal::compiler_version(this), target, stream);
   }
 
@@ -718,7 +730,7 @@ failure:
       n = static_cast<unsigned int>(this->_internal_proto_file_size()); i < n; i++) {
     target = stream->EnsureSpace(target);
     target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
-      InternalWriteMessageToArray(15, this->_internal_proto_file(i), target, stream);
+      InternalWriteMessage(15, this->_internal_proto_file(i), target, stream);
   }
 
   if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
@@ -829,7 +841,7 @@ void CodeGeneratorRequest::CopyFrom(const CodeGeneratorRequest& from) {
 }
 
 bool CodeGeneratorRequest::IsInitialized() const {
-  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(this->proto_file())) return false;
+  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(proto_file_)) return false;
   return true;
 }
 
@@ -952,21 +964,33 @@ const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::PROTOB
       // optional string name = 1;
       case 1:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) {
-          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8Verify(_internal_mutable_name(), ptr, ctx, "google.protobuf.compiler.CodeGeneratorResponse.File.name");
+          auto str = _internal_mutable_name();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+          #ifndef NDEBUG
+          ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.name");
+          #endif  // !NDEBUG
           CHK_(ptr);
         } else goto handle_unusual;
         continue;
       // optional string insertion_point = 2;
       case 2:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 18)) {
-          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8Verify(_internal_mutable_insertion_point(), ptr, ctx, "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point");
+          auto str = _internal_mutable_insertion_point();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+          #ifndef NDEBUG
+          ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point");
+          #endif  // !NDEBUG
           CHK_(ptr);
         } else goto handle_unusual;
         continue;
       // optional string content = 15;
       case 15:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 122)) {
-          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8Verify(_internal_mutable_content(), ptr, ctx, "google.protobuf.compiler.CodeGeneratorResponse.File.content");
+          auto str = _internal_mutable_content();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+          #ifndef NDEBUG
+          ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.content");
+          #endif  // !NDEBUG
           CHK_(ptr);
         } else goto handle_unusual;
         continue;
@@ -991,7 +1015,7 @@ failure:
 #undef CHK_
 }
 
-::PROTOBUF_NAMESPACE_ID::uint8* CodeGeneratorResponse_File::InternalSerializeWithCachedSizesToArray(
+::PROTOBUF_NAMESPACE_ID::uint8* CodeGeneratorResponse_File::_InternalSerialize(
     ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse.File)
   ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
@@ -1230,7 +1254,11 @@ const char* CodeGeneratorResponse::_InternalParse(const char* ptr, ::PROTOBUF_NA
       // optional string error = 1;
       case 1:
         if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) {
-          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8Verify(_internal_mutable_error(), ptr, ctx, "google.protobuf.compiler.CodeGeneratorResponse.error");
+          auto str = _internal_mutable_error();
+          ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+          #ifndef NDEBUG
+          ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.error");
+          #endif  // !NDEBUG
           CHK_(ptr);
         } else goto handle_unusual;
         continue;
@@ -1267,7 +1295,7 @@ failure:
 #undef CHK_
 }
 
-::PROTOBUF_NAMESPACE_ID::uint8* CodeGeneratorResponse::InternalSerializeWithCachedSizesToArray(
+::PROTOBUF_NAMESPACE_ID::uint8* CodeGeneratorResponse::_InternalSerialize(
     ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse)
   ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
@@ -1289,7 +1317,7 @@ failure:
       n = static_cast<unsigned int>(this->_internal_file_size()); i < n; i++) {
     target = stream->EnsureSpace(target);
     target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
-      InternalWriteMessageToArray(15, this->_internal_file(i), target, stream);
+      InternalWriteMessage(15, this->_internal_file(i), target, stream);
   }
 
   if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {

+ 10 - 10
src/google/protobuf/compiler/plugin.pb.h

@@ -165,7 +165,7 @@ class PROTOC_EXPORT Version :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -357,7 +357,7 @@ class PROTOC_EXPORT CodeGeneratorRequest :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -567,7 +567,7 @@ class PROTOC_EXPORT CodeGeneratorResponse_File :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -758,7 +758,7 @@ class PROTOC_EXPORT CodeGeneratorResponse :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -998,7 +998,7 @@ inline std::string* Version::_internal_mutable_suffix() {
 }
 inline std::string* Version::release_suffix() {
   // @@protoc_insertion_point(field_release:google.protobuf.compiler.Version.suffix)
-  if (!has_suffix()) {
+  if (!_internal_has_suffix()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
@@ -1147,7 +1147,7 @@ inline std::string* CodeGeneratorRequest::_internal_mutable_parameter() {
 }
 inline std::string* CodeGeneratorRequest::release_parameter() {
   // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.parameter)
-  if (!has_parameter()) {
+  if (!_internal_has_parameter()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
@@ -1318,7 +1318,7 @@ inline std::string* CodeGeneratorResponse_File::_internal_mutable_name() {
 }
 inline std::string* CodeGeneratorResponse_File::release_name() {
   // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.name)
-  if (!has_name()) {
+  if (!_internal_has_name()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
@@ -1389,7 +1389,7 @@ inline std::string* CodeGeneratorResponse_File::_internal_mutable_insertion_poin
 }
 inline std::string* CodeGeneratorResponse_File::release_insertion_point() {
   // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
-  if (!has_insertion_point()) {
+  if (!_internal_has_insertion_point()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000002u;
@@ -1460,7 +1460,7 @@ inline std::string* CodeGeneratorResponse_File::_internal_mutable_content() {
 }
 inline std::string* CodeGeneratorResponse_File::release_content() {
   // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.content)
-  if (!has_content()) {
+  if (!_internal_has_content()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000004u;
@@ -1535,7 +1535,7 @@ inline std::string* CodeGeneratorResponse::_internal_mutable_error() {
 }
 inline std::string* CodeGeneratorResponse::release_error() {
   // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.error)
-  if (!has_error()) {
+  if (!_internal_has_error()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;

+ 1 - 0
src/google/protobuf/descriptor.cc

@@ -6438,6 +6438,7 @@ bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption(
   std::vector<int> dest_path = options_path;
 
   for (int i = 0; i < uninterpreted_option_->name_size(); ++i) {
+    builder_->undefine_resolved_name_.clear();
     const std::string& name_part = uninterpreted_option_->name(i).name_part();
     if (debug_msg_name.size() > 0) {
       debug_msg_name += ".";

Різницю між файлами не показано, бо вона завелика
+ 236 - 120
src/google/protobuf/descriptor.pb.cc


+ 60 - 60
src/google/protobuf/descriptor.pb.h

@@ -422,7 +422,7 @@ class PROTOBUF_EXPORT FileDescriptorSet :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -590,7 +590,7 @@ class PROTOBUF_EXPORT FileDescriptorProto :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -1025,7 +1025,7 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -1223,7 +1223,7 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -1401,7 +1401,7 @@ class PROTOBUF_EXPORT DescriptorProto :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -1769,7 +1769,7 @@ class PROTOBUF_EXPORT ExtensionRangeOptions :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -1940,7 +1940,7 @@ class PROTOBUF_EXPORT FieldDescriptorProto :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -2417,7 +2417,7 @@ class PROTOBUF_EXPORT OneofDescriptorProto :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -2616,7 +2616,7 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -2794,7 +2794,7 @@ class PROTOBUF_EXPORT EnumDescriptorProto :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -3061,7 +3061,7 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -3275,7 +3275,7 @@ class PROTOBUF_EXPORT ServiceDescriptorProto :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -3494,7 +3494,7 @@ class PROTOBUF_EXPORT MethodDescriptorProto :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -3785,7 +3785,7 @@ class PROTOBUF_EXPORT FileOptions :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -4448,7 +4448,7 @@ class PROTOBUF_EXPORT MessageOptions :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -4679,7 +4679,7 @@ class PROTOBUF_EXPORT FieldOptions :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -5004,7 +5004,7 @@ class PROTOBUF_EXPORT OneofOptions :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -5175,7 +5175,7 @@ class PROTOBUF_EXPORT EnumOptions :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -5376,7 +5376,7 @@ class PROTOBUF_EXPORT EnumValueOptions :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -5562,7 +5562,7 @@ class PROTOBUF_EXPORT ServiceOptions :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -5748,7 +5748,7 @@ class PROTOBUF_EXPORT MethodOptions :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -5981,7 +5981,7 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -6178,7 +6178,7 @@ class PROTOBUF_EXPORT UninterpretedOption :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -6486,7 +6486,7 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -6772,7 +6772,7 @@ class PROTOBUF_EXPORT SourceCodeInfo :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -6942,7 +6942,7 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -7176,7 +7176,7 @@ class PROTOBUF_EXPORT GeneratedCodeInfo :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 
@@ -7363,7 +7363,7 @@ inline std::string* FileDescriptorProto::_internal_mutable_name() {
 }
 inline std::string* FileDescriptorProto::release_name() {
   // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.name)
-  if (!has_name()) {
+  if (!_internal_has_name()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
@@ -7456,7 +7456,7 @@ inline std::string* FileDescriptorProto::_internal_mutable_package() {
 }
 inline std::string* FileDescriptorProto::release_package() {
   // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.package)
-  if (!has_package()) {
+  if (!_internal_has_package()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000002u;
@@ -8009,7 +8009,7 @@ inline std::string* FileDescriptorProto::_internal_mutable_syntax() {
 }
 inline std::string* FileDescriptorProto::release_syntax() {
   // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.syntax)
-  if (!has_syntax()) {
+  if (!_internal_has_syntax()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000004u;
@@ -8294,7 +8294,7 @@ inline std::string* DescriptorProto::_internal_mutable_name() {
 }
 inline std::string* DescriptorProto::release_name() {
   // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.name)
-  if (!has_name()) {
+  if (!_internal_has_name()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
@@ -8849,7 +8849,7 @@ inline std::string* FieldDescriptorProto::_internal_mutable_name() {
 }
 inline std::string* FieldDescriptorProto::release_name() {
   // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.name)
-  if (!has_name()) {
+  if (!_internal_has_name()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
@@ -9028,7 +9028,7 @@ inline std::string* FieldDescriptorProto::_internal_mutable_type_name() {
 }
 inline std::string* FieldDescriptorProto::release_type_name() {
   // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.type_name)
-  if (!has_type_name()) {
+  if (!_internal_has_type_name()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000004u;
@@ -9121,7 +9121,7 @@ inline std::string* FieldDescriptorProto::_internal_mutable_extendee() {
 }
 inline std::string* FieldDescriptorProto::release_extendee() {
   // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.extendee)
-  if (!has_extendee()) {
+  if (!_internal_has_extendee()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000002u;
@@ -9214,7 +9214,7 @@ inline std::string* FieldDescriptorProto::_internal_mutable_default_value() {
 }
 inline std::string* FieldDescriptorProto::release_default_value() {
   // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.default_value)
-  if (!has_default_value()) {
+  if (!_internal_has_default_value()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000008u;
@@ -9335,7 +9335,7 @@ inline std::string* FieldDescriptorProto::_internal_mutable_json_name() {
 }
 inline std::string* FieldDescriptorProto::release_json_name() {
   // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.json_name)
-  if (!has_json_name()) {
+  if (!_internal_has_json_name()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000010u;
@@ -9500,7 +9500,7 @@ inline std::string* OneofDescriptorProto::_internal_mutable_name() {
 }
 inline std::string* OneofDescriptorProto::release_name() {
   // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.name)
-  if (!has_name()) {
+  if (!_internal_has_name()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
@@ -9725,7 +9725,7 @@ inline std::string* EnumDescriptorProto::_internal_mutable_name() {
 }
 inline std::string* EnumDescriptorProto::release_name() {
   // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.name)
-  if (!has_name()) {
+  if (!_internal_has_name()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
@@ -10042,7 +10042,7 @@ inline std::string* EnumValueDescriptorProto::_internal_mutable_name() {
 }
 inline std::string* EnumValueDescriptorProto::release_name() {
   // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.name)
-  if (!has_name()) {
+  if (!_internal_has_name()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
@@ -10235,7 +10235,7 @@ inline std::string* ServiceDescriptorProto::_internal_mutable_name() {
 }
 inline std::string* ServiceDescriptorProto::release_name() {
   // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.name)
-  if (!has_name()) {
+  if (!_internal_has_name()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
@@ -10439,7 +10439,7 @@ inline std::string* MethodDescriptorProto::_internal_mutable_name() {
 }
 inline std::string* MethodDescriptorProto::release_name() {
   // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.name)
-  if (!has_name()) {
+  if (!_internal_has_name()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
@@ -10532,7 +10532,7 @@ inline std::string* MethodDescriptorProto::_internal_mutable_input_type() {
 }
 inline std::string* MethodDescriptorProto::release_input_type() {
   // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.input_type)
-  if (!has_input_type()) {
+  if (!_internal_has_input_type()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000002u;
@@ -10625,7 +10625,7 @@ inline std::string* MethodDescriptorProto::_internal_mutable_output_type() {
 }
 inline std::string* MethodDescriptorProto::release_output_type() {
   // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.output_type)
-  if (!has_output_type()) {
+  if (!_internal_has_output_type()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000004u;
@@ -10846,7 +10846,7 @@ inline std::string* FileOptions::_internal_mutable_java_package() {
 }
 inline std::string* FileOptions::release_java_package() {
   // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_package)
-  if (!has_java_package()) {
+  if (!_internal_has_java_package()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
@@ -10939,7 +10939,7 @@ inline std::string* FileOptions::_internal_mutable_java_outer_classname() {
 }
 inline std::string* FileOptions::release_java_outer_classname() {
   // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_outer_classname)
-  if (!has_java_outer_classname()) {
+  if (!_internal_has_java_outer_classname()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000002u;
@@ -11145,7 +11145,7 @@ inline std::string* FileOptions::_internal_mutable_go_package() {
 }
 inline std::string* FileOptions::release_go_package() {
   // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.go_package)
-  if (!has_go_package()) {
+  if (!_internal_has_go_package()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000004u;
@@ -11406,7 +11406,7 @@ inline std::string* FileOptions::_internal_mutable_objc_class_prefix() {
 }
 inline std::string* FileOptions::release_objc_class_prefix() {
   // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.objc_class_prefix)
-  if (!has_objc_class_prefix()) {
+  if (!_internal_has_objc_class_prefix()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000008u;
@@ -11499,7 +11499,7 @@ inline std::string* FileOptions::_internal_mutable_csharp_namespace() {
 }
 inline std::string* FileOptions::release_csharp_namespace() {
   // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.csharp_namespace)
-  if (!has_csharp_namespace()) {
+  if (!_internal_has_csharp_namespace()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000010u;
@@ -11592,7 +11592,7 @@ inline std::string* FileOptions::_internal_mutable_swift_prefix() {
 }
 inline std::string* FileOptions::release_swift_prefix() {
   // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.swift_prefix)
-  if (!has_swift_prefix()) {
+  if (!_internal_has_swift_prefix()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000020u;
@@ -11685,7 +11685,7 @@ inline std::string* FileOptions::_internal_mutable_php_class_prefix() {
 }
 inline std::string* FileOptions::release_php_class_prefix() {
   // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_class_prefix)
-  if (!has_php_class_prefix()) {
+  if (!_internal_has_php_class_prefix()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000040u;
@@ -11778,7 +11778,7 @@ inline std::string* FileOptions::_internal_mutable_php_namespace() {
 }
 inline std::string* FileOptions::release_php_namespace() {
   // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_namespace)
-  if (!has_php_namespace()) {
+  if (!_internal_has_php_namespace()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000080u;
@@ -11871,7 +11871,7 @@ inline std::string* FileOptions::_internal_mutable_php_metadata_namespace() {
 }
 inline std::string* FileOptions::release_php_metadata_namespace() {
   // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_metadata_namespace)
-  if (!has_php_metadata_namespace()) {
+  if (!_internal_has_php_metadata_namespace()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000100u;
@@ -11964,7 +11964,7 @@ inline std::string* FileOptions::_internal_mutable_ruby_package() {
 }
 inline std::string* FileOptions::release_ruby_package() {
   // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.ruby_package)
-  if (!has_ruby_package()) {
+  if (!_internal_has_ruby_package()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000200u;
@@ -12852,7 +12852,7 @@ inline std::string* UninterpretedOption_NamePart::_internal_mutable_name_part()
 }
 inline std::string* UninterpretedOption_NamePart::release_name_part() {
   // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.NamePart.name_part)
-  if (!has_name_part()) {
+  if (!_internal_has_name_part()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
@@ -13016,7 +13016,7 @@ inline std::string* UninterpretedOption::_internal_mutable_identifier_value() {
 }
 inline std::string* UninterpretedOption::release_identifier_value() {
   // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.identifier_value)
-  if (!has_identifier_value()) {
+  if (!_internal_has_identifier_value()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
@@ -13193,7 +13193,7 @@ inline std::string* UninterpretedOption::_internal_mutable_string_value() {
 }
 inline std::string* UninterpretedOption::release_string_value() {
   // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.string_value)
-  if (!has_string_value()) {
+  if (!_internal_has_string_value()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000002u;
@@ -13286,7 +13286,7 @@ inline std::string* UninterpretedOption::_internal_mutable_aggregate_value() {
 }
 inline std::string* UninterpretedOption::release_aggregate_value() {
   // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.aggregate_value)
-  if (!has_aggregate_value()) {
+  if (!_internal_has_aggregate_value()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000004u;
@@ -13477,7 +13477,7 @@ inline std::string* SourceCodeInfo_Location::_internal_mutable_leading_comments(
 }
 inline std::string* SourceCodeInfo_Location::release_leading_comments() {
   // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.leading_comments)
-  if (!has_leading_comments()) {
+  if (!_internal_has_leading_comments()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;
@@ -13570,7 +13570,7 @@ inline std::string* SourceCodeInfo_Location::_internal_mutable_trailing_comments
 }
 inline std::string* SourceCodeInfo_Location::release_trailing_comments() {
   // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.trailing_comments)
-  if (!has_trailing_comments()) {
+  if (!_internal_has_trailing_comments()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000002u;
@@ -13831,7 +13831,7 @@ inline std::string* GeneratedCodeInfo_Annotation::_internal_mutable_source_file(
 }
 inline std::string* GeneratedCodeInfo_Annotation::release_source_file() {
   // @@protoc_insertion_point(field_release:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
-  if (!has_source_file()) {
+  if (!_internal_has_source_file()) {
     return nullptr;
   }
   _has_bits_[0] &= ~0x00000001u;

+ 6 - 6
src/google/protobuf/descriptor_unittest.cc

@@ -1902,7 +1902,7 @@ TEST_F(ExtensionDescriptorTest, ExtensionRanges) {
 
   EXPECT_EQ(20, foo_->extension_range(0)->end);
   EXPECT_EQ(40, foo_->extension_range(1)->end);
-};
+}
 
 TEST_F(ExtensionDescriptorTest, Extensions) {
   EXPECT_EQ(0, foo_->extension_count());
@@ -1947,7 +1947,7 @@ TEST_F(ExtensionDescriptorTest, Extensions) {
   EXPECT_TRUE(foo_file_->extension(1)->extension_scope() == nullptr);
   EXPECT_EQ(bar_, bar_->extension(0)->extension_scope());
   EXPECT_EQ(bar_, bar_->extension(1)->extension_scope());
-};
+}
 
 TEST_F(ExtensionDescriptorTest, IsExtensionNumber) {
   EXPECT_FALSE(foo_->IsExtensionNumber(9));
@@ -2095,7 +2095,7 @@ TEST_F(ReservedDescriptorTest, ReservedRanges) {
 
   EXPECT_EQ(15, foo_->reserved_range(2)->start);
   EXPECT_EQ(16, foo_->reserved_range(2)->end);
-};
+}
 
 TEST_F(ReservedDescriptorTest, IsReservedNumber) {
   EXPECT_FALSE(foo_->IsReservedNumber(1));
@@ -2110,20 +2110,20 @@ TEST_F(ReservedDescriptorTest, IsReservedNumber) {
   EXPECT_FALSE(foo_->IsReservedNumber(14));
   EXPECT_TRUE(foo_->IsReservedNumber(15));
   EXPECT_FALSE(foo_->IsReservedNumber(16));
-};
+}
 
 TEST_F(ReservedDescriptorTest, ReservedNames) {
   ASSERT_EQ(2, foo_->reserved_name_count());
 
   EXPECT_EQ("foo", foo_->reserved_name(0));
   EXPECT_EQ("bar", foo_->reserved_name(1));
-};
+}
 
 TEST_F(ReservedDescriptorTest, IsReservedName) {
   EXPECT_TRUE(foo_->IsReservedName("foo"));
   EXPECT_TRUE(foo_->IsReservedName("bar"));
   EXPECT_FALSE(foo_->IsReservedName("baz"));
-};
+}
 
 // ===================================================================
 

+ 1 - 1
src/google/protobuf/duration.pb.cc

@@ -195,7 +195,7 @@ failure:
 #undef CHK_
 }
 
-::PROTOBUF_NAMESPACE_ID::uint8* Duration::InternalSerializeWithCachedSizesToArray(
+::PROTOBUF_NAMESPACE_ID::uint8* Duration::_InternalSerialize(
     ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Duration)
   ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;

+ 1 - 1
src/google/protobuf/duration.pb.h

@@ -151,7 +151,7 @@ class PROTOBUF_EXPORT Duration :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 

+ 0 - 1
src/google/protobuf/dynamic_message.h

@@ -44,7 +44,6 @@
 
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/message.h>
-#include <google/protobuf/reflection.h>
 #include <google/protobuf/stubs/mutex.h>
 #include <google/protobuf/reflection.h>
 #include <google/protobuf/repeated_field.h>

+ 1 - 5
src/google/protobuf/empty.pb.cc

@@ -148,8 +148,6 @@ const char* Empty::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::inte
     ::PROTOBUF_NAMESPACE_ID::uint32 tag;
     ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
     CHK_(ptr);
-    switch (tag >> 3) {
-      default: {
         if ((tag & 7) == 4 || tag == 0) {
           ctx->SetLastTag(tag);
           goto success;
@@ -157,8 +155,6 @@ const char* Empty::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::inte
         ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx);
         CHK_(ptr != nullptr);
         continue;
-      }
-    }  // switch
   }  // while
 success:
   return ptr;
@@ -168,7 +164,7 @@ failure:
 #undef CHK_
 }
 
-::PROTOBUF_NAMESPACE_ID::uint8* Empty::InternalSerializeWithCachedSizesToArray(
+::PROTOBUF_NAMESPACE_ID::uint8* Empty::_InternalSerialize(
     ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Empty)
   ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;

+ 1 - 1
src/google/protobuf/empty.pb.h

@@ -151,7 +151,7 @@ class PROTOBUF_EXPORT Empty :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 

+ 9 - 9
src/google/protobuf/extension_set.cc

@@ -1462,9 +1462,9 @@ bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
   return ParseMessageSetLite(input, &finder, &skipper);
 }
 
-uint8* ExtensionSet::InternalSerializeWithCachedSizesToArray(
-    int start_field_number, int end_field_number, uint8* target,
-    io::EpsCopyOutputStream* stream) const {
+uint8* ExtensionSet::_InternalSerialize(int start_field_number,
+                                        int end_field_number, uint8* target,
+                                        io::EpsCopyOutputStream* stream) const {
   if (PROTOBUF_PREDICT_FALSE(is_large())) {
     const auto& end = map_.large->end();
     for (auto it = map_.large->lower_bound(start_field_number);
@@ -2010,7 +2010,7 @@ uint8* ExtensionSet::Extension::InternalSerializeFieldWithCachedSizesToArray(
   case WireFormatLite::TYPE_##UPPERCASE:                                 \
     for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {     \
       target = stream->EnsureSpace(target);                              \
-      target = WireFormatLite::InternalWrite##CAMELCASE##ToArray(        \
+      target = WireFormatLite::InternalWrite##CAMELCASE(                 \
           number, repeated_##LOWERCASE##_value->Get(i), target, stream); \
     }                                                                    \
     break
@@ -2053,8 +2053,8 @@ uint8* ExtensionSet::Extension::InternalSerializeFieldWithCachedSizesToArray(
 #undef HANDLE_TYPE
       case WireFormatLite::TYPE_GROUP:
         target = stream->EnsureSpace(target);
-        target = WireFormatLite::InternalWriteGroupToArray(
-            number, *message_value, target, stream);
+        target = WireFormatLite::InternalWriteGroup(number, *message_value,
+                                                    target, stream);
         break;
       case WireFormatLite::TYPE_MESSAGE:
         if (is_lazy) {
@@ -2062,8 +2062,8 @@ uint8* ExtensionSet::Extension::InternalSerializeFieldWithCachedSizesToArray(
               lazymessage_value->WriteMessageToArray(number, target, stream);
         } else {
           target = stream->EnsureSpace(target);
-          target = WireFormatLite::InternalWriteMessageToArray(
-              number, *message_value, target, stream);
+          target = WireFormatLite::InternalWriteMessage(number, *message_value,
+                                                        target, stream);
         }
         break;
     }
@@ -2094,7 +2094,7 @@ ExtensionSet::Extension::InternalSerializeMessageSetItemWithCachedSizesToArray(
     target = lazymessage_value->WriteMessageToArray(
         WireFormatLite::kMessageSetMessageNumber, target, stream);
   } else {
-    target = WireFormatLite::InternalWriteMessageToArray(
+    target = WireFormatLite::InternalWriteMessage(
         WireFormatLite::kMessageSetMessageNumber, *message_value, target,
         stream);
   }

+ 5 - 6
src/google/protobuf/extension_set.h

@@ -458,9 +458,8 @@ class PROTOBUF_EXPORT ExtensionSet {
   // last called.  Note that the range bounds are inclusive-exclusive.
   void SerializeWithCachedSizes(int start_field_number, int end_field_number,
                                 io::CodedOutputStream* output) const {
-    output->SetCur(InternalSerializeWithCachedSizesToArray(
-        start_field_number, end_field_number, output->Cur(),
-        output->EpsCopy()));
+    output->SetCur(_InternalSerialize(start_field_number, end_field_number,
+                                      output->Cur(), output->EpsCopy()));
   }
 
   // Same as SerializeWithCachedSizes, but without any bounds checking.
@@ -468,9 +467,9 @@ class PROTOBUF_EXPORT ExtensionSet {
   // serialized extensions.
   //
   // Returns a pointer past the last written byte.
-  uint8* InternalSerializeWithCachedSizesToArray(
-      int start_field_number, int end_field_number, uint8* target,
-      io::EpsCopyOutputStream* stream) const;
+  uint8* _InternalSerialize(int start_field_number, int end_field_number,
+                            uint8* target,
+                            io::EpsCopyOutputStream* stream) const;
 
   // Like above but serializes in MessageSet format.
   void SerializeMessageSetWithCachedSizes(io::CodedOutputStream* output) const {

+ 4 - 2
src/google/protobuf/field_mask.pb.cc

@@ -161,7 +161,9 @@ const char* FieldMask::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::
           ptr -= 1;
           do {
             ptr += 1;
-            ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8(_internal_add_paths(), ptr, ctx, "google.protobuf.FieldMask.paths");
+            auto str = _internal_add_paths();
+            ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
+            CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.FieldMask.paths"));
             CHK_(ptr);
             if (!ctx->DataAvailable(ptr)) break;
           } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr));
@@ -187,7 +189,7 @@ failure:
 #undef CHK_
 }
 
-::PROTOBUF_NAMESPACE_ID::uint8* FieldMask::InternalSerializeWithCachedSizesToArray(
+::PROTOBUF_NAMESPACE_ID::uint8* FieldMask::_InternalSerialize(
     ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
   // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldMask)
   ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;

+ 1 - 1
src/google/protobuf/field_mask.pb.h

@@ -151,7 +151,7 @@ class PROTOBUF_EXPORT FieldMask :
 
   size_t ByteSizeLong() const final;
   const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
-  ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray(
+  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
       ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
   int GetCachedSize() const final { return _cached_size_.Get(); }
 

+ 1 - 1
src/google/protobuf/field_mask.proto

@@ -238,7 +238,7 @@ option cc_enable_arenas = true;
 //
 // The implementation of any API method which has a FieldMask type field in the
 // request should verify the included field paths, and return an
-// `INVALID_ARGUMENT` error if any path is duplicated or unmappable.
+// `INVALID_ARGUMENT` error if any path is unmappable.
 message FieldMask {
   // The set of field mask paths.
   repeated string paths = 1;

+ 13 - 13
src/google/protobuf/generated_message_reflection.cc

@@ -2079,19 +2079,19 @@ void Reflection::ClearOneof(Message* message,
   }
 }
 
-#define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE)                               \
-  template <>                                                           \
-  const RepeatedField<TYPE>& Reflection::GetRepeatedField<TYPE>(        \
-      const Message& message, const FieldDescriptor* field) const {     \
-    return *static_cast<RepeatedField<TYPE>*>(MutableRawRepeatedField(  \
-        const_cast<Message*>(&message), field, CPPTYPE, CTYPE, NULL));  \
-  }                                                                     \
-                                                                        \
-  template <>                                                           \
-  RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>(          \
-      Message * message, const FieldDescriptor* field) const {          \
-    return static_cast<RepeatedField<TYPE>*>(                           \
-        MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, NULL)); \
+#define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE)                                \
+  template <>                                                            \
+  const RepeatedField<TYPE>& Reflection::GetRepeatedFieldInternal<TYPE>( \
+      const Message& message, const FieldDescriptor* field) const {      \
+    return *static_cast<RepeatedField<TYPE>*>(MutableRawRepeatedField(   \
+        const_cast<Message*>(&message), field, CPPTYPE, CTYPE, NULL));   \
+  }                                                                      \
+                                                                         \
+  template <>                                                            \
+  RepeatedField<TYPE>* Reflection::MutableRepeatedFieldInternal<TYPE>(   \
+      Message * message, const FieldDescriptor* field) const {           \
+    return static_cast<RepeatedField<TYPE>*>(                            \
+        MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, NULL));  \
   }
 
 HANDLE_TYPE(int32, FieldDescriptor::CPPTYPE_INT32, -1);

+ 5 - 2
src/google/protobuf/generated_message_util.h

@@ -39,17 +39,20 @@
 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
 
 #include <assert.h>
+
 #include <atomic>
 #include <climits>
 #include <string>
 #include <vector>
 
 #include <google/protobuf/stubs/common.h>
+#include <google/protobuf/any.h>
 #include <google/protobuf/has_bits.h>
 #include <google/protobuf/implicit_weak_message.h>
 #include <google/protobuf/message_lite.h>
 #include <google/protobuf/stubs/once.h>  // Add direct dep on port for pb.cc
 #include <google/protobuf/port.h>
+#include <google/protobuf/repeated_field.h>
 #include <google/protobuf/wire_format_lite.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/casts.h>
@@ -95,8 +98,8 @@ PROTOBUF_EXPORT inline const std::string& GetEmptyString() {
 // helper here to keep the protobuf compiler from ever having to emit loops in
 // IsInitialized() methods.  We want the C++ compiler to inline this or not
 // as it sees fit.
-template <class Type>
-bool AllAreInitialized(const Type& t) {
+template <typename Msg>
+bool AllAreInitialized(const RepeatedPtrField<Msg>& t) {
   for (int i = t.size(); --i >= 0;) {
     if (!t.Get(i).IsInitialized()) return false;
   }

+ 2 - 2
src/google/protobuf/implicit_weak_message.h

@@ -82,8 +82,8 @@ class PROTOBUF_EXPORT ImplicitWeakMessage : public MessageLite {
 
   size_t ByteSizeLong() const override { return data_.size(); }
 
-  uint8* InternalSerializeWithCachedSizesToArray(
-      uint8* target, io::EpsCopyOutputStream* stream) const final {
+  uint8* _InternalSerialize(uint8* target,
+                            io::EpsCopyOutputStream* stream) const final {
     return stream->WriteRaw(data_.data(), static_cast<int>(data_.size()),
                             target);
   }

+ 6 - 67
src/google/protobuf/io/strtod.cc

@@ -38,81 +38,16 @@
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 
+#include <google/protobuf/stubs/strutil.h>
+
 namespace google {
 namespace protobuf {
 namespace io {
 
-// ----------------------------------------------------------------------
-// NoLocaleStrtod()
-//   This code will make you cry.
-// ----------------------------------------------------------------------
-
-namespace {
-
 // This approximately 0x1.ffffffp127, but we don't use 0x1.ffffffp127 because
 // it won't compile in MSVC.
 const double MAX_FLOAT_AS_DOUBLE_ROUNDED = 3.4028235677973366e+38;
 
-// Returns a string identical to *input except that the character pointed to
-// by radix_pos (which should be '.') is replaced with the locale-specific
-// radix character.
-std::string LocalizeRadix(const char* input, const char* radix_pos) {
-  // Determine the locale-specific radix character by calling sprintf() to
-  // print the number 1.5, then stripping off the digits.  As far as I can
-  // tell, this is the only portable, thread-safe way to get the C library
-  // to divuldge the locale's radix character.  No, localeconv() is NOT
-  // thread-safe.
-  char temp[16];
-  int size = sprintf(temp, "%.1f", 1.5);
-  GOOGLE_CHECK_EQ(temp[0], '1');
-  GOOGLE_CHECK_EQ(temp[size - 1], '5');
-  GOOGLE_CHECK_LE(size, 6);
-
-  // Now replace the '.' in the input with it.
-  std::string result;
-  result.reserve(strlen(input) + size - 3);
-  result.append(input, radix_pos);
-  result.append(temp + 1, size - 2);
-  result.append(radix_pos + 1);
-  return result;
-}
-
-}  // namespace
-
-double NoLocaleStrtod(const char* text, char** original_endptr) {
-  // We cannot simply set the locale to "C" temporarily with setlocale()
-  // as this is not thread-safe.  Instead, we try to parse in the current
-  // locale first.  If parsing stops at a '.' character, then this is a
-  // pretty good hint that we're actually in some other locale in which
-  // '.' is not the radix character.
-
-  char* temp_endptr;
-  double result = strtod(text, &temp_endptr);
-  if (original_endptr != NULL) *original_endptr = temp_endptr;
-  if (*temp_endptr != '.') return result;
-
-  // Parsing halted on a '.'.  Perhaps we're in a different locale?  Let's
-  // try to replace the '.' with a locale-specific radix character and
-  // try again.
-  std::string localized = LocalizeRadix(text, temp_endptr);
-  const char* localized_cstr = localized.c_str();
-  char* localized_endptr;
-  result = strtod(localized_cstr, &localized_endptr);
-  if ((localized_endptr - localized_cstr) > (temp_endptr - text)) {
-    // This attempt got further, so replacing the decimal must have helped.
-    // Update original_endptr to point at the right location.
-    if (original_endptr != NULL) {
-      // size_diff is non-zero if the localized radix has multiple bytes.
-      int size_diff = localized.size() - strlen(text);
-      // const_cast is necessary to match the strtod() interface.
-      *original_endptr = const_cast<char*>(
-          text + (localized_endptr - localized_cstr - size_diff));
-    }
-  }
-
-  return result;
-}
-
 float SafeDoubleToFloat(double value) {
   // static_cast<float> on a number larger than float can result in illegal
   // instruction error, so we need to manually convert it to infinity or max.
@@ -138,6 +73,10 @@ float SafeDoubleToFloat(double value) {
   }
 }
 
+double NoLocaleStrtod(const char* str, char** endptr) {
+  return google::protobuf::internal::NoLocaleStrtod(str, endptr);
+}
+
 }  // namespace io
 }  // namespace protobuf
 }  // namespace google

+ 4 - 3
src/google/protobuf/map_entry_lite.h

@@ -128,7 +128,8 @@ struct MapEntryFuncs {
     // Tags for key and value will both be one byte (field numbers 1 and 2).
     size_t inner_length =
         2 + KeyTypeHandler::ByteSize(key) + ValueTypeHandler::ByteSize(value);
-    return inner_length + io::CodedOutputStream::VarintSize32(static_cast<uint32>(inner_length));
+    return inner_length + io::CodedOutputStream::VarintSize32(
+                              static_cast<uint32>(inner_length));
   }
 
   static int GetCachedSize(const Key& key, const Value& value) {
@@ -275,8 +276,8 @@ class MapEntryImpl : public Base {
     return size;
   }
 
-  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
-      ::google::protobuf::uint8* ptr, io::EpsCopyOutputStream* stream) const override {
+  ::google::protobuf::uint8* _InternalSerialize(::google::protobuf::uint8* ptr,
+                              io::EpsCopyOutputStream* stream) const override {
     ptr = KeyTypeHandler::Write(kKeyFieldNumber, key(), ptr, stream);
     return ValueTypeHandler::Write(kValueFieldNumber, value(), ptr, stream);
   }

+ 15 - 0
src/google/protobuf/map_field.h

@@ -36,6 +36,7 @@
 #include <google/protobuf/arena.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/map_entry.h>
 #include <google/protobuf/map_field_lite.h>
 #include <google/protobuf/map_type_handler.h>
@@ -311,6 +312,20 @@ class MapField : public TypeDefinedMapFieldBase<Key, T> {
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapField);
 };
 
+template <typename Derived, typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type, int default_enum_value>
+bool AllAreInitialized(
+    const MapField<Derived, Key, T, key_wire_type, value_wire_type,
+                   default_enum_value>& field) {
+  const auto& t = field.GetMap();
+  for (typename Map<Key, T>::const_iterator it = t.begin(); it != t.end();
+       ++it) {
+    if (!it->second.IsInitialized()) return false;
+  }
+  return true;
+}
+
 template <typename T, typename Key, typename Value,
           WireFormatLite::FieldType kKeyFieldType,
           WireFormatLite::FieldType kValueFieldType, int default_enum_value>

+ 7 - 2
src/google/protobuf/map_field_lite.h

@@ -153,8 +153,13 @@ EnumParseWrapper<T, Metadata> InitEnumParseWrapper(T* map_field,
 // expected to be message.  It's useful to have this helper here to keep the
 // protobuf compiler from ever having to emit loops in IsInitialized() methods.
 // We want the C++ compiler to inline this or not as it sees fit.
-template <typename Key, typename T>
-bool AllAreInitialized(const Map<Key, T>& t) {
+template <typename Derived, typename Key, typename T,
+          WireFormatLite::FieldType key_wire_type,
+          WireFormatLite::FieldType value_wire_type, int default_enum_value>
+bool AllAreInitialized(
+    const MapFieldLite<Derived, Key, T, key_wire_type, value_wire_type,
+                       default_enum_value>& field) {
+  const auto& t = field.GetMap();
   for (typename Map<Key, T>::const_iterator it = t.begin(); it != t.end();
        ++it) {
     if (!it->second.IsInitialized()) return false;

+ 1 - 1
src/google/protobuf/map_type_handler.h

@@ -363,7 +363,7 @@ inline uint8* MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Write(
     int field, const MapEntryAccessorType& value, uint8* ptr,
     io::EpsCopyOutputStream* stream) {
   ptr = stream->EnsureSpace(ptr);
-  return WireFormatLite::InternalWriteMessageToArray(field, value, ptr, stream);
+  return WireFormatLite::InternalWriteMessage(field, value, ptr, stream);
 }
 
 #define WRITE_METHOD(FieldType, DeclaredType)                                  \

+ 19 - 21
src/google/protobuf/message.cc

@@ -241,10 +241,11 @@ const char* ParsePackedField(const FieldDescriptor* field, Message* msg,
                              const Reflection* reflection, const char* ptr,
                              internal::ParseContext* ctx) {
   switch (field->type()) {
-#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, METHOD_NAME) \
-  case FieldDescriptor::TYPE_##TYPE:                   \
-    return internal::Packed##METHOD_NAME##Parser(      \
-        reflection->MutableRepeatedField<CPPTYPE>(msg, field), ptr, ctx)
+#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, METHOD_NAME)                      \
+  case FieldDescriptor::TYPE_##TYPE:                                        \
+    return internal::Packed##METHOD_NAME##Parser(                           \
+        reflection->MutableRepeatedFieldInternal<CPPTYPE>(msg, field), ptr, \
+        ctx)
     HANDLE_PACKED_TYPE(INT32, int32, Int32);
     HANDLE_PACKED_TYPE(INT64, int64, Int64);
     HANDLE_PACKED_TYPE(SINT32, int32, SInt32);
@@ -291,17 +292,13 @@ const char* ParseLenDelim(int field_number, const FieldDescriptor* field,
   const char* field_name = nullptr;
   auto parse_string = [ptr, ctx, &utf8_level,
                        &field_name](std::string* s) -> const char* {
-    switch (utf8_level) {
-      case kNone:
-        return internal::InlineGreedyStringParser(s, ptr, ctx);
-      case kVerify:
-        return internal::InlineGreedyStringParserUTF8Verify(s, ptr, ctx,
-                                                            field_name);
-      case kStrict:
-        return internal::InlineGreedyStringParserUTF8(s, ptr, ctx, field_name);
+    auto res = internal::InlineGreedyStringParser(s, ptr, ctx);
+    if (utf8_level != kNone) {
+      if (!internal::VerifyUTF8(s, field_name) && utf8_level == kStrict) {
+        return nullptr;
+      }
     }
-    GOOGLE_LOG(FATAL) << "Should not reach here";
-    return nullptr;  // Make compiler happy
+    return res;
   };
   switch (field->type()) {
     case FieldDescriptor::TYPE_STRING: {
@@ -324,12 +321,14 @@ const char* ParseLenDelim(int field_number, const FieldDescriptor* field,
         if (field->options().ctype() == FieldOptions::STRING ||
             field->is_extension()) {
           auto object =
-              reflection->MutableRepeatedPtrField<std::string>(msg, field)
+              reflection
+                  ->MutableRepeatedPtrFieldInternal<std::string>(msg, field)
                   ->Mutable(index);
           return parse_string(object);
         } else {
           auto object =
-              reflection->MutableRepeatedPtrField<std::string>(msg, field)
+              reflection
+                  ->MutableRepeatedPtrFieldInternal<std::string>(msg, field)
                   ->Mutable(index);
           return parse_string(object);
         }
@@ -490,7 +489,7 @@ const char* Message::_InternalParse(const char* ptr,
       // If that failed, check if the field is an extension.
       if (field == nullptr && descriptor_->IsExtensionNumber(num)) {
         const DescriptorPool* pool = ctx_->data().pool;
-        if (pool == NULL) {
+        if (pool == nullptr) {
           field = reflection_->FindKnownExtensionByNumber(num);
         } else {
           field = pool->FindExtensionByNumber(descriptor_, num);
@@ -521,10 +520,9 @@ const char* Message::_InternalParse(const char* ptr,
   return internal::WireFormatParser(field_parser, ptr, ctx);
 }
 
-uint8* Message::InternalSerializeWithCachedSizesToArray(
-    uint8* target, io::EpsCopyOutputStream* stream) const {
-  return WireFormat::InternalSerializeWithCachedSizesToArray(*this, target,
-                                                             stream);
+uint8* Message::_InternalSerialize(uint8* target,
+                                   io::EpsCopyOutputStream* stream) const {
+  return WireFormat::_InternalSerialize(*this, target, stream);
 }
 
 size_t Message::ByteSizeLong() const {

+ 56 - 28
src/google/protobuf/message.h

@@ -304,8 +304,8 @@ class PROTOBUF_EXPORT Message : public MessageLite {
   const char* _InternalParse(const char* ptr,
                              internal::ParseContext* ctx) override;
   size_t ByteSizeLong() const override;
-  uint8* InternalSerializeWithCachedSizesToArray(
-      uint8* target, io::EpsCopyOutputStream* stream) const override;
+  uint8* _InternalSerialize(uint8* target,
+                            io::EpsCopyOutputStream* stream) const override;
 
  private:
   // This is called only by the default implementation of ByteSize(), to
@@ -747,16 +747,20 @@ class PROTOBUF_EXPORT Reflection final {
   // for T = Cord and all protobuf scalar types except enums.
   template <typename T>
   PROTOBUF_DEPRECATED_MSG("Please use GetRepeatedFieldRef() instead")
-  const RepeatedField<T>& GetRepeatedField(const Message&,
-                                           const FieldDescriptor*) const;
+  const RepeatedField<T>& GetRepeatedField(const Message& msg,
+                                           const FieldDescriptor* d) const {
+    return GetRepeatedFieldInternal<T>(msg, d);
+  }
 
   // DEPRECATED. Please use GetMutableRepeatedFieldRef().
   //
   // for T = Cord and all protobuf scalar types except enums.
   template <typename T>
   PROTOBUF_DEPRECATED_MSG("Please use GetMutableRepeatedFieldRef() instead")
-  RepeatedField<T>* MutableRepeatedField(Message*,
-                                         const FieldDescriptor*) const;
+  RepeatedField<T>* MutableRepeatedField(Message* msg,
+                                         const FieldDescriptor* d) const {
+    return MutableRepeatedFieldInternal<T>(msg, d);
+  }
 
   // DEPRECATED. Please use GetRepeatedFieldRef().
   //
@@ -764,8 +768,10 @@ class PROTOBUF_EXPORT Reflection final {
   //         google::protobuf::Message & descendants.
   template <typename T>
   PROTOBUF_DEPRECATED_MSG("Please use GetRepeatedFieldRef() instead")
-  const RepeatedPtrField<T>& GetRepeatedPtrField(const Message&,
-                                                 const FieldDescriptor*) const;
+  const RepeatedPtrField<T>& GetRepeatedPtrField(
+      const Message& msg, const FieldDescriptor* d) const {
+    return GetRepeatedPtrFieldInternal<T>(msg, d);
+  }
 
   // DEPRECATED. Please use GetMutableRepeatedFieldRef().
   //
@@ -773,22 +779,20 @@ class PROTOBUF_EXPORT Reflection final {
   //         google::protobuf::Message & descendants.
   template <typename T>
   PROTOBUF_DEPRECATED_MSG("Please use GetMutableRepeatedFieldRef() instead")
-  RepeatedPtrField<T>* MutableRepeatedPtrField(Message*,
-                                               const FieldDescriptor*) const;
+  RepeatedPtrField<T>* MutableRepeatedPtrField(Message* msg,
+                                               const FieldDescriptor* d) const {
+    return MutableRepeatedPtrFieldInternal<T>(msg, d);
+  }
 
   // Extensions ----------------------------------------------------------------
 
   // Try to find an extension of this message type by fully-qualified field
   // name.  Returns nullptr if no extension is known for this name or number.
-  PROTOBUF_DEPRECATED_MSG(
-      "Please use DescriptorPool::FindExtensionByPrintableName instead")
   const FieldDescriptor* FindKnownExtensionByName(
       const std::string& name) const;
 
   // Try to find an extension of this message type by field number.
   // Returns nullptr if no extension is known for this name or number.
-  PROTOBUF_DEPRECATED_MSG(
-      "Please use DescriptorPool::FindExtensionByNumber instead")
   const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
 
   // Feature Flags -------------------------------------------------------------
@@ -835,6 +839,18 @@ class PROTOBUF_EXPORT Reflection final {
   MessageFactory* GetMessageFactory() const;
 
  private:
+  template <typename T>
+  const RepeatedField<T>& GetRepeatedFieldInternal(
+      const Message& message, const FieldDescriptor* field) const;
+  template <typename T>
+  RepeatedField<T>* MutableRepeatedFieldInternal(
+      Message* message, const FieldDescriptor* field) const;
+  template <typename T>
+  const RepeatedPtrField<T>& GetRepeatedPtrFieldInternal(
+      const Message& message, const FieldDescriptor* field) const;
+  template <typename T>
+  RepeatedPtrField<T>* MutableRepeatedPtrFieldInternal(
+      Message* message, const FieldDescriptor* field) const;
   // Obtain a pointer to a Repeated Field Structure and do some type checking:
   //   on field->cpp_type(),
   //   on field->field_option().ctype() (if ctype >= 0)
@@ -1059,6 +1075,17 @@ class PROTOBUF_EXPORT Reflection final {
   friend inline  // inline so nobody can call this function.
       void
       RegisterAllTypesInternal(const Metadata* file_level_metadata, int size);
+  friend inline const char* ParseLenDelim(int field_number,
+                                          const FieldDescriptor* field,
+                                          Message* msg,
+                                          const Reflection* reflection,
+                                          const char* ptr,
+                                          internal::ParseContext* ctx);
+  friend inline const char* ParsePackedField(const FieldDescriptor* field,
+                                             Message* msg,
+                                             const Reflection* reflection,
+                                             const char* ptr,
+                                             internal::ParseContext* ctx);
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection);
 };
@@ -1127,14 +1154,15 @@ class PROTOBUF_EXPORT MessageFactory {
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFactory);
 };
 
-#define DECLARE_GET_REPEATED_FIELD(TYPE)                                       \
-  template <>                                                                  \
-  PROTOBUF_EXPORT const RepeatedField<TYPE>&                                   \
-  Reflection::GetRepeatedField<TYPE>(const Message& message,                   \
-                                     const FieldDescriptor* field) const;      \
-                                                                               \
-  template <>                                                                  \
-  PROTOBUF_EXPORT RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>( \
+#define DECLARE_GET_REPEATED_FIELD(TYPE)                           \
+  template <>                                                      \
+  PROTOBUF_EXPORT const RepeatedField<TYPE>&                       \
+  Reflection::GetRepeatedFieldInternal<TYPE>(                      \
+      const Message& message, const FieldDescriptor* field) const; \
+                                                                   \
+  template <>                                                      \
+  PROTOBUF_EXPORT RepeatedField<TYPE>*                             \
+  Reflection::MutableRepeatedFieldInternal<TYPE>(                  \
       Message * message, const FieldDescriptor* field) const;
 
 DECLARE_GET_REPEATED_FIELD(int32)
@@ -1213,7 +1241,7 @@ void LinkMessageReflection() {
 
 template <>
 inline const RepeatedPtrField<std::string>&
-Reflection::GetRepeatedPtrField<std::string>(
+Reflection::GetRepeatedPtrFieldInternal<std::string>(
     const Message& message, const FieldDescriptor* field) const {
   return *static_cast<RepeatedPtrField<std::string>*>(
       MutableRawRepeatedString(const_cast<Message*>(&message), field, true));
@@ -1221,7 +1249,7 @@ Reflection::GetRepeatedPtrField<std::string>(
 
 template <>
 inline RepeatedPtrField<std::string>*
-Reflection::MutableRepeatedPtrField<std::string>(
+Reflection::MutableRepeatedPtrFieldInternal<std::string>(
     Message* message, const FieldDescriptor* field) const {
   return static_cast<RepeatedPtrField<std::string>*>(
       MutableRawRepeatedString(message, field, true));
@@ -1231,21 +1259,21 @@ Reflection::MutableRepeatedPtrField<std::string>(
 // -----
 
 template <>
-inline const RepeatedPtrField<Message>& Reflection::GetRepeatedPtrField(
+inline const RepeatedPtrField<Message>& Reflection::GetRepeatedPtrFieldInternal(
     const Message& message, const FieldDescriptor* field) const {
   return *static_cast<const RepeatedPtrField<Message>*>(GetRawRepeatedField(
       message, field, FieldDescriptor::CPPTYPE_MESSAGE, -1, nullptr));
 }
 
 template <>
-inline RepeatedPtrField<Message>* Reflection::MutableRepeatedPtrField(
+inline RepeatedPtrField<Message>* Reflection::MutableRepeatedPtrFieldInternal(
     Message* message, const FieldDescriptor* field) const {
   return static_cast<RepeatedPtrField<Message>*>(MutableRawRepeatedField(
       message, field, FieldDescriptor::CPPTYPE_MESSAGE, -1, nullptr));
 }
 
 template <typename PB>
-inline const RepeatedPtrField<PB>& Reflection::GetRepeatedPtrField(
+inline const RepeatedPtrField<PB>& Reflection::GetRepeatedPtrFieldInternal(
     const Message& message, const FieldDescriptor* field) const {
   return *static_cast<const RepeatedPtrField<PB>*>(
       GetRawRepeatedField(message, field, FieldDescriptor::CPPTYPE_MESSAGE, -1,
@@ -1253,7 +1281,7 @@ inline const RepeatedPtrField<PB>& Reflection::GetRepeatedPtrField(
 }
 
 template <typename PB>
-inline RepeatedPtrField<PB>* Reflection::MutableRepeatedPtrField(
+inline RepeatedPtrField<PB>* Reflection::MutableRepeatedPtrFieldInternal(
     Message* message, const FieldDescriptor* field) const {
   return static_cast<RepeatedPtrField<PB>*>(
       MutableRawRepeatedField(message, field, FieldDescriptor::CPPTYPE_MESSAGE,

+ 52 - 3
src/google/protobuf/message_lite.cc

@@ -53,6 +53,7 @@
 #include <google/protobuf/repeated_field.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/stl_util.h>
+#include <google/protobuf/stubs/mutex.h>
 
 #include <google/protobuf/port_def.inc>
 
@@ -316,7 +317,7 @@ inline uint8* SerializeToArrayImpl(const MessageLite& msg, uint8* target,
     io::EpsCopyOutputStream out(
         &stream, io::CodedOutputStream::IsDefaultSerializationDeterministic(),
         &ptr);
-    ptr = msg.InternalSerializeWithCachedSizesToArray(ptr, &out);
+    ptr = msg._InternalSerialize(ptr, &out);
     out.Trim(ptr);
     GOOGLE_DCHECK(!out.HadError() && stream.ByteCount() == size);
     return target + size;
@@ -324,7 +325,7 @@ inline uint8* SerializeToArrayImpl(const MessageLite& msg, uint8* target,
     io::EpsCopyOutputStream out(
         target, size,
         io::CodedOutputStream::IsDefaultSerializationDeterministic());
-    auto res = msg.InternalSerializeWithCachedSizesToArray(target, &out);
+    auto res = msg._InternalSerialize(target, &out);
     GOOGLE_DCHECK(target + size == res);
     return res;
   }
@@ -384,7 +385,7 @@ bool MessageLite::SerializePartialToZeroCopyStream(
   io::EpsCopyOutputStream stream(
       output, io::CodedOutputStream::IsDefaultSerializationDeterministic(),
       &target);
-  target = InternalSerializeWithCachedSizesToArray(target, &stream);
+  target = _InternalSerialize(target, &stream);
   stream.Trim(target);
   if (stream.HadError()) return false;
   return true;
@@ -499,5 +500,53 @@ void GenericTypeHandler<std::string>::Merge(const std::string& from,
 
 }  // namespace internal
 
+
+// ===================================================================
+// Shutdown support.
+
+namespace internal {
+
+struct ShutdownData {
+  ~ShutdownData() {
+    std::reverse(functions.begin(), functions.end());
+    for (auto pair : functions) pair.first(pair.second);
+  }
+
+  static ShutdownData* get() {
+    static auto* data = new ShutdownData;
+    return data;
+  }
+
+  std::vector<std::pair<void (*)(const void*), const void*>> functions;
+  Mutex mutex;
+};
+
+static void RunZeroArgFunc(const void* arg) {
+  void (*func)() = reinterpret_cast<void (*)()>(const_cast<void*>(arg));
+  func();
+}
+
+void OnShutdown(void (*func)()) {
+  OnShutdownRun(RunZeroArgFunc, reinterpret_cast<void*>(func));
+}
+
+void OnShutdownRun(void (*f)(const void*), const void* arg) {
+  auto shutdown_data = ShutdownData::get();
+  MutexLock lock(&shutdown_data->mutex);
+  shutdown_data->functions.push_back(std::make_pair(f, arg));
+}
+
+}  // namespace internal
+
+void ShutdownProtobufLibrary() {
+  // This function should be called only once, but accepts multiple calls.
+  static bool is_shutdown = false;
+  if (!is_shutdown) {
+    delete internal::ShutdownData::get();
+    is_shutdown = true;
+  }
+}
+
+
 }  // namespace protobuf
 }  // namespace google

+ 38 - 5
src/google/protobuf/message_lite.h

@@ -405,8 +405,7 @@ class PROTOBUF_EXPORT MessageLite {
   // have changed since the last call to ByteSize(), and the value returned by
   // ByteSize must be non-negative.  Otherwise the results are undefined.
   void SerializeWithCachedSizes(io::CodedOutputStream* output) const {
-    output->SetCur(InternalSerializeWithCachedSizesToArray(output->Cur(),
-                                                           output->EpsCopy()));
+    output->SetCur(_InternalSerialize(output->Cur(), output->EpsCopy()));
   }
 
   // Functions below here are not part of the public interface.  It isn't
@@ -461,9 +460,9 @@ class PROTOBUF_EXPORT MessageLite {
   bool ParseFrom(const T& input);
 
   // Fast path when conditions match (ie. non-deterministic)
-  //  uint8* InternalSerializeWithCachedSizesToArray(uint8* ptr) const;
-  virtual uint8* InternalSerializeWithCachedSizesToArray(
-      uint8* ptr, io::EpsCopyOutputStream* stream) const = 0;
+  //  uint8* _InternalSerialize(uint8* ptr) const;
+  virtual uint8* _InternalSerialize(uint8* ptr,
+                                    io::EpsCopyOutputStream* stream) const = 0;
 
  private:
   // TODO(gerbens) make this a pure abstract function
@@ -530,6 +529,40 @@ bool MessageLite::ParseFrom(const T& input) {
   return res && ((flags & kMergePartial) || IsInitializedWithErrors());
 }
 
+// ===================================================================
+// Shutdown support.
+
+
+// Shut down the entire protocol buffers library, deleting all static-duration
+// objects allocated by the library or by generated .pb.cc files.
+//
+// There are two reasons you might want to call this:
+// * You use a draconian definition of "memory leak" in which you expect
+//   every single malloc() to have a corresponding free(), even for objects
+//   which live until program exit.
+// * You are writing a dynamically-loaded library which needs to clean up
+//   after itself when the library is unloaded.
+//
+// It is safe to call this multiple times.  However, it is not safe to use
+// any other part of the protocol buffers library after
+// ShutdownProtobufLibrary() has been called. Furthermore this call is not
+// thread safe, user needs to synchronize multiple calls.
+PROTOBUF_EXPORT void ShutdownProtobufLibrary();
+
+namespace internal {
+
+// Register a function to be called when ShutdownProtocolBuffers() is called.
+PROTOBUF_EXPORT void OnShutdown(void (*func)());
+// Run an arbitrary function on an arg
+PROTOBUF_EXPORT void OnShutdownRun(void (*f)(const void*), const void* arg);
+
+template <typename T>
+T* OnShutdownDelete(T* p) {
+  OnShutdownRun([](const void* pp) { delete static_cast<const T*>(pp); }, p);
+  return p;
+}
+
+}  // namespace internal
 }  // namespace protobuf
 }  // namespace google
 

+ 0 - 8
src/google/protobuf/parse_context.cc

@@ -424,14 +424,6 @@ const char* InlineGreedyStringParser(std::string* s, const char* ptr,
   return ctx->ReadString(ptr, size, s);
 }
 
-const char* InlineGreedyStringParserUTF8(std::string* s, const char* ptr,
-                                         ParseContext* ctx,
-                                         const char* field_name) {
-  auto p = InlineGreedyStringParser(s, ptr, ctx);
-  GOOGLE_PROTOBUF_PARSER_ASSERT(VerifyUTF8(*s, field_name));
-  return p;
-}
-
 
 template <typename T, bool sign>
 const char* VarintParser(void* object, const char* ptr, ParseContext* ctx) {

Деякі файли не було показано, через те що забагато файлів було змінено