diff --git a/BUILD b/BUILD index e897617d03..5177e43df3 100644 --- a/BUILD +++ b/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", + ], +) + diff --git a/Protobuf.podspec b/Protobuf.podspec index b6b831c235..6aa89902c2 100644 --- a/Protobuf.podspec +++ b/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' diff --git a/WORKSPACE b/WORKSPACE index e69de29bb2..f72f239a06 100644 --- a/WORKSPACE +++ b/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", +) diff --git a/cmake/README.md b/cmake/README.md index 0abe078ecc..c68defd8af 100644 --- a/cmake/README.md +++ b/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. diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in index 4e34d81aa1..6b84c37828 100644 --- a/cmake/extract_includes.bat.in +++ b/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 diff --git a/conformance/ConformanceJava.java b/conformance/ConformanceJava.java index c1a53141fc..25646b8516 100644 --- a/conformance/ConformanceJava.java +++ b/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."); diff --git a/conformance/conformance.proto b/conformance/conformance.proto index 39eafdbb7c..714cbe781e 100644 --- a/conformance/conformance.proto +++ b/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; } } diff --git a/conformance/conformance_cpp.cc b/conformance/conformance_cpp.cc index ff47fbbffd..863b6a5b10 100644 --- a/conformance/conformance_cpp.cc +++ b/conformance/conformance_cpp.cc @@ -33,14 +33,33 @@ #include #include "conformance.pb.h" +#include +#include -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 " diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc index 7a7fc6f5bf..0ee201f3c5 100644 --- a/conformance/conformance_test.cc +++ b/conformance/conformance_test.cc @@ -35,18 +35,34 @@ #include "conformance_test.h" #include #include +#include +#include +#include +#include #include 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& set_to_check, return true; } else { StringAppendF(&output_, "\n"); - StringAppendF(&output_, "ERROR: %s:\n", msg); + StringAppendF(&output_, "%s:\n", msg); for (set::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& 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(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; diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h index 764a8d336d..cadda82881 100644 --- a/conformance/conformance_test.h +++ b/conformance/conformance_test.h @@ -39,6 +39,8 @@ #define CONFORMANCE_CONFORMANCE_TEST_H #include +#include +#include #include 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& 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 unexpected_succeeding_tests_; + + // The set of tests that the testee opted out of; + std::set skipped_; + + google::protobuf::internal::scoped_ptr + type_resolver_; + std::string type_url_; }; } // namespace protobuf diff --git a/conformance/failure_list_cpp.txt b/conformance/failure_list_cpp.txt index d792eddd62..53d90c9928 100644 --- a/conformance/failure_list_cpp.txt +++ b/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 diff --git a/gmock.BUILD b/gmock.BUILD new file mode 100644 index 0000000000..66cddea9f4 --- /dev/null +++ b/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"], +) diff --git a/objectivec/GPBProtocolBuffers.h b/objectivec/GPBProtocolBuffers.h index a66f295e3f..0c85259ef9 100644 --- a/objectivec/GPBProtocolBuffers.h +++ b/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" diff --git a/python/google/protobuf/internal/test_util.py b/python/google/protobuf/internal/test_util.py index 0cbdbad918..fec6538204 100755 --- a/python/google/protobuf/internal/test_util.py +++ b/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 ' diff --git a/ruby/ext/google/protobuf_c/encode_decode.c b/ruby/ext/google/protobuf_c/encode_decode.c index fe249d4535..f789f6d490 100644 --- a/ruby/ext/google/protobuf_c/encode_decode.c +++ b/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; } diff --git a/src/Makefile.am b/src/Makefile.am index cea3089e4a..233b62600d 100644 --- a/src/Makefile.am +++ b/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 \ diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index 17f67a7b59..b0e38755a2 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/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)), diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc index ae7336ca83..914b972daa 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.cc +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -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::infinity()) { return "double.NegativeInfinity"; - } else if (IsNaN(value)) { + } else if (MathLimits::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::infinity()) { return "float.NegativeInfinity"; - } else if (IsNaN(value)) { + } else if (MathLimits::IsNaN(value)) { return "float.NaN"; } return SimpleFtoa(value) + "F"; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index 9b645f09cf..45d122d169 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/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 #include #include #include diff --git a/src/google/protobuf/compiler/subprocess.cc b/src/google/protobuf/compiler/subprocess.cc index 61ae4381a3..a3cff1f8b8 100644 --- a/src/google/protobuf/compiler/subprocess.cc +++ b/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]; diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index 96d2f2017d..163ce9dca6 100644 --- a/src/google/protobuf/map.h +++ b/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 void construct(NodeType* p, Args&&... args) { new (p) NodeType(std::forward(args)...); diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h index 52746da595..8de11766d2 100644 --- a/src/google/protobuf/map_entry_lite.h +++ b/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; diff --git a/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h b/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h index dd7abf6f17..a0116a60ee 100644 --- a/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h +++ b/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; } diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index c36201462e..3a081e6017 100644 --- a/src/google/protobuf/stubs/common.h +++ b/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) diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h index 4da8a5d89a..9a6b217adb 100755 --- a/src/google/protobuf/stubs/hash.h +++ b/src/google/protobuf/stubs/hash.h @@ -37,12 +37,117 @@ #include #include -#include + +#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 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 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 +# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map +# include +# 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 +# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map +# include +# 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 +# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map +# include +# 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 +# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map +# include +# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set +# define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare +# else +# define GOOGLE_PROTOBUF_HASH_NAMESPACE std +# include +# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map +# include +# 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 +# define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map +# include +# define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set +#elif defined(GOOGLE_PROTOBUF_HAS_TR1) +# define GOOGLE_PROTOBUF_HASH_NAMESPACE std::tr1 +# include +# define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map +# include +# 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 @@ -92,13 +197,13 @@ template , typename EqualKey = std::equal_to, typename Alloc = std::allocator< std::pair > > -class hash_map : public std::map { - typedef std::map BaseClass; +class hash_map : public std::map { + typedef std::map 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 = 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 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 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 -# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map -# define GOOGLE_PROTOBUF_HASH_SET_H -# 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 -# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map -# define GOOGLE_PROTOBUF_HASH_SET_H -# 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 -# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map -# define GOOGLE_PROTOBUF_HASH_SET_H -# 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 -# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map -# define GOOGLE_PROTOBUF_HASH_SET_H -# 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 -# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map -# define GOOGLE_PROTOBUF_HASH_SET_H -# 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 -# define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map -# define GOOGLE_PROTOBUF_HASH_SET_H -# 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 -# define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map -# define GOOGLE_PROTOBUF_HASH_SET_H -# 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__ diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc index 99e8bf1dc8..2ec62b421e 100644 --- a/src/google/protobuf/stubs/strutil.cc +++ b/src/google/protobuf/stubs/strutil.cc @@ -31,6 +31,7 @@ // from google3/strings/strutil.cc #include +#include #include #include // 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::infinity()) { strcpy(buffer, "-inf"); return buffer; - } else if (IsNaN(value)) { + } else if (MathLimits::IsNaN(value)) { strcpy(buffer, "nan"); return buffer; } @@ -1328,7 +1324,7 @@ char* FloatToBuffer(float value, char* buffer) { } else if (value == -numeric_limits::infinity()) { strcpy(buffer, "-inf"); return buffer; - } else if (IsNaN(value)) { + } else if (MathLimits::IsNaN(value)) { strcpy(buffer, "nan"); return buffer; } diff --git a/src/google/protobuf/testing/zcgunzip.cc b/src/google/protobuf/testing/zcgunzip.cc index c9d085c8fc..76f8cfe11b 100644 --- a/src/google/protobuf/testing/zcgunzip.cc +++ b/src/google/protobuf/testing/zcgunzip.cc @@ -43,6 +43,15 @@ #include #include +#ifdef _WIN32 +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif +#endif + #include #include diff --git a/src/google/protobuf/testing/zcgzip.cc b/src/google/protobuf/testing/zcgzip.cc index e910f321fe..992ddc6ed6 100644 --- a/src/google/protobuf/testing/zcgzip.cc +++ b/src/google/protobuf/testing/zcgzip.cc @@ -42,6 +42,15 @@ #include #include +#ifdef _WIN32 +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif +#endif + #include #include diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index 1b18c5ede4..76ce987560 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -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::infinity()); EXPECT_EQ(message.repeated_double(9), -numeric_limits::infinity()); EXPECT_EQ(message.repeated_double(10), -numeric_limits::infinity()); - EXPECT_TRUE(IsNaN(message.repeated_double(11))); - EXPECT_TRUE(IsNaN(message.repeated_double(12))); + EXPECT_TRUE(MathLimits::IsNaN(message.repeated_double(11))); + EXPECT_TRUE(MathLimits::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. diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc index 766449003c..93f0f206ad 100644 --- a/src/google/protobuf/unknown_field_set.cc +++ b/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_); diff --git a/src/google/protobuf/util/field_comparator.cc b/src/google/protobuf/util/field_comparator.cc index b7676a8847..9f613265e8 100644 --- a/src/google/protobuf/util/field_comparator.cc +++ b/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; } } diff --git a/src/google/protobuf/util/internal/datapiece.cc b/src/google/protobuf/util/internal/datapiece.cc index 72b737e9eb..944fb2e362 100644 --- a/src/google/protobuf/util/internal/datapiece.cc +++ b/src/google/protobuf/util/internal/datapiece.cc @@ -36,6 +36,7 @@ #include #include #include +#include namespace google { namespace protobuf { @@ -78,7 +79,7 @@ StatusOr NumberConvertAndCheck(From before) { // For conversion between double and float only. template StatusOr FloatingPointConvertAndCheck(From before) { - if (isnan(before)) return std::numeric_limits::quiet_NaN(); + if (MathLimits::IsNaN(before)) return std::numeric_limits::quiet_NaN(); To after = static_cast(before); if (MathUtil::AlmostEquals(after, before)) { diff --git a/src/google/protobuf/util/internal/type_info_test_helper.cc b/src/google/protobuf/util/internal/type_info_test_helper.cc index f7aea85794..177b96e206 100644 --- a/src/google/protobuf/util/internal/type_info_test_helper.cc +++ b/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 diff --git a/src/google/protobuf/util/internal/utility.cc b/src/google/protobuf/util/internal/utility.cc index f550f43b38..794777d44d 100644 --- a/src/google/protobuf/util/internal/utility.cc +++ b/src/google/protobuf/util/internal/utility.cc @@ -41,6 +41,7 @@ #include #include #include +#include namespace google { namespace protobuf { @@ -302,7 +303,7 @@ bool IsMap(const google::protobuf::Field& field, string DoubleAsString(double value) { if (value == std::numeric_limits::infinity()) return "Infinity"; if (value == -std::numeric_limits::infinity()) return "-Infinity"; - if (::isnan(value)) return "NaN"; + if (google::protobuf::MathLimits::IsNaN(value)) return "NaN"; return SimpleDtoa(value); } diff --git a/src/google/protobuf/util/message_differencer.h b/src/google/protobuf/util/message_differencer.h index 0554889788..e002a0f3a1 100644 --- a/src/google/protobuf/util/message_differencer.h +++ b/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& parent_fields) const { - return IsMatch(message1, message2); + GOOGLE_CHECK(false) << "IsMatch() is not implemented."; + return false; } private: diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h index 8de491a633..84270fee7e 100644 --- a/src/google/protobuf/wire_format.h +++ b/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()); diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc index 4b151f979c..aef22b2936 100644 --- a/src/google/protobuf/wire_format_unittest.cc +++ b/src/google/protobuf/wire_format_unittest.cc @@ -795,9 +795,73 @@ TEST(WireFormatTest, CompatibleTypes) { ASSERT_EQ(static_cast(data), msg5.data()); } -class Proto3PrimitiveRepeatedWireFormatTest - : public ::testing::TestWithParam { +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 void SetProto3PrimitiveRepeatedFields(Proto* message) { message->add_repeated_int32(1); @@ -837,8 +901,7 @@ class Proto3PrimitiveRepeatedWireFormatTest } template - 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 + void TestParsing(Proto* message, const string& compatible_data) { + message->Clear(); + message->ParseFromString(compatible_data); + ExpectProto3PrimitiveRepeatedFieldsSet(*message); message->Clear(); io::CodedInputStream input( - reinterpret_cast(dynamic_data.data()), - dynamic_data.size()); + reinterpret_cast(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 { diff --git a/update_file_lists.sh b/update_file_lists.sh index aa0d15aec7..34443456f0 100755 --- a/update_file_lists.sh +++ b/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 +