diff --git a/conformance/BUILD.bazel b/conformance/BUILD.bazel index 0ce2cd82ec..72a127a2c5 100644 --- a/conformance/BUILD.bazel +++ b/conformance/BUILD.bazel @@ -196,6 +196,7 @@ cc_library( "@com_google_absl//absl/log:absl_log", "@com_google_absl//absl/log:die_if_null", "@com_google_absl//absl/strings", + "@com_google_absl//absl/strings:str_format", ], ) diff --git a/conformance/ConformanceJava.java b/conformance/ConformanceJava.java index 950657ef83..48aa4e8c5d 100644 --- a/conformance/ConformanceJava.java +++ b/conformance/ConformanceJava.java @@ -244,14 +244,19 @@ class ConformanceJava { AbstractMessage testMessage; String messageType = request.getMessageType(); + ExtensionRegistry extensions = ExtensionRegistry.newInstance(); + try { + createTestFile(messageType) + .getMethod("registerAllExtensions", ExtensionRegistry.class) + .invoke(null, extensions); + } catch (Exception e) { + throw new RuntimeException(e); + } + switch (request.getPayloadCase()) { case PROTOBUF_PAYLOAD: { try { - ExtensionRegistry extensions = ExtensionRegistry.newInstance(); - createTestFile(messageType) - .getMethod("registerAllExtensions", ExtensionRegistry.class) - .invoke(null, extensions); testMessage = parseBinary( request.getProtobufPayload(), @@ -295,7 +300,7 @@ class ConformanceJava { AbstractMessage.Builder builder = (AbstractMessage.Builder) createTestMessage(messageType).getMethod("newBuilder").invoke(null); - TextFormat.merge(request.getTextPayload(), builder); + TextFormat.merge(request.getTextPayload(), extensions, builder); testMessage = (AbstractMessage) builder.build(); } catch (TextFormat.ParseException e) { return Conformance.ConformanceResponse.newBuilder() diff --git a/conformance/text_format_conformance_suite.cc b/conformance/text_format_conformance_suite.cc index 1c2c17bdbe..cbef1231c8 100644 --- a/conformance/text_format_conformance_suite.cc +++ b/conformance/text_format_conformance_suite.cc @@ -14,6 +14,7 @@ #include "absl/log/absl_log.h" #include "absl/log/die_if_null.h" #include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" #include "conformance_test.h" #include "google/protobuf/editions/golden/test_messages_proto2_editions.pb.h" #include "google/protobuf/editions/golden/test_messages_proto3_editions.pb.h" @@ -242,6 +243,28 @@ void TextFormatConformanceTestSuiteImpl::RunGroupTests() { RunValidTextFormatTest("GroupFieldWithColon", REQUIRED, "Data: { group_int32: 1 }"); RunValidTextFormatTest("GroupFieldEmpty", REQUIRED, "Data {}"); + RunValidTextFormatTest("GroupFieldMultiWord", REQUIRED, + "MultiWordGroupField { group_int32: 1 }"); + + // Test that lower-cased group name (i.e. implicit field name) is not accepted + ExpectParseFailure("GroupFieldLowercased", REQUIRED, + "data { group_int32: 1 }"); + ExpectParseFailure("GroupFieldLowercasedMultiWord", REQUIRED, + "multiwordgroupfield { group_int32: 1 }"); + + // Test extensions of group type + RunValidTextFormatTest("GroupFieldExtension", REQUIRED, + absl::StrFormat("[%s] { group_int32: 1 }", + MessageType::GetDescriptor() + ->file() + ->FindExtensionByName("groupfield") + ->PrintableNameForExtension())); + ExpectParseFailure("GroupFieldExtensionGroupName", REQUIRED, + absl::StrFormat("[%s] { group_int32: 1 }", + MessageType::GetDescriptor() + ->file() + ->FindMessageTypeByName("GroupField") + ->full_name())); } template diff --git a/src/google/protobuf/editions/golden/test_messages_proto2_editions.proto b/src/google/protobuf/editions/golden/test_messages_proto2_editions.proto index ba9bbf6008..3738b6233a 100644 --- a/src/google/protobuf/editions/golden/test_messages_proto2_editions.proto +++ b/src/google/protobuf/editions/golden/test_messages_proto2_editions.proto @@ -221,6 +221,15 @@ message TestAllTypesProto2 { features.message_encoding = DELIMITED ]; + message MultiWordGroupField { + int32 group_int32 = 205; + uint32 group_uint32 = 206; + } + + MultiWordGroupField multiwordgroupfield = 204 [ + features.message_encoding = DELIMITED + ]; + // default values int32 default_int32 = 241 [ default = -123456789 @@ -344,6 +353,17 @@ extend TestAllTypesProto2 { int32 extension_int32 = 120; } +extend TestAllTypesProto2 { + GroupField groupfield = 121 [ + features.message_encoding = DELIMITED + ]; +} + +message GroupField { + int32 group_int32 = 122; + uint32 group_uint32 = 123; +} + message UnknownToTestAllTypes { int32 optional_int32 = 1001; string optional_string = 1002; diff --git a/src/google/protobuf/test_messages_proto2.proto b/src/google/protobuf/test_messages_proto2.proto index 45efa7ff14..73cba558c4 100644 --- a/src/google/protobuf/test_messages_proto2.proto +++ b/src/google/protobuf/test_messages_proto2.proto @@ -173,6 +173,11 @@ message TestAllTypesProto2 { optional uint32 group_uint32 = 203; } + optional group MultiWordGroupField = 204 { + optional int32 group_int32 = 205; + optional uint32 group_uint32 = 206; + } + // default values optional int32 default_int32 = 241 [default = -123456789]; optional int64 default_int64 = 242 [default = -9123456789123456789]; @@ -250,6 +255,13 @@ extend TestAllTypesProto2 { optional int32 extension_int32 = 120; } +extend TestAllTypesProto2 { + optional group GroupField = 121 { + optional int32 group_int32 = 122; + optional uint32 group_uint32 = 123; + } +} + message UnknownToTestAllTypes { optional int32 optional_int32 = 1001; optional string optional_string = 1002;