From ba3836703b4a9e98e474aea2bac8c5b49b6d3b5c Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Fri, 16 Apr 2021 09:55:03 -0700 Subject: [PATCH] Sync from Piper @368866736 PROTOBUF_SYNC_PIPER --- BUILD | 1 + CHANGES.txt | 11 ++++ conformance/binary_json_conformance_suite.cc | 6 ++ python/google/protobuf/json_format.py | 4 +- .../internal/protostream_objectwriter_test.cc | 55 +++++++++++++++++++ 5 files changed, 75 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index 07ee629a1..1788cfc06 100644 --- a/BUILD +++ b/BUILD @@ -369,6 +369,7 @@ cc_library( "src/google/protobuf/compiler/cpp/cpp_message.cc", "src/google/protobuf/compiler/cpp/cpp_message_field.cc", "src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc", + "src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc", "src/google/protobuf/compiler/cpp/cpp_primitive_field.cc", "src/google/protobuf/compiler/cpp/cpp_service.cc", "src/google/protobuf/compiler/cpp/cpp_string_field.cc", diff --git a/CHANGES.txt b/CHANGES.txt index 93ee2b8e8..9e6eb4488 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,16 @@ + Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + C++ + * Fix bug where `Descriptor::DebugString()` printed proto3 synthetic oneofs. + * Provide stable versions of `SortAndUnique()`. + * Make sure to cache proto3 optional message fields when they are cleared. + + Kotlin + * Restrict extension setter and getter operators to non-nullable T. + +3.16.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + C++ * The ::pb namespace is no longer exposed due to conflicts. * Allow MessageDifferencer::TreatAsSet() (and friends) to override previous diff --git a/conformance/binary_json_conformance_suite.cc b/conformance/binary_json_conformance_suite.cc index 48bfa9660..0275e2e30 100644 --- a/conformance/binary_json_conformance_suite.cc +++ b/conformance/binary_json_conformance_suite.cc @@ -2329,6 +2329,12 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForNonRepeatedTypes() { ExpectParseFailureForJson( "OneofFieldDuplicate", REQUIRED, R"({"oneofUint32": 1, "oneofString": "test"})"); + RunValidJsonTest("OneofFieldNullFirst", REQUIRED, + R"({"oneofUint32": null, "oneofString": "test"})", + "oneof_string: \"test\""); + RunValidJsonTest("OneofFieldNullSecond", REQUIRED, + R"({"oneofString": "test", "oneofUint32": null})", + "oneof_string: \"test\""); // Ensure zero values for oneof make it out/backs. TestAllTypesProto3 messageProto3; TestAllTypesProto2 messageProto2; diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py index c8f5602f3..965614d80 100644 --- a/python/google/protobuf/json_format.py +++ b/python/google/protobuf/json_format.py @@ -531,8 +531,9 @@ class _Parser(object): '"{1}" fields.'.format( message.DESCRIPTOR.full_name, name)) names.append(name) + value = js[name] # Check no other oneof field is parsed. - if field.containing_oneof is not None: + if field.containing_oneof is not None and value is not None: oneof_name = field.containing_oneof.name if oneof_name in names: raise ParseError('Message type "{0}" should not have multiple ' @@ -540,7 +541,6 @@ class _Parser(object): message.DESCRIPTOR.full_name, oneof_name)) names.append(oneof_name) - value = js[name] if value is None: if (field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE and field.message_type.full_name == 'google.protobuf.Value'): diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc index 211b7bcbf..2232bec56 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc @@ -699,6 +699,61 @@ TEST_P(ProtoStreamObjectWriterTest, ImplicitMessageList) { CheckOutput(expected); } +TEST_P(ProtoStreamObjectWriterTest, DisableImplicitMessageList) { + options_.disable_implicit_message_list = true; + options_.suppress_implicit_message_list_error = true; + ResetProtoWriter(); + + Book expected; + // The repeated friend field of the author is empty. + expected.mutable_author(); + + EXPECT_CALL(listener_, InvalidValue(_, _, _)).Times(0); + + ow_->StartObject("") + ->StartObject("author") + ->StartObject("friend") + ->RenderString("name", "first") + ->EndObject() + ->StartObject("friend") + ->RenderString("name", "second") + ->EndObject() + ->EndObject() + ->EndObject(); + CheckOutput(expected); +} + +TEST_P(ProtoStreamObjectWriterTest, + DisableImplicitMessageListWithoutErrorSuppressed) { + options_.disable_implicit_message_list = true; + ResetProtoWriter(); + + Book expected; + // The repeated friend field of the author is empty. + expected.mutable_author(); + EXPECT_CALL( + listener_, + InvalidValue( + _, StringPiece("friend"), + StringPiece( + "Starting an object in a repeated field but the parent object " + "is not a list"))) + .With(Args<0>(HasObjectLocation("author"))) + .Times(2); + + ow_->StartObject("") + ->StartObject("author") + ->StartObject("friend") + ->RenderString("name", "first") + ->EndObject() + ->StartObject("friend") + ->RenderString("name", "second") + ->EndObject() + ->EndObject() + ->EndObject(); + CheckOutput(expected); +} + TEST_P(ProtoStreamObjectWriterTest, LastWriteWinsOnNonRepeatedMessageFieldWithDuplicates) { Book expected;