diff --git a/conformance/binary_json_conformance_suite.cc b/conformance/binary_json_conformance_suite.cc index 66d85b5417c01..f8430bceeadac 100644 --- a/conformance/binary_json_conformance_suite.cc +++ b/conformance/binary_json_conformance_suite.cc @@ -155,6 +155,11 @@ std::string group(uint32_t fieldnum, std::string content) { tag(fieldnum, WireFormatLite::WIRETYPE_END_GROUP)); } +std::string len(uint32_t fieldnum, std::string content) { + return absl::StrCat(tag(fieldnum, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), + delim(content)); +} + std::string GetDefaultValue(FieldDescriptor::Type type) { switch (type) { case FieldDescriptor::TYPE_INT32: @@ -363,6 +368,33 @@ void BinaryAndJsonConformanceSuite::RunDelimitedFieldTests() { TestAllTypesEdition2023 prototype; SetTypeUrl(GetTypeUrl(TestAllTypesEdition2023::GetDescriptor())); + RunValidProtobufTest( + absl::StrCat("ValidNonMessage"), REQUIRED, + field(1, WireFormatLite::WIRETYPE_VARINT, varint(99)), + R"pb(optional_int32: 99)pb"); + + RunValidProtobufTest( + absl::StrCat("ValidLengthPrefixedField"), REQUIRED, + len(18, field(1, WireFormatLite::WIRETYPE_VARINT, varint(99))), + R"pb(optional_nested_message { a: 99 })pb"); + + RunValidProtobufTest( + absl::StrCat("ValidMap.Integer"), REQUIRED, + len(56, + absl::StrCat(field(1, WireFormatLite::WIRETYPE_VARINT, varint(99)), + field(2, WireFormatLite::WIRETYPE_VARINT, varint(87)))), + R"pb(map_int32_int32 { key: 99 value: 87 })pb"); + + RunValidProtobufTest( + absl::StrCat("ValidMap.LengthPrefixed"), REQUIRED, + len(71, absl::StrCat(len(1, "a"), + len(2, field(1, WireFormatLite::WIRETYPE_VARINT, + varint(87))))), + R"pb(map_string_nested_message { + key: "a" + value: { a: 87 } + })pb"); + RunValidProtobufTest( absl::StrCat("ValidDelimitedField.GroupLike"), REQUIRED, group(201, field(202, WireFormatLite::WIRETYPE_VARINT, varint(99))), diff --git a/conformance/test_protos/test_messages_edition2023.proto b/conformance/test_protos/test_messages_edition2023.proto index 7688c47321db9..b4c2a4afc5a60 100644 --- a/conformance/test_protos/test_messages_edition2023.proto +++ b/conformance/test_protos/test_messages_edition2023.proto @@ -2,6 +2,7 @@ edition = "2023"; package protobuf_test_messages.editions; +option features.message_encoding = DELIMITED; option java_package = "com.google.protobuf_test_messages.edition2023"; option java_multiple_files = true; option objc_class_prefix = "Editions"; @@ -9,7 +10,8 @@ option objc_class_prefix = "Editions"; message TestAllTypesEdition2023 { message NestedMessage { int32 a = 1; - TestAllTypesEdition2023 corecursive = 2; + TestAllTypesEdition2023 corecursive = 2 + [features.message_encoding = LENGTH_PREFIXED]; } enum NestedEnum { @@ -36,8 +38,10 @@ message TestAllTypesEdition2023 { string optional_string = 14; bytes optional_bytes = 15; - NestedMessage optional_nested_message = 18; - ForeignMessageEdition2023 optional_foreign_message = 19; + NestedMessage optional_nested_message = 18 + [features.message_encoding = LENGTH_PREFIXED]; + ForeignMessageEdition2023 optional_foreign_message = 19 + [features.message_encoding = LENGTH_PREFIXED]; NestedEnum optional_nested_enum = 21; ForeignEnumEdition2023 optional_foreign_enum = 22; @@ -45,7 +49,8 @@ message TestAllTypesEdition2023 { string optional_string_piece = 24 [ctype = STRING_PIECE]; string optional_cord = 25 [ctype = CORD]; - TestAllTypesEdition2023 recursive_message = 27; + TestAllTypesEdition2023 recursive_message = 27 + [features.message_encoding = LENGTH_PREFIXED]; // Repeated repeated int32 repeated_int32 = 31; @@ -64,8 +69,10 @@ message TestAllTypesEdition2023 { repeated string repeated_string = 44; repeated bytes repeated_bytes = 45; - repeated NestedMessage repeated_nested_message = 48; - repeated ForeignMessageEdition2023 repeated_foreign_message = 49; + repeated NestedMessage repeated_nested_message = 48 + [features.message_encoding = LENGTH_PREFIXED]; + repeated ForeignMessageEdition2023 repeated_foreign_message = 49 + [features.message_encoding = LENGTH_PREFIXED]; repeated NestedEnum repeated_nested_enum = 51; repeated ForeignEnumEdition2023 repeated_foreign_enum = 52; @@ -152,7 +159,8 @@ message TestAllTypesEdition2023 { oneof oneof_field { uint32 oneof_uint32 = 111; - NestedMessage oneof_nested_message = 112; + NestedMessage oneof_nested_message = 112 + [features.message_encoding = LENGTH_PREFIXED]; string oneof_string = 113; bytes oneof_bytes = 114; bool oneof_bool = 115; @@ -170,8 +178,8 @@ message TestAllTypesEdition2023 { int32 group_int32 = 202; uint32 group_uint32 = 203; } - GroupLikeType groupliketype = 201 [features.message_encoding = DELIMITED]; - GroupLikeType delimited_field = 202 [features.message_encoding = DELIMITED]; + GroupLikeType groupliketype = 201; + GroupLikeType delimited_field = 202; } message ForeignMessageEdition2023 { @@ -193,6 +201,6 @@ message GroupLikeType { } extend TestAllTypesEdition2023 { - GroupLikeType groupliketype = 121 [features.message_encoding = DELIMITED]; - GroupLikeType delimited_ext = 122 [features.message_encoding = DELIMITED]; + GroupLikeType groupliketype = 121; + GroupLikeType delimited_ext = 122; } diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesEdition2023.pb.cs b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesEdition2023.pb.cs index fa91760cc6921..f68c8ea3eefa3 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesEdition2023.pb.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesEdition2023.pb.cs @@ -26,7 +26,7 @@ static TestMessagesEdition2023Reflection() { string.Concat( "Cjdjb25mb3JtYW5jZS90ZXN0X3Byb3Rvcy90ZXN0X21lc3NhZ2VzX2VkaXRp", "b24yMDIzLnByb3RvEh9wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25z", - "Itw2ChdUZXN0QWxsVHlwZXNFZGl0aW9uMjAyMxIWCg5vcHRpb25hbF9pbnQz", + "Iv82ChdUZXN0QWxsVHlwZXNFZGl0aW9uMjAyMxIWCg5vcHRpb25hbF9pbnQz", "MhgBIAEoBRIWCg5vcHRpb25hbF9pbnQ2NBgCIAEoAxIXCg9vcHRpb25hbF91", "aW50MzIYAyABKA0SFwoPb3B0aW9uYWxfdWludDY0GAQgASgEEhcKD29wdGlv", "bmFsX3NpbnQzMhgFIAEoERIXCg9vcHRpb25hbF9zaW50NjQYBiABKBISGAoQ", @@ -34,167 +34,168 @@ static TestMessagesEdition2023Reflection() { "ASgGEhkKEW9wdGlvbmFsX3NmaXhlZDMyGAkgASgPEhkKEW9wdGlvbmFsX3Nm", "aXhlZDY0GAogASgQEhYKDm9wdGlvbmFsX2Zsb2F0GAsgASgCEhcKD29wdGlv", "bmFsX2RvdWJsZRgMIAEoARIVCg1vcHRpb25hbF9ib29sGA0gASgIEhcKD29w", - "dGlvbmFsX3N0cmluZxgOIAEoCRIWCg5vcHRpb25hbF9ieXRlcxgPIAEoDBJn", + "dGlvbmFsX3N0cmluZxgOIAEoCRIWCg5vcHRpb25hbF9ieXRlcxgPIAEoDBJu", "ChdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZRgSIAEoCzJGLnByb3RvYnVmX3Rl", "c3RfbWVzc2FnZXMuZWRpdGlvbnMuVGVzdEFsbFR5cGVzRWRpdGlvbjIwMjMu", - "TmVzdGVkTWVzc2FnZRJcChhvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UYEyAB", - "KAsyOi5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25zLkZvcmVpZ25N", - "ZXNzYWdlRWRpdGlvbjIwMjMSYQoUb3B0aW9uYWxfbmVzdGVkX2VudW0YFSAB", - "KA4yQy5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25zLlRlc3RBbGxU", - "eXBlc0VkaXRpb24yMDIzLk5lc3RlZEVudW0SVgoVb3B0aW9uYWxfZm9yZWln", - "bl9lbnVtGBYgASgOMjcucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5lZGl0aW9u", - "cy5Gb3JlaWduRW51bUVkaXRpb24yMDIzEiEKFW9wdGlvbmFsX3N0cmluZ19w", - "aWVjZRgYIAEoCUICCAISGQoNb3B0aW9uYWxfY29yZBgZIAEoCUICCAESUwoR", - "cmVjdXJzaXZlX21lc3NhZ2UYGyABKAsyOC5wcm90b2J1Zl90ZXN0X21lc3Nh", - "Z2VzLmVkaXRpb25zLlRlc3RBbGxUeXBlc0VkaXRpb24yMDIzEhYKDnJlcGVh", - "dGVkX2ludDMyGB8gAygFEhYKDnJlcGVhdGVkX2ludDY0GCAgAygDEhcKD3Jl", - "cGVhdGVkX3VpbnQzMhghIAMoDRIXCg9yZXBlYXRlZF91aW50NjQYIiADKAQS", - "FwoPcmVwZWF0ZWRfc2ludDMyGCMgAygREhcKD3JlcGVhdGVkX3NpbnQ2NBgk", - "IAMoEhIYChByZXBlYXRlZF9maXhlZDMyGCUgAygHEhgKEHJlcGVhdGVkX2Zp", - "eGVkNjQYJiADKAYSGQoRcmVwZWF0ZWRfc2ZpeGVkMzIYJyADKA8SGQoRcmVw", - "ZWF0ZWRfc2ZpeGVkNjQYKCADKBASFgoOcmVwZWF0ZWRfZmxvYXQYKSADKAIS", - "FwoPcmVwZWF0ZWRfZG91YmxlGCogAygBEhUKDXJlcGVhdGVkX2Jvb2wYKyAD", - "KAgSFwoPcmVwZWF0ZWRfc3RyaW5nGCwgAygJEhYKDnJlcGVhdGVkX2J5dGVz", - "GC0gAygMEmcKF3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlGDAgAygLMkYucHJv", - "dG9idWZfdGVzdF9tZXNzYWdlcy5lZGl0aW9ucy5UZXN0QWxsVHlwZXNFZGl0", - "aW9uMjAyMy5OZXN0ZWRNZXNzYWdlElwKGHJlcGVhdGVkX2ZvcmVpZ25fbWVz", - "c2FnZRgxIAMoCzI6LnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMu", - "Rm9yZWlnbk1lc3NhZ2VFZGl0aW9uMjAyMxJhChRyZXBlYXRlZF9uZXN0ZWRf", - "ZW51bRgzIAMoDjJDLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMu", - "VGVzdEFsbFR5cGVzRWRpdGlvbjIwMjMuTmVzdGVkRW51bRJWChVyZXBlYXRl", - "ZF9mb3JlaWduX2VudW0YNCADKA4yNy5wcm90b2J1Zl90ZXN0X21lc3NhZ2Vz", - "LmVkaXRpb25zLkZvcmVpZ25FbnVtRWRpdGlvbjIwMjMSIQoVcmVwZWF0ZWRf", - "c3RyaW5nX3BpZWNlGDYgAygJQgIIAhIZCg1yZXBlYXRlZF9jb3JkGDcgAygJ", - "QgIIARIbCgxwYWNrZWRfaW50MzIYSyADKAVCBaoBAhgBEhsKDHBhY2tlZF9p", - "bnQ2NBhMIAMoA0IFqgECGAESHAoNcGFja2VkX3VpbnQzMhhNIAMoDUIFqgEC", - "GAESHAoNcGFja2VkX3VpbnQ2NBhOIAMoBEIFqgECGAESHAoNcGFja2VkX3Np", - "bnQzMhhPIAMoEUIFqgECGAESHAoNcGFja2VkX3NpbnQ2NBhQIAMoEkIFqgEC", - "GAESHQoOcGFja2VkX2ZpeGVkMzIYUSADKAdCBaoBAhgBEh0KDnBhY2tlZF9m", - "aXhlZDY0GFIgAygGQgWqAQIYARIeCg9wYWNrZWRfc2ZpeGVkMzIYUyADKA9C", - "BaoBAhgBEh4KD3BhY2tlZF9zZml4ZWQ2NBhUIAMoEEIFqgECGAESGwoMcGFj", - "a2VkX2Zsb2F0GFUgAygCQgWqAQIYARIcCg1wYWNrZWRfZG91YmxlGFYgAygB", - "QgWqAQIYARIaCgtwYWNrZWRfYm9vbBhXIAMoCEIFqgECGAESZgoScGFja2Vk", - "X25lc3RlZF9lbnVtGFggAygOMkMucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5l", - "ZGl0aW9ucy5UZXN0QWxsVHlwZXNFZGl0aW9uMjAyMy5OZXN0ZWRFbnVtQgWq", - "AQIYARIdCg51bnBhY2tlZF9pbnQzMhhZIAMoBUIFqgECGAISHQoOdW5wYWNr", - "ZWRfaW50NjQYWiADKANCBaoBAhgCEh4KD3VucGFja2VkX3VpbnQzMhhbIAMo", - "DUIFqgECGAISHgoPdW5wYWNrZWRfdWludDY0GFwgAygEQgWqAQIYAhIeCg91", - "bnBhY2tlZF9zaW50MzIYXSADKBFCBaoBAhgCEh4KD3VucGFja2VkX3NpbnQ2", - "NBheIAMoEkIFqgECGAISHwoQdW5wYWNrZWRfZml4ZWQzMhhfIAMoB0IFqgEC", - "GAISHwoQdW5wYWNrZWRfZml4ZWQ2NBhgIAMoBkIFqgECGAISIAoRdW5wYWNr", - "ZWRfc2ZpeGVkMzIYYSADKA9CBaoBAhgCEiAKEXVucGFja2VkX3NmaXhlZDY0", - "GGIgAygQQgWqAQIYAhIdCg51bnBhY2tlZF9mbG9hdBhjIAMoAkIFqgECGAIS", - "HgoPdW5wYWNrZWRfZG91YmxlGGQgAygBQgWqAQIYAhIcCg11bnBhY2tlZF9i", - "b29sGGUgAygIQgWqAQIYAhJoChR1bnBhY2tlZF9uZXN0ZWRfZW51bRhmIAMo", - "DjJDLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMuVGVzdEFsbFR5", - "cGVzRWRpdGlvbjIwMjMuTmVzdGVkRW51bUIFqgECGAISZAoPbWFwX2ludDMy", - "X2ludDMyGDggAygLMksucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5lZGl0aW9u", - "cy5UZXN0QWxsVHlwZXNFZGl0aW9uMjAyMy5NYXBJbnQzMkludDMyRW50cnkS", - "ZAoPbWFwX2ludDY0X2ludDY0GDkgAygLMksucHJvdG9idWZfdGVzdF9tZXNz", - "YWdlcy5lZGl0aW9ucy5UZXN0QWxsVHlwZXNFZGl0aW9uMjAyMy5NYXBJbnQ2", - "NEludDY0RW50cnkSaAoRbWFwX3VpbnQzMl91aW50MzIYOiADKAsyTS5wcm90", - "b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25zLlRlc3RBbGxUeXBlc0VkaXRp", - "b24yMDIzLk1hcFVpbnQzMlVpbnQzMkVudHJ5EmgKEW1hcF91aW50NjRfdWlu", - "dDY0GDsgAygLMk0ucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5lZGl0aW9ucy5U", - "ZXN0QWxsVHlwZXNFZGl0aW9uMjAyMy5NYXBVaW50NjRVaW50NjRFbnRyeRJo", - "ChFtYXBfc2ludDMyX3NpbnQzMhg8IAMoCzJNLnByb3RvYnVmX3Rlc3RfbWVz", - "c2FnZXMuZWRpdGlvbnMuVGVzdEFsbFR5cGVzRWRpdGlvbjIwMjMuTWFwU2lu", - "dDMyU2ludDMyRW50cnkSaAoRbWFwX3NpbnQ2NF9zaW50NjQYPSADKAsyTS5w", - "cm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25zLlRlc3RBbGxUeXBlc0Vk", - "aXRpb24yMDIzLk1hcFNpbnQ2NFNpbnQ2NEVudHJ5EmwKE21hcF9maXhlZDMy", - "X2ZpeGVkMzIYPiADKAsyTy5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRp", - "b25zLlRlc3RBbGxUeXBlc0VkaXRpb24yMDIzLk1hcEZpeGVkMzJGaXhlZDMy", - "RW50cnkSbAoTbWFwX2ZpeGVkNjRfZml4ZWQ2NBg/IAMoCzJPLnByb3RvYnVm", - "X3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMuVGVzdEFsbFR5cGVzRWRpdGlvbjIw", - "MjMuTWFwRml4ZWQ2NEZpeGVkNjRFbnRyeRJwChVtYXBfc2ZpeGVkMzJfc2Zp", - "eGVkMzIYQCADKAsyUS5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25z", - "LlRlc3RBbGxUeXBlc0VkaXRpb24yMDIzLk1hcFNmaXhlZDMyU2ZpeGVkMzJF", - "bnRyeRJwChVtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQYQSADKAsyUS5wcm90b2J1", - "Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25zLlRlc3RBbGxUeXBlc0VkaXRpb24y", - "MDIzLk1hcFNmaXhlZDY0U2ZpeGVkNjRFbnRyeRJkCg9tYXBfaW50MzJfZmxv", - "YXQYQiADKAsySy5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25zLlRl", - "c3RBbGxUeXBlc0VkaXRpb24yMDIzLk1hcEludDMyRmxvYXRFbnRyeRJmChBt", - "YXBfaW50MzJfZG91YmxlGEMgAygLMkwucHJvdG9idWZfdGVzdF9tZXNzYWdl", - "cy5lZGl0aW9ucy5UZXN0QWxsVHlwZXNFZGl0aW9uMjAyMy5NYXBJbnQzMkRv", - "dWJsZUVudHJ5EmAKDW1hcF9ib29sX2Jvb2wYRCADKAsySS5wcm90b2J1Zl90", - "ZXN0X21lc3NhZ2VzLmVkaXRpb25zLlRlc3RBbGxUeXBlc0VkaXRpb24yMDIz", - "Lk1hcEJvb2xCb29sRW50cnkSaAoRbWFwX3N0cmluZ19zdHJpbmcYRSADKAsy", - "TS5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25zLlRlc3RBbGxUeXBl", - "c0VkaXRpb24yMDIzLk1hcFN0cmluZ1N0cmluZ0VudHJ5EmYKEG1hcF9zdHJp", - "bmdfYnl0ZXMYRiADKAsyTC5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRp", - "b25zLlRlc3RBbGxUeXBlc0VkaXRpb24yMDIzLk1hcFN0cmluZ0J5dGVzRW50", - "cnkSdwoZbWFwX3N0cmluZ19uZXN0ZWRfbWVzc2FnZRhHIAMoCzJULnByb3Rv", + "TmVzdGVkTWVzc2FnZUIFqgECKAESYwoYb3B0aW9uYWxfZm9yZWlnbl9tZXNz", + "YWdlGBMgASgLMjoucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5lZGl0aW9ucy5G", + "b3JlaWduTWVzc2FnZUVkaXRpb24yMDIzQgWqAQIoARJhChRvcHRpb25hbF9u", + "ZXN0ZWRfZW51bRgVIAEoDjJDLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRp", + "dGlvbnMuVGVzdEFsbFR5cGVzRWRpdGlvbjIwMjMuTmVzdGVkRW51bRJWChVv", + "cHRpb25hbF9mb3JlaWduX2VudW0YFiABKA4yNy5wcm90b2J1Zl90ZXN0X21l", + "c3NhZ2VzLmVkaXRpb25zLkZvcmVpZ25FbnVtRWRpdGlvbjIwMjMSIQoVb3B0", + "aW9uYWxfc3RyaW5nX3BpZWNlGBggASgJQgIIAhIZCg1vcHRpb25hbF9jb3Jk", + "GBkgASgJQgIIARJaChFyZWN1cnNpdmVfbWVzc2FnZRgbIAEoCzI4LnByb3Rv", "YnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMuVGVzdEFsbFR5cGVzRWRpdGlv", - "bjIwMjMuTWFwU3RyaW5nTmVzdGVkTWVzc2FnZUVudHJ5EnkKGm1hcF9zdHJp", - "bmdfZm9yZWlnbl9tZXNzYWdlGEggAygLMlUucHJvdG9idWZfdGVzdF9tZXNz", - "YWdlcy5lZGl0aW9ucy5UZXN0QWxsVHlwZXNFZGl0aW9uMjAyMy5NYXBTdHJp", - "bmdGb3JlaWduTWVzc2FnZUVudHJ5EnEKFm1hcF9zdHJpbmdfbmVzdGVkX2Vu", - "dW0YSSADKAsyUS5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25zLlRl", - "c3RBbGxUeXBlc0VkaXRpb24yMDIzLk1hcFN0cmluZ05lc3RlZEVudW1FbnRy", - "eRJzChdtYXBfc3RyaW5nX2ZvcmVpZ25fZW51bRhKIAMoCzJSLnByb3RvYnVm", + "bjIwMjNCBaoBAigBEhYKDnJlcGVhdGVkX2ludDMyGB8gAygFEhYKDnJlcGVh", + "dGVkX2ludDY0GCAgAygDEhcKD3JlcGVhdGVkX3VpbnQzMhghIAMoDRIXCg9y", + "ZXBlYXRlZF91aW50NjQYIiADKAQSFwoPcmVwZWF0ZWRfc2ludDMyGCMgAygR", + "EhcKD3JlcGVhdGVkX3NpbnQ2NBgkIAMoEhIYChByZXBlYXRlZF9maXhlZDMy", + "GCUgAygHEhgKEHJlcGVhdGVkX2ZpeGVkNjQYJiADKAYSGQoRcmVwZWF0ZWRf", + "c2ZpeGVkMzIYJyADKA8SGQoRcmVwZWF0ZWRfc2ZpeGVkNjQYKCADKBASFgoO", + "cmVwZWF0ZWRfZmxvYXQYKSADKAISFwoPcmVwZWF0ZWRfZG91YmxlGCogAygB", + "EhUKDXJlcGVhdGVkX2Jvb2wYKyADKAgSFwoPcmVwZWF0ZWRfc3RyaW5nGCwg", + "AygJEhYKDnJlcGVhdGVkX2J5dGVzGC0gAygMEm4KF3JlcGVhdGVkX25lc3Rl", + "ZF9tZXNzYWdlGDAgAygLMkYucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5lZGl0", + "aW9ucy5UZXN0QWxsVHlwZXNFZGl0aW9uMjAyMy5OZXN0ZWRNZXNzYWdlQgWq", + "AQIoARJjChhyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UYMSADKAsyOi5wcm90", + "b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25zLkZvcmVpZ25NZXNzYWdlRWRp", + "dGlvbjIwMjNCBaoBAigBEmEKFHJlcGVhdGVkX25lc3RlZF9lbnVtGDMgAygO", + "MkMucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5lZGl0aW9ucy5UZXN0QWxsVHlw", + "ZXNFZGl0aW9uMjAyMy5OZXN0ZWRFbnVtElYKFXJlcGVhdGVkX2ZvcmVpZ25f", + "ZW51bRg0IAMoDjI3LnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMu", + "Rm9yZWlnbkVudW1FZGl0aW9uMjAyMxIhChVyZXBlYXRlZF9zdHJpbmdfcGll", + "Y2UYNiADKAlCAggCEhkKDXJlcGVhdGVkX2NvcmQYNyADKAlCAggBEhsKDHBh", + "Y2tlZF9pbnQzMhhLIAMoBUIFqgECGAESGwoMcGFja2VkX2ludDY0GEwgAygD", + "QgWqAQIYARIcCg1wYWNrZWRfdWludDMyGE0gAygNQgWqAQIYARIcCg1wYWNr", + "ZWRfdWludDY0GE4gAygEQgWqAQIYARIcCg1wYWNrZWRfc2ludDMyGE8gAygR", + "QgWqAQIYARIcCg1wYWNrZWRfc2ludDY0GFAgAygSQgWqAQIYARIdCg5wYWNr", + "ZWRfZml4ZWQzMhhRIAMoB0IFqgECGAESHQoOcGFja2VkX2ZpeGVkNjQYUiAD", + "KAZCBaoBAhgBEh4KD3BhY2tlZF9zZml4ZWQzMhhTIAMoD0IFqgECGAESHgoP", + "cGFja2VkX3NmaXhlZDY0GFQgAygQQgWqAQIYARIbCgxwYWNrZWRfZmxvYXQY", + "VSADKAJCBaoBAhgBEhwKDXBhY2tlZF9kb3VibGUYViADKAFCBaoBAhgBEhoK", + "C3BhY2tlZF9ib29sGFcgAygIQgWqAQIYARJmChJwYWNrZWRfbmVzdGVkX2Vu", + "dW0YWCADKA4yQy5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25zLlRl", + "c3RBbGxUeXBlc0VkaXRpb24yMDIzLk5lc3RlZEVudW1CBaoBAhgBEh0KDnVu", + "cGFja2VkX2ludDMyGFkgAygFQgWqAQIYAhIdCg51bnBhY2tlZF9pbnQ2NBha", + "IAMoA0IFqgECGAISHgoPdW5wYWNrZWRfdWludDMyGFsgAygNQgWqAQIYAhIe", + "Cg91bnBhY2tlZF91aW50NjQYXCADKARCBaoBAhgCEh4KD3VucGFja2VkX3Np", + "bnQzMhhdIAMoEUIFqgECGAISHgoPdW5wYWNrZWRfc2ludDY0GF4gAygSQgWq", + "AQIYAhIfChB1bnBhY2tlZF9maXhlZDMyGF8gAygHQgWqAQIYAhIfChB1bnBh", + "Y2tlZF9maXhlZDY0GGAgAygGQgWqAQIYAhIgChF1bnBhY2tlZF9zZml4ZWQz", + "MhhhIAMoD0IFqgECGAISIAoRdW5wYWNrZWRfc2ZpeGVkNjQYYiADKBBCBaoB", + "AhgCEh0KDnVucGFja2VkX2Zsb2F0GGMgAygCQgWqAQIYAhIeCg91bnBhY2tl", + "ZF9kb3VibGUYZCADKAFCBaoBAhgCEhwKDXVucGFja2VkX2Jvb2wYZSADKAhC", + "BaoBAhgCEmgKFHVucGFja2VkX25lc3RlZF9lbnVtGGYgAygOMkMucHJvdG9i", + "dWZfdGVzdF9tZXNzYWdlcy5lZGl0aW9ucy5UZXN0QWxsVHlwZXNFZGl0aW9u", + "MjAyMy5OZXN0ZWRFbnVtQgWqAQIYAhJkCg9tYXBfaW50MzJfaW50MzIYOCAD", + "KAsySy5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25zLlRlc3RBbGxU", + "eXBlc0VkaXRpb24yMDIzLk1hcEludDMySW50MzJFbnRyeRJkCg9tYXBfaW50", + "NjRfaW50NjQYOSADKAsySy5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRp", + "b25zLlRlc3RBbGxUeXBlc0VkaXRpb24yMDIzLk1hcEludDY0SW50NjRFbnRy", + "eRJoChFtYXBfdWludDMyX3VpbnQzMhg6IAMoCzJNLnByb3RvYnVmX3Rlc3Rf", + "bWVzc2FnZXMuZWRpdGlvbnMuVGVzdEFsbFR5cGVzRWRpdGlvbjIwMjMuTWFw", + "VWludDMyVWludDMyRW50cnkSaAoRbWFwX3VpbnQ2NF91aW50NjQYOyADKAsy", + "TS5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25zLlRlc3RBbGxUeXBl", + "c0VkaXRpb24yMDIzLk1hcFVpbnQ2NFVpbnQ2NEVudHJ5EmgKEW1hcF9zaW50", + "MzJfc2ludDMyGDwgAygLMk0ucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5lZGl0", + "aW9ucy5UZXN0QWxsVHlwZXNFZGl0aW9uMjAyMy5NYXBTaW50MzJTaW50MzJF", + "bnRyeRJoChFtYXBfc2ludDY0X3NpbnQ2NBg9IAMoCzJNLnByb3RvYnVmX3Rl", + "c3RfbWVzc2FnZXMuZWRpdGlvbnMuVGVzdEFsbFR5cGVzRWRpdGlvbjIwMjMu", + "TWFwU2ludDY0U2ludDY0RW50cnkSbAoTbWFwX2ZpeGVkMzJfZml4ZWQzMhg+", + "IAMoCzJPLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMuVGVzdEFs", + "bFR5cGVzRWRpdGlvbjIwMjMuTWFwRml4ZWQzMkZpeGVkMzJFbnRyeRJsChNt", + "YXBfZml4ZWQ2NF9maXhlZDY0GD8gAygLMk8ucHJvdG9idWZfdGVzdF9tZXNz", + "YWdlcy5lZGl0aW9ucy5UZXN0QWxsVHlwZXNFZGl0aW9uMjAyMy5NYXBGaXhl", + "ZDY0Rml4ZWQ2NEVudHJ5EnAKFW1hcF9zZml4ZWQzMl9zZml4ZWQzMhhAIAMo", + "CzJRLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMuVGVzdEFsbFR5", + "cGVzRWRpdGlvbjIwMjMuTWFwU2ZpeGVkMzJTZml4ZWQzMkVudHJ5EnAKFW1h", + "cF9zZml4ZWQ2NF9zZml4ZWQ2NBhBIAMoCzJRLnByb3RvYnVmX3Rlc3RfbWVz", + "c2FnZXMuZWRpdGlvbnMuVGVzdEFsbFR5cGVzRWRpdGlvbjIwMjMuTWFwU2Zp", + "eGVkNjRTZml4ZWQ2NEVudHJ5EmQKD21hcF9pbnQzMl9mbG9hdBhCIAMoCzJL", + "LnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMuVGVzdEFsbFR5cGVz", + "RWRpdGlvbjIwMjMuTWFwSW50MzJGbG9hdEVudHJ5EmYKEG1hcF9pbnQzMl9k", + "b3VibGUYQyADKAsyTC5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25z", + "LlRlc3RBbGxUeXBlc0VkaXRpb24yMDIzLk1hcEludDMyRG91YmxlRW50cnkS", + "YAoNbWFwX2Jvb2xfYm9vbBhEIAMoCzJJLnByb3RvYnVmX3Rlc3RfbWVzc2Fn", + "ZXMuZWRpdGlvbnMuVGVzdEFsbFR5cGVzRWRpdGlvbjIwMjMuTWFwQm9vbEJv", + "b2xFbnRyeRJoChFtYXBfc3RyaW5nX3N0cmluZxhFIAMoCzJNLnByb3RvYnVm", "X3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMuVGVzdEFsbFR5cGVzRWRpdGlvbjIw", - "MjMuTWFwU3RyaW5nRm9yZWlnbkVudW1FbnRyeRIWCgxvbmVvZl91aW50MzIY", - "byABKA1IABJmChRvbmVvZl9uZXN0ZWRfbWVzc2FnZRhwIAEoCzJGLnByb3Rv", - "YnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMuVGVzdEFsbFR5cGVzRWRpdGlv", - "bjIwMjMuTmVzdGVkTWVzc2FnZUgAEhYKDG9uZW9mX3N0cmluZxhxIAEoCUgA", - "EhUKC29uZW9mX2J5dGVzGHIgASgMSAASFAoKb25lb2ZfYm9vbBhzIAEoCEgA", - "EhYKDG9uZW9mX3VpbnQ2NBh0IAEoBEgAEhUKC29uZW9mX2Zsb2F0GHUgASgC", - "SAASFgoMb25lb2ZfZG91YmxlGHYgASgBSAASWQoKb25lb2ZfZW51bRh3IAEo", - "DjJDLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMuVGVzdEFsbFR5", - "cGVzRWRpdGlvbjIwMjMuTmVzdGVkRW51bUgAEmUKDWdyb3VwbGlrZXR5cGUY", - "yQEgASgLMkYucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5lZGl0aW9ucy5UZXN0", - "QWxsVHlwZXNFZGl0aW9uMjAyMy5Hcm91cExpa2VUeXBlQgWqAQIoAhJnCg9k", - "ZWxpbWl0ZWRfZmllbGQYygEgASgLMkYucHJvdG9idWZfdGVzdF9tZXNzYWdl", - "cy5lZGl0aW9ucy5UZXN0QWxsVHlwZXNFZGl0aW9uMjAyMy5Hcm91cExpa2VU", - "eXBlQgWqAQIoAhppCg1OZXN0ZWRNZXNzYWdlEgkKAWEYASABKAUSTQoLY29y", - "ZWN1cnNpdmUYAiABKAsyOC5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRp", - "b25zLlRlc3RBbGxUeXBlc0VkaXRpb24yMDIzGjQKEk1hcEludDMySW50MzJF", - "bnRyeRILCgNrZXkYASABKAUSDQoFdmFsdWUYAiABKAU6AjgBGjQKEk1hcElu", - "dDY0SW50NjRFbnRyeRILCgNrZXkYASABKAMSDQoFdmFsdWUYAiABKAM6AjgB", - "GjYKFE1hcFVpbnQzMlVpbnQzMkVudHJ5EgsKA2tleRgBIAEoDRINCgV2YWx1", - "ZRgCIAEoDToCOAEaNgoUTWFwVWludDY0VWludDY0RW50cnkSCwoDa2V5GAEg", - "ASgEEg0KBXZhbHVlGAIgASgEOgI4ARo2ChRNYXBTaW50MzJTaW50MzJFbnRy", - "eRILCgNrZXkYASABKBESDQoFdmFsdWUYAiABKBE6AjgBGjYKFE1hcFNpbnQ2", - "NFNpbnQ2NEVudHJ5EgsKA2tleRgBIAEoEhINCgV2YWx1ZRgCIAEoEjoCOAEa", - "OAoWTWFwRml4ZWQzMkZpeGVkMzJFbnRyeRILCgNrZXkYASABKAcSDQoFdmFs", - "dWUYAiABKAc6AjgBGjgKFk1hcEZpeGVkNjRGaXhlZDY0RW50cnkSCwoDa2V5", - "GAEgASgGEg0KBXZhbHVlGAIgASgGOgI4ARo6ChhNYXBTZml4ZWQzMlNmaXhl", - "ZDMyRW50cnkSCwoDa2V5GAEgASgPEg0KBXZhbHVlGAIgASgPOgI4ARo6ChhN", - "YXBTZml4ZWQ2NFNmaXhlZDY0RW50cnkSCwoDa2V5GAEgASgQEg0KBXZhbHVl", - "GAIgASgQOgI4ARo0ChJNYXBJbnQzMkZsb2F0RW50cnkSCwoDa2V5GAEgASgF", - "Eg0KBXZhbHVlGAIgASgCOgI4ARo1ChNNYXBJbnQzMkRvdWJsZUVudHJ5EgsK", - "A2tleRgBIAEoBRINCgV2YWx1ZRgCIAEoAToCOAEaMgoQTWFwQm9vbEJvb2xF", - "bnRyeRILCgNrZXkYASABKAgSDQoFdmFsdWUYAiABKAg6AjgBGjYKFE1hcFN0", - "cmluZ1N0cmluZ0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToC", - "OAEaNQoTTWFwU3RyaW5nQnl0ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFs", - "dWUYAiABKAw6AjgBGoUBChtNYXBTdHJpbmdOZXN0ZWRNZXNzYWdlRW50cnkS", - "CwoDa2V5GAEgASgJElUKBXZhbHVlGAIgASgLMkYucHJvdG9idWZfdGVzdF9t", + "MjMuTWFwU3RyaW5nU3RyaW5nRW50cnkSZgoQbWFwX3N0cmluZ19ieXRlcxhG", + "IAMoCzJMLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMuVGVzdEFs", + "bFR5cGVzRWRpdGlvbjIwMjMuTWFwU3RyaW5nQnl0ZXNFbnRyeRJ3ChltYXBf", + "c3RyaW5nX25lc3RlZF9tZXNzYWdlGEcgAygLMlQucHJvdG9idWZfdGVzdF9t", + "ZXNzYWdlcy5lZGl0aW9ucy5UZXN0QWxsVHlwZXNFZGl0aW9uMjAyMy5NYXBT", + "dHJpbmdOZXN0ZWRNZXNzYWdlRW50cnkSeQoabWFwX3N0cmluZ19mb3JlaWdu", + "X21lc3NhZ2UYSCADKAsyVS5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRp", + "b25zLlRlc3RBbGxUeXBlc0VkaXRpb24yMDIzLk1hcFN0cmluZ0ZvcmVpZ25N", + "ZXNzYWdlRW50cnkScQoWbWFwX3N0cmluZ19uZXN0ZWRfZW51bRhJIAMoCzJR", + "LnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMuVGVzdEFsbFR5cGVz", + "RWRpdGlvbjIwMjMuTWFwU3RyaW5nTmVzdGVkRW51bUVudHJ5EnMKF21hcF9z", + "dHJpbmdfZm9yZWlnbl9lbnVtGEogAygLMlIucHJvdG9idWZfdGVzdF9tZXNz", + "YWdlcy5lZGl0aW9ucy5UZXN0QWxsVHlwZXNFZGl0aW9uMjAyMy5NYXBTdHJp", + "bmdGb3JlaWduRW51bUVudHJ5EhYKDG9uZW9mX3VpbnQzMhhvIAEoDUgAEm0K", + "FG9uZW9mX25lc3RlZF9tZXNzYWdlGHAgASgLMkYucHJvdG9idWZfdGVzdF9t", "ZXNzYWdlcy5lZGl0aW9ucy5UZXN0QWxsVHlwZXNFZGl0aW9uMjAyMy5OZXN0", - "ZWRNZXNzYWdlOgI4ARp6ChxNYXBTdHJpbmdGb3JlaWduTWVzc2FnZUVudHJ5", - "EgsKA2tleRgBIAEoCRJJCgV2YWx1ZRgCIAEoCzI6LnByb3RvYnVmX3Rlc3Rf", - "bWVzc2FnZXMuZWRpdGlvbnMuRm9yZWlnbk1lc3NhZ2VFZGl0aW9uMjAyMzoC", - "OAEafwoYTWFwU3RyaW5nTmVzdGVkRW51bUVudHJ5EgsKA2tleRgBIAEoCRJS", - "CgV2YWx1ZRgCIAEoDjJDLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlv", - "bnMuVGVzdEFsbFR5cGVzRWRpdGlvbjIwMjMuTmVzdGVkRW51bToCOAEadAoZ", - "TWFwU3RyaW5nRm9yZWlnbkVudW1FbnRyeRILCgNrZXkYASABKAkSRgoFdmFs", - "dWUYAiABKA4yNy5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25zLkZv", - "cmVpZ25FbnVtRWRpdGlvbjIwMjM6AjgBGjwKDUdyb3VwTGlrZVR5cGUSFAoL", - "Z3JvdXBfaW50MzIYygEgASgFEhUKDGdyb3VwX3VpbnQzMhjLASABKA0iOQoK", - "TmVzdGVkRW51bRIHCgNGT08QABIHCgNCQVIQARIHCgNCQVoQAhIQCgNORUcQ", - "////////////ASoFCHgQyQFCDQoLb25lb2ZfZmllbGQiJgoZRm9yZWlnbk1l", - "c3NhZ2VFZGl0aW9uMjAyMxIJCgFjGAEgASgFIhoKDUdyb3VwTGlrZVR5cGUS", - "CQoBYxgBIAEoBSpLChZGb3JlaWduRW51bUVkaXRpb24yMDIzEg8KC0ZPUkVJ", - "R05fRk9PEAASDwoLRk9SRUlHTl9CQVIQARIPCgtGT1JFSUdOX0JBWhACOlEK", - "D2V4dGVuc2lvbl9pbnQzMhI4LnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRp", - "dGlvbnMuVGVzdEFsbFR5cGVzRWRpdGlvbjIwMjMYeCABKAU6hgEKDWdyb3Vw", - "bGlrZXR5cGUSOC5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25zLlRl", - "c3RBbGxUeXBlc0VkaXRpb24yMDIzGHkgASgLMi4ucHJvdG9idWZfdGVzdF9t", - "ZXNzYWdlcy5lZGl0aW9ucy5Hcm91cExpa2VUeXBlQgWqAQIoAjqGAQoNZGVs", - "aW1pdGVkX2V4dBI4LnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMu", - "VGVzdEFsbFR5cGVzRWRpdGlvbjIwMjMYeiABKAsyLi5wcm90b2J1Zl90ZXN0", - "X21lc3NhZ2VzLmVkaXRpb25zLkdyb3VwTGlrZVR5cGVCBaoBAigCQjwKLWNv", - "bS5nb29nbGUucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5lZGl0aW9uMjAyM1AB", - "ogIIRWRpdGlvbnNiCGVkaXRpb25zcOgH")); + "ZWRNZXNzYWdlQgWqAQIoAUgAEhYKDG9uZW9mX3N0cmluZxhxIAEoCUgAEhUK", + "C29uZW9mX2J5dGVzGHIgASgMSAASFAoKb25lb2ZfYm9vbBhzIAEoCEgAEhYK", + "DG9uZW9mX3VpbnQ2NBh0IAEoBEgAEhUKC29uZW9mX2Zsb2F0GHUgASgCSAAS", + "FgoMb25lb2ZfZG91YmxlGHYgASgBSAASWQoKb25lb2ZfZW51bRh3IAEoDjJD", + "LnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMuVGVzdEFsbFR5cGVz", + "RWRpdGlvbjIwMjMuTmVzdGVkRW51bUgAEl4KDWdyb3VwbGlrZXR5cGUYyQEg", + "ASgLMkYucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5lZGl0aW9ucy5UZXN0QWxs", + "VHlwZXNFZGl0aW9uMjAyMy5Hcm91cExpa2VUeXBlEmAKD2RlbGltaXRlZF9m", + "aWVsZBjKASABKAsyRi5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVkaXRpb25z", + "LlRlc3RBbGxUeXBlc0VkaXRpb24yMDIzLkdyb3VwTGlrZVR5cGUacAoNTmVz", + "dGVkTWVzc2FnZRIJCgFhGAEgASgFElQKC2NvcmVjdXJzaXZlGAIgASgLMjgu", + "cHJvdG9idWZfdGVzdF9tZXNzYWdlcy5lZGl0aW9ucy5UZXN0QWxsVHlwZXNF", + "ZGl0aW9uMjAyM0IFqgECKAEaNAoSTWFwSW50MzJJbnQzMkVudHJ5EgsKA2tl", + "eRgBIAEoBRINCgV2YWx1ZRgCIAEoBToCOAEaNAoSTWFwSW50NjRJbnQ2NEVu", + "dHJ5EgsKA2tleRgBIAEoAxINCgV2YWx1ZRgCIAEoAzoCOAEaNgoUTWFwVWlu", + "dDMyVWludDMyRW50cnkSCwoDa2V5GAEgASgNEg0KBXZhbHVlGAIgASgNOgI4", + "ARo2ChRNYXBVaW50NjRVaW50NjRFbnRyeRILCgNrZXkYASABKAQSDQoFdmFs", + "dWUYAiABKAQ6AjgBGjYKFE1hcFNpbnQzMlNpbnQzMkVudHJ5EgsKA2tleRgB", + "IAEoERINCgV2YWx1ZRgCIAEoEToCOAEaNgoUTWFwU2ludDY0U2ludDY0RW50", + "cnkSCwoDa2V5GAEgASgSEg0KBXZhbHVlGAIgASgSOgI4ARo4ChZNYXBGaXhl", + "ZDMyRml4ZWQzMkVudHJ5EgsKA2tleRgBIAEoBxINCgV2YWx1ZRgCIAEoBzoC", + "OAEaOAoWTWFwRml4ZWQ2NEZpeGVkNjRFbnRyeRILCgNrZXkYASABKAYSDQoF", + "dmFsdWUYAiABKAY6AjgBGjoKGE1hcFNmaXhlZDMyU2ZpeGVkMzJFbnRyeRIL", + "CgNrZXkYASABKA8SDQoFdmFsdWUYAiABKA86AjgBGjoKGE1hcFNmaXhlZDY0", + "U2ZpeGVkNjRFbnRyeRILCgNrZXkYASABKBASDQoFdmFsdWUYAiABKBA6AjgB", + "GjQKEk1hcEludDMyRmxvYXRFbnRyeRILCgNrZXkYASABKAUSDQoFdmFsdWUY", + "AiABKAI6AjgBGjUKE01hcEludDMyRG91YmxlRW50cnkSCwoDa2V5GAEgASgF", + "Eg0KBXZhbHVlGAIgASgBOgI4ARoyChBNYXBCb29sQm9vbEVudHJ5EgsKA2tl", + "eRgBIAEoCBINCgV2YWx1ZRgCIAEoCDoCOAEaNgoUTWFwU3RyaW5nU3RyaW5n", + "RW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ARo1ChNNYXBT", + "dHJpbmdCeXRlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoDDoC", + "OAEahQEKG01hcFN0cmluZ05lc3RlZE1lc3NhZ2VFbnRyeRILCgNrZXkYASAB", + "KAkSVQoFdmFsdWUYAiABKAsyRi5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLmVk", + "aXRpb25zLlRlc3RBbGxUeXBlc0VkaXRpb24yMDIzLk5lc3RlZE1lc3NhZ2U6", + "AjgBGnoKHE1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlRW50cnkSCwoDa2V5GAEg", + "ASgJEkkKBXZhbHVlGAIgASgLMjoucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5l", + "ZGl0aW9ucy5Gb3JlaWduTWVzc2FnZUVkaXRpb24yMDIzOgI4ARp/ChhNYXBT", + "dHJpbmdOZXN0ZWRFbnVtRW50cnkSCwoDa2V5GAEgASgJElIKBXZhbHVlGAIg", + "ASgOMkMucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5lZGl0aW9ucy5UZXN0QWxs", + "VHlwZXNFZGl0aW9uMjAyMy5OZXN0ZWRFbnVtOgI4ARp0ChlNYXBTdHJpbmdG", + "b3JlaWduRW51bUVudHJ5EgsKA2tleRgBIAEoCRJGCgV2YWx1ZRgCIAEoDjI3", + "LnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMuRm9yZWlnbkVudW1F", + "ZGl0aW9uMjAyMzoCOAEaPAoNR3JvdXBMaWtlVHlwZRIUCgtncm91cF9pbnQz", + "MhjKASABKAUSFQoMZ3JvdXBfdWludDMyGMsBIAEoDSI5CgpOZXN0ZWRFbnVt", + "EgcKA0ZPTxAAEgcKA0JBUhABEgcKA0JBWhACEhAKA05FRxD///////////8B", + "KgUIeBDJAUINCgtvbmVvZl9maWVsZCImChlGb3JlaWduTWVzc2FnZUVkaXRp", + "b24yMDIzEgkKAWMYASABKAUiGgoNR3JvdXBMaWtlVHlwZRIJCgFjGAEgASgF", + "KksKFkZvcmVpZ25FbnVtRWRpdGlvbjIwMjMSDwoLRk9SRUlHTl9GT08QABIP", + "CgtGT1JFSUdOX0JBUhABEg8KC0ZPUkVJR05fQkFaEAI6UQoPZXh0ZW5zaW9u", + "X2ludDMyEjgucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5lZGl0aW9ucy5UZXN0", + "QWxsVHlwZXNFZGl0aW9uMjAyMxh4IAEoBTp/Cg1ncm91cGxpa2V0eXBlEjgu", + "cHJvdG9idWZfdGVzdF9tZXNzYWdlcy5lZGl0aW9ucy5UZXN0QWxsVHlwZXNF", + "ZGl0aW9uMjAyMxh5IAEoCzIuLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRp", + "dGlvbnMuR3JvdXBMaWtlVHlwZTp/Cg1kZWxpbWl0ZWRfZXh0EjgucHJvdG9i", + "dWZfdGVzdF9tZXNzYWdlcy5lZGl0aW9ucy5UZXN0QWxsVHlwZXNFZGl0aW9u", + "MjAyMxh6IAEoCzIuLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMuZWRpdGlvbnMu", + "R3JvdXBMaWtlVHlwZUJBCi1jb20uZ29vZ2xlLnByb3RvYnVmX3Rlc3RfbWVz", + "c2FnZXMuZWRpdGlvbjIwMjNQAaICCEVkaXRpb25zkgMCKAJiCGVkaXRpb25z", + "cOgH")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::ProtobufTestMessages.Editions.ForeignEnumEdition2023), }, new pb::Extension[] { TestMessagesEdition2023Extensions.ExtensionInt32, TestMessagesEdition2023Extensions.GroupLikeType, TestMessagesEdition2023Extensions.DelimitedExt }, new pbr::GeneratedClrTypeInfo[] { diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestFeatures.pb.cs b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestFeatures.pb.cs index 4f11d19d7f91a..e764623f525f5 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestFeatures.pb.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestFeatures.pb.cs @@ -59,7 +59,7 @@ static UnittestFeaturesReflection() { "IOkHElQKDmZ1dHVyZV9mZWF0dXJlGBIgASgOMg8ucGIuRW51bUZlYXR1cmVC", "K4gBAZgBAZgBBKIBCxIGVkFMVUUxGIQHogELEgZWQUxVRTIY6QeyAQMI6QcS", "VwoObGVnYWN5X2ZlYXR1cmUYEyABKA4yDy5wYi5FbnVtRmVhdHVyZUIuiAEB", - "mAEBmAEEogELEgZWQUxVRTEYhAeiAQsSBlZBTFVFMhjoB7IBBgjmByDoByrJ", + "mAEBmAEEogELEgZWQUxVRTEYhAeiAQsSBlZBTFVFMhjoB7IBBgjnByDoByrJ", "AgoLRW51bUZlYXR1cmUSHQoZVEVTVF9FTlVNX0ZFQVRVUkVfVU5LTk9XThAA", "EgoKBlZBTFVFMRABEgoKBlZBTFVFMhACEgoKBlZBTFVFMxADEgoKBlZBTFVF", "NBAEEgoKBlZBTFVFNRAFEgoKBlZBTFVFNhAGEgoKBlZBTFVFNxAHEgoKBlZB", diff --git a/csharp/src/Google.Protobuf.Test/testprotos.pb b/csharp/src/Google.Protobuf.Test/testprotos.pb index dff0f368c6538..a0a648b11791a 100644 Binary files a/csharp/src/Google.Protobuf.Test/testprotos.pb and b/csharp/src/Google.Protobuf.Test/testprotos.pb differ diff --git a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs index f46667ed070ba..2aeabbd25571d 100644 --- a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs @@ -407,6 +407,11 @@ internal void CrossLink() throw new DescriptorValidationException(this, $"\"{Proto.TypeName}\" is not a message type."); } messageType = m; + if (m.Proto.Options?.MapEntry == true || ContainingType?.Proto.Options?.MapEntry == true) + { + // Maps can't inherit delimited encoding. + FieldType = FieldType.Message; + } if (Proto.HasDefaultValue) { diff --git a/java/core/src/main/java/com/google/protobuf/Descriptors.java b/java/core/src/main/java/com/google/protobuf/Descriptors.java index 1a81fe6f50588..0eb67eebeda22 100644 --- a/java/core/src/main/java/com/google/protobuf/Descriptors.java +++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java @@ -1297,6 +1297,8 @@ public Type getType() { // since these are used before feature resolution when parsing java feature set defaults // (custom options) into unknown fields. if (type == Type.MESSAGE + && !(messageType != null && messageType.toProto().getOptions().getMapEntry()) + && !(containingType != null && containingType.toProto().getOptions().getMapEntry()) && this.features != null && getFeatures().getMessageEncoding() == FeatureSet.MessageEncoding.DELIMITED) { return Type.GROUP; @@ -1476,8 +1478,7 @@ public boolean hasPresence() { * been upgraded to editions. */ boolean isGroupLike() { - if (getFeatures().getMessageEncoding() - != DescriptorProtos.FeatureSet.MessageEncoding.DELIMITED) { + if (getType() != Type.GROUP) { // Groups are always tag-delimited. return false; } @@ -1900,7 +1901,9 @@ private void crossLink() throws DescriptorValidationException { } } - if (getJavaType() == JavaType.MESSAGE) { + // Use raw type since inferred type considers messageType which may not be fully cross + // linked yet. + if (type.getJavaType() == JavaType.MESSAGE) { if (!(typeDescriptor instanceof Descriptor)) { throw new DescriptorValidationException( this, '\"' + proto.getTypeName() + "\" is not a message type."); @@ -1910,7 +1913,7 @@ private void crossLink() throws DescriptorValidationException { if (proto.hasDefaultValue()) { throw new DescriptorValidationException(this, "Messages can't have default values."); } - } else if (getJavaType() == JavaType.ENUM) { + } else if (type.getJavaType() == JavaType.ENUM) { if (!(typeDescriptor instanceof EnumDescriptor)) { throw new DescriptorValidationException( this, '\"' + proto.getTypeName() + "\" is not an enum type."); @@ -1920,7 +1923,7 @@ private void crossLink() throws DescriptorValidationException { throw new DescriptorValidationException(this, "Field with primitive type has type_name."); } } else { - if (getJavaType() == JavaType.MESSAGE || getJavaType() == JavaType.ENUM) { + if (type.getJavaType() == JavaType.MESSAGE || type.getJavaType() == JavaType.ENUM) { throw new DescriptorValidationException( this, "Field with message or enum type missing type_name."); } @@ -1941,7 +1944,7 @@ private void crossLink() throws DescriptorValidationException { } try { - switch (getType()) { + switch (type) { case INT32: case SINT32: case SFIXED32: @@ -2016,7 +2019,7 @@ private void crossLink() throws DescriptorValidationException { if (isRepeated()) { defaultValue = Collections.emptyList(); } else { - switch (getJavaType()) { + switch (type.getJavaType()) { case ENUM: // We guarantee elsewhere that an enum type always has at least // one possible value. @@ -2026,7 +2029,7 @@ private void crossLink() throws DescriptorValidationException { defaultValue = null; break; default: - defaultValue = getJavaType().defaultDefault; + defaultValue = type.getJavaType().defaultDefault; break; } } diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index e32a6bf02a9b6..96010883fa568 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -13723,8 +13723,7 @@ bool _upb_FieldDef_ValidateUtf8(const upb_FieldDef* f) { bool _upb_FieldDef_IsGroupLike(const upb_FieldDef* f) { // Groups are always tag-delimited. - if (UPB_DESC(FeatureSet_message_encoding)(upb_FieldDef_ResolvedFeatures(f)) != - UPB_DESC(FeatureSet_DELIMITED)) { + if (f->type_ != kUpb_FieldType_Group) { return false; } @@ -14158,12 +14157,6 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix, UPB_DESC(FieldDescriptorProto_has_type_name)(field_proto); f->type_ = (int)UPB_DESC(FieldDescriptorProto_type)(field_proto); - if (f->type_ == kUpb_FieldType_Message && - // TODO: remove once we can deprecate kUpb_FieldType_Group. - UPB_DESC(FeatureSet_message_encoding)(f->resolved_features) == - UPB_DESC(FeatureSet_DELIMITED)) { - f->type_ = kUpb_FieldType_Group; - } if (has_type) { switch (f->type_) { @@ -14184,7 +14177,7 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix, } } - if (!has_type && has_type_name) { + if ((!has_type && has_type_name) || f->type_ == kUpb_FieldType_Message) { f->type_ = UPB_FIELD_TYPE_UNSPECIFIED; // We'll assign this in resolve_subdef() } else { @@ -14334,8 +14327,15 @@ static void resolve_subdef(upb_DefBuilder* ctx, const char* prefix, break; case UPB_DEFTYPE_MSG: f->sub.msgdef = def; - f->type_ = kUpb_FieldType_Message; // It appears there is no way of - // this being a group. + f->type_ = kUpb_FieldType_Message; + // TODO: remove once we can deprecate + // kUpb_FieldType_Group. + if (UPB_DESC(FeatureSet_message_encoding)(f->resolved_features) == + UPB_DESC(FeatureSet_DELIMITED) && + !upb_MessageDef_IsMapEntry(def) && + !(f->msgdef && upb_MessageDef_IsMapEntry(f->msgdef))) { + f->type_ = kUpb_FieldType_Group; + } f->has_presence = !upb_FieldDef_IsRepeated(f); break; default: diff --git a/python/google/protobuf/descriptor.py b/python/google/protobuf/descriptor.py index 80c75ae04cd7f..d8c6a4352b112 100755 --- a/python/google/protobuf/descriptor.py +++ b/python/google/protobuf/descriptor.py @@ -708,6 +708,9 @@ def type(self): if ( self._GetFeatures().message_encoding == _FEATURESET_MESSAGE_ENCODING_DELIMITED + and self.message_type + and not self.message_type.GetOptions().map_entry + and not self.containing_type.GetOptions().map_entry ): return FieldDescriptor.TYPE_GROUP return self._type diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py index 2244ccca3cb54..bc611092cb5c9 100644 --- a/python/google/protobuf/text_format.py +++ b/python/google/protobuf/text_format.py @@ -195,10 +195,7 @@ def _IsGroupLike(field): True if this field is group-like, false otherwise. """ # Groups are always tag-delimited. - if ( - field._GetFeatures().message_encoding - != descriptor._FEATURESET_MESSAGE_ENCODING_DELIMITED - ): + if field.type != descriptor.FieldDescriptor.TYPE_GROUP: return False # Group fields always are always the lowercase type name. diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c index bf4728137c029..21d6df7c9eba0 100644 --- a/ruby/ext/google/protobuf_c/ruby-upb.c +++ b/ruby/ext/google/protobuf_c/ruby-upb.c @@ -13212,8 +13212,7 @@ bool _upb_FieldDef_ValidateUtf8(const upb_FieldDef* f) { bool _upb_FieldDef_IsGroupLike(const upb_FieldDef* f) { // Groups are always tag-delimited. - if (UPB_DESC(FeatureSet_message_encoding)(upb_FieldDef_ResolvedFeatures(f)) != - UPB_DESC(FeatureSet_DELIMITED)) { + if (f->type_ != kUpb_FieldType_Group) { return false; } @@ -13647,12 +13646,6 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix, UPB_DESC(FieldDescriptorProto_has_type_name)(field_proto); f->type_ = (int)UPB_DESC(FieldDescriptorProto_type)(field_proto); - if (f->type_ == kUpb_FieldType_Message && - // TODO: remove once we can deprecate kUpb_FieldType_Group. - UPB_DESC(FeatureSet_message_encoding)(f->resolved_features) == - UPB_DESC(FeatureSet_DELIMITED)) { - f->type_ = kUpb_FieldType_Group; - } if (has_type) { switch (f->type_) { @@ -13673,7 +13666,7 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix, } } - if (!has_type && has_type_name) { + if ((!has_type && has_type_name) || f->type_ == kUpb_FieldType_Message) { f->type_ = UPB_FIELD_TYPE_UNSPECIFIED; // We'll assign this in resolve_subdef() } else { @@ -13823,8 +13816,15 @@ static void resolve_subdef(upb_DefBuilder* ctx, const char* prefix, break; case UPB_DEFTYPE_MSG: f->sub.msgdef = def; - f->type_ = kUpb_FieldType_Message; // It appears there is no way of - // this being a group. + f->type_ = kUpb_FieldType_Message; + // TODO: remove once we can deprecate + // kUpb_FieldType_Group. + if (UPB_DESC(FeatureSet_message_encoding)(f->resolved_features) == + UPB_DESC(FeatureSet_DELIMITED) && + !upb_MessageDef_IsMapEntry(def) && + !(f->msgdef && upb_MessageDef_IsMapEntry(f->msgdef))) { + f->type_ = kUpb_FieldType_Group; + } f->has_presence = !upb_FieldDef_IsRepeated(f); break; default: diff --git a/upb/reflection/field_def.c b/upb/reflection/field_def.c index 98fa37092be03..6bc636ad7d9d2 100644 --- a/upb/reflection/field_def.c +++ b/upb/reflection/field_def.c @@ -252,8 +252,7 @@ bool _upb_FieldDef_ValidateUtf8(const upb_FieldDef* f) { bool _upb_FieldDef_IsGroupLike(const upb_FieldDef* f) { // Groups are always tag-delimited. - if (UPB_DESC(FeatureSet_message_encoding)(upb_FieldDef_ResolvedFeatures(f)) != - UPB_DESC(FeatureSet_DELIMITED)) { + if (f->type_ != kUpb_FieldType_Group) { return false; } @@ -687,12 +686,6 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix, UPB_DESC(FieldDescriptorProto_has_type_name)(field_proto); f->type_ = (int)UPB_DESC(FieldDescriptorProto_type)(field_proto); - if (f->type_ == kUpb_FieldType_Message && - // TODO: remove once we can deprecate kUpb_FieldType_Group. - UPB_DESC(FeatureSet_message_encoding)(f->resolved_features) == - UPB_DESC(FeatureSet_DELIMITED)) { - f->type_ = kUpb_FieldType_Group; - } if (has_type) { switch (f->type_) { @@ -713,7 +706,7 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix, } } - if (!has_type && has_type_name) { + if ((!has_type && has_type_name) || f->type_ == kUpb_FieldType_Message) { f->type_ = UPB_FIELD_TYPE_UNSPECIFIED; // We'll assign this in resolve_subdef() } else { @@ -863,8 +856,15 @@ static void resolve_subdef(upb_DefBuilder* ctx, const char* prefix, break; case UPB_DEFTYPE_MSG: f->sub.msgdef = def; - f->type_ = kUpb_FieldType_Message; // It appears there is no way of - // this being a group. + f->type_ = kUpb_FieldType_Message; + // TODO: remove once we can deprecate + // kUpb_FieldType_Group. + if (UPB_DESC(FeatureSet_message_encoding)(f->resolved_features) == + UPB_DESC(FeatureSet_DELIMITED) && + !upb_MessageDef_IsMapEntry(def) && + !(f->msgdef && upb_MessageDef_IsMapEntry(f->msgdef))) { + f->type_ = kUpb_FieldType_Group; + } f->has_presence = !upb_FieldDef_IsRepeated(f); break; default: