فهرست منبع

Merge pull request #606 from jtattermusch/csharp-experimental-merged

Update csharp-experimental with changes from upstream/master
Jon Skeet 10 سال پیش
والد
کامیت
19cf9d1e00
39فایلهای تغییر یافته به همراه761 افزوده شده و 430 حذف شده
  1. 131 93
      BUILD
  2. 5 19
      Protobuf.podspec
  3. 16 0
      WORKSPACE
  4. 1 1
      cmake/README.md
  5. 0 1
      cmake/extract_includes.bat.in
  6. 3 3
      conformance/ConformanceJava.java
  7. 11 7
      conformance/conformance.proto
  8. 47 9
      conformance/conformance_cpp.cc
  9. 167 19
      conformance/conformance_test.cc
  10. 23 2
      conformance/conformance_test.h
  11. 12 12
      conformance/failure_list_cpp.txt
  12. 23 0
      gmock.BUILD
  13. 12 0
      objectivec/GPBProtocolBuffers.h
  14. 7 0
      python/google/protobuf/internal/test_util.py
  15. 13 1
      ruby/ext/google/protobuf_c/encode_decode.c
  16. 0 1
      src/Makefile.am
  17. 5 5
      src/google/protobuf/compiler/cpp/cpp_message.cc
  18. 3 7
      src/google/protobuf/compiler/csharp/csharp_field_base.cc
  19. 1 0
      src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
  20. 1 1
      src/google/protobuf/compiler/subprocess.cc
  21. 2 1
      src/google/protobuf/map.h
  22. 12 0
      src/google/protobuf/map_entry_lite.h
  23. 2 2
      src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
  24. 22 14
      src/google/protobuf/stubs/common.h
  25. 111 6
      src/google/protobuf/stubs/hash.h
  26. 0 142
      src/google/protobuf/stubs/pbconfig.h
  27. 3 7
      src/google/protobuf/stubs/strutil.cc
  28. 9 0
      src/google/protobuf/testing/zcgunzip.cc
  29. 9 0
      src/google/protobuf/testing/zcgzip.cc
  30. 3 7
      src/google/protobuf/text_format_unittest.cc
  31. 5 0
      src/google/protobuf/unknown_field_set.cc
  32. 1 0
      src/google/protobuf/util/field_comparator.cc
  33. 2 1
      src/google/protobuf/util/internal/datapiece.cc
  34. 3 0
      src/google/protobuf/util/internal/type_info_test_helper.cc
  35. 2 1
      src/google/protobuf/util/internal/utility.cc
  36. 2 11
      src/google/protobuf/util/message_differencer.h
  37. 1 1
      src/google/protobuf/wire_format.h
  38. 88 56
      src/google/protobuf/wire_format_unittest.cc
  39. 3 0
      update_file_lists.sh

+ 131 - 93
BUILD

@@ -2,6 +2,10 @@
 
 licenses(["notice"])
 
+################################################################################
+# Protobuf Runtime Library
+################################################################################
+
 COPTS = [
     "-DHAVE_PTHREAD",
     "-Wall",
@@ -109,6 +113,34 @@ cc_library(
     deps = [":protobuf_lite"],
 )
 
+objc_library(
+    name = "protobuf_objc",
+    hdrs = ["objectivec/GPBProtocolBuffers.h"],
+    includes = ["objectivec"],
+    non_arc_srcs = ["objectivec/GPBProtocolBuffers.m"],
+    visibility = ["//visibility:public"],
+)
+
+WELL_KNOWN_PROTOS = [
+    # AUTOGEN(well_known_protos)
+    "google/protobuf/any.proto",
+    "google/protobuf/api.proto",
+    "google/protobuf/compiler/plugin.proto",
+    "google/protobuf/descriptor.proto",
+    "google/protobuf/duration.proto",
+    "google/protobuf/empty.proto",
+    "google/protobuf/field_mask.proto",
+    "google/protobuf/source_context.proto",
+    "google/protobuf/struct.proto",
+    "google/protobuf/timestamp.proto",
+    "google/protobuf/type.proto",
+    "google/protobuf/wrappers.proto",
+]
+
+################################################################################
+# Protocol Buffers Compiler
+################################################################################
+
 cc_library(
     name = "protoc_lib",
     srcs = [
@@ -216,22 +248,6 @@ cc_binary(
     deps = [":protoc_lib"],
 )
 
-WELL_KNOWN_PROTOS = [
-    # AUTOGEN(well_known_protos)
-    "google/protobuf/any.proto",
-    "google/protobuf/api.proto",
-    "google/protobuf/compiler/plugin.proto",
-    "google/protobuf/descriptor.proto",
-    "google/protobuf/duration.proto",
-    "google/protobuf/empty.proto",
-    "google/protobuf/field_mask.proto",
-    "google/protobuf/source_context.proto",
-    "google/protobuf/struct.proto",
-    "google/protobuf/timestamp.proto",
-    "google/protobuf/type.proto",
-    "google/protobuf/wrappers.proto",
-]
-
 ################################################################################
 # Tests
 ################################################################################
@@ -286,11 +302,13 @@ PROTOS = LITE_TEST_PROTOS + TEST_PROTOS
 
 INPUTS = PROTOS + WELL_KNOWN_PROTOS
 
+OUTPUTS = ["src/" + x[:-5] + "pb.h" for x in PROTOS] + \
+          ["src/" + x[:-5] + "pb.cc" for x in PROTOS]
+
 genrule(
     name = "gen_test_protos",
     srcs = ["src/" + x for x in INPUTS],
-    outs = ["src/" + x[:-5] + "pb.h" for x in PROTOS] +
-           ["src/" + x[:-5] + "pb.cc" for x in PROTOS],
+    outs = OUTPUTS,
     cmd =
         "$(location :protoc) --cpp_out=$(@D)/src" +
         "".join([" -I" + x + "=$(location src/" + x + ")" for x in INPUTS]) +
@@ -307,78 +325,98 @@ COMMON_TEST_SRCS = [
     "src/google/protobuf/testing/googletest.cc",
 ]
 
-# TODO(liujisi): Add gtest dependency and enable tests.
-# cc_test(
-#     name = "protobuf_test",
-#     srcs = OUTPUTS + COMMON_TEST_SRCS + [
-#         "src/google/protobuf/any_test.cc",
-#         "src/google/protobuf/arena_unittest.cc",
-#         "src/google/protobuf/arenastring_unittest.cc",
-#         "src/google/protobuf/compiler/command_line_interface_unittest.cc",
-#         "src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc",
-#         "src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc",
-#         "src/google/protobuf/compiler/cpp/cpp_unittest.cc",
-#         "src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc",
-#         "src/google/protobuf/compiler/importer_unittest.cc",
-#         "src/google/protobuf/compiler/java/java_doc_comment_unittest.cc",
-#         "src/google/protobuf/compiler/java/java_plugin_unittest.cc",
-#         "src/google/protobuf/compiler/mock_code_generator.cc",
-#         "src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc",
-#         "src/google/protobuf/compiler/parser_unittest.cc",
-#         "src/google/protobuf/compiler/python/python_plugin_unittest.cc",
-#         "src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc",
-#         "src/google/protobuf/descriptor_database_unittest.cc",
-#         "src/google/protobuf/descriptor_unittest.cc",
-#         "src/google/protobuf/drop_unknown_fields_test.cc",
-#         "src/google/protobuf/dynamic_message_unittest.cc",
-#         "src/google/protobuf/extension_set_unittest.cc",
-#         "src/google/protobuf/generated_message_reflection_unittest.cc",
-#         "src/google/protobuf/io/coded_stream_unittest.cc",
-#         "src/google/protobuf/io/printer_unittest.cc",
-#         "src/google/protobuf/io/tokenizer_unittest.cc",
-#         "src/google/protobuf/io/zero_copy_stream_unittest.cc",
-#         "src/google/protobuf/map_field_test.cc",
-#         "src/google/protobuf/map_test.cc",
-#         "src/google/protobuf/message_unittest.cc",
-#         "src/google/protobuf/no_field_presence_test.cc",
-#         "src/google/protobuf/preserve_unknown_enum_test.cc",
-#         "src/google/protobuf/proto3_arena_unittest.cc",
-#         "src/google/protobuf/reflection_ops_unittest.cc",
-#         "src/google/protobuf/repeated_field_reflection_unittest.cc",
-#         "src/google/protobuf/repeated_field_unittest.cc",
-#         "src/google/protobuf/stubs/bytestream_unittest.cc",
-#         "src/google/protobuf/stubs/common_unittest.cc",
-#         "src/google/protobuf/stubs/once_unittest.cc",
-#         "src/google/protobuf/stubs/status_test.cc",
-#         "src/google/protobuf/stubs/statusor_test.cc",
-#         "src/google/protobuf/stubs/stringpiece_unittest.cc",
-#         "src/google/protobuf/stubs/stringprintf_unittest.cc",
-#         "src/google/protobuf/stubs/structurally_valid_unittest.cc",
-#         "src/google/protobuf/stubs/strutil_unittest.cc",
-#         "src/google/protobuf/stubs/template_util_unittest.cc",
-#         "src/google/protobuf/stubs/time_test.cc",
-#         "src/google/protobuf/stubs/type_traits_unittest.cc",
-#         "src/google/protobuf/text_format_unittest.cc",
-#         "src/google/protobuf/unknown_field_set_unittest.cc",
-#         "src/google/protobuf/util/field_comparator_test.cc",
-#         "src/google/protobuf/util/internal/default_value_objectwriter_test.cc",
-#         "src/google/protobuf/util/internal/json_objectwriter_test.cc",
-#         "src/google/protobuf/util/internal/json_stream_parser_test.cc",
-#         "src/google/protobuf/util/internal/protostream_objectsource_test.cc",
-#         "src/google/protobuf/util/internal/protostream_objectwriter_test.cc",
-#         "src/google/protobuf/util/internal/type_info_test_helper.cc",
-#         "src/google/protobuf/util/json_util_test.cc",
-#         "src/google/protobuf/util/type_resolver_util_test.cc",
-#         "src/google/protobuf/well_known_types_unittest.cc",
-#         "src/google/protobuf/wire_format_unittest.cc",
-#     ],
-#     copts = COPTS,
-#     includes = [
-#         "src/",
-#     ],
-#     linkopts = LINK_OPTS,
-#     deps = [
-#         ":protobuf",
-#         ":protoc_lib",
-#     ],
-# )
+cc_binary(
+    name = "test_plugin",
+    srcs = [
+        # AUTOGEN(test_plugin_srcs)
+        "src/google/protobuf/compiler/mock_code_generator.cc",
+        "src/google/protobuf/compiler/test_plugin.cc",
+        "src/google/protobuf/testing/file.cc",
+    ],
+    deps = [
+        ":protobuf",
+        ":protoc_lib",
+        "//external:gtest",
+    ],
+)
+
+cc_test(
+    name = "protobuf_test",
+    srcs = OUTPUTS + COMMON_TEST_SRCS + [
+        # AUTOGEN(test_srcs)
+        "src/google/protobuf/any_test.cc",
+        "src/google/protobuf/arena_unittest.cc",
+        "src/google/protobuf/arenastring_unittest.cc",
+        "src/google/protobuf/compiler/command_line_interface_unittest.cc",
+        "src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc",
+        "src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc",
+        "src/google/protobuf/compiler/cpp/cpp_unittest.cc",
+        "src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc",
+        "src/google/protobuf/compiler/importer_unittest.cc",
+        "src/google/protobuf/compiler/java/java_doc_comment_unittest.cc",
+        "src/google/protobuf/compiler/java/java_plugin_unittest.cc",
+        "src/google/protobuf/compiler/mock_code_generator.cc",
+        "src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc",
+        "src/google/protobuf/compiler/parser_unittest.cc",
+        "src/google/protobuf/compiler/python/python_plugin_unittest.cc",
+        "src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc",
+        "src/google/protobuf/descriptor_database_unittest.cc",
+        "src/google/protobuf/descriptor_unittest.cc",
+        "src/google/protobuf/drop_unknown_fields_test.cc",
+        "src/google/protobuf/dynamic_message_unittest.cc",
+        "src/google/protobuf/extension_set_unittest.cc",
+        "src/google/protobuf/generated_message_reflection_unittest.cc",
+        "src/google/protobuf/io/coded_stream_unittest.cc",
+        "src/google/protobuf/io/printer_unittest.cc",
+        "src/google/protobuf/io/tokenizer_unittest.cc",
+        "src/google/protobuf/io/zero_copy_stream_unittest.cc",
+        "src/google/protobuf/map_field_test.cc",
+        "src/google/protobuf/map_test.cc",
+        "src/google/protobuf/message_unittest.cc",
+        "src/google/protobuf/no_field_presence_test.cc",
+        "src/google/protobuf/preserve_unknown_enum_test.cc",
+        "src/google/protobuf/proto3_arena_unittest.cc",
+        "src/google/protobuf/reflection_ops_unittest.cc",
+        "src/google/protobuf/repeated_field_reflection_unittest.cc",
+        "src/google/protobuf/repeated_field_unittest.cc",
+        "src/google/protobuf/stubs/bytestream_unittest.cc",
+        "src/google/protobuf/stubs/common_unittest.cc",
+        "src/google/protobuf/stubs/once_unittest.cc",
+        "src/google/protobuf/stubs/status_test.cc",
+        "src/google/protobuf/stubs/statusor_test.cc",
+        "src/google/protobuf/stubs/stringpiece_unittest.cc",
+        "src/google/protobuf/stubs/stringprintf_unittest.cc",
+        "src/google/protobuf/stubs/structurally_valid_unittest.cc",
+        "src/google/protobuf/stubs/strutil_unittest.cc",
+        "src/google/protobuf/stubs/template_util_unittest.cc",
+        "src/google/protobuf/stubs/time_test.cc",
+        "src/google/protobuf/stubs/type_traits_unittest.cc",
+        "src/google/protobuf/text_format_unittest.cc",
+        "src/google/protobuf/unknown_field_set_unittest.cc",
+        "src/google/protobuf/util/field_comparator_test.cc",
+        "src/google/protobuf/util/internal/default_value_objectwriter_test.cc",
+        "src/google/protobuf/util/internal/json_objectwriter_test.cc",
+        "src/google/protobuf/util/internal/json_stream_parser_test.cc",
+        "src/google/protobuf/util/internal/protostream_objectsource_test.cc",
+        "src/google/protobuf/util/internal/protostream_objectwriter_test.cc",
+        "src/google/protobuf/util/internal/type_info_test_helper.cc",
+        "src/google/protobuf/util/json_util_test.cc",
+        "src/google/protobuf/util/type_resolver_util_test.cc",
+        "src/google/protobuf/well_known_types_unittest.cc",
+        "src/google/protobuf/wire_format_unittest.cc",
+    ],
+    copts = COPTS,
+    data = [
+        ":test_plugin",
+    ],
+    includes = [
+        "src/",
+    ],
+    linkopts = LINK_OPTS,
+    deps = [
+        ":protobuf",
+        ":protoc_lib",
+        "//external:gtest_main",
+    ],
+)
+

+ 5 - 19
Protobuf.podspec

@@ -11,25 +11,11 @@ Pod::Spec.new do |s|
   s.license  = 'New BSD'
   s.authors  = { 'The Protocol Buffers contributors' => 'protobuf@googlegroups.com' }
 
-  s.source_files = 'objectivec/*.{h,m}',
-                   'objectivec/google/protobuf/Any.pbobjc.{h,m}',
-                   'objectivec/google/protobuf/Api.pbobjc.{h,m}',
-                   'objectivec/google/protobuf/Descriptor.pbobjc.{h,m}',
-                   'objectivec/google/protobuf/Duration.pbobjc.h',
-                   'objectivec/google/protobuf/Empty.pbobjc.{h,m}',
-                   'objectivec/google/protobuf/FieldMask.pbobjc.{h,m}',
-                   'objectivec/google/protobuf/SourceContext.pbobjc.{h,m}',
-                   'objectivec/google/protobuf/Struct.pbobjc.{h,m}',
-                   'objectivec/google/protobuf/Timestamp.pbobjc.h',
-                   'objectivec/google/protobuf/Type.pbobjc.{h,m}'
-                   'objectivec/google/protobuf/Wrappers.pbobjc.{h,m}'
-  # Timestamp.pbobjc.m and Duration.pbobjc.m are #imported by GPBWellKnownTypes.m. So we can't
-  # compile them (duplicate symbols), but we need them available for the importing:
-  s.preserve_paths = 'objectivec/google/protobuf/Duration.pbobjc.m',
-                     'objectivec/google/protobuf/Timestamp.pbobjc.m'
-  # The following would cause duplicate symbol definitions. GPBProtocolBuffers is expected to be
-  # left out, as it's an umbrella implementation file.
-  s.exclude_files = 'objectivec/GPBProtocolBuffers.m'
+  s.source_files = 'objectivec/GPBProtocolBuffers.{h,m}'
+  # GPBProtocolBuffers.{h,m} are umbrella files. We need Cocoapods to preserve the files imported by
+  # them.
+  s.preserve_paths = 'objectivec/*.{h,m}',
+                     'objectivec/google/protobuf/*.pbobjc.{h,m}'
   s.header_mappings_dir = 'objectivec'
 
   s.ios.deployment_target = '6.0'

+ 16 - 0
WORKSPACE

@@ -0,0 +1,16 @@
+new_http_archive(
+  name = "gmock_archive",
+  url = "https://googlemock.googlecode.com/files/gmock-1.7.0.zip",
+  sha256 = "26fcbb5925b74ad5fc8c26b0495dfc96353f4d553492eb97e85a8a6d2f43095b",
+  build_file = "gmock.BUILD",
+)
+
+bind(
+  name = "gtest",
+  actual = "@gmock_archive//:gtest",
+)
+
+bind(
+  name = "gtest_main",
+  actual = "@gmock_archive//:gtest_main",
+)

+ 1 - 1
cmake/README.md

@@ -32,7 +32,7 @@ Compiling and Installing
    If you don't have gmock, skip the build of tests by turning off the
    BUILD_TESTING option:
 
-        $ cmake -G "Visutal Studio 9 2008" -DBUILD_TESTING=OFF ..
+        $ cmake -G "Visual Studio 9 2008" -DBUILD_TESTING=OFF ..
 
 3. Open the generated protobuf.sln file in Microsoft Visual Studio.
 4. Choose "Debug" or "Release" configuration as desired.

+ 0 - 1
cmake/extract_includes.bat.in

@@ -89,7 +89,6 @@ copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\common.h include
 copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\fastmem.h include\google\protobuf\stubs\fastmem.h
 copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\hash.h include\google\protobuf\stubs\hash.h
 copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\once.h include\google\protobuf\stubs\once.h
-copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\pbconfig.h include\google\protobuf\stubs\pbconfig.h
 copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\platform_macros.h include\google\protobuf\stubs\platform_macros.h
 copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\shared_ptr.h include\google\protobuf\stubs\shared_ptr.h
 copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\singleton.h include\google\protobuf\stubs\singleton.h

+ 3 - 3
conformance/ConformanceJava.java

@@ -54,7 +54,7 @@ class ConformanceJava {
         break;
       }
       case JSON_PAYLOAD: {
-        return Conformance.ConformanceResponse.newBuilder().setRuntimeError("JSON not yet supported.").build();
+        return Conformance.ConformanceResponse.newBuilder().setSkipped("JSON not yet supported.").build();
       }
       case PAYLOAD_NOT_SET: {
         throw new RuntimeException("Request didn't have payload.");
@@ -65,7 +65,7 @@ class ConformanceJava {
       }
     }
 
-    switch (request.getRequestedOutput()) {
+    switch (request.getRequestedOutputFormat()) {
       case UNSPECIFIED:
         throw new RuntimeException("Unspecified output format.");
 
@@ -73,7 +73,7 @@ class ConformanceJava {
         return Conformance.ConformanceResponse.newBuilder().setProtobufPayload(testMessage.toByteString()).build();
 
       case JSON:
-        return Conformance.ConformanceResponse.newBuilder().setRuntimeError("JSON not yet supported.").build();
+        return Conformance.ConformanceResponse.newBuilder().setSkipped("JSON not yet supported.").build();
 
       default: {
         throw new RuntimeException("Unexpected request output.");

+ 11 - 7
conformance/conformance.proto

@@ -51,6 +51,12 @@ option java_package = "com.google.protobuf.conformance";
 //   - running as a sub-process may be more tricky in unusual environments like
 //     iOS apps, where fork/stdin/stdout are not available.
 
+enum WireFormat {
+  UNSPECIFIED = 0;
+  PROTOBUF = 1;
+  JSON = 2;
+}
+
 // Represents a single test case's input.  The testee should:
 //
 //   1. parse this proto (which should always succeed)
@@ -64,14 +70,8 @@ message ConformanceRequest {
     string json_payload = 2;
   }
 
-  enum RequestedOutput {
-    UNSPECIFIED = 0;
-    PROTOBUF = 1;
-    JSON = 2;
-  }
-
   // Which format should the testee serialize its message to?
-  RequestedOutput requested_output = 3;
+  WireFormat requested_output_format = 3;
 }
 
 // Represents a single test case's output.
@@ -96,6 +96,10 @@ message ConformanceResponse {
     // If the input was successfully parsed and the requested output was JSON,
     // serialize to JSON and set it in this field.
     string json_payload = 4;
+
+    // For when the testee skipped the test, likely because a certain feature
+    // wasn't supported, like JSON input/output.
+    string skipped = 5;
   }
 }
 

+ 47 - 9
conformance/conformance_cpp.cc

@@ -33,14 +33,33 @@
 #include <unistd.h>
 
 #include "conformance.pb.h"
+#include <google/protobuf/util/json_util.h>
+#include <google/protobuf/util/type_resolver_util.h>
 
-using std::string;
 using conformance::ConformanceRequest;
 using conformance::ConformanceResponse;
 using conformance::TestAllTypes;
+using google::protobuf::Descriptor;
+using google::protobuf::DescriptorPool;
+using google::protobuf::internal::scoped_ptr;
+using google::protobuf::util::BinaryToJsonString;
+using google::protobuf::util::JsonToBinaryString;
+using google::protobuf::util::NewTypeResolverForDescriptorPool;
+using google::protobuf::util::Status;
+using google::protobuf::util::TypeResolver;
+using std::string;
+
+static const char kTypeUrlPrefix[] = "type.googleapis.com";
+
+static string GetTypeUrl(const Descriptor* message) {
+  return string(kTypeUrlPrefix) + "/" + message->full_name();
+}
 
 int test_count = 0;
 bool verbose = false;
+TypeResolver* type_resolver;
+string* type_url;
+
 
 bool CheckedRead(int fd, void *buf, size_t len) {
   size_t ofs = 0;
@@ -79,27 +98,43 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
       }
       break;
 
-    case ConformanceRequest::kJsonPayload:
-      response->set_runtime_error("JSON input is not yet supported.");
+    case ConformanceRequest::kJsonPayload: {
+      string proto_binary;
+      Status status = JsonToBinaryString(type_resolver, *type_url,
+                                         request.json_payload(), &proto_binary);
+      if (!status.ok()) {
+        response->set_parse_error(string("Parse error: ") +
+                                  status.error_message().as_string());
+        return;
+      }
+
+      GOOGLE_CHECK(test_message.ParseFromString(proto_binary));
       break;
+    }
 
     case ConformanceRequest::PAYLOAD_NOT_SET:
       GOOGLE_LOG(FATAL) << "Request didn't have payload.";
       break;
   }
 
-  switch (request.requested_output()) {
-    case ConformanceRequest::UNSPECIFIED:
+  switch (request.requested_output_format()) {
+    case conformance::UNSPECIFIED:
       GOOGLE_LOG(FATAL) << "Unspecified output format";
       break;
 
-    case ConformanceRequest::PROTOBUF:
-      test_message.SerializeToString(response->mutable_protobuf_payload());
+    case conformance::PROTOBUF:
+      GOOGLE_CHECK(
+          test_message.SerializeToString(response->mutable_protobuf_payload()));
       break;
 
-    case ConformanceRequest::JSON:
-      response->set_runtime_error("JSON output is not yet supported.");
+    case conformance::JSON: {
+      string proto_binary;
+      GOOGLE_CHECK(test_message.SerializeToString(&proto_binary));
+      Status status = BinaryToJsonString(type_resolver, *type_url, proto_binary,
+                                         response->mutable_json_payload());
+      GOOGLE_CHECK(status.ok());
       break;
+    }
   }
 }
 
@@ -146,6 +181,9 @@ bool DoTestIo() {
 }
 
 int main() {
+  type_resolver = NewTypeResolverForDescriptorPool(
+      kTypeUrlPrefix, DescriptorPool::generated_pool());
+  type_url = new string(GetTypeUrl(TestAllTypes::descriptor()));
   while (1) {
     if (!DoTestIo()) {
       fprintf(stderr, "conformance-cpp: received EOF from test runner "

+ 167 - 19
conformance/conformance_test.cc

@@ -35,18 +35,34 @@
 #include "conformance_test.h"
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/util/json_util.h>
+#include <google/protobuf/util/message_differencer.h>
+#include <google/protobuf/util/type_resolver_util.h>
 #include <google/protobuf/wire_format_lite.h>
 
 using conformance::ConformanceRequest;
 using conformance::ConformanceResponse;
 using conformance::TestAllTypes;
+using conformance::WireFormat;
 using google::protobuf::Descriptor;
 using google::protobuf::FieldDescriptor;
 using google::protobuf::internal::WireFormatLite;
+using google::protobuf::TextFormat;
+using google::protobuf::util::JsonToBinaryString;
+using google::protobuf::util::MessageDifferencer;
+using google::protobuf::util::NewTypeResolverForDescriptorPool;
+using google::protobuf::util::Status;
 using std::string;
 
 namespace {
 
+static const char kTypeUrlPrefix[] = "type.googleapis.com";
+
+static string GetTypeUrl(const Descriptor* message) {
+  return string(kTypeUrlPrefix) + "/" + message->full_name();
+}
+
 /* Routines for building arbitrary protos *************************************/
 
 // We would use CodedOutputStream except that we want more freedom to build
@@ -162,9 +178,13 @@ void ConformanceTestSuite::ReportSuccess(const string& test_name) {
 }
 
 void ConformanceTestSuite::ReportFailure(const string& test_name,
+                                         const ConformanceRequest& request,
+                                         const ConformanceResponse& response,
                                          const char* fmt, ...) {
   if (expected_to_fail_.erase(test_name) == 1) {
-    StringAppendF(&output_, "FAILED AS EXPECTED, test=%s: ", test_name.c_str());
+    expected_failures_++;
+    if (!verbose_)
+      return;
   } else {
     StringAppendF(&output_, "ERROR, test=%s: ", test_name.c_str());
     unexpected_failing_tests_.insert(test_name);
@@ -173,7 +193,20 @@ void ConformanceTestSuite::ReportFailure(const string& test_name,
   va_start(args, fmt);
   StringAppendV(&output_, fmt, args);
   va_end(args);
-  failures_++;
+  StringAppendF(&output_, " request=%s, response=%s\n",
+                request.ShortDebugString().c_str(),
+                response.ShortDebugString().c_str());
+}
+
+void ConformanceTestSuite::ReportSkip(const string& test_name,
+                                      const ConformanceRequest& request,
+                                      const ConformanceResponse& response) {
+  if (verbose_) {
+    StringAppendF(&output_, "SKIPPED, test=%s request=%s, response=%s\n",
+                  test_name.c_str(), request.ShortDebugString().c_str(),
+                  response.ShortDebugString().c_str());
+  }
+  skipped_.insert(test_name);
 }
 
 void ConformanceTestSuite::RunTest(const string& test_name,
@@ -202,26 +235,117 @@ void ConformanceTestSuite::RunTest(const string& test_name,
   }
 }
 
+void ConformanceTestSuite::RunValidInputTest(
+    const string& test_name, const string& input, WireFormat input_format,
+    const string& equivalent_text_format, WireFormat requested_output) {
+  TestAllTypes reference_message;
+  GOOGLE_CHECK(
+      TextFormat::ParseFromString(equivalent_text_format, &reference_message));
+
+  ConformanceRequest request;
+  ConformanceResponse response;
+
+  switch (input_format) {
+    case conformance::PROTOBUF:
+      request.set_protobuf_payload(input);
+      break;
+
+    case conformance::JSON:
+      request.set_json_payload(input);
+      break;
+
+    case conformance::UNSPECIFIED:
+      GOOGLE_LOG(FATAL) << "Unspecified input format";
+
+  }
+
+  request.set_requested_output_format(requested_output);
+
+  RunTest(test_name, request, &response);
+
+  TestAllTypes test_message;
+
+  switch (response.result_case()) {
+    case ConformanceResponse::kParseError:
+    case ConformanceResponse::kRuntimeError:
+      ReportFailure(test_name, request, response,
+                    "Failed to parse valid JSON input.");
+      return;
+
+    case ConformanceResponse::kSkipped:
+      ReportSkip(test_name, request, response);
+      return;
+
+    case ConformanceResponse::kJsonPayload: {
+      if (requested_output != conformance::JSON) {
+        ReportFailure(
+            test_name, request, response,
+            "Test was asked for protobuf output but provided JSON instead.");
+        return;
+      }
+      string binary_protobuf;
+      Status status =
+          JsonToBinaryString(type_resolver_.get(), type_url_,
+                             response.json_payload(), &binary_protobuf);
+      if (!status.ok()) {
+        ReportFailure(test_name, request, response,
+                      "JSON output we received from test was unparseable.");
+        return;
+      }
+
+      GOOGLE_CHECK(test_message.ParseFromString(binary_protobuf));
+      break;
+    }
+
+    case ConformanceResponse::kProtobufPayload: {
+      if (requested_output != conformance::PROTOBUF) {
+        ReportFailure(
+            test_name, request, response,
+            "Test was asked for JSON output but provided protobuf instead.");
+        return;
+      }
+
+      if (!test_message.ParseFromString(response.protobuf_payload())) {
+        ReportFailure(test_name, request, response,
+                      "Protobuf output we received from test was unparseable.");
+        return;
+      }
+
+      break;
+    }
+  }
+
+  MessageDifferencer differencer;
+  string differences;
+  differencer.ReportDifferencesToString(&differences);
+
+  if (differencer.Equals(reference_message, test_message)) {
+    ReportSuccess(test_name);
+  } else {
+    ReportFailure(test_name, request, response,
+                  "Output was not equivalent to reference message: %s.",
+                  differences.c_str());
+  }
+}
+
 // Expect that this precise protobuf will cause a parse error.
 void ConformanceTestSuite::ExpectParseFailureForProto(
     const string& proto, const string& test_name) {
   ConformanceRequest request;
   ConformanceResponse response;
   request.set_protobuf_payload(proto);
+  string effective_test_name = "ProtobufInput." + test_name;
 
   // We don't expect output, but if the program erroneously accepts the protobuf
   // we let it send its response as this.  We must not leave it unspecified.
-  request.set_requested_output(ConformanceRequest::PROTOBUF);
+  request.set_requested_output_format(conformance::PROTOBUF);
 
-  RunTest(test_name, request, &response);
+  RunTest(effective_test_name, request, &response);
   if (response.result_case() == ConformanceResponse::kParseError) {
-    ReportSuccess(test_name);
+    ReportSuccess(effective_test_name);
   } else {
-    ReportFailure(test_name,
-                  "Should have failed to parse, but didn't. Request: %s, "
-                  "response: %s\n",
-                  request.ShortDebugString().c_str(),
-                  response.ShortDebugString().c_str());
+    ReportFailure(effective_test_name, request, response,
+                  "Should have failed to parse, but didn't.");
   }
 }
 
@@ -235,6 +359,16 @@ void ConformanceTestSuite::ExpectHardParseFailureForProto(
   return ExpectParseFailureForProto(proto, test_name);
 }
 
+void ConformanceTestSuite::RunValidJsonTest(
+    const string& test_name, const string& input_json,
+    const string& equivalent_text_format) {
+  RunValidInputTest("JsonInput." + test_name + ".JsonOutput", input_json,
+                    conformance::JSON, equivalent_text_format,
+                    conformance::PROTOBUF);
+  RunValidInputTest("JsonInput." + test_name + ".ProtobufOutput", input_json, conformance::JSON,
+                    equivalent_text_format, conformance::JSON);
+}
+
 void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
   // Incomplete values for each wire type.
   static const string incompletes[6] = {
@@ -333,11 +467,12 @@ bool ConformanceTestSuite::CheckSetEmpty(const set<string>& set_to_check,
     return true;
   } else {
     StringAppendF(&output_, "\n");
-    StringAppendF(&output_, "ERROR: %s:\n", msg);
+    StringAppendF(&output_, "%s:\n", msg);
     for (set<string>::const_iterator iter = set_to_check.begin();
          iter != set_to_check.end(); ++iter) {
-      StringAppendF(&output_, "%s\n", iter->c_str());
+      StringAppendF(&output_, "  %s\n", iter->c_str());
     }
+    StringAppendF(&output_, "\n");
     return false;
   }
 }
@@ -345,23 +480,25 @@ bool ConformanceTestSuite::CheckSetEmpty(const set<string>& set_to_check,
 bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
                                     std::string* output) {
   runner_ = runner;
-  output_.clear();
   successes_ = 0;
-  failures_ = 0;
+  expected_failures_ = 0;
+  skipped_.clear();
   test_names_.clear();
   unexpected_failing_tests_.clear();
   unexpected_succeeding_tests_.clear();
+  type_resolver_.reset(NewTypeResolverForDescriptorPool(
+      kTypeUrlPrefix, DescriptorPool::generated_pool()));
+  type_url_ = GetTypeUrl(TestAllTypes::descriptor());
+
+  output_ = "\nCONFORMANCE TEST BEGIN ====================================\n\n";
 
   for (int i = 1; i <= FieldDescriptor::MAX_TYPE; i++) {
     if (i == FieldDescriptor::TYPE_GROUP) continue;
     TestPrematureEOFForType(static_cast<FieldDescriptor::Type>(i));
   }
 
-  StringAppendF(&output_, "\n");
-  StringAppendF(&output_,
-                "CONFORMANCE SUITE FINISHED: completed %d tests, %d successes, "
-                "%d failures.\n",
-                successes_ + failures_, successes_, failures_);
+  RunValidJsonTest("HelloWorld", "{\"optionalString\":\"Hello, World!\"}",
+                   "optional_string: 'Hello, World!'");
 
   bool ok =
       CheckSetEmpty(expected_to_fail_,
@@ -377,6 +514,17 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
                     "These tests succeeded, even though they were listed in "
                     "the failure list.  Remove them from the failure list");
 
+  CheckSetEmpty(skipped_,
+                "These tests were skipped (probably because support for some "
+                "features is not implemented)");
+
+  StringAppendF(&output_,
+                "CONFORMANCE SUITE %s: %d successes, %d skipped, "
+                "%d expected failures, %d unexpected failures.\n",
+                ok ? "PASSED" : "FAILED", successes_, skipped_.size(),
+                expected_failures_, unexpected_failing_tests_.size());
+  StringAppendF(&output_, "\n");
+
   output->assign(output_);
 
   return ok;

+ 23 - 2
conformance/conformance_test.h

@@ -39,6 +39,8 @@
 #define CONFORMANCE_CONFORMANCE_TEST_H
 
 #include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/util/type_resolver.h>
 #include <google/protobuf/wire_format_lite.h>
 
 namespace conformance {
@@ -98,10 +100,22 @@ class ConformanceTestSuite {
 
  private:
   void ReportSuccess(const std::string& test_name);
-  void ReportFailure(const std::string& test_name, const char* fmt, ...);
+  void ReportFailure(const string& test_name,
+                     const conformance::ConformanceRequest& request,
+                     const conformance::ConformanceResponse& response,
+                     const char* fmt, ...);
+  void ReportSkip(const string& test_name,
+                  const conformance::ConformanceRequest& request,
+                  const conformance::ConformanceResponse& response);
   void RunTest(const std::string& test_name,
                const conformance::ConformanceRequest& request,
                conformance::ConformanceResponse* response);
+  void RunValidInputTest(const string& test_name, const string& input,
+                         conformance::WireFormat input_format,
+                         const string& equivalent_text_format,
+                         conformance::WireFormat requested_output);
+  void RunValidJsonTest(const string& test_name, const string& input_json,
+                        const string& equivalent_text_format);
   void ExpectParseFailureForProto(const std::string& proto,
                                   const std::string& test_name);
   void ExpectHardParseFailureForProto(const std::string& proto,
@@ -110,7 +124,7 @@ class ConformanceTestSuite {
   bool CheckSetEmpty(const set<string>& set_to_check, const char* msg);
   ConformanceTestRunner* runner_;
   int successes_;
-  int failures_;
+  int expected_failures_;
   bool verbose_;
   std::string output_;
 
@@ -127,6 +141,13 @@ class ConformanceTestSuite {
 
   // The set of tests that succeeded, but weren't expected to.
   std::set<std::string> unexpected_succeeding_tests_;
+
+  // The set of tests that the testee opted out of;
+  std::set<std::string> skipped_;
+
+  google::protobuf::internal::scoped_ptr<google::protobuf::util::TypeResolver>
+      type_resolver_;
+  std::string type_url_;
 };
 
 }  // namespace protobuf

+ 12 - 12
conformance/failure_list_cpp.txt

@@ -7,15 +7,15 @@
 # TODO(haberman): insert links to corresponding bugs tracking the issue.
 # Should we use GitHub issues or the Google-internal bug tracker?
 
-PrematureEofBeforeKnownRepeatedValue.MESSAGE
-PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
-PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
-PrematureEofInPackedField.BOOL
-PrematureEofInPackedField.ENUM
-PrematureEofInPackedField.INT32
-PrematureEofInPackedField.INT64
-PrematureEofInPackedField.SINT32
-PrematureEofInPackedField.SINT64
-PrematureEofInPackedField.UINT32
-PrematureEofInPackedField.UINT64
-PrematureEofInsideKnownRepeatedValue.MESSAGE
+ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
+ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
+ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
+ProtobufInput.PrematureEofInPackedField.BOOL
+ProtobufInput.PrematureEofInPackedField.ENUM
+ProtobufInput.PrematureEofInPackedField.INT32
+ProtobufInput.PrematureEofInPackedField.INT64
+ProtobufInput.PrematureEofInPackedField.SINT32
+ProtobufInput.PrematureEofInPackedField.SINT64
+ProtobufInput.PrematureEofInPackedField.UINT32
+ProtobufInput.PrematureEofInPackedField.UINT64
+ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE

+ 23 - 0
gmock.BUILD

@@ -0,0 +1,23 @@
+cc_library(
+    name = "gtest",
+    srcs = [
+        "gmock-1.7.0/gtest/src/gtest-all.cc",
+        "gmock-1.7.0/src/gmock-all.cc",
+    ],
+    includes = [
+        "gmock-1.7.0",
+        "gmock-1.7.0/gtest",
+        "gmock-1.7.0/gtest/include",
+        "gmock-1.7.0/include",
+    ],
+    linkopts = ["-pthread"],
+    visibility = ["//visibility:public"],
+)
+
+cc_library(
+    name = "gtest_main",
+    srcs = ["gmock-1.7.0/src/gmock_main.cc"],
+    linkopts = ["-pthread"],
+    visibility = ["//visibility:public"],
+    deps = [":gtest"],
+)

+ 12 - 0
objectivec/GPBProtocolBuffers.h

@@ -42,3 +42,15 @@
 #import "GPBUnknownFieldSet.h"
 #import "GPBUtilities.h"
 #import "GPBWireFormat.h"
+
+// Well-known proto types
+#import "google/protobuf/Any.pbobjc.h"
+#import "google/protobuf/Api.pbobjc.h"
+#import "google/protobuf/Duration.pbobjc.h"
+#import "google/protobuf/Empty.pbobjc.h"
+#import "google/protobuf/FieldMask.pbobjc.h"
+#import "google/protobuf/SourceContext.pbobjc.h"
+#import "google/protobuf/Struct.pbobjc.h"
+#import "google/protobuf/Timestamp.pbobjc.h"
+#import "google/protobuf/Type.pbobjc.h"
+#import "google/protobuf/Wrappers.pbobjc.h"

+ 7 - 0
python/google/protobuf/internal/test_util.py

@@ -602,6 +602,13 @@ def GoldenFile(filename):
       return open(full_path, 'rb')
     path = os.path.join(path, '..')
 
+  # Search internally.
+  path = '.'
+  full_path = os.path.join(path, 'third_party/py/google/protobuf/testdata', filename)
+  if os.path.exists(full_path):
+    # Found it.  Load the golden file from the testdata directory.
+    return open(full_path, 'rb')
+
   raise RuntimeError(
       'Could not find golden files.  This test must be run from within the '
       'protobuf source package so that it can read test data files from the '

+ 13 - 1
ruby/ext/google/protobuf_c/encode_decode.c

@@ -30,6 +30,18 @@
 
 #include "protobuf.h"
 
+// This function is equivalent to rb_str_cat(), but unlike the real
+// rb_str_cat(), it doesn't leak memory in some versions of Ruby.
+// For more information, see:
+//   https://bugs.ruby-lang.org/issues/11328
+VALUE noleak_rb_str_cat(VALUE rb_str, const char *str, long len) {
+  size_t oldlen = RSTRING_LEN(rb_str);
+  rb_str_modify_expand(rb_str, len);
+  char *p = RSTRING_PTR(rb_str);
+  memcpy(p + oldlen, str, len);
+  rb_str_set_len(rb_str, oldlen + len);
+}
+
 // -----------------------------------------------------------------------------
 // Parsing.
 // -----------------------------------------------------------------------------
@@ -164,7 +176,7 @@ static size_t stringdata_handler(void* closure, const void* hd,
                                  const char* str, size_t len,
                                  const upb_bufhandle* handle) {
   VALUE rb_str = (VALUE)closure;
-  rb_str_cat(rb_str, str, len);
+  noleak_rb_str_cat(rb_str, str, len);
   return len;
 }
 

+ 0 - 1
src/Makefile.am

@@ -76,7 +76,6 @@ nobase_include_HEADERS =                                        \
   google/protobuf/stubs/fastmem.h                               \
   google/protobuf/stubs/hash.h                                  \
   google/protobuf/stubs/once.h                                  \
-  google/protobuf/stubs/pbconfig.h                              \
   google/protobuf/stubs/platform_macros.h                       \
   google/protobuf/stubs/shared_ptr.h                            \
   google/protobuf/stubs/singleton.h                             \

+ 5 - 5
src/google/protobuf/compiler/cpp/cpp_message.cc

@@ -2932,7 +2932,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
                      "commontag", SimpleItoa(WireFormat::MakeTag(field)));
 
       if (need_label ||
-          (field->is_repeated() && !field->options().packed() && !loops)) {
+          (field->is_repeated() && !field->is_packed() && !loops)) {
         printer->Print(
             " parse_$name$:\n",
             "name", field->name());
@@ -2945,7 +2945,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
       }
 
       printer->Indent();
-      if (field->options().packed()) {
+      if (field->is_packed()) {
         field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
       } else {
         field_generator.GenerateMergeFromCodedStream(printer);
@@ -2953,7 +2953,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
       printer->Outdent();
 
       // Emit code to parse unexpectedly packed or unpacked values.
-      if (field->is_packable() && field->options().packed()) {
+      if (field->is_packed()) {
         internal::WireFormatLite::WireType wiretype =
             WireFormat::WireTypeForFieldType(field->type());
         printer->Print("} else if (tag == $uncommontag$) {\n",
@@ -2963,7 +2963,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
         printer->Indent();
         field_generator.GenerateMergeFromCodedStream(printer);
         printer->Outdent();
-      } else if (field->is_packable() && !field->options().packed()) {
+      } else if (field->is_packable() && !field->is_packed()) {
         internal::WireFormatLite::WireType wiretype =
             internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
         printer->Print("} else if (tag == $uncommontag$) {\n",
@@ -2988,7 +2988,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
           "if (input->ExpectTag($tag$)) goto parse_loop_$name$;\n",
           "tag", SimpleItoa(WireFormat::MakeTag(field)),
           "name", field->name());
-      } else if (field->is_repeated() && !field->options().packed()) {
+      } else if (field->is_repeated() && !field->is_packed()) {
         printer->Print(
           "if (input->ExpectTag($tag$)) goto parse_$name$;\n",
           "tag", SimpleItoa(WireFormat::MakeTag(field)),

+ 3 - 7
src/google/protobuf/compiler/csharp/csharp_field_base.cc

@@ -38,6 +38,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/mathlimits.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/wire_format.h>
 
@@ -276,11 +277,6 @@ bool FieldGeneratorBase::is_nullable_type() {
   }
 }
 
-inline bool IsNaN(double value) {
-  // NaN is never equal to anything, even itself.
-  return value != value;
-}
-
 bool AllPrintableAscii(const std::string& text) {
   for(int i = 0; i < text.size(); i++) {
     if (text[i] < 0x20 || text[i] > 0x7e) {
@@ -313,7 +309,7 @@ std::string FieldGeneratorBase::default_value() {
         return "double.PositiveInfinity";
       } else if (value == -numeric_limits<double>::infinity()) {
         return "double.NegativeInfinity";
-      } else if (IsNaN(value)) {
+      } else if (MathLimits<double>::IsNaN(value)) {
         return "double.NaN";
       }
       return SimpleDtoa(value) + "D";
@@ -324,7 +320,7 @@ std::string FieldGeneratorBase::default_value() {
         return "float.PositiveInfinity";
       } else if (value == -numeric_limits<float>::infinity()) {
         return "float.NegativeInfinity";
-      } else if (IsNaN(value)) {
+      } else if (MathLimits<float>::IsNaN(value)) {
         return "float.NaN";
       }
       return SimpleFtoa(value) + "F";

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

@@ -28,6 +28,7 @@
 // (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 <climits>
 #include <fstream>
 #include <iostream>
 #include <sstream>

+ 1 - 1
src/google/protobuf/compiler/subprocess.cc

@@ -171,7 +171,7 @@ bool Subprocess::Communicate(const Message& input, Message* output,
     DWORD wait_result =
         WaitForMultipleObjects(handle_count, handles, FALSE, INFINITE);
 
-    HANDLE signaled_handle;
+    HANDLE signaled_handle = NULL;
     if (wait_result >= WAIT_OBJECT_0 &&
         wait_result < WAIT_OBJECT_0 + handle_count) {
       signaled_handle = handles[wait_result - WAIT_OBJECT_0];

+ 2 - 1
src/google/protobuf/map.h

@@ -168,7 +168,8 @@ class Map {
       }
     }
 
-#if __cplusplus >= 201103L && !defined(GOOGLE_PROTOBUF_OS_APPLE)
+#if __cplusplus >= 201103L && !defined(GOOGLE_PROTOBUF_OS_APPLE) && \
+    !defined(GOOGLE_PROTOBUF_OS_NACL) && !defined(GOOGLE_PROTOBUF_OS_ANDROID)
     template<class NodeType, class... Args>
     void construct(NodeType* p, Args&&... args) {
       new (p) NodeType(std::forward<Args>(args)...);

+ 12 - 0
src/google/protobuf/map_entry_lite.h

@@ -162,7 +162,19 @@ class MapEntryLite : public MessageLite {
           if (!KeyWireHandler::Read(input, mutable_key())) return false;
           set_has_key();
           if (!input->ExpectTag(kValueTag)) break;
+          // BEGIN GOOGLE LOCAL MODIFICATION
+          //   Add __has_cpp_attribute and NaCl and Emscripten checks.
+#if defined(__clang__) && defined(__has_cpp_attribute) \
+    && !defined(GOOGLE_PROTOBUF_OS_APPLE)
+#if defined(GOOGLE_PROTOBUF_OS_NACL) || defined(EMSCRIPTEN)
+          [[clang::fallthrough]];
+#elif __has_cpp_attribute(clang::fallthrough)
+          [[clang::fallthrough]];
+#endif
+#else
           GOOGLE_FALLTHROUGH_INTENDED;
+#endif
+          // END GOOGLE LOCAL MODIFICATION
 
         case kValueTag:
           if (!ValueWireHandler::Read(input, mutable_value())) return false;

+ 2 - 2
src/google/protobuf/stubs/atomicops_internals_generic_gcc.h

@@ -61,8 +61,8 @@ inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
 inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
                                        Atomic32 old_value,
                                        Atomic32 new_value) {
-  __atomic_compare_exchange(ptr, &old_value, &new_value, true,
-                            __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+  __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
+                              __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
   return old_value;
 }
 

+ 22 - 14
src/google/protobuf/stubs/common.h

@@ -203,14 +203,22 @@ typedef unsigned __int16 uint16;
 typedef unsigned __int32 uint32;
 typedef unsigned __int64 uint64;
 #else
-typedef int8_t  int8;
-typedef int16_t int16;
-typedef int32_t int32;
+typedef signed char  int8;
+typedef short int16;
+typedef int int32;
+// NOTE: This should be "long long" for consistency with upstream, but
+// something is stacked against this particular type for 64bit hashing.
+// Switching it causes an obvious missing hash function (with an unobvious
+// cause) when building the tests.
 typedef int64_t int64;
 
-typedef uint8_t  uint8;
-typedef uint16_t uint16;
-typedef uint32_t uint32;
+typedef unsigned char  uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+// NOTE: This should be "unsigned long long" for consistency with upstream, but
+// something is stacked against this particular type for 64bit hashing.
+// Switching it causes an obvious missing hash function (with an unobvious
+// cause) when building the tests.
 typedef uint64_t uint64;
 #endif
 
@@ -1459,14 +1467,14 @@ static inline uint32 bswap_32(uint32 x) {
 }
 #define bswap_32(x) bswap_32(x)
 static inline uint64 bswap_64(uint64 x) {
-  return (((x & GG_ULONGLONG(0xFF)) << 56) |
-          ((x & GG_ULONGLONG(0xFF00)) << 40) |
-          ((x & GG_ULONGLONG(0xFF0000)) << 24) |
-          ((x & GG_ULONGLONG(0xFF000000)) << 8) |
-          ((x & GG_ULONGLONG(0xFF00000000)) >> 8) |
-          ((x & GG_ULONGLONG(0xFF0000000000)) >> 24) |
-          ((x & GG_ULONGLONG(0xFF000000000000)) >> 40) |
-          ((x & GG_ULONGLONG(0xFF00000000000000)) >> 56));
+  return (((x & GOOGLE_ULONGLONG(0xFF)) << 56) |
+          ((x & GOOGLE_ULONGLONG(0xFF00)) << 40) |
+          ((x & GOOGLE_ULONGLONG(0xFF0000)) << 24) |
+          ((x & GOOGLE_ULONGLONG(0xFF000000)) << 8) |
+          ((x & GOOGLE_ULONGLONG(0xFF00000000)) >> 8) |
+          ((x & GOOGLE_ULONGLONG(0xFF0000000000)) >> 24) |
+          ((x & GOOGLE_ULONGLONG(0xFF000000000000)) >> 40) |
+          ((x & GOOGLE_ULONGLONG(0xFF00000000000000)) >> 56));
 }
 #define bswap_64(x) bswap_64(x)
 

+ 111 - 6
src/google/protobuf/stubs/hash.h

@@ -37,12 +37,117 @@
 
 #include <string.h>
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/pbconfig.h>
+
+#define GOOGLE_PROTOBUF_HAVE_HASH_MAP 1
+#define GOOGLE_PROTOBUF_HAVE_HASH_SET 1
+
+// Use C++11 unordered_{map|set} if available. Otherwise, libc++ always support
+// unordered_{map|set}
+#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X) || \
+    defined(_LIBCPP_VERSION)
+# define GOOGLE_PROTOBUF_HAS_CXX11_HASH
+
+// For XCode >= 4.6:  the compiler is clang with libc++.
+// For earlier XCode version: the compiler is gcc-4.2.1 with libstdc++.
+// libc++ provides <unordered_map> and friends even in non C++11 mode,
+// and it does not provide the tr1 library. Therefore the following macro
+// checks against this special case.
+// Note that we should not test the __APPLE_CC__ version number or the
+// __clang__ macro, since the new compiler can still use -stdlib=libstdc++, in
+// which case <unordered_map> is not compilable without -std=c++11
+#elif defined(__APPLE_CC__)
+# if __GNUC__ >= 4
+#  define GOOGLE_PROTOBUF_HAS_TR1
+# else
+// Not tested for gcc < 4... These setting can compile under 4.2.1 though.
+#  define GOOGLE_PROTOBUF_HASH_NAMESPACE __gnu_cxx
+#  include <ext/hash_map>
+#  define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
+#  include <ext/hash_set>
+#  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
+# endif
+
+// Version checks for gcc.
+#elif defined(__GNUC__)
+// For GCC 4.x+, use tr1::unordered_map/set; otherwise, follow the
+// instructions from:
+// https://gcc.gnu.org/onlinedocs/libstdc++/manual/backwards.html
+# if __GNUC__ >= 4
+#  define GOOGLE_PROTOBUF_HAS_TR1
+# elif __GNUC__ >= 3
+#  include <backward/hash_map>
+#  define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
+#  include <backward/hash_set>
+#  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
+#  if __GNUC__ == 3 && __GNUC_MINOR__ == 0
+#   define GOOGLE_PROTOBUF_HASH_NAMESPACE std       // GCC 3.0
+#  else
+#   define GOOGLE_PROTOBUF_HASH_NAMESPACE __gnu_cxx // GCC 3.1 and later
+#  endif
+# else
+#  define GOOGLE_PROTOBUF_HASH_NAMESPACE
+#  include <hash_map>
+#  define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
+#  include <hash_set>
+#  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
+# endif
+
+// Version checks for MSC.
+// Apparently Microsoft decided to move hash_map *back* to the std namespace in
+// MSVC 2010:
+// http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx
+// And.. they are moved back to stdext in MSVC 2013 (haven't checked 2012). That
+// said, use unordered_map for MSVC 2010 and beyond is our safest bet.
+#elif defined(_MSC_VER)
+# if _MSC_VER >= 1600  // Since Visual Studio 2010
+#  define GOOGLE_PROTOBUF_HAS_CXX11_HASH
+#  define GOOGLE_PROTOBUF_HASH_COMPARE std::hash_compare
+# elif _MSC_VER >= 1500  // Since Visual Studio 2008
+#  define GOOGLE_PROTOBUF_HAS_TR1
+#  define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
+# elif _MSC_VER >= 1310
+#  define GOOGLE_PROTOBUF_HASH_NAMESPACE stdext
+#  include <hash_map>
+#  define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
+#  include <hash_set>
+#  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
+#  define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
+# else
+#  define GOOGLE_PROTOBUF_HASH_NAMESPACE std
+#  include <hash_map>
+#  define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
+#  include <hash_set>
+#  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
+#  define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
+# endif
+
+// **ADD NEW COMPILERS SUPPORT HERE.**
+// For other compilers, undefine the macro and fallback to use std::map, in
+// google/protobuf/stubs/hash.h
+#else
+# undef GOOGLE_PROTOBUF_HAVE_HASH_MAP
+# undef GOOGLE_PROTOBUF_HAVE_HASH_SET
+#endif
+
+#if defined(GOOGLE_PROTOBUF_HAS_CXX11_HASH)
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE std
+# include <unordered_map>
+# define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map
+# include <unordered_set>
+# define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set
+#elif defined(GOOGLE_PROTOBUF_HAS_TR1)
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE std::tr1
+# include <tr1/unordered_map>
+# define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map
+# include <tr1/unordered_set>
+# define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set
+#endif
+
+#undef GOOGLE_PROTOBUF_HAS_CXX11_HASH
+#undef GOOGLE_PROTOBUF_HAS_TR1
 
 #if defined(GOOGLE_PROTOBUF_HAVE_HASH_MAP) && \
     defined(GOOGLE_PROTOBUF_HAVE_HASH_SET)
-#include GOOGLE_PROTOBUF_HASH_MAP_H
-#include GOOGLE_PROTOBUF_HASH_SET_H
 #else
 #define GOOGLE_PROTOBUF_MISSING_HASH
 #include <map>
@@ -92,13 +197,13 @@ template <typename Key, typename Data,
           typename HashFcn = hash<Key>,
           typename EqualKey = std::equal_to<Key>,
           typename Alloc = std::allocator< std::pair<const Key, Data> > >
-class hash_map : public std::map<Key, Data, HashFcn, EqualKey, Alloc> {
-  typedef std::map<Key, Data, HashFcn, EqualKey, Alloc> BaseClass;
+class hash_map : public std::map<Key, Data, HashFcn, Alloc> {
+  typedef std::map<Key, Data, HashFcn, Alloc> BaseClass;
 
  public:
   hash_map(int a = 0, const HashFcn& b = HashFcn(),
            const EqualKey& c = EqualKey(),
-           const Alloc& d = Alloc()) : BaseClass(a, b, c, d) {}
+           const Alloc& d = Alloc()) : BaseClass(b, d) {}
 };
 
 template <typename Key,

+ 0 - 142
src/google/protobuf/stubs/pbconfig.h

@@ -1,142 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef GOOGLE_PROTOBUF_STUBS_PBCONFIG_H__
-#define GOOGLE_PROTOBUF_STUBS_PBCONFIG_H__
-
-#define GOOGLE_PROTOBUF_HAVE_HASH_MAP 1
-#define GOOGLE_PROTOBUF_HAVE_HASH_SET 1
-
-// Use C++11 unordered_{map|set} if available.
-#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X)
-# define GOOGLE_PROTOBUF_HAS_CXX11_HASH
-
-// For XCode >= 4.6:  the compiler is clang with libc++.
-// For earlier XCode version: the compiler is gcc-4.2.1 with libstdc++.
-// libc++ provides <unordered_map> and friends even in non C++11 mode,
-// and it does not provide the tr1 library. Therefore the following macro
-// checks against this special case.
-// Note that we should not test the __APPLE_CC__ version number or the
-// __clang__ macro, since the new compiler can still use -stdlib=libstdc++, in
-// which case <unordered_map> is not compilable without -std=c++11
-#elif defined(__APPLE_CC__)
-# if defined(_LIBCPP_VERSION)
-#  define GOOGLE_PROTOBUF_HAS_CXX11_HASH
-# elif __GNUC__ >= 4
-#  define GOOGLE_PROTOBUF_HAS_TR1
-# else
-// Not tested for gcc < 4... These setting can compile under 4.2.1 though.
-#  define GOOGLE_PROTOBUF_HASH_NAMESPACE __gnu_cxx
-#  define GOOGLE_PROTOBUF_HASH_MAP_H <ext/hash_map>
-#  define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
-#  define GOOGLE_PROTOBUF_HASH_SET_H <ext/hash_set>
-#  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
-# endif
-
-// Version checks for gcc.
-#elif defined(__GNUC__)
-// For GCC 4.x+, use tr1::unordered_map/set; otherwise, follow the
-// instructions from:
-// https://gcc.gnu.org/onlinedocs/libstdc++/manual/backwards.html
-# if __GNUC__ >= 4
-#  define GOOGLE_PROTOBUF_HAS_TR1
-# elif __GNUC__ >= 3
-#  define GOOGLE_PROTOBUF_HASH_MAP_H <backward/hash_map>
-#  define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
-#  define GOOGLE_PROTOBUF_HASH_SET_H <backward/hash_set>
-#  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
-#  if __GNUC__ == 3 && __GNUC_MINOR__ == 0
-#   define GOOGLE_PROTOBUF_HASH_NAMESPACE std       // GCC 3.0
-#  else
-#   define GOOGLE_PROTOBUF_HASH_NAMESPACE __gnu_cxx // GCC 3.1 and later
-#  endif
-# else
-#  define GOOGLE_PROTOBUF_HASH_NAMESPACE
-#  define GOOGLE_PROTOBUF_HASH_MAP_H <hash_map>
-#  define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
-#  define GOOGLE_PROTOBUF_HASH_SET_H <hash_set>
-#  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
-# endif
-
-// Version checks for MSC.
-// Apparently Microsoft decided to move hash_map *back* to the std namespace in
-// MSVC 2010:
-// http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx
-// And.. they are moved back to stdext in MSVC 2013 (haven't checked 2012). That
-// said, use unordered_map for MSVC 2010 and beyond is our safest bet.
-#elif defined(_MSC_VER)
-# if _MSC_VER >= 1600  // Since Visual Studio 2010
-#  define GOOGLE_PROTOBUF_HAS_CXX11_HASH
-#  define GOOGLE_PROTOBUF_HASH_COMPARE std::hash_compare
-# elif _MSC_VER >= 1500  // Since Visual Studio 2008
-#  define GOOGLE_PROTOBUF_HAS_TR1
-#  define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
-# elif _MSC_VER >= 1310
-#  define GOOGLE_PROTOBUF_HASH_NAMESPACE stdext
-#  define GOOGLE_PROTOBUF_HASH_MAP_H <hash_map>
-#  define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
-#  define GOOGLE_PROTOBUF_HASH_SET_H <hash_set>
-#  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
-#  define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
-# else
-#  define GOOGLE_PROTOBUF_HASH_NAMESPACE std
-#  define GOOGLE_PROTOBUF_HASH_MAP_H <hash_map>
-#  define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
-#  define GOOGLE_PROTOBUF_HASH_SET_H <hash_set>
-#  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
-#  define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
-# endif
-
-// **ADD NEW COMPILERS SUPPORT HERE.**
-// For other compilers, undefine the macro and fallback to use std::map, in
-// google/protobuf/stubs/hash.h
-#else
-# undef GOOGLE_PROTOBUF_HAVE_HASH_MAP
-# undef GOOGLE_PROTOBUF_HAVE_HASH_SET
-#endif
-
-#if defined(GOOGLE_PROTOBUF_HAS_CXX11_HASH)
-# define GOOGLE_PROTOBUF_HASH_NAMESPACE std
-# define GOOGLE_PROTOBUF_HASH_MAP_H <unordered_map>
-# define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map
-# define GOOGLE_PROTOBUF_HASH_SET_H <unordered_set>
-# define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set
-#elif defined(GOOGLE_PROTOBUF_HAS_TR1)
-# define GOOGLE_PROTOBUF_HASH_NAMESPACE std::tr1
-# define GOOGLE_PROTOBUF_HASH_MAP_H <tr1/unordered_map>
-# define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map
-# define GOOGLE_PROTOBUF_HASH_SET_H <tr1/unordered_set>
-# define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set
-#endif
-
-#undef GOOGLE_PROTOBUF_HAS_CXX11_HASH
-#undef GOOGLE_PROTOBUF_HAS_TR1
-
-#endif // GOOGLE_PROTOBUF_STUBS_PBCONFIG_H__

+ 3 - 7
src/google/protobuf/stubs/strutil.cc

@@ -31,6 +31,7 @@
 // from google3/strings/strutil.cc
 
 #include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/mathlimits.h>
 
 #include <errno.h>
 #include <float.h>    // FLT_DIG and DBL_DIG
@@ -58,11 +59,6 @@
 namespace google {
 namespace protobuf {
 
-inline bool IsNaN(double value) {
-  // NaN is never equal to anything, even itself.
-  return value != value;
-}
-
 // These are defined as macros on some platforms.  #undef them so that we can
 // redefine them.
 #undef isxdigit
@@ -1210,7 +1206,7 @@ char* DoubleToBuffer(double value, char* buffer) {
   } else if (value == -numeric_limits<double>::infinity()) {
     strcpy(buffer, "-inf");
     return buffer;
-  } else if (IsNaN(value)) {
+  } else if (MathLimits<double>::IsNaN(value)) {
     strcpy(buffer, "nan");
     return buffer;
   }
@@ -1328,7 +1324,7 @@ char* FloatToBuffer(float value, char* buffer) {
   } else if (value == -numeric_limits<double>::infinity()) {
     strcpy(buffer, "-inf");
     return buffer;
-  } else if (IsNaN(value)) {
+  } else if (MathLimits<float>::IsNaN(value)) {
     strcpy(buffer, "nan");
     return buffer;
   }

+ 9 - 0
src/google/protobuf/testing/zcgunzip.cc

@@ -43,6 +43,15 @@
 #include <stdlib.h>
 #include <fcntl.h>
 
+#ifdef _WIN32
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+#endif
+
 #include <google/protobuf/io/gzip_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 

+ 9 - 0
src/google/protobuf/testing/zcgzip.cc

@@ -42,6 +42,15 @@
 #include <stdlib.h>
 #include <fcntl.h>
 
+#ifdef _WIN32
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+#endif
+
 #include <google/protobuf/io/gzip_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 

+ 3 - 7
src/google/protobuf/text_format_unittest.cc

@@ -46,6 +46,7 @@
 #include <google/protobuf/io/tokenizer.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/mathlimits.h>
 #include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
@@ -57,11 +58,6 @@ namespace protobuf {
 // Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
 namespace text_format_unittest {
 
-inline bool IsNaN(double value) {
-  // NaN is never equal to anything, even itself.
-  return value != value;
-}
-
 // A basic string with different escapable characters for testing.
 const string kEscapeTestString =
   "\"A string with ' characters \n and \r newlines and \t tabs and \001 "
@@ -898,8 +894,8 @@ TEST_F(TextFormatTest, ParseExotic) {
   EXPECT_EQ(message.repeated_double(8), numeric_limits<double>::infinity());
   EXPECT_EQ(message.repeated_double(9), -numeric_limits<double>::infinity());
   EXPECT_EQ(message.repeated_double(10), -numeric_limits<double>::infinity());
-  EXPECT_TRUE(IsNaN(message.repeated_double(11)));
-  EXPECT_TRUE(IsNaN(message.repeated_double(12)));
+  EXPECT_TRUE(MathLimits<double>::IsNaN(message.repeated_double(11)));
+  EXPECT_TRUE(MathLimits<double>::IsNaN(message.repeated_double(12)));
 
   // Note:  Since these string literals have \0's in them, we must explicitly
   //   pass their sizes to string's constructor.

+ 5 - 0
src/google/protobuf/unknown_field_set.cc

@@ -50,8 +50,13 @@ namespace {
 // instantiate the UnknownFieldSet dynamically only when required.
 UnknownFieldSet* default_unknown_field_set_instance_ = NULL;
 
+void DeleteDefaultUnknownFieldSet() {
+  delete default_unknown_field_set_instance_;
+}
+
 void InitDefaultUnknownFieldSet() {
   default_unknown_field_set_instance_ = new UnknownFieldSet();
+  internal::OnShutdown(&DeleteDefaultUnknownFieldSet);
 }
 
 GOOGLE_PROTOBUF_DECLARE_ONCE(default_unknown_field_set_once_init_);

+ 1 - 0
src/google/protobuf/util/field_comparator.cc

@@ -106,6 +106,7 @@ FieldComparator::ComparisonResult DefaultFieldComparator::Compare(
     default:
       GOOGLE_LOG(FATAL) << "No comparison code for field " << field->full_name()
                  << " of CppType = " << field->cpp_type();
+      return DIFFERENT;
   }
 }
 

+ 2 - 1
src/google/protobuf/util/internal/datapiece.cc

@@ -36,6 +36,7 @@
 #include <google/protobuf/util/internal/utility.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/mathutil.h>
+#include <google/protobuf/stubs/mathlimits.h>
 
 namespace google {
 namespace protobuf {
@@ -78,7 +79,7 @@ StatusOr<To> NumberConvertAndCheck(From before) {
 // For conversion between double and float only.
 template <typename To, typename From>
 StatusOr<To> FloatingPointConvertAndCheck(From before) {
-  if (isnan(before)) return std::numeric_limits<To>::quiet_NaN();
+  if (MathLimits<From>::IsNaN(before)) return std::numeric_limits<To>::quiet_NaN();
 
   To after = static_cast<To>(before);
   if (MathUtil::AlmostEquals<To>(after, before)) {

+ 3 - 0
src/google/protobuf/util/internal/type_info_test_helper.cc

@@ -97,6 +97,7 @@ ProtoStreamObjectSource* TypeInfoTestHelper::NewProtoSource(
     }
   }
   GOOGLE_LOG(FATAL) << "Can not reach here.";
+  return NULL;
 }
 
 ProtoStreamObjectWriter* TypeInfoTestHelper::NewProtoWriter(
@@ -110,6 +111,7 @@ ProtoStreamObjectWriter* TypeInfoTestHelper::NewProtoWriter(
     }
   }
   GOOGLE_LOG(FATAL) << "Can not reach here.";
+  return NULL;
 }
 
 DefaultValueObjectWriter* TypeInfoTestHelper::NewDefaultValueWriter(
@@ -121,6 +123,7 @@ DefaultValueObjectWriter* TypeInfoTestHelper::NewDefaultValueWriter(
     }
   }
   GOOGLE_LOG(FATAL) << "Can not reach here.";
+  return NULL;
 }
 
 }  // namespace testing

+ 2 - 1
src/google/protobuf/util/internal/utility.cc

@@ -41,6 +41,7 @@
 #include <google/protobuf/util/internal/constants.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/map_util.h>
+#include <google/protobuf/stubs/mathlimits.h>
 
 namespace google {
 namespace protobuf {
@@ -302,7 +303,7 @@ bool IsMap(const google::protobuf::Field& field,
 string DoubleAsString(double value) {
   if (value == std::numeric_limits<double>::infinity()) return "Infinity";
   if (value == -std::numeric_limits<double>::infinity()) return "-Infinity";
-  if (::isnan(value)) return "NaN";
+  if (google::protobuf::MathLimits<double>::IsNaN(value)) return "NaN";
 
   return SimpleDtoa(value);
 }

+ 2 - 11
src/google/protobuf/util/message_differencer.h

@@ -289,20 +289,11 @@ class LIBPROTOBUF_EXPORT MessageDifferencer {
     MapKeyComparator();
     virtual ~MapKeyComparator();
 
-    // The first IsMatch without parent_fields is only for backward
-    // compatibility. New users should override the second one instead.
-    //
-    // Deprecated.
-    // TODO(ykzhu): remove this function.
-    virtual bool IsMatch(const Message& message1,
-                         const Message& message2) const {
-      GOOGLE_CHECK(false) << "This function shouldn't get called";
-      return false;
-    }
     virtual bool IsMatch(const Message& message1,
                          const Message& message2,
                          const vector<SpecificField>& parent_fields) const {
-      return IsMatch(message1, message2);
+      GOOGLE_CHECK(false) << "IsMatch() is not implemented.";
+      return false;
     }
 
    private:

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

@@ -290,7 +290,7 @@ class LIBPROTOBUF_EXPORT UnknownFieldSetFieldSkipper : public FieldSkipper {
 
 inline WireFormatLite::WireType WireFormat::WireTypeForField(
     const FieldDescriptor* field) {
-  if (field->options().packed()) {
+  if (field->is_packed()) {
     return WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
   } else {
     return WireTypeForFieldType(field->type());

+ 88 - 56
src/google/protobuf/wire_format_unittest.cc

@@ -795,9 +795,73 @@ TEST(WireFormatTest, CompatibleTypes) {
   ASSERT_EQ(static_cast<uint32>(data), msg5.data());
 }
 
-class Proto3PrimitiveRepeatedWireFormatTest
-    : public ::testing::TestWithParam<bool> {
+class Proto3PrimitiveRepeatedWireFormatTest : public ::testing::Test {
  protected:
+  Proto3PrimitiveRepeatedWireFormatTest()
+      : packedTestAllTypes_(
+            "\xFA\x01\x01\x01"
+            "\x82\x02\x01\x01"
+            "\x8A\x02\x01\x01"
+            "\x92\x02\x01\x01"
+            "\x9A\x02\x01\x02"
+            "\xA2\x02\x01\x02"
+            "\xAA\x02\x04\x01\x00\x00\x00"
+            "\xB2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00"
+            "\xBA\x02\x04\x01\x00\x00\x00"
+            "\xC2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00"
+            "\xCA\x02\x04\x00\x00\x80\x3f"
+            "\xD2\x02\x08\x00\x00\x00\x00\x00\x00\xf0\x3f"
+            "\xDA\x02\x01\x01"
+            "\x9A\x03\x01\x01",
+            86),
+        packedTestUnpackedTypes_(
+            "\x0A\x01\x01"
+            "\x12\x01\x01"
+            "\x1A\x01\x01"
+            "\x22\x01\x01"
+            "\x2A\x01\x02"
+            "\x32\x01\x02"
+            "\x3A\x04\x01\x00\x00\x00"
+            "\x42\x08\x01\x00\x00\x00\x00\x00\x00\x00"
+            "\x4A\x04\x01\x00\x00\x00"
+            "\x52\x08\x01\x00\x00\x00\x00\x00\x00\x00"
+            "\x5A\x04\x00\x00\x80\x3f"
+            "\x62\x08\x00\x00\x00\x00\x00\x00\xf0\x3f"
+            "\x6A\x01\x01"
+            "\x72\x01\x01",
+            72),
+        unpackedTestAllTypes_(
+            "\xF8\x01\x01"
+            "\x80\x02\x01"
+            "\x88\x02\x01"
+            "\x90\x02\x01"
+            "\x98\x02\x02"
+            "\xA0\x02\x02"
+            "\xAD\x02\x01\x00\x00\x00"
+            "\xB1\x02\x01\x00\x00\x00\x00\x00\x00\x00"
+            "\xBD\x02\x01\x00\x00\x00"
+            "\xC1\x02\x01\x00\x00\x00\x00\x00\x00\x00"
+            "\xCD\x02\x00\x00\x80\x3f"
+            "\xD1\x02\x00\x00\x00\x00\x00\x00\xf0\x3f"
+            "\xD8\x02\x01"
+            "\x98\x03\x01",
+            72),
+        unpackedTestUnpackedTypes_(
+            "\x08\x01"
+            "\x10\x01"
+            "\x18\x01"
+            "\x20\x01"
+            "\x28\x02"
+            "\x30\x02"
+            "\x3D\x01\x00\x00\x00"
+            "\x41\x01\x00\x00\x00\x00\x00\x00\x00"
+            "\x4D\x01\x00\x00\x00"
+            "\x51\x01\x00\x00\x00\x00\x00\x00\x00"
+            "\x5D\x00\x00\x80\x3f"
+            "\x61\x00\x00\x00\x00\x00\x00\xf0\x3f"
+            "\x68\x01"
+            "\x70\x01",
+            58) {}
   template <class Proto>
   void SetProto3PrimitiveRepeatedFields(Proto* message) {
     message->add_repeated_int32(1);
@@ -837,8 +901,7 @@ class Proto3PrimitiveRepeatedWireFormatTest
   }
 
   template <class Proto>
-  void TestProto3PrimitiveRepeatedFields(Proto* message,
-                                         const string& expected) {
+  void TestSerialization(Proto* message, const string& expected) {
     SetProto3PrimitiveRepeatedFields(message);
 
     int size = message->ByteSize();
@@ -851,13 +914,8 @@ class Proto3PrimitiveRepeatedWireFormatTest
       message->SerializeWithCachedSizes(&output);
       ASSERT_FALSE(output.HadError());
     }
-
     EXPECT_TRUE(expected == generated_data);
 
-    message->Clear();
-    message->ParseFromString(generated_data);
-    ExpectProto3PrimitiveRepeatedFieldsSet(*message);
-
     // Serialize using the dynamic code.
     string dynamic_data;
     {
@@ -866,64 +924,38 @@ class Proto3PrimitiveRepeatedWireFormatTest
       WireFormat::SerializeWithCachedSizes(*message, size, &output);
       ASSERT_FALSE(output.HadError());
     }
-
     EXPECT_TRUE(expected == dynamic_data);
+  }
+
+  template <class Proto>
+  void TestParsing(Proto* message, const string& compatible_data) {
+    message->Clear();
+    message->ParseFromString(compatible_data);
+    ExpectProto3PrimitiveRepeatedFieldsSet(*message);
 
     message->Clear();
     io::CodedInputStream input(
-        reinterpret_cast<const uint8*>(dynamic_data.data()),
-        dynamic_data.size());
+        reinterpret_cast<const uint8*>(compatible_data.data()),
+        compatible_data.size());
     WireFormat::ParseAndMergePartial(&input, message);
     ExpectProto3PrimitiveRepeatedFieldsSet(*message);
   }
+
+  const string packedTestAllTypes_;
+  const string packedTestUnpackedTypes_;
+  const string unpackedTestAllTypes_;
+  const string unpackedTestUnpackedTypes_;
 };
-INSTANTIATE_TEST_CASE_P(SetPacked,
-                        Proto3PrimitiveRepeatedWireFormatTest,
-                        ::testing::Values(false, true));
 
-TEST_P(Proto3PrimitiveRepeatedWireFormatTest, Proto3PrimitiveRepeated) {
+TEST_F(Proto3PrimitiveRepeatedWireFormatTest, Proto3PrimitiveRepeated) {
   proto3_arena_unittest::TestAllTypes packed_message;
   proto3_arena_unittest::TestUnpackedTypes unpacked_message;
-
-  const string packedExpected(
-      "\xFA\x01\x01\x01"
-      "\x82\x02\x01\x01"
-      "\x8A\x02\x01\x01"
-      "\x92\x02\x01\x01"
-      "\x9A\x02\x01\x02"
-      "\xA2\x02\x01\x02"
-      "\xAA\x02\x04\x01\x00\x00\x00"
-      "\xB2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00"
-      "\xBA\x02\x04\x01\x00\x00\x00"
-      "\xC2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00"
-      "\xCA\x02\x04\x00\x00\x80\x3f"
-      "\xD2\x02\x08\x00\x00\x00\x00\x00\x00\xf0\x3f"
-      "\xDA\x02\x01\x01"
-      "\x9A\x03\x01\x01",
-      86);
-
-  const string unpackedExpected(
-      "\x08\x01"
-      "\x10\x01"
-      "\x18\x01"
-      "\x20\x01"
-      "\x28\x02"
-      "\x30\x02"
-      "\x3D\x01\x00\x00\x00"
-      "\x41\x01\x00\x00\x00\x00\x00\x00\x00"
-      "\x4D\x01\x00\x00\x00"
-      "\x51\x01\x00\x00\x00\x00\x00\x00\x00"
-      "\x5D\x00\x00\x80\x3f"
-      "\x61\x00\x00\x00\x00\x00\x00\xf0\x3f"
-      "\x68\x01"
-      "\x70\x01",
-      58);
-
-  if (GetParam()) {
-    TestProto3PrimitiveRepeatedFields(&packed_message, packedExpected);
-  } else {
-    TestProto3PrimitiveRepeatedFields(&unpacked_message, unpackedExpected);
-  }
+  TestSerialization(&packed_message, packedTestAllTypes_);
+  TestParsing(&packed_message, packedTestAllTypes_);
+  TestParsing(&packed_message, unpackedTestAllTypes_);
+  TestSerialization(&unpacked_message, unpackedTestUnpackedTypes_);
+  TestParsing(&unpacked_message, packedTestUnpackedTypes_);
+  TestParsing(&unpacked_message, unpackedTestUnpackedTypes_);
 }
 
 class WireFormatInvalidInputTest : public testing::Test {

+ 3 - 0
update_file_lists.sh

@@ -57,6 +57,7 @@ WKT_PROTOS=$(get_variable_value $MAKEFILE nobase_dist_proto_DATA)
 COMMON_TEST_SOURCES=$(get_source_files $MAKEFILE COMMON_TEST_SOURCES)
 TEST_SOURCES=$(get_source_files $MAKEFILE protobuf_test_SOURCES)
 LITE_TEST_SOURCES=$(get_source_files $MAKEFILE protobuf_lite_test_SOURCES)
+TEST_PLUGIN_SOURCES=$(get_source_files $MAKEFILE test_plugin_SOURCES)
 
 ################################################################################
 # Update cmake files.
@@ -177,3 +178,5 @@ set_bazel_value $BAZEL_BUILD well_known_protos "" $WKT_PROTOS
 set_bazel_value $BAZEL_BUILD test_protos "" $PROTOS
 set_bazel_value $BAZEL_BUILD common_test_srcs $BAZEL_PREFIX $COMMON_TEST_SOURCES
 set_bazel_value $BAZEL_BUILD test_srcs $BAZEL_PREFIX $TEST_SOURCES
+set_bazel_value $BAZEL_BUILD test_plugin_srcs $BAZEL_PREFIX $TEST_PLUGIN_SOURCES
+