Release prototype of Protobuf Editions.

This represents the future direction of protobuf, replacing proto2/proto3 syntax with editions.  These will enable more incremental evolution of protobuf APIs through features, which are individual behaviors (such as whether field presence is explicit or implicit).  For more details see https://protobuf.dev/editions/overview/.

This PR contains a working implementation of editions for the protoc frontend and C++ code generation, along with various infrastructure improvements to support it.  It gives early access for anyone who wants to a preview of editions, but has no effect on proto2/proto3 syntax.  It is flag-guarded behind the `--experimental_editions` flag, and is an experimental feature with no guarantees.

PiperOrigin-RevId: 544805690
pull/13196/head
Mike Kruskal 2023-06-30 20:14:50 -07:00 committed by Copybara-Service
parent bd589d9060
commit 4f9e41767a
82 changed files with 15324 additions and 1420 deletions

View File

@ -103,6 +103,12 @@ alias(
# Built-in runtime protos: these are part of protobuf's internal
# implementation, but are not Well-Known Types.
alias(
name = "cpp_features_proto",
actual = "//src/google/protobuf:cpp_features_proto", # proto_library
visibility = ["//visibility:public"],
)
alias(
name = "descriptor_proto",
actual = "//src/google/protobuf:descriptor_proto", # proto_library

View File

@ -65,6 +65,7 @@ set(protobuf_HEADERS
${libprotobuf_hdrs}
${libprotoc_hdrs}
${wkt_protos_files}
${cpp_features_proto_proto_srcs}
${descriptor_proto_proto_srcs}
${plugin_proto_proto_srcs}
)

View File

@ -172,6 +172,7 @@ file(GLOB_RECURSE _local_hdrs
# Exclude the bootstrapping that are directly used by tests.
set(_exclude_hdrs
"${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_features.pb.h"
"${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor.pb.h"
"${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.pb.h")

View File

@ -23,6 +23,7 @@ cd src
declare -a RUNTIME_PROTO_FILES=(\
google/protobuf/any.proto \
google/protobuf/api.proto \
google/protobuf/cpp_features.proto \
google/protobuf/descriptor.proto \
google/protobuf/duration.proto \
google/protobuf/empty.proto \

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -110,6 +110,7 @@ gen_file_lists(
":protoc": "libprotoc",
# Protos:
"//src/google/protobuf:well_known_type_protos": "wkt_protos",
"//src/google/protobuf:cpp_features_proto": "cpp_features_proto",
"//src/google/protobuf:descriptor_proto": "descriptor_proto",
"//src/google/protobuf/compiler:plugin_proto": "plugin_proto",
# Test libraries:

View File

@ -894,22 +894,24 @@ const upb_MiniTable google_protobuf_DescriptorProto_ReservedRange_msg_init = {
})
};
static const upb_MiniTableSub google_protobuf_ExtensionRangeOptions_submsgs[3] = {
static const upb_MiniTableSub google_protobuf_ExtensionRangeOptions_submsgs[4] = {
{.submsg = &google_protobuf_ExtensionRangeOptions_Declaration_msg_init},
{.submsg = &google_protobuf_FeatureSet_msg_init},
{.submsg = &google_protobuf_UninterpretedOption_msg_init},
{.subenum = &google_protobuf_ExtensionRangeOptions_VerificationState_enum_init},
};
static const upb_MiniTableField google_protobuf_ExtensionRangeOptions__fields[3] = {
static const upb_MiniTableField google_protobuf_ExtensionRangeOptions__fields[4] = {
{2, UPB_SIZE(4, 8), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{3, UPB_SIZE(8, 4), 1, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(12, 16), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{3, UPB_SIZE(8, 4), 1, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{50, UPB_SIZE(12, 16), 2, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(16, 24), 0, 2, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
};
const upb_MiniTable google_protobuf_ExtensionRangeOptions_msg_init = {
&google_protobuf_ExtensionRangeOptions_submsgs[0],
&google_protobuf_ExtensionRangeOptions__fields[0],
UPB_SIZE(16, 24), 3, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(248), 0,
UPB_SIZE(24, 32), 4, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(248), 0,
UPB_FASTTABLE_INIT({
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -929,12 +931,12 @@ const upb_MiniTable google_protobuf_ExtensionRangeOptions_msg_init = {
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0010000002010392, &upb_psm_2bt_max64b},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x001000003f013eba, &upb_prm_2bt_max128b},
{0x001800003f023eba, &upb_prm_2bt_max128b},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1004,7 +1006,7 @@ const upb_MiniTable google_protobuf_FieldDescriptorProto_msg_init = {
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0038000006000032, &upb_pss_1bt},
{0x004800000700003a, &upb_pss_1bt},
{0x0058000008000042, &upb_psm_1bt_max64b},
{0x0058000008000042, &upb_psm_1bt_max128b},
{0x0010000009000048, &upb_psv4_1bt},
{0x006000000a000052, &upb_pss_1bt},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1173,17 +1175,18 @@ const upb_MiniTable google_protobuf_MethodDescriptorProto_msg_init = {
})
};
static const upb_MiniTableSub google_protobuf_FileOptions_submsgs[2] = {
static const upb_MiniTableSub google_protobuf_FileOptions_submsgs[3] = {
{.submsg = &google_protobuf_FeatureSet_msg_init},
{.submsg = &google_protobuf_UninterpretedOption_msg_init},
{.subenum = &google_protobuf_FileOptions_OptimizeMode_enum_init},
};
static const upb_MiniTableField google_protobuf_FileOptions__fields[21] = {
{1, 24, 1, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{8, UPB_SIZE(32, 40), 2, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{9, 4, 3, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
static const upb_MiniTableField google_protobuf_FileOptions__fields[22] = {
{1, UPB_SIZE(28, 24), 1, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{8, UPB_SIZE(36, 40), 2, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{9, 4, 3, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{10, 8, 4, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{11, UPB_SIZE(40, 56), 5, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{11, UPB_SIZE(44, 56), 5, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{16, 9, 6, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{17, 10, 7, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{18, 11, 8, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
@ -1191,21 +1194,22 @@ static const upb_MiniTableField google_protobuf_FileOptions__fields[21] = {
{23, 13, 10, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{27, 14, 11, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{31, 15, 12, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{36, UPB_SIZE(48, 72), 13, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{37, UPB_SIZE(56, 88), 14, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{39, UPB_SIZE(64, 104), 15, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{40, UPB_SIZE(72, 120), 16, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{41, UPB_SIZE(80, 136), 17, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{36, UPB_SIZE(52, 72), 13, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{37, UPB_SIZE(60, 88), 14, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{39, UPB_SIZE(68, 104), 15, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{40, UPB_SIZE(76, 120), 16, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{41, UPB_SIZE(84, 136), 17, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{42, 16, 18, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{44, UPB_SIZE(88, 152), 19, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{45, UPB_SIZE(96, 168), 20, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(20, 184), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{44, UPB_SIZE(92, 152), 19, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{45, UPB_SIZE(100, 168), 20, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{50, UPB_SIZE(20, 184), 21, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(24, 192), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
};
const upb_MiniTable google_protobuf_FileOptions_msg_init = {
&google_protobuf_FileOptions_submsgs[0],
&google_protobuf_FileOptions__fields[0],
UPB_SIZE(104, 192), 21, kUpb_ExtMode_Extendable, 1, UPB_FASTTABLE_MASK(248), 0,
UPB_SIZE(112, 200), 22, kUpb_ExtMode_Extendable, 1, UPB_FASTTABLE_MASK(248), 0,
UPB_FASTTABLE_INIT({
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x001800000100000a, &upb_pss_1bt},
@ -1242,23 +1246,25 @@ const upb_MiniTable google_protobuf_FileOptions_msg_init = {
})
};
static const upb_MiniTableSub google_protobuf_MessageOptions_submsgs[1] = {
static const upb_MiniTableSub google_protobuf_MessageOptions_submsgs[2] = {
{.submsg = &google_protobuf_FeatureSet_msg_init},
{.submsg = &google_protobuf_UninterpretedOption_msg_init},
};
static const upb_MiniTableField google_protobuf_MessageOptions__fields[6] = {
static const upb_MiniTableField google_protobuf_MessageOptions__fields[7] = {
{1, 1, 1, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{2, 2, 2, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{3, 3, 3, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{7, 4, 4, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{11, 5, 5, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{999, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{12, 8, 6, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(12, 16), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
};
const upb_MiniTable google_protobuf_MessageOptions_msg_init = {
&google_protobuf_MessageOptions_submsgs[0],
&google_protobuf_MessageOptions__fields[0],
16, 6, kUpb_ExtMode_Extendable, 3, UPB_FASTTABLE_MASK(248), 0,
UPB_SIZE(16, 24), 7, kUpb_ExtMode_Extendable, 3, UPB_FASTTABLE_MASK(248), 0,
UPB_FASTTABLE_INIT({
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0001000001000008, &upb_psb1_1bt},
@ -1272,6 +1278,7 @@ const upb_MiniTable google_protobuf_MessageOptions_msg_init = {
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0005000005000058, &upb_psb1_1bt},
{0x0008000006000062, &upb_psm_1bt_max64b},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1282,8 +1289,7 @@ const upb_MiniTable google_protobuf_MessageOptions_msg_init = {
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x000800003f003eba, &upb_prm_2bt_max128b},
{0x001000003f013eba, &upb_prm_2bt_max128b},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1295,7 +1301,9 @@ const upb_MiniTable google_protobuf_MessageOptions_msg_init = {
})
};
static const upb_MiniTableSub google_protobuf_FieldOptions_submsgs[6] = {
static const upb_MiniTableSub google_protobuf_FieldOptions_submsgs[8] = {
{.submsg = &google_protobuf_FieldOptions_EditionDefault_msg_init},
{.submsg = &google_protobuf_FeatureSet_msg_init},
{.submsg = &google_protobuf_UninterpretedOption_msg_init},
{.subenum = &google_protobuf_FieldOptions_CType_enum_init},
{.subenum = &google_protobuf_FieldOptions_JSType_enum_init},
@ -1304,25 +1312,27 @@ static const upb_MiniTableSub google_protobuf_FieldOptions_submsgs[6] = {
{.subenum = &google_protobuf_FieldOptions_OptionTargetType_enum_init},
};
static const upb_MiniTableField google_protobuf_FieldOptions__fields[12] = {
{1, 4, 1, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
static const upb_MiniTableField google_protobuf_FieldOptions__fields[14] = {
{1, 4, 1, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{2, 8, 2, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{3, 9, 3, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{5, 10, 4, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{6, 12, 5, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{6, 12, 5, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{10, 16, 6, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{15, 17, 7, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{16, 18, 8, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{17, 20, 9, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{18, 24, 10, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{19, UPB_SIZE(28, 32), 0, 5, 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(32, 40), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{17, 20, 9, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{18, 24, 10, 6, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{19, UPB_SIZE(28, 32), 0, 7, 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{20, UPB_SIZE(32, 40), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{21, UPB_SIZE(36, 48), 11, 1, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(40, 56), 0, 2, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
};
const upb_MiniTable google_protobuf_FieldOptions_msg_init = {
&google_protobuf_FieldOptions_submsgs[0],
&google_protobuf_FieldOptions__fields[0],
UPB_SIZE(40, 48), 12, kUpb_ExtMode_Extendable, 3, UPB_FASTTABLE_MASK(248), 0,
UPB_SIZE(48, 64), 14, kUpb_ExtMode_Extendable, 3, UPB_FASTTABLE_MASK(248), 0,
UPB_FASTTABLE_INIT({
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1344,10 +1354,10 @@ const upb_MiniTable google_protobuf_FieldOptions_msg_init = {
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x002800003f0001a2, &upb_prm_2bt_max64b},
{0x003000000b0101aa, &upb_psm_2bt_max64b},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x002800003f003eba, &upb_prm_2bt_max128b},
{0x003800003f023eba, &upb_prm_2bt_max128b},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1359,20 +1369,40 @@ const upb_MiniTable google_protobuf_FieldOptions_msg_init = {
})
};
static const upb_MiniTableSub google_protobuf_OneofOptions_submsgs[1] = {
static const upb_MiniTableField google_protobuf_FieldOptions_EditionDefault__fields[2] = {
{1, UPB_SIZE(4, 8), 1, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{2, UPB_SIZE(12, 24), 2, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
};
const upb_MiniTable google_protobuf_FieldOptions_EditionDefault_msg_init = {
NULL,
&google_protobuf_FieldOptions_EditionDefault__fields[0],
UPB_SIZE(24, 40), 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(24), 0,
UPB_FASTTABLE_INIT({
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x000800000100000a, &upb_pss_1bt},
{0x0018000002000012, &upb_pss_1bt},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
})
};
static const upb_MiniTableSub google_protobuf_OneofOptions_submsgs[2] = {
{.submsg = &google_protobuf_FeatureSet_msg_init},
{.submsg = &google_protobuf_UninterpretedOption_msg_init},
};
static const upb_MiniTableField google_protobuf_OneofOptions__fields[1] = {
{999, 0, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
static const upb_MiniTableField google_protobuf_OneofOptions__fields[2] = {
{1, UPB_SIZE(4, 8), 1, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(8, 16), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
};
const upb_MiniTable google_protobuf_OneofOptions_msg_init = {
&google_protobuf_OneofOptions_submsgs[0],
&google_protobuf_OneofOptions__fields[0],
8, 1, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(248), 0,
UPB_SIZE(16, 24), 2, kUpb_ExtMode_Extendable, 1, UPB_FASTTABLE_MASK(248), 0,
UPB_FASTTABLE_INIT({
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x000800000100000a, &upb_psm_1bt_max64b},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1394,8 +1424,7 @@ const upb_MiniTable google_protobuf_OneofOptions_msg_init = {
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x000000003f003eba, &upb_prm_2bt_max128b},
{0x001000003f013eba, &upb_prm_2bt_max128b},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1407,21 +1436,23 @@ const upb_MiniTable google_protobuf_OneofOptions_msg_init = {
})
};
static const upb_MiniTableSub google_protobuf_EnumOptions_submsgs[1] = {
static const upb_MiniTableSub google_protobuf_EnumOptions_submsgs[2] = {
{.submsg = &google_protobuf_FeatureSet_msg_init},
{.submsg = &google_protobuf_UninterpretedOption_msg_init},
};
static const upb_MiniTableField google_protobuf_EnumOptions__fields[4] = {
static const upb_MiniTableField google_protobuf_EnumOptions__fields[5] = {
{2, 1, 1, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{3, 2, 2, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{6, 3, 3, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(4, 8), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{7, UPB_SIZE(4, 8), 4, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(8, 16), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
};
const upb_MiniTable google_protobuf_EnumOptions_msg_init = {
&google_protobuf_EnumOptions_submsgs[0],
&google_protobuf_EnumOptions__fields[0],
UPB_SIZE(8, 16), 4, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(248), 0,
UPB_SIZE(16, 24), 5, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(248), 0,
UPB_FASTTABLE_INIT({
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1430,6 +1461,7 @@ const upb_MiniTable google_protobuf_EnumOptions_msg_init = {
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0003000003000030, &upb_psb1_1bt},
{0x000800000400003a, &upb_psm_1bt_max64b},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1445,8 +1477,7 @@ const upb_MiniTable google_protobuf_EnumOptions_msg_init = {
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x000800003f003eba, &upb_prm_2bt_max128b},
{0x001000003f013eba, &upb_prm_2bt_max128b},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1458,25 +1489,27 @@ const upb_MiniTable google_protobuf_EnumOptions_msg_init = {
})
};
static const upb_MiniTableSub google_protobuf_EnumValueOptions_submsgs[1] = {
static const upb_MiniTableSub google_protobuf_EnumValueOptions_submsgs[2] = {
{.submsg = &google_protobuf_FeatureSet_msg_init},
{.submsg = &google_protobuf_UninterpretedOption_msg_init},
};
static const upb_MiniTableField google_protobuf_EnumValueOptions__fields[3] = {
static const upb_MiniTableField google_protobuf_EnumValueOptions__fields[4] = {
{1, 1, 1, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{3, 2, 2, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(4, 8), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{2, UPB_SIZE(4, 8), 2, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{3, UPB_SIZE(8, 2), 3, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(12, 16), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
};
const upb_MiniTable google_protobuf_EnumValueOptions_msg_init = {
&google_protobuf_EnumValueOptions_submsgs[0],
&google_protobuf_EnumValueOptions__fields[0],
UPB_SIZE(8, 16), 3, kUpb_ExtMode_Extendable, 1, UPB_FASTTABLE_MASK(248), 0,
UPB_SIZE(16, 24), 4, kUpb_ExtMode_Extendable, 3, UPB_FASTTABLE_MASK(248), 0,
UPB_FASTTABLE_INIT({
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0001000001000008, &upb_psb1_1bt},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0002000002000018, &upb_psb1_1bt},
{0x0008000002000012, &upb_psm_1bt_max64b},
{0x0002000003000018, &upb_psb1_1bt},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1496,7 +1529,7 @@ const upb_MiniTable google_protobuf_EnumValueOptions_msg_init = {
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x000800003f003eba, &upb_prm_2bt_max128b},
{0x001000003f013eba, &upb_prm_2bt_max128b},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1508,19 +1541,21 @@ const upb_MiniTable google_protobuf_EnumValueOptions_msg_init = {
})
};
static const upb_MiniTableSub google_protobuf_ServiceOptions_submsgs[1] = {
static const upb_MiniTableSub google_protobuf_ServiceOptions_submsgs[2] = {
{.submsg = &google_protobuf_FeatureSet_msg_init},
{.submsg = &google_protobuf_UninterpretedOption_msg_init},
};
static const upb_MiniTableField google_protobuf_ServiceOptions__fields[2] = {
static const upb_MiniTableField google_protobuf_ServiceOptions__fields[3] = {
{33, 1, 1, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(4, 8), 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{34, UPB_SIZE(4, 8), 2, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(8, 16), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
};
const upb_MiniTable google_protobuf_ServiceOptions_msg_init = {
&google_protobuf_ServiceOptions_submsgs[0],
&google_protobuf_ServiceOptions__fields[0],
UPB_SIZE(8, 16), 2, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(248), 0,
UPB_SIZE(16, 24), 3, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(248), 0,
UPB_FASTTABLE_INIT({
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1540,12 +1575,12 @@ const upb_MiniTable google_protobuf_ServiceOptions_msg_init = {
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0001000001000288, &upb_psb1_2bt},
{0x0008000002000292, &upb_psm_2bt_max64b},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x000800003f003eba, &upb_prm_2bt_max128b},
{0x001000003f013eba, &upb_prm_2bt_max128b},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1557,21 +1592,23 @@ const upb_MiniTable google_protobuf_ServiceOptions_msg_init = {
})
};
static const upb_MiniTableSub google_protobuf_MethodOptions_submsgs[2] = {
static const upb_MiniTableSub google_protobuf_MethodOptions_submsgs[3] = {
{.submsg = &google_protobuf_FeatureSet_msg_init},
{.submsg = &google_protobuf_UninterpretedOption_msg_init},
{.subenum = &google_protobuf_MethodOptions_IdempotencyLevel_enum_init},
};
static const upb_MiniTableField google_protobuf_MethodOptions__fields[3] = {
static const upb_MiniTableField google_protobuf_MethodOptions__fields[4] = {
{33, 1, 1, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{34, 4, 2, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{999, 8, 0, 0, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{34, 4, 2, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{35, 8, 3, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(12, 16), 0, 1, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
};
const upb_MiniTable google_protobuf_MethodOptions_msg_init = {
&google_protobuf_MethodOptions_submsgs[0],
&google_protobuf_MethodOptions__fields[0],
16, 3, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(248), 0,
UPB_SIZE(16, 24), 4, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(248), 0,
UPB_FASTTABLE_INIT({
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1592,11 +1629,11 @@ const upb_MiniTable google_protobuf_MethodOptions_msg_init = {
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0001000001000288, &upb_psb1_2bt},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x000800000300029a, &upb_psm_2bt_max64b},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x000800003f003eba, &upb_prm_2bt_max128b},
{0x001000003f013eba, &upb_prm_2bt_max128b},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@ -1663,6 +1700,30 @@ const upb_MiniTable google_protobuf_UninterpretedOption_NamePart_msg_init = {
})
};
static const upb_MiniTableSub google_protobuf_FeatureSet_submsgs[6] = {
{.subenum = &google_protobuf_FeatureSet_FieldPresence_enum_init},
{.subenum = &google_protobuf_FeatureSet_EnumType_enum_init},
{.subenum = &google_protobuf_FeatureSet_RepeatedFieldEncoding_enum_init},
{.subenum = &google_protobuf_FeatureSet_StringFieldValidation_enum_init},
{.subenum = &google_protobuf_FeatureSet_MessageEncoding_enum_init},
{.subenum = &google_protobuf_FeatureSet_JsonFormat_enum_init},
};
static const upb_MiniTableField google_protobuf_FeatureSet__fields[6] = {
{1, 4, 1, 0, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{2, 8, 2, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{3, 12, 3, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{4, 16, 4, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{5, 20, 5, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{6, 24, 6, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
};
const upb_MiniTable google_protobuf_FeatureSet_msg_init = {
&google_protobuf_FeatureSet_submsgs[0],
&google_protobuf_FeatureSet__fields[0],
32, 6, kUpb_ExtMode_Extendable, 6, UPB_FASTTABLE_MASK(255), 0,
};
static const upb_MiniTableSub google_protobuf_SourceCodeInfo_submsgs[1] = {
{.submsg = &google_protobuf_SourceCodeInfo_Location_msg_init},
};
@ -1751,7 +1812,7 @@ const upb_MiniTable google_protobuf_GeneratedCodeInfo_Annotation_msg_init = {
})
};
static const upb_MiniTable *messages_layout[28] = {
static const upb_MiniTable *messages_layout[30] = {
&google_protobuf_FileDescriptorSet_msg_init,
&google_protobuf_FileDescriptorProto_msg_init,
&google_protobuf_DescriptorProto_msg_init,
@ -1769,6 +1830,7 @@ static const upb_MiniTable *messages_layout[28] = {
&google_protobuf_FileOptions_msg_init,
&google_protobuf_MessageOptions_msg_init,
&google_protobuf_FieldOptions_msg_init,
&google_protobuf_FieldOptions_EditionDefault_msg_init,
&google_protobuf_OneofOptions_msg_init,
&google_protobuf_EnumOptions_msg_init,
&google_protobuf_EnumValueOptions_msg_init,
@ -1776,6 +1838,7 @@ static const upb_MiniTable *messages_layout[28] = {
&google_protobuf_MethodOptions_msg_init,
&google_protobuf_UninterpretedOption_msg_init,
&google_protobuf_UninterpretedOption_NamePart_msg_init,
&google_protobuf_FeatureSet_msg_init,
&google_protobuf_SourceCodeInfo_msg_init,
&google_protobuf_SourceCodeInfo_Location_msg_init,
&google_protobuf_GeneratedCodeInfo_msg_init,
@ -1791,6 +1854,60 @@ const upb_MiniTableEnum google_protobuf_ExtensionRangeOptions_VerificationState_
},
};
const upb_MiniTableEnum google_protobuf_FeatureSet_EnumType_enum_init = {
64,
0,
{
0x7,
0x0,
},
};
const upb_MiniTableEnum google_protobuf_FeatureSet_FieldPresence_enum_init = {
64,
0,
{
0xf,
0x0,
},
};
const upb_MiniTableEnum google_protobuf_FeatureSet_JsonFormat_enum_init = {
64,
0,
{
0x7,
0x0,
},
};
const upb_MiniTableEnum google_protobuf_FeatureSet_MessageEncoding_enum_init = {
64,
0,
{
0x7,
0x0,
},
};
const upb_MiniTableEnum google_protobuf_FeatureSet_RepeatedFieldEncoding_enum_init = {
64,
0,
{
0x7,
0x0,
},
};
const upb_MiniTableEnum google_protobuf_FeatureSet_StringFieldValidation_enum_init = {
64,
0,
{
0xf,
0x0,
},
};
const upb_MiniTableEnum google_protobuf_FieldDescriptorProto_Label_enum_init = {
64,
0,
@ -1872,8 +1989,14 @@ const upb_MiniTableEnum google_protobuf_MethodOptions_IdempotencyLevel_enum_init
},
};
static const upb_MiniTableEnum *enums_layout[10] = {
static const upb_MiniTableEnum *enums_layout[16] = {
&google_protobuf_ExtensionRangeOptions_VerificationState_enum_init,
&google_protobuf_FeatureSet_EnumType_enum_init,
&google_protobuf_FeatureSet_FieldPresence_enum_init,
&google_protobuf_FeatureSet_JsonFormat_enum_init,
&google_protobuf_FeatureSet_MessageEncoding_enum_init,
&google_protobuf_FeatureSet_RepeatedFieldEncoding_enum_init,
&google_protobuf_FeatureSet_StringFieldValidation_enum_init,
&google_protobuf_FieldDescriptorProto_Label_enum_init,
&google_protobuf_FieldDescriptorProto_Type_enum_init,
&google_protobuf_FieldOptions_CType_enum_init,
@ -1889,8 +2012,8 @@ const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout = {
messages_layout,
enums_layout,
NULL,
28,
10,
30,
16,
0,
};

File diff suppressed because it is too large Load Diff

View File

@ -109,6 +109,7 @@ WELL_KNOWN_TYPES = [
proto_library(
name = "wkt_proto",
strip_import_prefix = "/src",
visibility = ["//visibility:private"],
deps = [wkt + "_proto" for wkt in WELL_KNOWN_TYPES],
)
@ -177,6 +178,14 @@ proto_library(
],
)
proto_library(
name = "cpp_features_proto",
srcs = ["cpp_features.proto"],
strip_import_prefix = "/src",
visibility = ["//:__subpackages__"],
deps = [":descriptor_proto"],
)
################################################################################
# C++ Runtime Library
################################################################################
@ -419,11 +428,13 @@ cc_library(
name = "protobuf_nowkt",
srcs = [
"any.cc",
"cpp_features.pb.cc",
"descriptor.cc",
"descriptor.pb.cc",
"descriptor_database.cc",
"dynamic_message.cc",
"extension_set_heavy.cc",
"feature_resolver.cc",
"generated_message_bases.cc",
"generated_message_reflection.cc",
"generated_message_tctable_full.cc",
@ -439,12 +450,14 @@ cc_library(
"wire_format.cc",
],
hdrs = [
"cpp_features.pb.h",
"descriptor.h",
"descriptor.pb.h",
"descriptor_database.h",
"descriptor_legacy.h",
"descriptor_visitor.h",
"dynamic_message.h",
"feature_resolver.h",
"field_access_listener.h",
"generated_enum_reflection.h",
"generated_message_bases.h",
@ -574,6 +587,12 @@ filegroup(
visibility = ["//:__subpackages__"],
)
filegroup(
name = "cpp_features_proto_srcs",
srcs = ["cpp_features.proto"],
visibility = ["//src/google/protobuf/compiler/cpp:__pkg__"],
)
filegroup(
name = "testdata",
srcs = glob(["testdata/**/*"]) + [
@ -630,8 +649,10 @@ filegroup(
"unittest_embed_optimize_for.proto",
"unittest_empty.proto",
"unittest_enormous_descriptor.proto",
"unittest_features.proto",
"unittest_import.proto",
"unittest_import_public.proto",
"unittest_invalid_features.proto",
"unittest_lazy_dependencies.proto",
"unittest_lazy_dependencies_custom_option.proto",
"unittest_lazy_dependencies_enum.proto",
@ -793,6 +814,16 @@ filegroup(
visibility = ["//src/google/protobuf/compiler/cpp:__pkg__"],
)
filegroup(
name = "cpp_features_cc_srcs",
testonly = 1,
data = [
"cpp_features.pb.cc",
"cpp_features.pb.h",
],
visibility = ["//src/google/protobuf/compiler/cpp:__pkg__"],
)
cc_library(
name = "lite_test_util",
testonly = 1,
@ -981,7 +1012,10 @@ cc_library(
testonly = True,
hdrs = ["test_textproto.h"],
strip_include_prefix = "/src",
visibility = ["//pkg:__pkg__"],
visibility = [
"//pkg:__pkg__",
"//src/google/protobuf:__subpackages__",
],
deps = [
":protobuf",
"@com_google_absl//absl/log:absl_check",
@ -1044,6 +1078,23 @@ cc_test(
],
)
cc_test(
name = "feature_resolver_test",
srcs = ["feature_resolver_test.cc"],
copts = COPTS,
deps = [
":cc_test_protos",
":protobuf",
":test_textproto",
":test_util",
"//src/google/protobuf/compiler:importer",
"//src/google/protobuf/stubs",
"//src/google/protobuf/testing",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "generated_message_reflection_unittest",
srcs = ["generated_message_reflection_unittest.cc"],

View File

@ -8,4 +8,4 @@ proto_library(
name = "message_set_proto",
srcs = ["message_set.proto"],
strip_import_prefix = "/src",
)
)

View File

@ -294,8 +294,8 @@ cc_library(
copts = COPTS,
strip_include_prefix = "/src",
visibility = [
"//pkg:__pkg__",
"//src/google/protobuf/compiler:__subpackages__",
"//pkg:__pkg__",
"//src/google/protobuf/compiler:__subpackages__",
],
deps = [
":code_generator",

View File

@ -39,9 +39,12 @@ namespace compiler {
// NOTE: These files have early default access to go/editions. The protoc flag
// `--experimental_editions` can also be used to enable editions.
static constexpr auto kEarlyEditionsFile = internal::MakeAllowlist({
static constexpr auto kEarlyEditionsFile = internal::MakeAllowlist(
{
// Intentionally left blank.
});
"google/protobuf/editions/",
},
internal::AllowlistFlags::kMatchPrefix);
bool IsEarlyEditionsFile(absl::string_view file) {
return kEarlyEditionsFile.Allows(file);

View File

@ -126,6 +126,24 @@ class PROTOC_EXPORT CodeGenerator {
// method can be removed.
virtual bool HasGenerateAll() const { return true; }
#ifdef PROTOBUF_FUTURE_EDITIONS
protected:
// Retrieves the resolved source features for a given descriptor. These
// should be used to make any feature-based decisions during code generation.
template <typename DescriptorT>
static const FeatureSet& GetSourceFeatures(const DescriptorT& desc) {
return ::google::protobuf::internal::InternalFeatureHelper::GetFeatures(desc);
}
// Retrieves the raw source features for a given descriptor. These should be
// used to validate the original .proto file and make any decisions about it
// during code generation.
template <typename DescriptorT>
static const FeatureSet& GetSourceRawFeatures(const DescriptorT& desc) {
return ::google::protobuf::internal::InternalFeatureHelper::GetRawFeatures(desc);
}
#endif // PROTOBUF_FUTURE_EDITIONS
};
// CodeGenerators generate one or more files in a given directory. This

View File

@ -1551,6 +1551,21 @@ bool CommandLineInterface::ParseInputFiles(
}
parsed_files->push_back(parsed_file);
#ifdef PROTOBUF_FUTURE_EDITIONS
if (!experimental_editions_ && !IsEarlyEditionsFile(parsed_file->name())) {
if (FileDescriptorLegacy(parsed_file).syntax() ==
FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS) {
std::cerr
<< parsed_file->name()
<< ": This file uses editions, but --experimental_editions has not "
"been enabled. This syntax is experimental and should be "
"avoided."
<< std::endl;
result = false;
break;
}
}
#endif // PROTOBUF_FUTURE_EDITIONS
// Enforce --disallow_services.
if (disallow_services_ && parsed_file->service_count() > 0) {
@ -1601,6 +1616,9 @@ void CommandLineInterface::Clear() {
descriptor_set_out_name_.clear();
dependency_out_name_.clear();
#ifdef PROTOBUF_FUTURE_EDITIONS
experimental_editions_ = false;
#endif // PROTOBUF_FUTURE_EDITIONS
mode_ = MODE_COMPILE;
print_mode_ = PRINT_NONE;
@ -1919,6 +1937,9 @@ bool CommandLineInterface::ParseArgument(const char* arg, std::string* name,
*name == "--include_imports" || *name == "--include_source_info" ||
*name == "--retain_options" || *name == "--version" ||
*name == "--decode_raw" ||
#ifdef PROTOBUF_FUTURE_EDITIONS
*name == "--experimental_editions" ||
#endif // PROTOBUF_FUTURE_EDITIONS
*name == "--print_free_field_numbers" ||
*name == "--experimental_allow_proto3_optional" ||
*name == "--deterministic_output" || *name == "--fatal_warnings") {
@ -2245,6 +2266,14 @@ CommandLineInterface::InterpretArgument(const std::string& name,
#else
::setenv(io::Printer::kProtocCodegenTrace.data(), "yes", 0);
#endif
#ifdef PROTOBUF_FUTURE_EDITIONS
} else if (name == "--experimental_editions") {
// If you're reading this, you're probably wondering what
// --experimental_editions is for and thinking of turning it on. This is an
// experimental, undocumented, unsupported flag. Enable it at your own risk
// (or, just don't!).
experimental_editions_ = true;
#endif // PROTOBUF_FUTURE_EDITIONS
} else {
// Some other flag. Look it up in the generators list.
const GeneratorInfo* generator_info = FindGeneratorByFlag(name);

View File

@ -428,6 +428,9 @@ class PROTOC_EXPORT CommandLineInterface {
// dependency file will be written. Otherwise, empty.
std::string dependency_out_name_;
#ifdef PROTOBUF_FUTURE_EDITIONS
bool experimental_editions_ = false;
#endif // PROTOBUF_FUTURE_EDITIONS
// True if --include_imports was given, meaning that we should
// write all transitive dependencies to the DescriptorSet. Otherwise, only

View File

@ -1344,6 +1344,145 @@ TEST_F(CommandLineInterfaceTest, AllowServicesHasService) {
ExpectGenerated("test_generator", "", "foo.proto", "Foo");
}
#ifdef PROTOBUF_FUTURE_EDITIONS
TEST_F(CommandLineInterfaceTest, EditionsAreNotAllowed) {
CreateTempFile("foo.proto",
"edition = \"very-cool\";\n"
"message FooRequest {}\n");
Run("protocol_compiler --proto_path=$tmpdir --test_out=$tmpdir foo.proto");
ExpectErrorSubstring(
"This file uses editions, but --experimental_editions has not been "
"enabled.");
}
TEST_F(CommandLineInterfaceTest, EditionsFlagExplicitTrue) {
CreateTempFile("foo.proto",
"edition = \"very-cool\";\n"
"message FooRequest {}\n");
Run("protocol_compiler --proto_path=$tmpdir --test_out=$tmpdir "
"--experimental_editions foo.proto");
ExpectNoErrors();
}
TEST_F(CommandLineInterfaceTest, FeaturesEditionZero) {
CreateTempFile("foo.proto",
R"schema(
edition = "2023";
option features.field_presence = IMPLICIT;
message Foo {
int32 bar = 1 [default = 5, features.field_presence = EXPLICIT];
int32 baz = 2;
})schema");
Run("protocol_compiler --proto_path=$tmpdir --test_out=$tmpdir "
"--experimental_editions foo.proto");
ExpectNoErrors();
}
TEST_F(CommandLineInterfaceTest, FeatureExtensions) {
CreateTempFile("net/proto2/proto/descriptor.proto",
google::protobuf::DescriptorProto::descriptor()->file()->DebugString());
CreateTempFile("features.proto",
R"schema(
syntax = "proto2";
package pb;
import "net/proto2/proto/descriptor.proto";
extend google.protobuf.FeatureSet {
optional TestFeatures test = 9999;
}
message TestFeatures {
optional int32 int_feature = 1 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2023", value: "3" }
];
})schema");
CreateTempFile("foo.proto",
R"schema(
edition = "2023";
import "features.proto";
message Foo {
int32 bar = 1;
int32 baz = 2 [features.(pb.test).int_feature = 5];
})schema");
Run("protocol_compiler --proto_path=$tmpdir --test_out=$tmpdir "
"--experimental_editions foo.proto");
ExpectNoErrors();
}
TEST_F(CommandLineInterfaceTest, FeatureValidationError) {
CreateTempFile("foo.proto",
R"schema(
edition = "2023";
option features.field_presence = IMPLICIT;
message Foo {
int32 bar = 1 [default = 5, features.field_presence = FIELD_PRESENCE_UNKNOWN];
int32 baz = 2;
})schema");
Run("protocol_compiler --proto_path=$tmpdir --test_out=$tmpdir "
"--experimental_editions foo.proto");
ExpectErrorSubstring(
"FeatureSet.field_presence must resolve to a known value, found "
"FIELD_PRESENCE_UNKNOWN");
}
TEST_F(CommandLineInterfaceTest, FeatureTargetError) {
CreateTempFile("foo.proto",
R"schema(
edition = "2023";
message Foo {
option features.field_presence = IMPLICIT;
int32 bar = 1 [default = 5, features.field_presence = EXPLICIT];
int32 baz = 2;
})schema");
Run("protocol_compiler --proto_path=$tmpdir --test_out=$tmpdir "
"--experimental_editions foo.proto");
ExpectErrorSubstring(
"FeatureSet.field_presence cannot be set on an entity of type `message`");
}
TEST_F(CommandLineInterfaceTest, FeatureExtensionError) {
CreateTempFile("net/proto2/proto/descriptor.proto",
google::protobuf::DescriptorProto::descriptor()->file()->DebugString());
CreateTempFile("features.proto",
R"schema(
syntax = "proto2";
package pb;
import "net/proto2/proto/descriptor.proto";
extend google.protobuf.FeatureSet {
optional TestFeatures test = 9999;
}
message TestFeatures {
repeated int32 repeated_feature = 1 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2023", value: "3" }
];
})schema");
CreateTempFile("foo.proto",
R"schema(
edition = "2023";
import "features.proto";
message Foo {
int32 bar = 1;
int32 baz = 2 [features.(pb.test).int_feature = 5];
})schema");
Run("protocol_compiler --proto_path=$tmpdir --test_out=$tmpdir "
"--experimental_editions foo.proto");
ExpectErrorSubstring(
"Feature field pb.TestFeatures.repeated_feature is an unsupported "
"repeated field");
}
#endif // PROTOBUF_FUTURE_EDITIONS
TEST_F(CommandLineInterfaceTest, DirectDependencies_Missing_EmptyList) {

View File

@ -166,6 +166,8 @@ cc_test(
srcs = ["bootstrap_unittest.cc"],
data = [
"//:well_known_type_protos",
"//src/google/protobuf:cpp_features_cc_srcs",
"//src/google/protobuf:cpp_features_proto_srcs",
"//src/google/protobuf:descriptor_cc_srcs",
"//src/google/protobuf:descriptor_proto_srcs",
"//src/google/protobuf:testdata",

View File

@ -129,11 +129,13 @@ class MockGeneratorContext : public GeneratorContext {
};
const char kDescriptorParameter[] = "dllexport_decl=PROTOBUF_EXPORT";
const char kCppFeaturesParameter[] = "dllexport_decl=PROTOBUF_EXPORT";
const char kPluginParameter[] = "dllexport_decl=PROTOC_EXPORT";
const char* test_protos[][2] = {
{"google/protobuf/descriptor", kDescriptorParameter},
{"google/protobuf/cpp_features", kCppFeaturesParameter},
{"google/protobuf/compiler/plugin", kPluginParameter},
};

View File

@ -49,6 +49,9 @@
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/descriptor_visitor.h"
#ifdef PROTOBUF_FUTURE_EDITIONS
#include "google/protobuf/cpp_features.pb.h"
#endif // PROTOBUF_FUTURE_EDITIONS
namespace google {
namespace protobuf {
@ -364,6 +367,25 @@ bool CppGenerator::Generate(const FileDescriptor* file,
absl::Status CppGenerator::ValidateFeatures(const FileDescriptor* file) const {
absl::Status status = absl::OkStatus();
#ifdef PROTOBUF_FUTURE_EDITIONS
google::protobuf::internal::VisitDescriptors(*file, [&](const FieldDescriptor& field) {
const FeatureSet& source_features = GetSourceFeatures(field);
const FeatureSet& raw_features = GetSourceRawFeatures(field);
if (raw_features.GetExtension(::pb::cpp).has_legacy_closed_enum() &&
field.cpp_type() != FieldDescriptor::CPPTYPE_ENUM) {
status = absl::FailedPreconditionError(absl::StrCat(
"Field ", field.full_name(),
" specifies the legacy_closed_enum feature but has non-enum type."));
}
if (field.enum_type() != nullptr &&
source_features.GetExtension(::pb::cpp).legacy_closed_enum() &&
source_features.field_presence() == FeatureSet::IMPLICIT) {
status = absl::FailedPreconditionError(
absl::StrCat("Field ", field.full_name(),
" has a closed enum type with implicit presence."));
}
});
#endif // PROTOBUF_FUTURE_EDITIONS
return status;
}

View File

@ -35,6 +35,9 @@
#include "google/protobuf/descriptor.pb.h"
#include <gtest/gtest.h>
#include "google/protobuf/compiler/command_line_interface_tester.h"
#ifdef PROTOBUF_FUTURE_EDITIONS
#include "google/protobuf/cpp_features.pb.h"
#endif // PROTOBUF_FUTURE_EDITIONS
namespace google {
namespace protobuf {
@ -52,6 +55,10 @@ class CppGeneratorTest : public CommandLineInterfaceTester {
CreateTempFile(
"google/protobuf/descriptor.proto",
google::protobuf::DescriptorProto::descriptor()->file()->DebugString());
#ifdef PROTOBUF_FUTURE_EDITIONS
CreateTempFile("third_party/protobuf/cpp_features.proto",
pb::CppFeatures::descriptor()->file()->DebugString());
#endif // PROTOBUF_FUTURE_EDITIONS
}
};
@ -84,6 +91,92 @@ TEST_F(CppGeneratorTest, BasicError) {
"foo.proto:4:7: Expected \"required\", \"optional\", or \"repeated\"");
}
#ifdef PROTOBUF_FUTURE_EDITIONS
TEST_F(CppGeneratorTest, LegacyClosedEnumOnNonEnumField) {
CreateTempFile("foo.proto",
R"schema(
edition = "2023";
import "third_party/protobuf/cpp_features.proto";
message Foo {
int32 bar = 1 [features.(pb.cpp).legacy_closed_enum = true];
})schema");
RunProtoc(
"protocol_compiler --proto_path=$tmpdir --cpp_out=$tmpdir "
"--experimental_editions foo.proto");
ExpectErrorSubstring(
"Field Foo.bar specifies the legacy_closed_enum feature but has non-enum "
"type.");
}
TEST_F(CppGeneratorTest, LegacyClosedEnum) {
CreateTempFile("foo.proto",
R"schema(
edition = "2023";
import "third_party/protobuf/cpp_features.proto";
enum TestEnum {
TEST_ENUM_UNKNOWN = 0;
}
message Foo {
TestEnum bar = 1 [features.(pb.cpp).legacy_closed_enum = true];
})schema");
RunProtoc(
"protocol_compiler --proto_path=$tmpdir --cpp_out=$tmpdir "
"--experimental_editions foo.proto");
ExpectNoErrors();
}
TEST_F(CppGeneratorTest, LegacyClosedEnumInherited) {
CreateTempFile("foo.proto",
R"schema(
edition = "2023";
import "third_party/protobuf/cpp_features.proto";
option features.(pb.cpp).legacy_closed_enum = true;
enum TestEnum {
TEST_ENUM_UNKNOWN = 0;
}
message Foo {
TestEnum bar = 1;
int32 baz = 2;
})schema");
RunProtoc(
"protocol_compiler --proto_path=$tmpdir --cpp_out=$tmpdir "
"--experimental_editions foo.proto");
ExpectNoErrors();
}
TEST_F(CppGeneratorTest, LegacyClosedEnumImplicit) {
CreateTempFile("foo.proto",
R"schema(
edition = "2023";
import "third_party/protobuf/cpp_features.proto";
option features.(pb.cpp).legacy_closed_enum = true;
enum TestEnum {
TEST_ENUM_UNKNOWN = 0;
}
message Foo {
TestEnum bar = 1 [features.field_presence = IMPLICIT];
int32 baz = 2;
})schema");
RunProtoc(
"protocol_compiler --proto_path=$tmpdir --cpp_out=$tmpdir "
"--experimental_editions foo.proto");
ExpectErrorSubstring(
"Field Foo.bar has a closed enum type with implicit presence.");
}
#endif // PROTOBUF_FUTURE_EDITIONS
} // namespace
} // namespace cpp

View File

@ -1400,6 +1400,10 @@ bool GetBootstrapBasename(const Options& options, absl::string_view basename,
new absl::flat_hash_map<absl::string_view, std::string>{
{"net/proto2/proto/descriptor",
"third_party/protobuf/descriptor"},
#ifdef PROTOBUF_FUTURE_EDITIONS
{"third_party/protobuf/cpp_features",
"third_party/protobuf/cpp_features"},
#endif // PROTOBUF_FUTURE_EDITIONS
{"third_party/protobuf/compiler/plugin",
"third_party/protobuf/compiler/plugin"},
{"net/proto2/compiler/proto/profile",

View File

@ -700,6 +700,11 @@ void FileGenerator::EmitFileDescription(io::Printer* p) const {
case FileDescriptorLegacy::Syntax::SYNTAX_PROTO3:
syntax = "GPBFileSyntaxProto3";
break;
#ifdef PROTOBUF_FUTURE_EDITIONS
case FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS:
syntax = "GPBFileSyntaxProtoEditions";
break;
#endif // PROTOBUF_FUTURE_EDITIONS
}
p->Emit({{"file_description_name", file_description_name_},

View File

@ -662,6 +662,9 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
DescriptorPool::ErrorCollector::OTHER);
if (require_syntax_identifier_ || LookingAt("syntax")
#ifdef PROTOBUF_FUTURE_EDITIONS
|| LookingAt("edition")
#endif // PROTOBUF_FUTURE_EDITIONS
) {
if (!ParseSyntaxIdentifier(file, root_location)) {
// Don't attempt to parse the file if we didn't recognize the syntax
@ -671,6 +674,11 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
// Store the syntax into the file.
if (file != nullptr) {
file->set_syntax(syntax_identifier_);
#ifdef PROTOBUF_FUTURE_EDITIONS
if (syntax_identifier_ == "editions") {
file->set_edition(edition_);
}
#endif // PROTOBUF_FUTURE_EDITIONS
}
} else if (!stop_after_syntax_identifier_) {
ABSL_LOG(WARNING) << "No syntax specified for the proto file: "
@ -710,9 +718,20 @@ bool Parser::ParseSyntaxIdentifier(const FileDescriptorProto* file,
const LocationRecorder& parent) {
LocationRecorder syntax_location(parent,
FileDescriptorProto::kSyntaxFieldNumber);
#ifdef PROTOBUF_FUTURE_EDITIONS
syntax_location.RecordLegacyLocation(
file, DescriptorPool::ErrorCollector::EDITIONS);
bool has_edition = false;
if (TryConsume("edition")) {
has_edition = true;
} else {
#endif // PROTOBUF_FUTURE_EDITIONS
DO(Consume("syntax",
"File must begin with a syntax statement, e.g. 'syntax = "
"\"proto2\";'."));
#ifdef PROTOBUF_FUTURE_EDITIONS
}
#endif // PROTOBUF_FUTURE_EDITIONS
DO(Consume("="));
io::Tokenizer::Token syntax_token = input_->current();
@ -720,6 +739,19 @@ bool Parser::ParseSyntaxIdentifier(const FileDescriptorProto* file,
DO(ConsumeString(&syntax, "Expected syntax identifier."));
DO(ConsumeEndOfDeclaration(";", &syntax_location));
#ifdef PROTOBUF_FUTURE_EDITIONS
(has_edition ? edition_ : syntax_identifier_) = syntax;
if (has_edition) {
if (syntax.empty()) {
RecordError(syntax_token.line, syntax_token.column,
"A file's edition must be a nonempty string.");
return false;
}
edition_ = syntax;
syntax_identifier_ = "editions";
return true;
}
#endif // PROTOBUF_FUTURE_EDITIONS
syntax_identifier_ = syntax;
if (syntax != "proto2" && syntax != "proto3" &&
!stop_after_syntax_identifier_) {
@ -2307,6 +2339,18 @@ bool Parser::ParseLabel(FieldDescriptorProto::Label* label,
!LookingAt("required")) {
return false;
}
#ifdef PROTOBUF_FUTURE_EDITIONS
if (LookingAt("optional") && syntax_identifier_ == "editions") {
RecordError(
"Label \"optional\" is not supported in editions. By default, all "
"singular fields have presence unless features.field_presence is set.");
}
if (LookingAt("required") && syntax_identifier_ == "editions") {
RecordError(
"Label \"required\" is not supported in editions, use "
"features.field_presence = LEGACY_REQUIRED.");
}
#endif // PROTOBUF_FUTURE_EDITIONS
LocationRecorder location(field_location,
FieldDescriptorProto::kLabelFieldNumber);
@ -2326,6 +2370,15 @@ bool Parser::ParseType(FieldDescriptorProto::Type* type,
const auto& type_names_table = GetTypeNameTable();
auto iter = type_names_table.find(input_->current().text);
if (iter != type_names_table.end()) {
#ifdef PROTOBUF_FUTURE_EDITIONS
if (syntax_identifier_ == "editions" &&
iter->second == FieldDescriptorProto::TYPE_GROUP) {
RecordError(
"Group syntax is no longer supported in editions. To get group "
"behavior you can specify features.message_encoding = DELIMITED on a "
"message field.");
}
#endif // PROTOBUF_FUTURE_EDITIONS
*type = iter->second;
input_->Next();
} else {

View File

@ -530,6 +530,9 @@ class PROTOBUF_EXPORT Parser {
// Whether fields without label default to optional fields.
bool DefaultToOptionalFields() const {
#ifdef PROTOBUF_FUTURE_EDITIONS
if (syntax_identifier_ == "editions") return true;
#endif // PROTOBUF_FUTURE_EDITIONS
return syntax_identifier_ == "proto3";
}
@ -545,6 +548,9 @@ class PROTOBUF_EXPORT Parser {
bool require_syntax_identifier_;
bool stop_after_syntax_identifier_;
std::string syntax_identifier_;
#ifdef PROTOBUF_FUTURE_EDITIONS
std::string edition_;
#endif // PROTOBUF_FUTURE_EDITIONS
// Leading doc comments for the next declaration. These are not complete
// yet; use ConsumeEndOfDeclaration() to get the complete comments.

View File

@ -3915,6 +3915,177 @@ TEST_F(SourceInfoTest, DocCommentsOneof) {
// ===================================================================
#ifdef PROTOBUF_FUTURE_EDITIONS
typedef ParserTest ParseEditionsTest;
TEST_F(ParseEditionsTest, Editions) {
ExpectParsesTo(
R"schema(
edition = "super-cool";
message A {
int32 b = 1;
})schema",
"message_type \t {"
" name: \"A\""
" field {"
" name: \"b\""
" number: 1"
" label: LABEL_OPTIONAL"
" type: TYPE_INT32"
" }"
"}"
"syntax: \"editions\""
"edition: \"super-cool\"\n");
}
TEST_F(ParseEditionsTest, ExtensionsParse) {
ExpectParsesTo(
R"schema(
edition = '2023';
message Foo {
extensions 100 to 199;
}
extend Foo { string foo = 101; })schema",
"message_type \t {"
" name: \"Foo\""
" extension_range {"
" start: 100"
" end: 200"
" }"
"}"
"extension {"
" name: \"foo\""
" extendee: \"Foo\""
" number: 101"
" label: LABEL_OPTIONAL"
" type: TYPE_STRING"
"}"
"syntax: \"editions\""
"edition: \"2023\"\n");
}
TEST_F(ParseEditionsTest, EmptyEdition) {
ExpectHasEarlyExitErrors(
R"schema(
edition = "";
message A {
optional int32 b = 1;
})schema",
"1:18: A file's edition must be a nonempty string.\n");
}
TEST_F(ParseEditionsTest, SyntaxEditions) {
ExpectHasEarlyExitErrors(
R"schema(
syntax = "editions";
message A {
optional int32 b = 1;
})schema",
"1:17: Unrecognized syntax identifier \"editions\". This parser only "
"recognizes \"proto2\" and \"proto3\".\n");
}
TEST_F(ParseEditionsTest, MixedSyntaxAndEdition) {
ExpectHasErrors(
R"schema(
syntax = "proto2";
edition = "super-cool";
message A {
optional int32 b = 1;
})schema",
"2:8: Expected top-level statement (e.g. \"message\").\n");
}
TEST_F(ParseEditionsTest, MixedEditionAndSyntax) {
ExpectHasErrors(
R"schema(
edition = "super-cool";
syntax = "proto2";
message A {
int32 b = 1;
})schema",
"2:8: Expected top-level statement (e.g. \"message\").\n");
}
TEST_F(ParseEditionsTest, OptionalKeywordBanned) {
ExpectHasErrors(
R"schema(
edition = "2023";
message A {
optional int32 b = 1;
})schema",
"3:10: Label \"optional\" is not supported in editions. By default, all "
"singular fields have presence unless features.field_presence is set.\n");
}
TEST_F(ParseEditionsTest, RequiredKeywordBanned) {
ExpectHasErrors(
R"schema(
edition = "2023";
message A {
required int32 b = 1;
})schema",
"3:10: Label \"required\" is not supported in editions, use "
"features.field_presence = LEGACY_REQUIRED.\n");
}
TEST_F(ParseEditionsTest, GroupsBanned) {
ExpectHasErrors(
R"schema(
edition = "2023";
message TestMessage {
group TestGroup = 1 {};
})schema",
"3:10: Group syntax is no longer supported in editions. To get group "
"behavior you can specify features.message_encoding = DELIMITED on a "
"message field.\n");
}
TEST_F(ParseEditionsTest, ValidationError) {
ExpectHasValidationErrors(
R"schema(
edition = "2023";
option features.field_presence = IMPLICIT;
option java_package = "blah";
message TestMessage {
string foo = 1 [default = "hello"];
})schema",
"5:17: Implicit presence fields can't specify defaults.\n");
}
TEST_F(ParseEditionsTest, InvalidMerge) {
ExpectHasValidationErrors(
R"schema(
edition = "2023";
option features.field_presence = IMPLICIT;
option java_package = "blah";
message TestMessage {
string foo = 1 [
default = "hello",
features.field_presence = FIELD_PRESENCE_UNKNOWN,
features.string_field_validation = STRING_FIELD_VALIDATION_UNKNOWN
];
})schema",
"5:17: Feature field google.protobuf.FeatureSet.field_presence must resolve to a "
"known value, found FIELD_PRESENCE_UNKNOWN\n");
}
TEST_F(ParseEditionsTest, FeaturesWithoutEditions) {
ExpectHasValidationErrors(
R"schema(
syntax = "proto3";
option features.field_presence = IMPLICIT;
message TestMessage {
string foo = 1 [
default = "hello",
features.field_presence = EXPLICIT
];
})schema",
"1:8: Features are only valid under editions.\n"
"4:17: Features are only valid under editions.\n");
}
#endif // PROTOBUF_FUTURE_EDITIONS
} // anonymous namespace

View File

@ -0,0 +1,306 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/cpp_features.proto
#include "google/protobuf/cpp_features.pb.h"
#include <algorithm>
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/extension_set.h"
#include "google/protobuf/wire_format_lite.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/generated_message_reflection.h"
#include "google/protobuf/reflection_ops.h"
#include "google/protobuf/wire_format.h"
#include "google/protobuf/generated_message_tctable_impl.h"
// @@protoc_insertion_point(includes)
// Must be included last.
#include "google/protobuf/port_def.inc"
PROTOBUF_PRAGMA_INIT_SEG
namespace _pb = ::google::protobuf;
namespace _pbi = ::google::protobuf::internal;
namespace _fl = ::google::protobuf::internal::field_layout;
namespace pb {
template <typename>
PROTOBUF_CONSTEXPR CppFeatures::CppFeatures(::_pbi::ConstantInitialized)
: _impl_{
/*decltype(_impl_._has_bits_)*/ {},
/*decltype(_impl_._cached_size_)*/ {},
/*decltype(_impl_.legacy_closed_enum_)*/ false,
} {}
struct CppFeaturesDefaultTypeInternal {
PROTOBUF_CONSTEXPR CppFeaturesDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {}
~CppFeaturesDefaultTypeInternal() {}
union {
CppFeatures _instance;
};
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CppFeaturesDefaultTypeInternal _CppFeatures_default_instance_;
} // namespace pb
static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fcpp_5ffeatures_2eproto[1];
static constexpr const ::_pb::EnumDescriptor**
file_level_enum_descriptors_google_2fprotobuf_2fcpp_5ffeatures_2eproto = nullptr;
static constexpr const ::_pb::ServiceDescriptor**
file_level_service_descriptors_google_2fprotobuf_2fcpp_5ffeatures_2eproto = nullptr;
const ::uint32_t TableStruct_google_2fprotobuf_2fcpp_5ffeatures_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(
protodesc_cold) = {
PROTOBUF_FIELD_OFFSET(::pb::CppFeatures, _impl_._has_bits_),
PROTOBUF_FIELD_OFFSET(::pb::CppFeatures, _internal_metadata_),
~0u, // no _extensions_
~0u, // no _oneof_case_
~0u, // no _weak_field_map_
~0u, // no _inlined_string_donated_
~0u, // no _split_
~0u, // no sizeof(Split)
PROTOBUF_FIELD_OFFSET(::pb::CppFeatures, _impl_.legacy_closed_enum_),
0,
};
static const ::_pbi::MigrationSchema
schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
{0, 9, -1, sizeof(::pb::CppFeatures)},
};
static const ::_pb::Message* const file_default_instances[] = {
&::pb::_CppFeatures_default_instance_._instance,
};
const char descriptor_table_protodef_google_2fprotobuf_2fcpp_5ffeatures_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
"\n\"google/protobuf/cpp_features.proto\022\002pb"
"\032 google/protobuf/descriptor.proto\"D\n\013Cp"
"pFeatures\0225\n\022legacy_closed_enum\030\001 \001(\010B\031\210"
"\001\001\230\001\004\230\001\001\242\001\r\n\0042023\022\005false::\n\003cpp\022\033.google"
".protobuf.FeatureSet\030\350\007 \001(\0132\017.pb.CppFeat"
"ures"
};
static const ::_pbi::DescriptorTable* const descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_deps[1] =
{
&::descriptor_table_google_2fprotobuf_2fdescriptor_2eproto,
};
static ::absl::once_flag descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_once;
const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto = {
false,
false,
204,
descriptor_table_protodef_google_2fprotobuf_2fcpp_5ffeatures_2eproto,
"google/protobuf/cpp_features.proto",
&descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_once,
descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_deps,
1,
1,
schemas,
file_default_instances,
TableStruct_google_2fprotobuf_2fcpp_5ffeatures_2eproto::offsets,
file_level_metadata_google_2fprotobuf_2fcpp_5ffeatures_2eproto,
file_level_enum_descriptors_google_2fprotobuf_2fcpp_5ffeatures_2eproto,
file_level_service_descriptors_google_2fprotobuf_2fcpp_5ffeatures_2eproto,
};
// This function exists to be marked as weak.
// It can significantly speed up compilation by breaking up LLVM's SCC
// in the .pb.cc translation units. Large translation units see a
// reduction of more than 35% of walltime for optimized builds. Without
// the weak attribute all the messages in the file, including all the
// vtables and everything they use become part of the same SCC through
// a cycle like:
// GetMetadata -> descriptor table -> default instances ->
// vtables -> GetMetadata
// By adding a weak function here we break the connection from the
// individual vtables back into the descriptor table.
PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_getter() {
return &descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto;
}
namespace pb {
// ===================================================================
class CppFeatures::_Internal {
public:
using HasBits = decltype(std::declval<CppFeatures>()._impl_._has_bits_);
static constexpr ::int32_t kHasBitsOffset =
8 * PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_._has_bits_);
static void set_has_legacy_closed_enum(HasBits* has_bits) {
(*has_bits)[0] |= 1u;
}
};
CppFeatures::CppFeatures(::google::protobuf::Arena* arena)
: ::google::protobuf::Message(arena) {
SharedCtor(arena);
// @@protoc_insertion_point(arena_constructor:pb.CppFeatures)
}
CppFeatures::CppFeatures(const CppFeatures& from)
: ::google::protobuf::Message(), _impl_(from._impl_) {
_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
from._internal_metadata_);
// @@protoc_insertion_point(copy_constructor:pb.CppFeatures)
}
inline void CppFeatures::SharedCtor(::_pb::Arena* arena) {
(void)arena;
new (&_impl_) Impl_{
decltype(_impl_._has_bits_){},
/*decltype(_impl_._cached_size_)*/ {},
decltype(_impl_.legacy_closed_enum_){false},
};
}
CppFeatures::~CppFeatures() {
// @@protoc_insertion_point(destructor:pb.CppFeatures)
_internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
SharedDtor();
}
inline void CppFeatures::SharedDtor() {
ABSL_DCHECK(GetArenaForAllocation() == nullptr);
}
void CppFeatures::SetCachedSize(int size) const {
_impl_._cached_size_.Set(size);
}
PROTOBUF_NOINLINE void CppFeatures::Clear() {
// @@protoc_insertion_point(message_clear_start:pb.CppFeatures)
::uint32_t cached_has_bits = 0;
// Prevent compiler warnings about cached_has_bits being unused
(void) cached_has_bits;
_impl_.legacy_closed_enum_ = false;
_impl_._has_bits_.Clear();
_internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
}
const char* CppFeatures::_InternalParse(
const char* ptr, ::_pbi::ParseContext* ctx) {
ptr = ::_pbi::TcParser::ParseLoop(this, ptr, ctx, &_table_.header);
return ptr;
}
PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::_pbi::TcParseTable<0, 1, 0, 0, 2> CppFeatures::_table_ = {
{
PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_._has_bits_),
0, // no _extensions_
1, 0, // max_field_number, fast_idx_mask
offsetof(decltype(_table_), field_lookup_table),
4294967294, // skipmap
offsetof(decltype(_table_), field_entries),
1, // num_field_entries
0, // num_aux_entries
offsetof(decltype(_table_), field_names), // no aux_entries
&_CppFeatures_default_instance_._instance,
::_pbi::TcParser::GenericFallback, // fallback
}, {{
// optional bool legacy_closed_enum = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
{::_pbi::TcParser::SingularVarintNoZag1<bool, offsetof(CppFeatures, _impl_.legacy_closed_enum_), 0>(),
{8, 0, 0, PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_.legacy_closed_enum_)}},
}}, {{
65535, 65535
}}, {{
// optional bool legacy_closed_enum = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
{PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_.legacy_closed_enum_), _Internal::kHasBitsOffset + 0, 0,
(0 | ::_fl::kFcOptional | ::_fl::kBool)},
}},
// no aux_entries
{{
}},
};
::uint8_t* CppFeatures::_InternalSerialize(
::uint8_t* target,
::google::protobuf::io::EpsCopyOutputStream* stream) const {
// @@protoc_insertion_point(serialize_to_array_start:pb.CppFeatures)
::uint32_t cached_has_bits = 0;
(void)cached_has_bits;
cached_has_bits = _impl_._has_bits_[0];
// optional bool legacy_closed_enum = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
if (cached_has_bits & 0x00000001u) {
target = stream->EnsureSpace(target);
target = ::_pbi::WireFormatLite::WriteBoolToArray(
1, this->_internal_legacy_closed_enum(), target);
}
if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
target =
::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
_internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream);
}
// @@protoc_insertion_point(serialize_to_array_end:pb.CppFeatures)
return target;
}
::size_t CppFeatures::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:pb.CppFeatures)
::size_t total_size = 0;
::uint32_t cached_has_bits = 0;
// Prevent compiler warnings about cached_has_bits being unused
(void) cached_has_bits;
// optional bool legacy_closed_enum = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
cached_has_bits = _impl_._has_bits_[0];
if (cached_has_bits & 0x00000001u) {
total_size += 2;
}
return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}
const ::google::protobuf::Message::ClassData CppFeatures::_class_data_ = {
::google::protobuf::Message::CopyWithSourceCheck,
CppFeatures::MergeImpl
};
const ::google::protobuf::Message::ClassData*CppFeatures::GetClassData() const { return &_class_data_; }
void CppFeatures::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) {
auto* const _this = static_cast<CppFeatures*>(&to_msg);
auto& from = static_cast<const CppFeatures&>(from_msg);
// @@protoc_insertion_point(class_specific_merge_from_start:pb.CppFeatures)
ABSL_DCHECK_NE(&from, _this);
::uint32_t cached_has_bits = 0;
(void) cached_has_bits;
if ((from._impl_._has_bits_[0] & 0x00000001u) != 0) {
_this->_internal_set_legacy_closed_enum(from._internal_legacy_closed_enum());
}
_this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_);
}
void CppFeatures::CopyFrom(const CppFeatures& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:pb.CppFeatures)
if (&from == this) return;
Clear();
MergeFrom(from);
}
PROTOBUF_NOINLINE bool CppFeatures::IsInitialized() const {
return true;
}
void CppFeatures::InternalSwap(CppFeatures* other) {
using std::swap;
_internal_metadata_.InternalSwap(&other->_internal_metadata_);
swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
swap(_impl_.legacy_closed_enum_, other->_impl_.legacy_closed_enum_);
}
::google::protobuf::Metadata CppFeatures::GetMetadata() const {
return ::_pbi::AssignDescriptors(
&descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_once,
file_level_metadata_google_2fprotobuf_2fcpp_5ffeatures_2eproto[0]);
}
PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY2
::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::FeatureSet,
::google::protobuf::internal::MessageTypeTraits< ::pb::CppFeatures >, 11, false>
cpp(kCppFieldNumber);
// @@protoc_insertion_point(namespace_scope)
} // namespace pb
namespace google {
namespace protobuf {
template<> PROTOBUF_NOINLINE ::pb::CppFeatures*
Arena::CreateMaybeMessage< ::pb::CppFeatures >(Arena* arena) {
return Arena::CreateMessageInternal< ::pb::CppFeatures >(arena);
}
} // namespace protobuf
} // namespace google
// @@protoc_insertion_point(global_scope)
#include "google/protobuf/port_undef.inc"

View File

@ -0,0 +1,295 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/cpp_features.proto
#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcpp_5ffeatures_2eproto_2epb_2eh
#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcpp_5ffeatures_2eproto_2epb_2eh
#include <limits>
#include <string>
#include <type_traits>
#include "google/protobuf/port_def.inc"
#if PROTOBUF_VERSION < 4023000
#error "This file was generated by a newer version of protoc which is"
#error "incompatible with your Protocol Buffer headers. Please update"
#error "your headers."
#endif // PROTOBUF_VERSION
#if 4023000 < PROTOBUF_MIN_PROTOC_VERSION
#error "This file was generated by an older version of protoc which is"
#error "incompatible with your Protocol Buffer headers. Please"
#error "regenerate this file with a newer version of protoc."
#endif // PROTOBUF_MIN_PROTOC_VERSION
#include "google/protobuf/port_undef.inc"
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/arena.h"
#include "google/protobuf/arenastring.h"
#include "google/protobuf/generated_message_tctable_decl.h"
#include "google/protobuf/generated_message_util.h"
#include "google/protobuf/metadata_lite.h"
#include "google/protobuf/generated_message_reflection.h"
#include "google/protobuf/message.h"
#include "google/protobuf/repeated_field.h" // IWYU pragma: export
#include "google/protobuf/extension_set.h" // IWYU pragma: export
#include "google/protobuf/unknown_field_set.h"
#include "google/protobuf/descriptor.pb.h"
// @@protoc_insertion_point(includes)
// Must be included last.
#include "google/protobuf/port_def.inc"
#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcpp_5ffeatures_2eproto PROTOBUF_EXPORT
namespace google {
namespace protobuf {
namespace internal {
class AnyMetadata;
} // namespace internal
} // namespace protobuf
} // namespace google
// Internal implementation detail -- do not use these members.
struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fcpp_5ffeatures_2eproto {
static const ::uint32_t offsets[];
};
PROTOBUF_EXPORT extern const ::google::protobuf::internal::DescriptorTable
descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto;
namespace pb {
class CppFeatures;
struct CppFeaturesDefaultTypeInternal;
PROTOBUF_EXPORT extern CppFeaturesDefaultTypeInternal _CppFeatures_default_instance_;
} // namespace pb
namespace google {
namespace protobuf {
template <>
PROTOBUF_EXPORT ::pb::CppFeatures* Arena::CreateMaybeMessage<::pb::CppFeatures>(Arena*);
} // namespace protobuf
} // namespace google
namespace pb {
// ===================================================================
// -------------------------------------------------------------------
class PROTOBUF_EXPORT CppFeatures final :
public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:pb.CppFeatures) */ {
public:
inline CppFeatures() : CppFeatures(nullptr) {}
~CppFeatures() override;
template<typename = void>
explicit PROTOBUF_CONSTEXPR CppFeatures(::google::protobuf::internal::ConstantInitialized);
CppFeatures(const CppFeatures& from);
CppFeatures(CppFeatures&& from) noexcept
: CppFeatures() {
*this = ::std::move(from);
}
inline CppFeatures& operator=(const CppFeatures& from) {
CopyFrom(from);
return *this;
}
inline CppFeatures& operator=(CppFeatures&& from) noexcept {
if (this == &from) return *this;
if (GetOwningArena() == from.GetOwningArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
&& GetOwningArena() != nullptr
#endif // !PROTOBUF_FORCE_COPY_IN_MOVE
) {
InternalSwap(&from);
} else {
CopyFrom(from);
}
return *this;
}
inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
return _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance);
}
inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>();
}
static const ::google::protobuf::Descriptor* descriptor() {
return GetDescriptor();
}
static const ::google::protobuf::Descriptor* GetDescriptor() {
return default_instance().GetMetadata().descriptor;
}
static const ::google::protobuf::Reflection* GetReflection() {
return default_instance().GetMetadata().reflection;
}
static const CppFeatures& default_instance() {
return *internal_default_instance();
}
static inline const CppFeatures* internal_default_instance() {
return reinterpret_cast<const CppFeatures*>(
&_CppFeatures_default_instance_);
}
static constexpr int kIndexInFileMessages =
0;
friend void swap(CppFeatures& a, CppFeatures& b) {
a.Swap(&b);
}
inline void Swap(CppFeatures* other) {
if (other == this) return;
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
if (GetOwningArena() != nullptr &&
GetOwningArena() == other->GetOwningArena()) {
#else // PROTOBUF_FORCE_COPY_IN_SWAP
if (GetOwningArena() == other->GetOwningArena()) {
#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
InternalSwap(other);
} else {
::google::protobuf::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(CppFeatures* other) {
if (other == this) return;
ABSL_DCHECK(GetOwningArena() == other->GetOwningArena());
InternalSwap(other);
}
// implements Message ----------------------------------------------
CppFeatures* New(::google::protobuf::Arena* arena = nullptr) const final {
return CreateMaybeMessage<CppFeatures>(arena);
}
using ::google::protobuf::Message::CopyFrom;
void CopyFrom(const CppFeatures& from);
using ::google::protobuf::Message::MergeFrom;
void MergeFrom( const CppFeatures& from) {
CppFeatures::MergeImpl(*this, from);
}
private:
static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg);
public:
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
::size_t ByteSizeLong() const final;
const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
::uint8_t* _InternalSerialize(
::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final;
int GetCachedSize() const final { return _impl_._cached_size_.Get(); }
private:
void SharedCtor(::google::protobuf::Arena* arena);
void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(CppFeatures* other);
private:
friend class ::google::protobuf::internal::AnyMetadata;
static ::absl::string_view FullMessageName() {
return "pb.CppFeatures";
}
protected:
explicit CppFeatures(::google::protobuf::Arena* arena);
public:
static const ClassData _class_data_;
const ::google::protobuf::Message::ClassData*GetClassData() const final;
::google::protobuf::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
enum : int {
kLegacyClosedEnumFieldNumber = 1,
};
// optional bool legacy_closed_enum = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
bool has_legacy_closed_enum() const;
void clear_legacy_closed_enum() ;
bool legacy_closed_enum() const;
void set_legacy_closed_enum(bool value);
private:
bool _internal_legacy_closed_enum() const;
void _internal_set_legacy_closed_enum(bool value);
public:
// @@protoc_insertion_point(class_scope:pb.CppFeatures)
private:
class _Internal;
friend class ::google::protobuf::internal::TcParser;
static const ::google::protobuf::internal::TcParseTable<0, 1, 0, 0, 2> _table_;
template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
typedef void InternalArenaConstructable_;
typedef void DestructorSkippable_;
struct Impl_ {
::google::protobuf::internal::HasBits<1> _has_bits_;
mutable ::google::protobuf::internal::CachedSize _cached_size_;
bool legacy_closed_enum_;
PROTOBUF_TSAN_DECLARE_MEMBER;
};
union { Impl_ _impl_; };
friend struct ::TableStruct_google_2fprotobuf_2fcpp_5ffeatures_2eproto;
};
// ===================================================================
static const int kCppFieldNumber = 1000;
PROTOBUF_EXPORT extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::FeatureSet,
::google::protobuf::internal::MessageTypeTraits< ::pb::CppFeatures >, 11, false >
cpp;
// ===================================================================
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif // __GNUC__
// -------------------------------------------------------------------
// CppFeatures
// optional bool legacy_closed_enum = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
inline bool CppFeatures::has_legacy_closed_enum() const {
bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
return value;
}
inline void CppFeatures::clear_legacy_closed_enum() {
_impl_.legacy_closed_enum_ = false;
_impl_._has_bits_[0] &= ~0x00000001u;
}
inline bool CppFeatures::legacy_closed_enum() const {
// @@protoc_insertion_point(field_get:pb.CppFeatures.legacy_closed_enum)
return _internal_legacy_closed_enum();
}
inline void CppFeatures::set_legacy_closed_enum(bool value) {
_internal_set_legacy_closed_enum(value);
// @@protoc_insertion_point(field_set:pb.CppFeatures.legacy_closed_enum)
}
inline bool CppFeatures::_internal_legacy_closed_enum() const {
PROTOBUF_TSAN_READ_PRIMITIVE(&_impl_._tsan_detect_race);
return _impl_.legacy_closed_enum_;
}
inline void CppFeatures::_internal_set_legacy_closed_enum(bool value) {
PROTOBUF_TSAN_WRITE_PRIMITIVE(&_impl_._tsan_detect_race);
_impl_._has_bits_[0] |= 0x00000001u;
_impl_.legacy_closed_enum_ = value;
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif // __GNUC__
// @@protoc_insertion_point(namespace_scope)
} // namespace pb
// @@protoc_insertion_point(global_scope)
#include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcpp_5ffeatures_2eproto_2epb_2eh

View File

@ -0,0 +1,52 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
package pb;
import "google/protobuf/descriptor.proto";
extend google.protobuf.FeatureSet {
optional CppFeatures cpp = 1000;
}
message CppFeatures {
// Whether or not to treat an enum field as closed. This option is only
// applicable to enum fields, and will be removed in the future. It is
// consistent with the legacy behavior of using proto3 enum types for proto2
// fields.
optional bool legacy_closed_enum = 1 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FIELD,
targets = TARGET_TYPE_FILE,
edition_defaults = { edition: "2023", value: "false" }
];
}

File diff suppressed because it is too large Load Diff

View File

@ -258,6 +258,25 @@ class PROTOBUF_EXPORT SymbolBase {
template <int N>
class PROTOBUF_EXPORT SymbolBaseN : public SymbolBase {};
#ifdef PROTOBUF_FUTURE_EDITIONS
// This class is for internal use only and provides access to the FeatureSets
// defined on descriptors. These features are not designed to be stable, and
// depending directly on them (vs the public descriptor APIs) is not safe.
class InternalFeatureHelper {
public:
template <typename DescriptorT>
static const FeatureSet& GetFeatures(const DescriptorT& desc) {
return desc.features();
}
private:
friend class ::google::protobuf::compiler::CodeGenerator;
template <typename DescriptorT>
static const FeatureSet& GetRawFeatures(const DescriptorT& desc) {
return *desc.proto_features_;
}
};
#endif // PROTOBUF_FUTURE_EDITIONS
} // namespace internal
@ -473,7 +492,19 @@ class PROTOBUF_EXPORT Descriptor : private internal::SymbolBase {
private:
const Descriptor* containing_type_;
#ifdef PROTOBUF_FUTURE_EDITIONS
const FeatureSet* proto_features_;
const FeatureSet* merged_features_;
#endif // PROTOBUF_FUTURE_EDITIONS
#ifdef PROTOBUF_FUTURE_EDITIONS
// Get the merged features that apply to this extension range. These are
// specified in the .proto file through the feature options in the message
// definition. Allowed features are defined by Features in descriptor.proto,
// along with any backend-specific extensions to it.
const FeatureSet& features() const { return *merged_features_; }
friend class internal::InternalFeatureHelper;
#endif // PROTOBUF_FUTURE_EDITIONS
// Walks up the descriptor tree to generate the source location path
// to this descriptor from the file root.
@ -598,6 +629,14 @@ class PROTOBUF_EXPORT Descriptor : private internal::SymbolBase {
friend class io::Printer;
friend class compiler::cpp::Formatter;
#ifdef PROTOBUF_FUTURE_EDITIONS
// Get the merged features that apply to this message type. These are
// specified in the .proto file through the feature options in the message
// definition. Allowed features are defined by Features in descriptor.proto,
// along with any backend-specific extensions to it.
const FeatureSet& features() const { return *merged_features_; }
friend class internal::InternalFeatureHelper;
#endif // PROTOBUF_FUTURE_EDITIONS
// Fill the json_name field of FieldDescriptorProto.
void CopyJsonNameTo(DescriptorProto* proto) const;
@ -637,6 +676,10 @@ class PROTOBUF_EXPORT Descriptor : private internal::SymbolBase {
const FileDescriptor* file_;
const Descriptor* containing_type_;
const MessageOptions* options_;
#ifdef PROTOBUF_FUTURE_EDITIONS
const FeatureSet* proto_features_;
const FeatureSet* merged_features_;
#endif // PROTOBUF_FUTURE_EDITIONS
// These arrays are separated from their sizes to minimize padding on 64-bit.
FieldDescriptor* fields_;
@ -673,7 +716,11 @@ class PROTOBUF_EXPORT Descriptor : private internal::SymbolBase {
friend class FileDescriptor;
};
#ifdef PROTOBUF_FUTURE_EDITIONS
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(Descriptor, 152);
#else // PROTOBUF_FUTURE_EDITIONS
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(Descriptor, 136);
#endif // PROTOBUF_FUTURE_EDITIONS
// Describes a single field of a message. To get the descriptor for a given
// field, first get the Descriptor for the message in which it is defined,
@ -987,6 +1034,14 @@ class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase {
private:
#ifdef PROTOBUF_FUTURE_EDITIONS
// Get the merged features that apply to this field. These are specified in
// the .proto file through the feature options in the message definition.
// Allowed features are defined by Features in descriptor.proto, along with
// any backend-specific extensions to it.
const FeatureSet& features() const { return *merged_features_; }
friend class internal::InternalFeatureHelper;
#endif // PROTOBUF_FUTURE_EDITIONS
// Fill the json_name field of FieldDescriptorProto.
void CopyJsonNameTo(FieldDescriptorProto* proto) const;
@ -1055,6 +1110,10 @@ class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase {
mutable const EnumDescriptor* enum_type;
} type_descriptor_;
const FieldOptions* options_;
#ifdef PROTOBUF_FUTURE_EDITIONS
const FeatureSet* proto_features_;
const FeatureSet* merged_features_;
#endif // PROTOBUF_FUTURE_EDITIONS
// IMPORTANT: If you add a new field, make sure to search for all instances
// of Allocate<FieldDescriptor>() and AllocateArray<FieldDescriptor>() in
// descriptor.cc and update them to initialize the field.
@ -1089,7 +1148,11 @@ class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase {
friend class OneofDescriptor;
};
#ifdef PROTOBUF_FUTURE_EDITIONS
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(FieldDescriptor, 88);
#else // PROTOBUF_FUTURE_EDITIONS
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(FieldDescriptor, 72);
#endif // PROTOBUF_FUTURE_EDITIONS
// Describes a oneof defined in a message type.
class PROTOBUF_EXPORT OneofDescriptor : private internal::SymbolBase {
@ -1156,6 +1219,14 @@ class PROTOBUF_EXPORT OneofDescriptor : private internal::SymbolBase {
private:
#ifdef PROTOBUF_FUTURE_EDITIONS
// Get the merged features that apply to this oneof. These are specified in
// the .proto file through the feature options in the oneof definition.
// Allowed features are defined by Features in descriptor.proto, along with
// any backend-specific extensions to it.
const FeatureSet& features() const { return *merged_features_; }
friend class internal::InternalFeatureHelper;
#endif // PROTOBUF_FUTURE_EDITIONS
// See Descriptor::DebugString().
void DebugString(int depth, std::string* contents,
@ -1171,6 +1242,10 @@ class PROTOBUF_EXPORT OneofDescriptor : private internal::SymbolBase {
const std::string* all_names_;
const Descriptor* containing_type_;
const OneofOptions* options_;
#ifdef PROTOBUF_FUTURE_EDITIONS
const FeatureSet* proto_features_;
const FeatureSet* merged_features_;
#endif // PROTOBUF_FUTURE_EDITIONS
const FieldDescriptor* fields_;
// IMPORTANT: If you add a new field, make sure to search for all instances
@ -1184,7 +1259,11 @@ class PROTOBUF_EXPORT OneofDescriptor : private internal::SymbolBase {
friend class FieldDescriptor;
};
#ifdef PROTOBUF_FUTURE_EDITIONS
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(OneofDescriptor, 56);
#else // PROTOBUF_FUTURE_EDITIONS
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(OneofDescriptor, 40);
#endif // PROTOBUF_FUTURE_EDITIONS
// Describes an enum type defined in a .proto file. To get the EnumDescriptor
// for a generated enum type, call TypeName_descriptor(). Use DescriptorPool
@ -1315,6 +1394,14 @@ class PROTOBUF_EXPORT EnumDescriptor : private internal::SymbolBase {
// Allow access to FindValueByNumberCreatingIfUnknown.
friend class descriptor_unittest::DescriptorTest;
#ifdef PROTOBUF_FUTURE_EDITIONS
// Get the merged features that apply to this enum type. These are specified
// in the .proto file through the feature options in the message definition.
// Allowed features are defined by Features in descriptor.proto, along with
// any backend-specific extensions to it.
const FeatureSet& features() const { return *merged_features_; }
friend class internal::InternalFeatureHelper;
#endif // PROTOBUF_FUTURE_EDITIONS
// Looks up a value by number. If the value does not exist, dynamically
// creates a new EnumValueDescriptor for that value, assuming that it was
@ -1356,6 +1443,10 @@ class PROTOBUF_EXPORT EnumDescriptor : private internal::SymbolBase {
const FileDescriptor* file_;
const Descriptor* containing_type_;
const EnumOptions* options_;
#ifdef PROTOBUF_FUTURE_EDITIONS
const FeatureSet* proto_features_;
const FeatureSet* merged_features_;
#endif // PROTOBUF_FUTURE_EDITIONS
EnumValueDescriptor* values_;
int reserved_range_count_;
@ -1379,7 +1470,11 @@ class PROTOBUF_EXPORT EnumDescriptor : private internal::SymbolBase {
friend class Reflection;
};
#ifdef PROTOBUF_FUTURE_EDITIONS
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(EnumDescriptor, 88);
#else // PROTOBUF_FUTURE_EDITIONS
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(EnumDescriptor, 72);
#endif // PROTOBUF_FUTURE_EDITIONS
// Describes an individual enum constant of a particular type. To get the
// EnumValueDescriptor for a given enum value, first get the EnumDescriptor
@ -1442,6 +1537,14 @@ class PROTOBUF_EXPORT EnumValueDescriptor : private internal::SymbolBaseN<0>,
friend class io::Printer;
friend class compiler::cpp::Formatter;
#ifdef PROTOBUF_FUTURE_EDITIONS
// Get the merged features that apply to this enum value. These are specified
// in the .proto file through the feature options in the message definition.
// Allowed features are defined by Features in descriptor.proto, along with
// any backend-specific extensions to it.
const FeatureSet& features() const { return *merged_features_; }
friend class internal::InternalFeatureHelper;
#endif // PROTOBUF_FUTURE_EDITIONS
// See Descriptor::DebugString().
void DebugString(int depth, std::string* contents,
@ -1456,6 +1559,10 @@ class PROTOBUF_EXPORT EnumValueDescriptor : private internal::SymbolBaseN<0>,
const std::string* all_names_;
const EnumDescriptor* type_;
const EnumValueOptions* options_;
#ifdef PROTOBUF_FUTURE_EDITIONS
const FeatureSet* proto_features_;
const FeatureSet* merged_features_;
#endif // PROTOBUF_FUTURE_EDITIONS
// IMPORTANT: If you add a new field, make sure to search for all instances
// of Allocate<EnumValueDescriptor>() and AllocateArray<EnumValueDescriptor>()
// in descriptor.cc and update them to initialize the field.
@ -1469,7 +1576,11 @@ class PROTOBUF_EXPORT EnumValueDescriptor : private internal::SymbolBaseN<0>,
friend class Reflection;
};
#ifdef PROTOBUF_FUTURE_EDITIONS
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(EnumValueDescriptor, 48);
#else // PROTOBUF_FUTURE_EDITIONS
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(EnumValueDescriptor, 32);
#endif // PROTOBUF_FUTURE_EDITIONS
// Describes an RPC service. Use DescriptorPool to construct your own
// descriptors.
@ -1531,6 +1642,14 @@ class PROTOBUF_EXPORT ServiceDescriptor : private internal::SymbolBase {
friend class io::Printer;
friend class compiler::cpp::Formatter;
#ifdef PROTOBUF_FUTURE_EDITIONS
// Get the merged features that apply to this service type. These are
// specified in the .proto file through the feature options in the service
// definition. Allowed features are defined by Features in descriptor.proto,
// along with any backend-specific extensions to it.
const FeatureSet& features() const { return *merged_features_; }
friend class internal::InternalFeatureHelper;
#endif // PROTOBUF_FUTURE_EDITIONS
// See Descriptor::DebugString().
void DebugString(std::string* contents,
@ -1544,6 +1663,10 @@ class PROTOBUF_EXPORT ServiceDescriptor : private internal::SymbolBase {
const std::string* all_names_;
const FileDescriptor* file_;
const ServiceOptions* options_;
#ifdef PROTOBUF_FUTURE_EDITIONS
const FeatureSet* proto_features_;
const FeatureSet* merged_features_;
#endif // PROTOBUF_FUTURE_EDITIONS
MethodDescriptor* methods_;
int method_count_;
// IMPORTANT: If you add a new field, make sure to search for all instances
@ -1557,7 +1680,11 @@ class PROTOBUF_EXPORT ServiceDescriptor : private internal::SymbolBase {
friend class MethodDescriptor;
};
#ifdef PROTOBUF_FUTURE_EDITIONS
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(ServiceDescriptor, 64);
#else // PROTOBUF_FUTURE_EDITIONS
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(ServiceDescriptor, 48);
#endif // PROTOBUF_FUTURE_EDITIONS
// Describes an individual service method. To obtain a MethodDescriptor given
// a service, first get its ServiceDescriptor, then call
@ -1624,6 +1751,14 @@ class PROTOBUF_EXPORT MethodDescriptor : private internal::SymbolBase {
friend class io::Printer;
friend class compiler::cpp::Formatter;
#ifdef PROTOBUF_FUTURE_EDITIONS
// Get the merged features that apply to this method. These are specified in
// the .proto file through the feature options in the method definition.
// Allowed features are defined by Features in descriptor.proto, along with
// any backend-specific extensions to it.
const FeatureSet& features() const { return *merged_features_; }
friend class internal::InternalFeatureHelper;
#endif // PROTOBUF_FUTURE_EDITIONS
// See Descriptor::DebugString().
void DebugString(int depth, std::string* contents,
@ -1641,6 +1776,10 @@ class PROTOBUF_EXPORT MethodDescriptor : private internal::SymbolBase {
mutable internal::LazyDescriptor input_type_;
mutable internal::LazyDescriptor output_type_;
const MethodOptions* options_;
#ifdef PROTOBUF_FUTURE_EDITIONS
const FeatureSet* proto_features_;
const FeatureSet* merged_features_;
#endif // PROTOBUF_FUTURE_EDITIONS
// IMPORTANT: If you add a new field, make sure to search for all instances
// of Allocate<MethodDescriptor>() and AllocateArray<MethodDescriptor>() in
// descriptor.cc and update them to initialize the field.
@ -1651,7 +1790,11 @@ class PROTOBUF_EXPORT MethodDescriptor : private internal::SymbolBase {
friend class ServiceDescriptor;
};
#ifdef PROTOBUF_FUTURE_EDITIONS
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(MethodDescriptor, 80);
#else // PROTOBUF_FUTURE_EDITIONS
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(MethodDescriptor, 64);
#endif // PROTOBUF_FUTURE_EDITIONS
// Describes a whole .proto file. To get the FileDescriptor for a compiled-in
// file, get the descriptor for something defined in that file and call
@ -1750,6 +1893,9 @@ class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase {
SYNTAX_UNKNOWN = 0,
SYNTAX_PROTO2 = 2,
SYNTAX_PROTO3 = 3,
#ifdef PROTOBUF_FUTURE_EDITIONS
SYNTAX_EDITIONS = 99,
#endif // PROTOBUF_FUTURE_EDITIONS
};
PROTOBUF_IGNORE_DEPRECATION_START
ABSL_DEPRECATED(
@ -1769,6 +1915,10 @@ class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase {
PROTOBUF_IGNORE_DEPRECATION_STOP
public:
#ifdef PROTOBUF_FUTURE_EDITIONS
// Returns an unspecified value if syntax() is not SYNTAX_EDITIONS.
absl::string_view edition() const;
#endif // PROTOBUF_FUTURE_EDITIONS
// Find a top-level message type by name (not full_name). Returns nullptr if
// not found.
@ -1847,7 +1997,18 @@ class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase {
const std::string* name_;
const std::string* package_;
const DescriptorPool* pool_;
#ifdef PROTOBUF_FUTURE_EDITIONS
const std::string* edition_ = nullptr;
#endif // PROTOBUF_FUTURE_EDITIONS
#ifdef PROTOBUF_FUTURE_EDITIONS
// Get the merged features that apply to this file. These are specified in
// the .proto file through the feature options in the message definition.
// Allowed features are defined by FeatureSet in descriptor.proto, along with
// any backend-specific extensions to it.
const FeatureSet& features() const { return *merged_features_; }
friend class internal::InternalFeatureHelper;
#endif // PROTOBUF_FUTURE_EDITIONS
// dependencies_once_ contain a once_flag followed by N NUL terminated
// strings. Dependencies that do not need to be loaded will be empty. ie just
@ -1872,6 +2033,10 @@ class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase {
ServiceDescriptor* services_;
FieldDescriptor* extensions_;
const FileOptions* options_;
#ifdef PROTOBUF_FUTURE_EDITIONS
const FeatureSet* proto_features_;
const FeatureSet* merged_features_;
#endif // PROTOBUF_FUTURE_EDITIONS
const FileDescriptorTables* tables_;
const SourceCodeInfo* source_code_info_;
@ -1893,7 +2058,11 @@ class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase {
friend class ServiceDescriptor;
};
#ifdef PROTOBUF_FUTURE_EDITIONS
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(FileDescriptor, 168);
#else // PROTOBUF_FUTURE_EDITIONS
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(FileDescriptor, 152);
#endif // PROTOBUF_FUTURE_EDITIONS
// ===================================================================
@ -2039,6 +2208,9 @@ class PROTOBUF_EXPORT DescriptorPool {
OPTION_NAME, // name in assignment
OPTION_VALUE, // value in option assignment
IMPORT, // import error
#ifdef PROTOBUF_FUTURE_EDITIONS
EDITIONS, // editions-related error
#endif // PROTOBUF_FUTURE_EDITIONS
OTHER // some other problem
};
static absl::string_view ErrorLocationName(ErrorLocation location);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -164,6 +164,9 @@ message ExtensionRangeOptions {
// used externally.
repeated Declaration declaration = 2 [retention = RETENTION_SOURCE];
// Any features defined in the specific edition.
optional FeatureSet features = 50;
// The verification state of the extension range.
enum VerificationState {
// All the extensions of the range must be declared.
@ -490,6 +493,9 @@ message FileOptions {
// determining the ruby package.
optional string ruby_package = 45;
// Any features defined in the specific edition.
optional FeatureSet features = 50;
// The parser stores options it doesn't recognize here.
// See the documentation for the "Options" section above.
repeated UninterpretedOption uninterpreted_option = 999;
@ -573,6 +579,9 @@ message MessageOptions {
// teams have had time to migrate.
optional bool deprecated_legacy_json_field_conflicts = 11 [deprecated = true];
// Any features defined in the specific edition.
optional FeatureSet features = 12;
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@ -712,6 +721,15 @@ message FieldOptions {
repeated OptionTargetType targets = 19;
message EditionDefault {
optional string edition = 1;
optional string value = 2; // Textproto value.
}
repeated EditionDefault edition_defaults = 20;
// Any features defined in the specific edition.
optional FeatureSet features = 21;
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@ -723,6 +741,8 @@ message FieldOptions {
}
message OneofOptions {
// Any features defined in the specific edition.
optional FeatureSet features = 1;
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@ -753,6 +773,9 @@ message EnumOptions {
// had time to migrate.
optional bool deprecated_legacy_json_field_conflicts = 6 [deprecated = true];
// Any features defined in the specific edition.
optional FeatureSet features = 7;
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@ -767,6 +790,9 @@ message EnumValueOptions {
// this is a formalization for deprecating enum values.
optional bool deprecated = 1 [default = false];
// Any features defined in the specific edition.
optional FeatureSet features = 2;
// Indicate that fields annotated with this enum value should not be printed
// out when using debug formats, e.g. when the field contains sensitive
// credentials.
@ -781,6 +807,9 @@ message EnumValueOptions {
message ServiceOptions {
// Any features defined in the specific edition.
optional FeatureSet features = 34;
// Note: Field numbers 1 through 32 are reserved for Google's internal RPC
// framework. We apologize for hoarding these numbers to ourselves, but
// we were already using them long before we decided to release Protocol
@ -823,6 +852,9 @@ message MethodOptions {
optional IdempotencyLevel idempotency_level = 34
[default = IDEMPOTENCY_UNKNOWN];
// Any features defined in the specific edition.
optional FeatureSet features = 35;
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@ -858,6 +890,97 @@ message UninterpretedOption {
optional string aggregate_value = 8;
}
// ===================================================================
// Features
// TODO(b/274655146) Enums in C++ gencode (and potentially other languages) are
// not well scoped. This means that each of the feature enums below can clash
// with each other. The short names we've chosen maximize call-site
// readability, but leave us very open to this scenario. A future feature will
// be designed and implemented to handle this, hopefully before we ever hit a
// conflict here.
message FeatureSet {
enum FieldPresence {
FIELD_PRESENCE_UNKNOWN = 0;
EXPLICIT = 1;
IMPLICIT = 2;
LEGACY_REQUIRED = 3;
}
optional FieldPresence field_presence = 1 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FIELD,
targets = TARGET_TYPE_FILE,
edition_defaults = { edition: "2023", value: "EXPLICIT" }
];
enum EnumType {
ENUM_TYPE_UNKNOWN = 0;
OPEN = 1;
CLOSED = 2;
}
optional EnumType enum_type = 2 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_ENUM,
targets = TARGET_TYPE_FILE,
edition_defaults = { edition: "2023", value: "OPEN" }
];
enum RepeatedFieldEncoding {
REPEATED_FIELD_ENCODING_UNKNOWN = 0;
PACKED = 1;
EXPANDED = 2;
}
optional RepeatedFieldEncoding repeated_field_encoding = 3 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FIELD,
targets = TARGET_TYPE_FILE,
edition_defaults = { edition: "2023", value: "PACKED" }
];
enum StringFieldValidation {
STRING_FIELD_VALIDATION_UNKNOWN = 0;
MANDATORY = 1;
HINT = 2;
NONE = 3;
}
optional StringFieldValidation string_field_validation = 4 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FIELD,
targets = TARGET_TYPE_FILE,
edition_defaults = { edition: "2023", value: "MANDATORY" }
];
enum MessageEncoding {
MESSAGE_ENCODING_UNKNOWN = 0;
LENGTH_PREFIXED = 1;
DELIMITED = 2;
}
optional MessageEncoding message_encoding = 5 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FIELD,
targets = TARGET_TYPE_FILE,
edition_defaults = { edition: "2023", value: "LENGTH_PREFIXED" }
];
enum JsonFormat {
JSON_FORMAT_UNKNOWN = 0;
ALLOW = 1;
LEGACY_BEST_EFFORT = 2;
}
optional JsonFormat json_format = 6 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_MESSAGE,
targets = TARGET_TYPE_ENUM,
targets = TARGET_TYPE_FILE,
edition_defaults = { edition: "2023", value: "ALLOW" }
];
extensions 1000; // for Protobuf C++
extensions 1001; // for Protobuf Java
extensions 9995 to 9999; // For internal testing
}
// ===================================================================
// Optional source code info

View File

@ -79,6 +79,9 @@ class PROTOBUF_EXPORT FileDescriptorLegacy {
SYNTAX_UNKNOWN = FileDescriptor::SYNTAX_UNKNOWN,
SYNTAX_PROTO2 = FileDescriptor::SYNTAX_PROTO2,
SYNTAX_PROTO3 = FileDescriptor::SYNTAX_PROTO3,
#ifdef PROTOBUF_FUTURE_EDITIONS
SYNTAX_EDITIONS = FileDescriptor::SYNTAX_EDITIONS,
#endif // PROTOBUF_FUTURE_EDITIONS
};
Syntax syntax() const { return static_cast<Syntax>(desc_->syntax()); }
static absl::string_view SyntaxName(Syntax syntax) {

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,54 @@
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
proto_library(
name = "test_messages_proto2_proto",
srcs = ["golden/test_messages_proto2.proto"],
strip_import_prefix = "/src",
deps = ["//src/google/protobuf:cpp_features_proto"],
)
proto_library(
name = "test_messages_proto3_proto",
srcs = ["golden/test_messages_proto3.proto"],
strip_import_prefix = "/src",
deps = [
"//:any_proto",
"//:duration_proto",
"//:field_mask_proto",
"//:struct_proto",
"//:timestamp_proto",
"//:wrappers_proto",
"//src/google/protobuf:cpp_features_proto",
],
)
cc_proto_library(
name = "test_messages_proto2_cc_proto",
deps = [":test_messages_proto2_proto"],
)
cc_proto_library(
name = "test_messages_proto3_cc_proto",
deps = [":test_messages_proto3_proto"],
)
cc_test(
name = "generated_files_test",
srcs = ["generated_files_test.cc"],
deps = [
":test_messages_proto2_cc_proto",
":test_messages_proto3_cc_proto",
"//src/google/protobuf",
"//src/google/protobuf:test_textproto",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "generated_reflection_test",
srcs = ["generated_reflection_test.cc"],
deps = [
":test_messages_proto2_cc_proto",
"@com_google_googletest//:gtest_main",
],
)

View File

@ -0,0 +1,129 @@
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
exports_files(
glob(["*.proto"]),
visibility = [
"//src/google/protobuf/editions:__pkg__",
],
)
proto_library(
name = "proto2_required_proto",
srcs = ["proto2_required.proto"],
strip_import_prefix = "/src",
)
proto_library(
name = "proto3_optional_proto",
srcs = ["proto3_optional.proto"],
strip_import_prefix = "/src",
)
proto_library(
name = "proto3_implicit_proto",
srcs = ["proto3_implicit.proto"],
strip_import_prefix = "/src",
)
proto_library(
name = "proto2_optional_proto",
srcs = ["proto2_optional.proto"],
strip_import_prefix = "/src",
)
proto_library(
name = "proto2_enum_proto",
srcs = ["proto2_enum.proto"],
strip_import_prefix = "/src",
)
proto_library(
name = "proto3_enum_proto",
srcs = ["proto3_enum.proto"],
strip_import_prefix = "/src",
)
proto_library(
name = "proto2_packed_proto",
srcs = ["proto2_packed.proto"],
strip_import_prefix = "/src",
)
proto_library(
name = "proto3_packed_proto",
srcs = ["proto3_packed.proto"],
strip_import_prefix = "/src",
)
proto_library(
name = "proto2_group_proto",
srcs = ["proto2_group.proto"],
strip_import_prefix = "/src",
)
proto_library(
name = "proto2_unpacked_proto",
srcs = ["proto2_unpacked.proto"],
strip_import_prefix = "/src",
)
proto_library(
name = "proto3_unpacked_proto",
srcs = ["proto3_unpacked.proto"],
strip_import_prefix = "/src",
)
proto_library(
name = "proto2_utf8_verify_proto",
srcs = ["proto2_utf8_verify.proto"],
strip_import_prefix = "/src",
)
proto_library(
name = "proto3_utf8_disabled_proto",
srcs = ["proto3_utf8_disabled.proto"],
strip_import_prefix = "/src",
)
proto_library(
name = "proto2_import_proto",
srcs = ["proto2_import.proto"],
strip_import_prefix = "/src",
deps = [":proto2_optional_proto"],
)
proto_library(
name = "proto2_utf8_disabled_proto",
srcs = ["proto2_utf8_disabled.proto"],
strip_import_prefix = "/src",
)
cc_proto_library(
name = "proto2_utf8_disabled_cc_proto",
deps = [":proto2_utf8_disabled_proto"],
)
proto_library(
name = "proto2_proto3_enum_proto",
srcs = ["proto2_proto3_enum.proto"],
strip_import_prefix = "/src",
deps = [":proto3_enum_proto"],
)
proto_library(
name = "proto3_utf8_strict_proto",
srcs = ["proto3_utf8_strict.proto"],
strip_import_prefix = "/src",
)
proto_library(
name = "proto3_import_proto",
srcs = ["proto3_import.proto"],
strip_import_prefix = "/src",
deps = [":proto3_implicit_proto"],
)
cc_proto_library(
name = "proto3_import_cc_proto",
deps = [":proto3_import_proto"],
)

View File

@ -0,0 +1,43 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
package protobuf_editions_test.proto2;
enum Proto2Enum {
BAR = 1;
BAZ = 2;
}
message Proto2EnumMessage {
optional Proto2Enum enum_field = 1;
optional Proto2Enum enum_field_default = 2 [default = BAZ];
}

View File

@ -0,0 +1,41 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
package protobuf_editions_test.proto2;
// LINT: ALLOW_GROUPS
message Proto2Group {
optional group GroupField = 2 {
optional int32 int32_field = 1;
}
}

View File

@ -0,0 +1,39 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
package protobuf_editions_test.proto2;
import "google/protobuf/editions/codegen_tests/proto2_optional.proto";
message Proto2ImportMessage {
optional Proto2Optional sub_message_field = 1;
}

View File

@ -0,0 +1,42 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
package protobuf_editions_test.proto2;
message Proto2Optional {
optional int32 int32_field = 1;
message SubMessage {
optional int32 int32_field = 1;
}
optional SubMessage sub_message = 2;
}

View File

@ -0,0 +1,37 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
package protobuf_editions_test.proto2;
message Proto2Packed {
repeated int32 int32_field = 1 [packed = true];
}

View File

@ -0,0 +1,43 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
package protobuf_editions_test.proto2;
import "google/protobuf/editions/codegen_tests/proto3_enum.proto";
message Proto2ImportedEnumMessage {
optional protobuf_editions_test.proto3.Proto3Enum enum_field = 1;
// clang-format off
// TODO(b/284470608) Transforms don't support multi-line fields yet.
optional protobuf_editions_test.proto3.Proto3Enum enum_field_default = 2 [default = BAZ];
// clang-format on
}

View File

@ -0,0 +1,42 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
package protobuf_editions_test.proto2;
message Proto2Required {
required int32 int32_field = 1;
message SubMessage {
required int32 int32_field = 1;
}
required SubMessage sub_message = 2;
}

View File

@ -0,0 +1,42 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
package protobuf_editions_test.proto2;
message Proto2Unpacked {
repeated int32 int32_field = 1;
repeated string string_field = 2;
message SubMessage {
optional int32 int32_field = 1;
}
repeated SubMessage sub_message_field = 3;
}

View File

@ -0,0 +1,38 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
package protobuf_editions_test.proto2;
message Proto2Utf8Strict {
optional string string_field = 1;
}

View File

@ -0,0 +1,37 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
package protobuf_editions_test.proto2;
message Proto2Utf8Verify {
optional string string_field = 1;
}

View File

@ -0,0 +1,43 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package protobuf_editions_test.proto3;
enum Proto3Enum {
UNKNOWN = 0;
BAR = 1;
BAZ = 2;
}
message Proto3EnumMessage {
Proto3Enum enum_field = 1;
}

View File

@ -0,0 +1,42 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package protobuf_editions_test.proto3;
message Proto3Implicit {
int32 int32_field = 1;
message SubMessage {
int32 int32_field = 1;
}
SubMessage sub_message = 2;
}

View File

@ -0,0 +1,39 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package protobuf_editions_test.proto3;
import "google/protobuf/editions/codegen_tests/proto3_implicit.proto";
message Proto3ImportMessage {
Proto3Implicit sub_message_field = 1;
}

View File

@ -0,0 +1,42 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package protobuf_editions_test.proto3;
message Proto3Optional {
optional int32 int32_field = 1;
message SubMessage {
optional int32 int32_field = 1;
}
optional SubMessage optional_message = 2;
}

View File

@ -0,0 +1,42 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package protobuf_editions_test.proto3;
message Proto3Packed {
repeated int32 int32_field = 1;
repeated string string_field = 2;
message SubMessage {
int32 int32_field = 1;
}
repeated SubMessage sub_message_field = 3;
}

View File

@ -0,0 +1,42 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package protobuf_editions_test.proto3;
message Proto3Unpacked {
repeated int32 int32_field = 1 [packed = false];
repeated string string_field = 2 [packed = false];
message SubMessage {
int32 int32_field = 1;
}
repeated SubMessage sub_message_field = 3 [packed = false];
}

View File

@ -0,0 +1,37 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package protobuf_editions_test.proto3;
message Proto3Utf8Disabled {
string string_field = 1;
}

View File

@ -0,0 +1,37 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package protobuf_editions_test.proto3;
message Proto3Utf8Strict {
string string_field = 1;
}

View File

@ -0,0 +1,148 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "google/protobuf/descriptor.h"
#include "google/protobuf/editions/golden/test_messages_proto2.pb.h"
#include "google/protobuf/editions/golden/test_messages_proto3.pb.h"
#include "google/protobuf/test_textproto.h"
// These tests provide some basic minimal coverage that protos work as expected.
// Full coverage will come as we migrate test protos to editions.
namespace google {
namespace protobuf {
namespace {
using ::protobuf_test_messages::proto2::TestAllRequiredTypesProto2;
using ::protobuf_test_messages::proto2::TestAllTypesProto2;
using ::protobuf_test_messages::proto3::TestAllTypesProto3;
using ::testing::NotNull;
TEST(Gemerated, Parsing) {
TestAllTypesProto2 message = ParseTextOrDie(R"pb(
Data { group_int32: 9 }
)pb");
EXPECT_EQ(message.data().group_int32(), 9);
}
TEST(Gemerated, GeneratedMethods) {
TestAllTypesProto3 message;
message.set_optional_int32(9);
EXPECT_THAT(message, EqualsProto(R"pb(optional_int32: 9)pb"));
}
TEST(Gemerated, ExplicitPresence) {
const FieldDescriptor* field =
TestAllTypesProto2::descriptor()->FindFieldByName("default_int32");
ASSERT_THAT(field, NotNull());
EXPECT_TRUE(field->has_presence());
}
TEST(Gemerated, RequiredPresence) {
const FieldDescriptor* field =
TestAllRequiredTypesProto2::descriptor()->FindFieldByName(
"required_int32");
ASSERT_THAT(field, NotNull());
EXPECT_TRUE(field->has_presence());
EXPECT_TRUE(field->is_required());
EXPECT_EQ(field->label(), FieldDescriptor::LABEL_REQUIRED);
}
TEST(Gemerated, ImplicitPresence) {
const FieldDescriptor* field =
TestAllTypesProto3::descriptor()->FindFieldByName("optional_int32");
ASSERT_THAT(field, NotNull());
EXPECT_FALSE(field->has_presence());
}
TEST(Gemerated, ClosedEnum) {
const EnumDescriptor* enm =
TestAllTypesProto2::descriptor()->FindEnumTypeByName("NestedEnum");
ASSERT_THAT(enm, NotNull());
EXPECT_TRUE(enm->is_closed());
}
TEST(Gemerated, OpenEnum) {
const EnumDescriptor* enm =
TestAllTypesProto3::descriptor()->FindEnumTypeByName("NestedEnum");
ASSERT_THAT(enm, NotNull());
EXPECT_FALSE(enm->is_closed());
}
TEST(Gemerated, PackedRepeated) {
const FieldDescriptor* field =
TestAllTypesProto2::descriptor()->FindFieldByName("packed_int32");
ASSERT_THAT(field, NotNull());
EXPECT_TRUE(field->is_packed());
}
TEST(Gemerated, ExpandedRepeated) {
const FieldDescriptor* field =
TestAllTypesProto2::descriptor()->FindFieldByName("repeated_int32");
ASSERT_THAT(field, NotNull());
EXPECT_FALSE(field->is_packed());
}
TEST(Gemerated, DoesNotEnforceUtf8) {
const FieldDescriptor* field =
TestAllTypesProto2::descriptor()->FindFieldByName("optional_string");
ASSERT_THAT(field, NotNull());
EXPECT_FALSE(field->requires_utf8_validation());
}
TEST(Gemerated, EnforceUtf8) {
const FieldDescriptor* field =
TestAllTypesProto3::descriptor()->FindFieldByName("optional_string");
ASSERT_THAT(field, NotNull());
EXPECT_TRUE(field->requires_utf8_validation());
}
TEST(Gemerated, DelimitedEncoding) {
const FieldDescriptor* field =
TestAllTypesProto2::descriptor()->FindFieldByName("data");
ASSERT_THAT(field, NotNull());
EXPECT_EQ(field->type(), FieldDescriptor::TYPE_GROUP);
}
TEST(Gemerated, LengthPrefixedEncoding) {
const FieldDescriptor* field =
TestAllTypesProto2::descriptor()->FindFieldByName(
"optional_nested_message");
ASSERT_THAT(field, NotNull());
EXPECT_EQ(field->type(), FieldDescriptor::TYPE_MESSAGE);
}
} // namespace
} // namespace protobuf
} // namespace google

View File

@ -0,0 +1,53 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <gtest/gtest.h>
#include "google/protobuf/editions/golden/test_messages_proto2.pb.h"
namespace google {
namespace protobuf {
namespace {
using ::protobuf_test_messages::proto2::TestAllTypesProto2;
// It's important that no calls that would initialize the generated pool occur
// in any tests in this file. This test guarantees that there's no mutex
// deadlock from lazily loading cpp_features.proto during reflection.
TEST(Generated, Reflection) {
TestAllTypesProto2 message;
message.GetReflection()->SetInt32(
&message, message.GetDescriptor()->FindFieldByName("optional_int32"), 1);
EXPECT_EQ(message.optional_int32(), 1);
}
} // namespace
} // namespace protobuf
} // namespace google

View File

@ -0,0 +1,58 @@
[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.cc
@@ @@
&_SimpleProto3_default_instance_._instance,
::_pbi::TcParser::GenericFallbackLite, // fallback
}, {{
- // optional int32 int32_field = 1;
+ // int32 int32_field = 1 [features = {
{::_pbi::TcParser::FastV32S1,
{8, 0, 0, PROTOBUF_FIELD_OFFSET(SimpleProto3, _impl_.int32_field_)}},
}}, {{
65535, 65535
}}, {{
- // optional int32 int32_field = 1;
+ // int32 int32_field = 1 [features = {
{PROTOBUF_FIELD_OFFSET(SimpleProto3, _impl_.int32_field_), _Internal::kHasBitsOffset + 0, 0,
(0 | ::_fl::kFcOptional | ::_fl::kInt32)},
}},
@@ @@
(void)cached_has_bits;
cached_has_bits = _impl_._has_bits_[0];
- // optional int32 int32_field = 1;
+ // int32 int32_field = 1 [features = {
if (cached_has_bits & 0x00000001u) {
target = ::proto2::internal::WireFormatLite::
WriteInt32ToArrayWithField<1>(
@@ @@
// Prevent compiler warnings about cached_has_bits being unused
(void) cached_has_bits;
- // optional int32 int32_field = 1;
+ // int32 int32_field = 1 [features = {
cached_has_bits = _impl_._has_bits_[0];
if (cached_has_bits & 0x00000001u) {
total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(
[ FAILED ] third_party/protobuf/editions/golden/simple_proto3.pb.cc
[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.h
@@ @@
enum : int {
kInt32FieldFieldNumber = 1,
};
- // optional int32 int32_field = 1;
+ // int32 int32_field = 1 [features = {
bool has_int32_field() const;
void clear_int32_field() ;
::int32_t int32_field() const;
@@ @@
// SimpleProto3
-// optional int32 int32_field = 1;
+// int32 int32_field = 1 [features = {
inline bool SimpleProto3::has_int32_field() const {
bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
return value;
[ FAILED ] third_party/protobuf/editions/golden/simple_proto3.pb.h
[ RUN ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h
[ OK ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="1" name="AllTests">
<testsuite name="EditionsCodegenTests">
<testcase name="third_party/protobuf/editions/golden/simple_proto3.pb.cc" status="run" result="completed" classname="DiffTest">
<failure message="Value of: third_party/protobuf/editions/golden/simple_proto3.pb.cc&#x0A;Expected: &#x0A;// Generated by the protocol buffer compiler. DO NOT EDIT!&#x0A;// source: third_party/protobuf/editions/golden/simple_proto3.proto&#x0A;&#x0A;#include &quot;third_party/protobuf/editions/golden/simple_proto3.pb.h&quot;&#x0A;&#x0A;#include &lt;algorithm&gt;&#x0A;#include &quot;third_party/protobuf/io/coded_stream.h&quot;&#x0A;#include &quot;third_party/protobuf/extension_set.h&quot;&#x0A;#include &quot;third_party/protobuf/wire_format_lite.h&quot;&#x0A;#include &quot;third_party/protobuf/io/zero_copy_stream_impl_lite.h&quot;&#x0A;#include &quot;third_party/protobuf/generated_message_tctable_impl.h&quot;&#x0A;// @@protoc_insertion_point(includes)&#x0A;&#x0A;// Must be included last.&#x0A;, with the difference:&#x0A;@@ @@&#x0A; &amp;_SimpleProto3_default_instance_._instance,&#x0A; ::_pbi::TcParser::GenericFallbackLite, // fallback&#x0A; }, {{&#x0A;- // optional int32 int32_field = 1;&#x0A;+ // int32 int32_field = 1 [features = {&#x0A; {::_pbi::TcParser::FastV32S1,&#x0A; {8, 0, 0, PROTOBUF_FIELD_OFFSET(SimpleProto3, _impl_.int32_field_)}},&#x0A; }}, {{&#x0A; 65535, 65535&#x0A; }}, {{&#x0A;- // optional int32 int32_field = 1;&#x0A;+ // int32 int32_field = 1 [features = {&#x0A; {PROTOBUF_FIELD_OFFSET(SimpleProto3, _impl_.int32_field_), _Internal::kHasBitsOffset + 0, 0,&#x0A; (0 | ::_fl::kFcOptional | ::_fl::kInt32)},&#x0A; }},&#x0A;@@ @@&#x0A; (void)cached_has_bits;&#x0A; &#x0A; cached_has_bits = _impl_._has_bits_[0];&#x0A;- // optional int32 int32_field = 1;&#x0A;+ // int32 int32_field = 1 [features = {&#x0A; if (cached_has_bits &amp; 0x00000001u) {&#x0A; target = ::proto2::internal::WireFormatLite::&#x0A; WriteInt32ToArrayWithField&lt;1&gt;(&#x0A;@@ @@&#x0A; // Prevent compiler warnings about cached_has_bits being unused&#x0A; (void) cached_has_bits;&#x0A; &#x0A;- // optional int32 int32_field = 1;&#x0A;+ // int32 int32_field = 1 [features = {&#x0A; cached_has_bits = _impl_._has_bits_[0];&#x0A; if (cached_has_bits &amp; 0x00000001u) {&#x0A; total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(" type=""></failure>
</testcase>
<testcase name="third_party/protobuf/editions/golden/simple_proto3.pb.h" status="run" result="completed" classname="DiffTest">
<failure message="Value of: third_party/protobuf/editions/golden/simple_proto3.pb.h&#x0A;Expected: &#x0A;// Generated by the protocol buffer compiler. DO NOT EDIT!&#x0A;// source: third_party/protobuf/editions/golden/simple_proto3.proto&#x0A;&#x0A;#ifndef GOOGLE_PROTOBUF_INCLUDED_third_5fparty_2fprotobuf_2feditions_2fgolden_2fsimple_5fproto3_2eproto_2epb_2eh&#x0A;#define GOOGLE_PROTOBUF_INCLUDED_third_5fparty_2fprotobuf_2feditions_2fgolden_2fsimple_5fproto3_2eproto_2epb_2eh&#x0A;&#x0A;#include &lt;limits&gt;&#x0A;#include &lt;string&gt;&#x0A;#include &lt;type_traits&gt;&#x0A;&#x0A;#include &quot;third_party/protobuf/wire_format_verify.h&quot;&#x0A;#include &quot;third_party/protobuf/io/coded_stream.h&quot;&#x0A;#include &quot;third_party/protobuf/arena.h&quot;&#x0A;#include &quot;third_party/protobuf/arenastring.h&quot;&#x0A;#include &quot;third_party/protobuf/inlined_string_field.h&quot;&#x0A;#include &quot;third_party/protobuf/generated_message_tctable_decl.h&quot;&#x0A;#include &quot;third_party/protobuf/generated_message_util.h&quot;&#x0A;#include &quot;third_party/protobuf/metadata_lite.h&quot;&#x0A;#include &quot;third_party/protobuf/message_lite.h&quot;&#x0A;// @@protoc_insertion_point(includes)&#x0A;&#x0A;// Must be included last.&#x0A;&#x0A;#endif // GOOGLE_PROTOBUF_INCLUDED_third_5fparty_2fprotobuf_2feditions_2fgolden_2fsimple_5fproto3_2eproto_2epb_2eh&#x0A;, with the difference:&#x0A;@@ @@&#x0A; enum : int {&#x0A; kInt32FieldFieldNumber = 1,&#x0A; };&#x0A;- // optional int32 int32_field = 1;&#x0A;+ // int32 int32_field = 1 [features = {&#x0A; bool has_int32_field() const;&#x0A; void clear_int32_field() ;&#x0A; ::int32_t int32_field() const;&#x0A;@@ @@&#x0A; &#x0A; // SimpleProto3&#x0A; &#x0A;-// optional int32 int32_field = 1;&#x0A;+// int32 int32_field = 1 [features = {&#x0A; inline bool SimpleProto3::has_int32_field() const {&#x0A; bool value = (_impl_._has_bits_[0] &amp; 0x00000001u) != 0;&#x0A; return value;" type=""></failure>
</testcase>
<testcase name="third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h" status="run" result="completed" classname="DiffTest">
</testcase>
</testsuite>
</testsuites>

View File

@ -0,0 +1,12 @@
[ RUN ] third_party/protobuf/editions/golden/simple_proto2.pb.cc
[ OK ] third_party/protobuf/editions/golden/simple_proto2.pb.cc
[ RUN ] third_party/protobuf/editions/golden/simple_proto2.pb.h
[ OK ] third_party/protobuf/editions/golden/simple_proto2.pb.h
[ RUN ] third_party/protobuf/editions/golden/simple_proto2.proto.static_reflection.h
[ OK ] third_party/protobuf/editions/golden/simple_proto2.proto.static_reflection.h
[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.cc
[ OK ] third_party/protobuf/editions/golden/simple_proto3.pb.cc
[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.h
[ OK ] third_party/protobuf/editions/golden/simple_proto3.pb.h
[ RUN ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h
[ OK ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="1" name="AllTests">
<testsuite name="EditionsCodegenTests">
<testcase name="third_party/protobuf/editions/golden/simple_proto2.pb.cc" status="run" result="completed" classname="DiffTest">
</testcase>
<testcase name="third_party/protobuf/editions/golden/simple_proto2.pb.h" status="run" result="completed" classname="DiffTest">
</testcase>
<testcase name="third_party/protobuf/editions/golden/simple_proto2.proto.static_reflection.h" status="run" result="completed" classname="DiffTest">
</testcase>
<testcase name="third_party/protobuf/editions/golden/simple_proto3.pb.cc" status="run" result="completed" classname="DiffTest">
</testcase>
<testcase name="third_party/protobuf/editions/golden/simple_proto3.pb.h" status="run" result="completed" classname="DiffTest">
</testcase>
<testcase name="third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h" status="run" result="completed" classname="DiffTest">
</testcase>
</testsuite>
</testsuites>

View File

@ -0,0 +1,6 @@
[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.cc
[ OK ] third_party/protobuf/editions/golden/simple_proto3.pb.cc
[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.h
[ OK ] third_party/protobuf/editions/golden/simple_proto3.pb.h
[ RUN ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h
[ OK ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="1" name="AllTests">
<testsuite name="EditionsCodegenTests">
<testcase name="third_party/protobuf/editions/golden/simple_proto3.pb.cc" status="run" result="completed" classname="DiffTest">
</testcase>
<testcase name="third_party/protobuf/editions/golden/simple_proto3.pb.h" status="run" result="completed" classname="DiffTest">
</testcase>
<testcase name="third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h" status="run" result="completed" classname="DiffTest">
</testcase>
</testsuite>
</testsuites>

View File

@ -0,0 +1,95 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
edition = "2023";
import "google/protobuf/cpp_features.proto";
option features.enum_type = CLOSED;
option features.repeated_field_encoding = EXPANDED;
option features.string_field_validation = NONE;
option features.json_format = LEGACY_BEST_EFFORT;
option features.(pb.cpp).legacy_closed_enum = true;
// This file contains various edge cases we've collected from migrating real
// protos in order to lock down the transformations.
// LINT: ALLOW_GROUPS
package protobuf_editions_test;
option java_multiple_files = true;
option cc_enable_arenas = true;
message EmptyMessage {}
message EmptyMessage2 {}
service EmptyService {}
service BasicService {
rpc BasicMethod(EmptyMessage) returns (EmptyMessage) {}
}
// clang-format off
message UnformattedMessage{
int32 a=1 ;
message Foo { int32 a = 1; }
Foo foo = 2 [features.message_encoding = DELIMITED];
string string_piece_with_zero = 3 [ctype=STRING_PIECE, default="ab\000c"];
float long_float_name_wrapped = 4;
}
// clang-format on
message ParentMessage {
message ExtendedMessage {
extensions 536860000 to 536869999 [declaration = {
number: 536860000
full_name: ".protobuf_editions_test.extension"
type: ".protobuf_editions_test.EmptyMessage"
}];
}
}
extend ParentMessage.ExtendedMessage {
EmptyMessage extension = 536860000;
}
message TestMessage {
message OptionalGroup {
int32 a = 17;
}
OptionalGroup optionalgroup = 16 [features.message_encoding = DELIMITED];
}
enum TestEnum {
FOO = 1; // Non-zero default
BAR = 2;
BAZ = 3;
NEG = -1; // Intentionally negative.
}

View File

@ -0,0 +1,37 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
package protobuf_editions_test.golden;
message SimpleProto2 {
optional int32 int32_field = 1;
}

View File

@ -0,0 +1,39 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
package protobuf_editions_test.golden;
import "google/protobuf/editions/golden/simple_proto2.proto";
message AnotherMessage {
optional SimpleProto2 field = 1;
}

View File

@ -0,0 +1,37 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package protobuf_editions_test.golden;
message SimpleProto3 {
optional int32 int32_field = 1;
}

View File

@ -0,0 +1,406 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Test schema for proto2 messages. This test schema is used by:
//
// - conformance tests
//
// LINT: ALLOW_GROUPS
edition = "2023";
import "google/protobuf/cpp_features.proto";
option features.enum_type = CLOSED;
option features.repeated_field_encoding = EXPANDED;
option features.string_field_validation = NONE;
option features.json_format = LEGACY_BEST_EFFORT;
option features.(pb.cpp).legacy_closed_enum = true;
package protobuf_test_messages.proto2;
option java_package = "com.google.protobuf_test_messages.proto2";
option objc_class_prefix = "Proto2";
// This is the default, but we specify it here explicitly.
option optimize_for = SPEED;
option cc_enable_arenas = true;
// This proto includes every type of field in both singular and repeated
// forms.
//
// Also, crucially, all messages and enums in this file are eventually
// submessages of this message. So for example, a fuzz test of TestAllTypes
// could trigger bugs that occur in any message type in this file. We verify
// this stays true in a unit test.
message TestAllTypesProto2 {
message NestedMessage {
int32 a = 1;
TestAllTypesProto2 corecursive = 2;
}
enum NestedEnum {
FOO = 0;
BAR = 1;
BAZ = 2;
NEG = -1; // Intentionally negative.
}
// Singular
int32 optional_int32 = 1;
int64 optional_int64 = 2;
uint32 optional_uint32 = 3;
uint64 optional_uint64 = 4;
sint32 optional_sint32 = 5;
sint64 optional_sint64 = 6;
fixed32 optional_fixed32 = 7;
fixed64 optional_fixed64 = 8;
sfixed32 optional_sfixed32 = 9;
sfixed64 optional_sfixed64 = 10;
float optional_float = 11;
double optional_double = 12;
bool optional_bool = 13;
string optional_string = 14;
bytes optional_bytes = 15;
NestedMessage optional_nested_message = 18;
ForeignMessageProto2 optional_foreign_message = 19;
NestedEnum optional_nested_enum = 21;
ForeignEnumProto2 optional_foreign_enum = 22;
string optional_string_piece = 24 [ctype = STRING_PIECE];
string optional_cord = 25 [ctype = CORD];
TestAllTypesProto2 recursive_message = 27;
// Repeated
repeated int32 repeated_int32 = 31;
repeated int64 repeated_int64 = 32;
repeated uint32 repeated_uint32 = 33;
repeated uint64 repeated_uint64 = 34;
repeated sint32 repeated_sint32 = 35;
repeated sint64 repeated_sint64 = 36;
repeated fixed32 repeated_fixed32 = 37;
repeated fixed64 repeated_fixed64 = 38;
repeated sfixed32 repeated_sfixed32 = 39;
repeated sfixed64 repeated_sfixed64 = 40;
repeated float repeated_float = 41;
repeated double repeated_double = 42;
repeated bool repeated_bool = 43;
repeated string repeated_string = 44;
repeated bytes repeated_bytes = 45;
repeated NestedMessage repeated_nested_message = 48;
repeated ForeignMessageProto2 repeated_foreign_message = 49;
repeated NestedEnum repeated_nested_enum = 51;
repeated ForeignEnumProto2 repeated_foreign_enum = 52;
repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];
repeated string repeated_cord = 55 [ctype = CORD];
// Packed
repeated int32 packed_int32 = 75 [features.repeated_field_encoding = PACKED];
repeated int64 packed_int64 = 76 [features.repeated_field_encoding = PACKED];
repeated uint32 packed_uint32 = 77 [features.repeated_field_encoding = PACKED];
repeated uint64 packed_uint64 = 78 [features.repeated_field_encoding = PACKED];
repeated sint32 packed_sint32 = 79 [features.repeated_field_encoding = PACKED];
repeated sint64 packed_sint64 = 80 [features.repeated_field_encoding = PACKED];
repeated fixed32 packed_fixed32 = 81 [features.repeated_field_encoding = PACKED];
repeated fixed64 packed_fixed64 = 82 [features.repeated_field_encoding = PACKED];
repeated sfixed32 packed_sfixed32 = 83 [features.repeated_field_encoding = PACKED];
repeated sfixed64 packed_sfixed64 = 84 [features.repeated_field_encoding = PACKED];
repeated float packed_float = 85 [features.repeated_field_encoding = PACKED];
repeated double packed_double = 86 [features.repeated_field_encoding = PACKED];
repeated bool packed_bool = 87 [features.repeated_field_encoding = PACKED];
repeated NestedEnum packed_nested_enum = 88 [features.repeated_field_encoding = PACKED];
// Unpacked
repeated int32 unpacked_int32 = 89;
repeated int64 unpacked_int64 = 90;
repeated uint32 unpacked_uint32 = 91;
repeated uint64 unpacked_uint64 = 92;
repeated sint32 unpacked_sint32 = 93;
repeated sint64 unpacked_sint64 = 94;
repeated fixed32 unpacked_fixed32 = 95;
repeated fixed64 unpacked_fixed64 = 96;
repeated sfixed32 unpacked_sfixed32 = 97;
repeated sfixed64 unpacked_sfixed64 = 98;
repeated float unpacked_float = 99;
repeated double unpacked_double = 100;
repeated bool unpacked_bool = 101;
repeated NestedEnum unpacked_nested_enum = 102;
// Map
map<int32, int32> map_int32_int32 = 56;
map<int64, int64> map_int64_int64 = 57;
map<uint32, uint32> map_uint32_uint32 = 58;
map<uint64, uint64> map_uint64_uint64 = 59;
map<sint32, sint32> map_sint32_sint32 = 60;
map<sint64, sint64> map_sint64_sint64 = 61;
map<fixed32, fixed32> map_fixed32_fixed32 = 62;
map<fixed64, fixed64> map_fixed64_fixed64 = 63;
map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 64;
map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 65;
map<int32, float> map_int32_float = 66;
map<int32, double> map_int32_double = 67;
map<bool, bool> map_bool_bool = 68;
map<string, string> map_string_string = 69;
map<string, bytes> map_string_bytes = 70;
map<string, NestedMessage> map_string_nested_message = 71;
map<string, ForeignMessageProto2> map_string_foreign_message = 72;
map<string, NestedEnum> map_string_nested_enum = 73;
map<string, ForeignEnumProto2> map_string_foreign_enum = 74;
oneof oneof_field {
uint32 oneof_uint32 = 111;
NestedMessage oneof_nested_message = 112;
string oneof_string = 113;
bytes oneof_bytes = 114;
bool oneof_bool = 115;
uint64 oneof_uint64 = 116;
float oneof_float = 117;
double oneof_double = 118;
NestedEnum oneof_enum = 119;
}
// extensions
extensions 120 to 200;
// groups
message Data {
int32 group_int32 = 202;
uint32 group_uint32 = 203;
}
Data data = 201 [features.message_encoding = DELIMITED];
// default values
int32 default_int32 = 241 [default = -123456789];
int64 default_int64 = 242 [default = -9123456789123456789];
uint32 default_uint32 = 243 [default = 2123456789];
uint64 default_uint64 = 244 [default = 10123456789123456789];
sint32 default_sint32 = 245 [default = -123456789];
sint64 default_sint64 = 246 [default = -9123456789123456789];
fixed32 default_fixed32 = 247 [default = 2123456789];
fixed64 default_fixed64 = 248 [default = 10123456789123456789];
sfixed32 default_sfixed32 = 249 [default = -123456789];
sfixed64 default_sfixed64 = 250 [default = -9123456789123456789];
float default_float = 251 [default = 9e9];
double default_double = 252 [default = 7e22];
bool default_bool = 253 [default = true];
string default_string = 254 [default = "Rosebud"];
bytes default_bytes = 255 [default = "joshua"];
// Test field-name-to-JSON-name convention.
// (protobuf says names can be any valid C/C++ identifier.)
int32 fieldname1 = 401;
int32 field_name2 = 402;
int32 _field_name3 = 403;
int32 field__name4_ = 404;
int32 field0name5 = 405;
int32 field_0_name6 = 406;
int32 fieldName7 = 407;
int32 FieldName8 = 408;
int32 field_Name9 = 409;
int32 Field_Name10 = 410;
int32 FIELD_NAME11 = 411;
int32 FIELD_name12 = 412;
int32 __field_name13 = 413;
int32 __Field_name14 = 414;
int32 field__name15 = 415;
int32 field__Name16 = 416;
int32 field_name17__ = 417;
int32 Field_name18__ = 418;
// Reserved for unknown fields test.
reserved 1000 to 9999;
// message_set test case.
message MessageSetCorrect {
option message_set_wire_format = true;
extensions 4 to max;
}
message MessageSetCorrectExtension1 {
extend MessageSetCorrect {
MessageSetCorrectExtension1 message_set_extension = 1547769;
}
string str = 25;
}
message MessageSetCorrectExtension2 {
extend MessageSetCorrect {
MessageSetCorrectExtension2 message_set_extension = 4135312;
}
int32 i = 9;
}
}
message ForeignMessageProto2 {
int32 c = 1;
}
enum ForeignEnumProto2 {
FOREIGN_FOO = 0;
FOREIGN_BAR = 1;
FOREIGN_BAZ = 2;
}
extend TestAllTypesProto2 {
int32 extension_int32 = 120;
}
message UnknownToTestAllTypes {
int32 optional_int32 = 1001;
string optional_string = 1002;
ForeignMessageProto2 nested_message = 1003;
message OptionalGroup {
int32 a = 1;
}
OptionalGroup optionalgroup = 1004 [features.message_encoding = DELIMITED];
bool optional_bool = 1006;
repeated int32 repeated_int32 = 1011;
}
message NullHypothesisProto2 {}
message EnumOnlyProto2 {
enum Bool {
kFalse = 0;
kTrue = 1;
}
}
message OneStringProto2 {
string data = 1;
}
message ProtoWithKeywords {
int32 inline = 1;
string concept = 2;
repeated string requires = 3;
}
message TestAllRequiredTypesProto2 {
message NestedMessage {
int32 a = 1 [features.field_presence = LEGACY_REQUIRED];
TestAllRequiredTypesProto2 corecursive = 2 [features.field_presence = LEGACY_REQUIRED];
TestAllRequiredTypesProto2 optional_corecursive = 3;
}
enum NestedEnum {
FOO = 0;
BAR = 1;
BAZ = 2;
NEG = -1; // Intentionally negative.
}
// Singular
int32 required_int32 = 1 [features.field_presence = LEGACY_REQUIRED];
int64 required_int64 = 2 [features.field_presence = LEGACY_REQUIRED];
uint32 required_uint32 = 3 [features.field_presence = LEGACY_REQUIRED];
uint64 required_uint64 = 4 [features.field_presence = LEGACY_REQUIRED];
sint32 required_sint32 = 5 [features.field_presence = LEGACY_REQUIRED];
sint64 required_sint64 = 6 [features.field_presence = LEGACY_REQUIRED];
fixed32 required_fixed32 = 7 [features.field_presence = LEGACY_REQUIRED];
fixed64 required_fixed64 = 8 [features.field_presence = LEGACY_REQUIRED];
sfixed32 required_sfixed32 = 9 [features.field_presence = LEGACY_REQUIRED];
sfixed64 required_sfixed64 = 10 [features.field_presence = LEGACY_REQUIRED];
float required_float = 11 [features.field_presence = LEGACY_REQUIRED];
double required_double = 12 [features.field_presence = LEGACY_REQUIRED];
bool required_bool = 13 [features.field_presence = LEGACY_REQUIRED];
string required_string = 14 [features.field_presence = LEGACY_REQUIRED];
bytes required_bytes = 15 [features.field_presence = LEGACY_REQUIRED];
NestedMessage required_nested_message = 18 [features.field_presence = LEGACY_REQUIRED];
ForeignMessageProto2 required_foreign_message = 19 [features.field_presence = LEGACY_REQUIRED];
NestedEnum required_nested_enum = 21 [features.field_presence = LEGACY_REQUIRED];
ForeignEnumProto2 required_foreign_enum = 22 [features.field_presence = LEGACY_REQUIRED];
string required_string_piece = 24 [ctype = STRING_PIECE, features.field_presence = LEGACY_REQUIRED];
string required_cord = 25 [ctype = CORD, features.field_presence = LEGACY_REQUIRED];
TestAllRequiredTypesProto2 recursive_message = 27 [features.field_presence = LEGACY_REQUIRED];
TestAllRequiredTypesProto2 optional_recursive_message = 28;
// extensions
extensions 120 to 200;
// groups
message Data {
int32 group_int32 = 202 [features.field_presence = LEGACY_REQUIRED];
uint32 group_uint32 = 203 [features.field_presence = LEGACY_REQUIRED];
}
Data data = 201 [features.message_encoding = DELIMITED, features.field_presence = LEGACY_REQUIRED];
// default values
int32 default_int32 = 241 [default = -123456789, features.field_presence = LEGACY_REQUIRED];
int64 default_int64 = 242 [default = -9123456789123456789, features.field_presence = LEGACY_REQUIRED];
uint32 default_uint32 = 243 [default = 2123456789, features.field_presence = LEGACY_REQUIRED];
uint64 default_uint64 = 244 [default = 10123456789123456789, features.field_presence = LEGACY_REQUIRED];
sint32 default_sint32 = 245 [default = -123456789, features.field_presence = LEGACY_REQUIRED];
sint64 default_sint64 = 246 [default = -9123456789123456789, features.field_presence = LEGACY_REQUIRED];
fixed32 default_fixed32 = 247 [default = 2123456789, features.field_presence = LEGACY_REQUIRED];
fixed64 default_fixed64 = 248 [default = 10123456789123456789, features.field_presence = LEGACY_REQUIRED];
sfixed32 default_sfixed32 = 249 [default = -123456789, features.field_presence = LEGACY_REQUIRED];
sfixed64 default_sfixed64 = 250 [default = -9123456789123456789, features.field_presence = LEGACY_REQUIRED];
float default_float = 251 [default = 9e9, features.field_presence = LEGACY_REQUIRED];
double default_double = 252 [default = 7e22, features.field_presence = LEGACY_REQUIRED];
bool default_bool = 253 [default = true, features.field_presence = LEGACY_REQUIRED];
string default_string = 254 [default = "Rosebud", features.field_presence = LEGACY_REQUIRED];
bytes default_bytes = 255 [default = "joshua", features.field_presence = LEGACY_REQUIRED];
// Reserved for unknown fields test.
reserved 1000 to 9999;
// message_set test case.
message MessageSetCorrect {
option message_set_wire_format = true;
extensions 4 to max;
}
message MessageSetCorrectExtension1 {
extend MessageSetCorrect {
MessageSetCorrectExtension1 message_set_extension = 1547769;
}
string str = 25 [features.field_presence = LEGACY_REQUIRED];
}
message MessageSetCorrectExtension2 {
extend MessageSetCorrect {
MessageSetCorrectExtension2 message_set_extension = 4135312;
}
int32 i = 9 [features.field_presence = LEGACY_REQUIRED];
}
}

View File

@ -0,0 +1,289 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Test schema for proto3 messages. This test schema is used by:
//
// - benchmarks
// - fuzz tests
// - conformance tests
//
edition = "2023";
option features.field_presence = IMPLICIT;
package protobuf_test_messages.proto3;
option java_package = "com.google.protobuf_test_messages.proto3";
option objc_class_prefix = "Proto3";
// This is the default, but we specify it here explicitly.
option optimize_for = SPEED;
import "google/protobuf/any.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
option cc_enable_arenas = true;
// This proto includes every type of field in both singular and repeated
// forms.
//
// Also, crucially, all messages and enums in this file are eventually
// submessages of this message. So for example, a fuzz test of TestAllTypes
// could trigger bugs that occur in any message type in this file. We verify
// this stays true in a unit test.
message TestAllTypesProto3 {
message NestedMessage {
int32 a = 1;
TestAllTypesProto3 corecursive = 2;
}
enum NestedEnum {
FOO = 0;
BAR = 1;
BAZ = 2;
NEG = -1; // Intentionally negative.
}
enum AliasedEnum {
option allow_alias = true;
ALIAS_FOO = 0;
ALIAS_BAR = 1;
ALIAS_BAZ = 2;
MOO = 2;
moo = 2;
bAz = 2;
}
// Singular
int32 optional_int32 = 1;
int64 optional_int64 = 2;
uint32 optional_uint32 = 3;
uint64 optional_uint64 = 4;
sint32 optional_sint32 = 5;
sint64 optional_sint64 = 6;
fixed32 optional_fixed32 = 7;
fixed64 optional_fixed64 = 8;
sfixed32 optional_sfixed32 = 9;
sfixed64 optional_sfixed64 = 10;
float optional_float = 11;
double optional_double = 12;
bool optional_bool = 13;
string optional_string = 14;
bytes optional_bytes = 15;
NestedMessage optional_nested_message = 18;
ForeignMessage optional_foreign_message = 19;
NestedEnum optional_nested_enum = 21;
ForeignEnum optional_foreign_enum = 22;
AliasedEnum optional_aliased_enum = 23;
string optional_string_piece = 24 [ctype = STRING_PIECE];
string optional_cord = 25 [ctype = CORD];
TestAllTypesProto3 recursive_message = 27;
// Repeated
repeated int32 repeated_int32 = 31;
repeated int64 repeated_int64 = 32;
repeated uint32 repeated_uint32 = 33;
repeated uint64 repeated_uint64 = 34;
repeated sint32 repeated_sint32 = 35;
repeated sint64 repeated_sint64 = 36;
repeated fixed32 repeated_fixed32 = 37;
repeated fixed64 repeated_fixed64 = 38;
repeated sfixed32 repeated_sfixed32 = 39;
repeated sfixed64 repeated_sfixed64 = 40;
repeated float repeated_float = 41;
repeated double repeated_double = 42;
repeated bool repeated_bool = 43;
repeated string repeated_string = 44;
repeated bytes repeated_bytes = 45;
repeated NestedMessage repeated_nested_message = 48;
repeated ForeignMessage repeated_foreign_message = 49;
repeated NestedEnum repeated_nested_enum = 51;
repeated ForeignEnum repeated_foreign_enum = 52;
repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];
repeated string repeated_cord = 55 [ctype = CORD];
// Packed
repeated int32 packed_int32 = 75;
repeated int64 packed_int64 = 76;
repeated uint32 packed_uint32 = 77;
repeated uint64 packed_uint64 = 78;
repeated sint32 packed_sint32 = 79;
repeated sint64 packed_sint64 = 80;
repeated fixed32 packed_fixed32 = 81;
repeated fixed64 packed_fixed64 = 82;
repeated sfixed32 packed_sfixed32 = 83;
repeated sfixed64 packed_sfixed64 = 84;
repeated float packed_float = 85;
repeated double packed_double = 86;
repeated bool packed_bool = 87;
repeated NestedEnum packed_nested_enum = 88;
// Unpacked
repeated int32 unpacked_int32 = 89 [features.repeated_field_encoding = EXPANDED];
repeated int64 unpacked_int64 = 90 [features.repeated_field_encoding = EXPANDED];
repeated uint32 unpacked_uint32 = 91 [features.repeated_field_encoding = EXPANDED];
repeated uint64 unpacked_uint64 = 92 [features.repeated_field_encoding = EXPANDED];
repeated sint32 unpacked_sint32 = 93 [features.repeated_field_encoding = EXPANDED];
repeated sint64 unpacked_sint64 = 94 [features.repeated_field_encoding = EXPANDED];
repeated fixed32 unpacked_fixed32 = 95 [features.repeated_field_encoding = EXPANDED];
repeated fixed64 unpacked_fixed64 = 96 [features.repeated_field_encoding = EXPANDED];
repeated sfixed32 unpacked_sfixed32 = 97 [features.repeated_field_encoding = EXPANDED];
repeated sfixed64 unpacked_sfixed64 = 98 [features.repeated_field_encoding = EXPANDED];
repeated float unpacked_float = 99 [features.repeated_field_encoding = EXPANDED];
repeated double unpacked_double = 100 [features.repeated_field_encoding = EXPANDED];
repeated bool unpacked_bool = 101 [features.repeated_field_encoding = EXPANDED];
repeated NestedEnum unpacked_nested_enum = 102 [features.repeated_field_encoding = EXPANDED];
// Map
map<int32, int32> map_int32_int32 = 56;
map<int64, int64> map_int64_int64 = 57;
map<uint32, uint32> map_uint32_uint32 = 58;
map<uint64, uint64> map_uint64_uint64 = 59;
map<sint32, sint32> map_sint32_sint32 = 60;
map<sint64, sint64> map_sint64_sint64 = 61;
map<fixed32, fixed32> map_fixed32_fixed32 = 62;
map<fixed64, fixed64> map_fixed64_fixed64 = 63;
map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 64;
map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 65;
map<int32, float> map_int32_float = 66;
map<int32, double> map_int32_double = 67;
map<bool, bool> map_bool_bool = 68;
map<string, string> map_string_string = 69;
map<string, bytes> map_string_bytes = 70;
map<string, NestedMessage> map_string_nested_message = 71;
map<string, ForeignMessage> map_string_foreign_message = 72;
map<string, NestedEnum> map_string_nested_enum = 73;
map<string, ForeignEnum> map_string_foreign_enum = 74;
oneof oneof_field {
uint32 oneof_uint32 = 111;
NestedMessage oneof_nested_message = 112;
string oneof_string = 113;
bytes oneof_bytes = 114;
bool oneof_bool = 115;
uint64 oneof_uint64 = 116;
float oneof_float = 117;
double oneof_double = 118;
NestedEnum oneof_enum = 119;
google.protobuf.NullValue oneof_null_value = 120;
}
// Well-known types
google.protobuf.BoolValue optional_bool_wrapper = 201;
google.protobuf.Int32Value optional_int32_wrapper = 202;
google.protobuf.Int64Value optional_int64_wrapper = 203;
google.protobuf.UInt32Value optional_uint32_wrapper = 204;
google.protobuf.UInt64Value optional_uint64_wrapper = 205;
google.protobuf.FloatValue optional_float_wrapper = 206;
google.protobuf.DoubleValue optional_double_wrapper = 207;
google.protobuf.StringValue optional_string_wrapper = 208;
google.protobuf.BytesValue optional_bytes_wrapper = 209;
repeated google.protobuf.BoolValue repeated_bool_wrapper = 211;
repeated google.protobuf.Int32Value repeated_int32_wrapper = 212;
repeated google.protobuf.Int64Value repeated_int64_wrapper = 213;
repeated google.protobuf.UInt32Value repeated_uint32_wrapper = 214;
repeated google.protobuf.UInt64Value repeated_uint64_wrapper = 215;
repeated google.protobuf.FloatValue repeated_float_wrapper = 216;
repeated google.protobuf.DoubleValue repeated_double_wrapper = 217;
repeated google.protobuf.StringValue repeated_string_wrapper = 218;
repeated google.protobuf.BytesValue repeated_bytes_wrapper = 219;
google.protobuf.Duration optional_duration = 301;
google.protobuf.Timestamp optional_timestamp = 302;
google.protobuf.FieldMask optional_field_mask = 303;
google.protobuf.Struct optional_struct = 304;
google.protobuf.Any optional_any = 305;
google.protobuf.Value optional_value = 306;
google.protobuf.NullValue optional_null_value = 307;
repeated google.protobuf.Duration repeated_duration = 311;
repeated google.protobuf.Timestamp repeated_timestamp = 312;
repeated google.protobuf.FieldMask repeated_fieldmask = 313;
repeated google.protobuf.Struct repeated_struct = 324;
repeated google.protobuf.Any repeated_any = 315;
repeated google.protobuf.Value repeated_value = 316;
repeated google.protobuf.ListValue repeated_list_value = 317;
// Test field-name-to-JSON-name convention.
// (protobuf says names can be any valid C/C++ identifier.)
int32 fieldname1 = 401;
int32 field_name2 = 402;
int32 _field_name3 = 403;
int32 field__name4_ = 404;
int32 field0name5 = 405;
int32 field_0_name6 = 406;
int32 fieldName7 = 407;
int32 FieldName8 = 408;
int32 field_Name9 = 409;
int32 Field_Name10 = 410;
int32 FIELD_NAME11 = 411;
int32 FIELD_name12 = 412;
int32 __field_name13 = 413;
int32 __Field_name14 = 414;
int32 field__name15 = 415;
int32 field__Name16 = 416;
int32 field_name17__ = 417;
int32 Field_name18__ = 418;
// Reserved for testing unknown fields
reserved 501 to 510;
}
message ForeignMessage {
int32 c = 1;
}
enum ForeignEnum {
FOREIGN_FOO = 0;
FOREIGN_BAR = 1;
FOREIGN_BAZ = 2;
}
message NullHypothesisProto3 {}
message EnumOnlyProto3 {
enum Bool {
kFalse = 0;
kTrue = 1;
}
}

View File

@ -0,0 +1,89 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
// This file contains various edge cases we've collected from migrating real
// protos in order to lock down the transformations.
// LINT: ALLOW_GROUPS
package protobuf_editions_test;
option java_multiple_files = true;
option cc_enable_arenas = true;
message EmptyMessage {}
message EmptyMessage2 {}
service EmptyService {}
service BasicService {
rpc BasicMethod(EmptyMessage) returns (EmptyMessage) {}
}
// clang-format off
message UnformattedMessage{
optional int32 a=1 ;
optional group Foo = 2 { optional int32 a = 1; }
optional string string_piece_with_zero = 3 [ctype=STRING_PIECE,
default="ab\000c"];
optional float
long_float_name_wrapped = 4;
}
// clang-format on
message ParentMessage {
message ExtendedMessage {
extensions 536860000 to 536869999 [declaration = {
number: 536860000
full_name: ".protobuf_editions_test.extension"
type: ".protobuf_editions_test.EmptyMessage"
}];
}
}
extend ParentMessage.ExtendedMessage {
optional EmptyMessage extension = 536860000;
}
message TestMessage {
optional group OptionalGroup = 16 {
optional int32 a = 17;
}
}
enum TestEnum {
FOO = 1; // Non-zero default
BAR = 2;
BAZ = 3;
NEG = -1; // Intentionally negative.
}

View File

@ -0,0 +1,179 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2023 Google Inc. All rights reserved.
# https://developers.google.com/protocol-buffers/
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
noop = 0
function join(array, len, sep)
{
if(len== 0) {
return ""
}
result = array[1]
for (i = 2; i <= len; i++)
result = result sep array[i]
return result
}
function transform_field(field)
{
if (!match(field, /\w+\s*=\s*[0-9-]+/)) {
return field
}
if (match(field, /(.*[0-9])\s*\[(.*)\];(.*)/, arr)) {
field_def = arr[1]
existing_options = arr[2]
field_comments = arr[3]
} else {
match(field, /(.*);(.*)/, arr)
field_def = arr[1]
field_comments = arr[2]
existing_options = 0
}
num_options = 0
if(syntax == 2) {
sub(/\<optional /, "", field_def)
sub(/\<packed = true\>/, "features.repeated_field_encoding = PACKED", existing_options)
sub(/\<packed = false\>,/, "", existing_options)
sub(/,?packed = false\>/, "", existing_options)
if (match($0, /\<required\>/)) {
sub(/\<required /, "", field_def)
options[++num_options] = "features.field_presence = LEGACY_REQUIRED"
}
}
if(syntax == 3) {
sub(/\<packed = false\>/, "features.repeated_field_encoding = EXPANDED", existing_options)
sub(/\<packed = true\>,/, "", existing_options)
sub(/,?packed = true\>/, "", existing_options)
if (match($0, /\<optional\>/)) {
sub(/\<optional /, "", field_def)
options[++num_options] = "features.field_presence = EXPLICIT"
}
}
if (existing_options && num_options > 0) {
ret = field_def " [" existing_options ", " join(options, num_options, ",") "];" field_comments
} else if (existing_options) {
ret = field_def " [" existing_options "];" field_comments
} else if(num_options > 0) {
ret = field_def " [" join(options, num_options, ",") "];" field_comments
} else {
ret = field_def ";" field_comments
}
delete options
return ret
}
# Skip comments
/^\s*\/\// {
print $0
next
}
/syntax = "proto2"/ {
print "edition = \"2023\";"
print "import \"third_party/protobuf/cpp_features.proto\";"
print "option features.enum_type = CLOSED;"
print "option features.repeated_field_encoding = EXPANDED;"
print "option features.string_field_validation = NONE;"
print "option features.json_format = LEGACY_BEST_EFFORT;"
print "option features.(pb.cpp).legacy_closed_enum = true;"
syntax = 2
next
}
/syntax = "proto3"/ {
print "edition = \"2023\";"
print "option features.field_presence = IMPLICIT;"
syntax = 3
next
}
# Group handling.
/\<group \w* = [0-9]* {/, /}/ {
if (match($0, /\<group\>/)) {
match($0, /(\s*)(\w*)\s*group\s*(\w*)\s*=\s*([0-9]*)\s*{(\s*[^}]*}?)/, arr)
if (arr[0, "length"] == 0) {
print("[ERROR] Invalid group match: ", $0)
exit
}
current_group_whitespace = arr[1]
current_group_presence = arr[2]
current_group_name = arr[3]
current_group_number = arr[4]
current_group_extra = transform_field(arr[5])
print current_group_whitespace "message", current_group_name, "{" current_group_extra
} else if (match($0, /}/)) {
print $0
}
if (match($0, /}/)) {
$0 = current_group_whitespace current_group_presence " " current_group_name " " tolower(current_group_name) " = " current_group_number " [features.message_encoding = DELIMITED];"
} else if (match($0, /\<group\>/)) {
next
}
}
# Skip declarations we don't transform.
/^\s*(message|enum|oneof|extend|service)\s+(\w|\.)*\s*{/ {
noop = 1
}
/^\s*rpc\s+\w*\s*\(/ {
noop = 1
}
/^\s*(}|\/\/|$)/ {
noop = 1
}
/^\s*(extensions|package|reserved|import) .*;/ {
noop = 1
}
/^\s*option\s+[a-zA-Z0-9._()]*\s*=.*;/ {
noop = 1
}
/\s*extensions.* \[/, /\]/ {
noop = 1
}
noop {
print $0
next
}
/./, /;/ {
if (buffered_field != "") {
sub(/\s+/, " ", $0)
}
buffered_field = (buffered_field $0)
if (!match($0, /;/)) {
next
}
print(transform_field(buffered_field))
buffered_field = ""
}

View File

@ -76,6 +76,9 @@ class Message; // message.h
class MessageFactory; // message.h
class Reflection; // message.h
class UnknownFieldSet; // unknown_field_set.h
#ifdef PROTOBUF_FUTURE_EDITIONS
class FeatureSet;
#endif // PROTOBUF_FUTURE_EDITIONS
namespace internal {
class FieldSkipper; // wire_format_lite.h
class WireFormat;
@ -83,6 +86,11 @@ enum class LazyVerifyOption;
} // namespace internal
} // namespace protobuf
} // namespace google
#ifdef PROTOBUF_FUTURE_EDITIONS
namespace pb {
class CppFeatures;
} // namespace pb
#endif // PROTOBUF_FUTURE_EDITIONS
namespace google {
namespace protobuf {
@ -1537,6 +1545,39 @@ class ExtensionIdentifier {
extern PROTOBUF_ATTRIBUTE_WEAK ExtensionSet::LazyMessageExtension*
MaybeCreateLazyExtension(Arena* arena);
#ifdef PROTOBUF_FUTURE_EDITIONS
// Define a specialization of ExtensionIdentifier for bootstrapped extensions
// that we need to register lazily.
template <>
class ExtensionIdentifier<FeatureSet, MessageTypeTraits<::pb::CppFeatures>, 11,
false> {
public:
explicit constexpr ExtensionIdentifier(int number) : number_(number) {}
int number() const { return number_; }
const ::pb::CppFeatures& default_value() const { return *default_value_; }
template <typename MessageType = ::pb::CppFeatures,
typename ExtendeeType = FeatureSet>
void LazyRegister(
const MessageType& default_instance = MessageType::default_instance(),
LazyEagerVerifyFnType verify_func = nullptr) const {
absl::call_once(once_, [&] {
default_value_ = &default_instance;
MessageTypeTraits<MessageType>::template Register<ExtendeeType>(
number_, 11, false, verify_func);
});
}
const ::pb::CppFeatures& default_value_ref() const { return *default_value_; }
private:
const int number_;
mutable const ::pb::CppFeatures* default_value_ = nullptr;
mutable absl::once_flag once_;
};
#endif // PROTOBUF_FUTURE_EDITIONS
} // namespace internal

View File

@ -0,0 +1,279 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "google/protobuf/feature_resolver.h"
#include <algorithm>
#include <iterator>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/algorithm/container.h"
#include "absl/log/absl_check.h"
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/dynamic_message.h"
#include "google/protobuf/message.h"
#include "google/protobuf/reflection_ops.h"
#include "google/protobuf/text_format.h"
// Must be included last.
#include "google/protobuf/port_def.inc"
#define RETURN_IF_ERROR(expr) \
do { \
const absl::Status _status = (expr); \
if (PROTOBUF_PREDICT_FALSE(!_status.ok())) return _status; \
} while (0)
namespace google {
namespace protobuf {
namespace {
template <typename... Args>
absl::Status Error(Args... args) {
return absl::FailedPreconditionError(absl::StrCat(args...));
}
bool EditionsLessThan(absl::string_view a, absl::string_view b) {
std::vector<absl::string_view> as = absl::StrSplit(a, '.');
std::vector<absl::string_view> bs = absl::StrSplit(b, '.');
size_t min_size = std::min(as.size(), bs.size());
for (size_t i = 0; i < min_size; ++i) {
if (as[i].size() != bs[i].size()) {
return as[i].size() < bs[i].size();
} else if (as[i] != bs[i]) {
return as[i] < bs[i];
}
}
// Both strings are equal up until an extra element, which makes that string
// more recent.
return as.size() < bs.size();
}
absl::Status ValidateDescriptor(absl::string_view edition,
const Descriptor& descriptor) {
if (descriptor.oneof_decl_count() > 0) {
return Error("Type ", descriptor.full_name(),
" contains unsupported oneof feature fields.");
}
for (int i = 0; i < descriptor.field_count(); ++i) {
const FieldDescriptor& field = *descriptor.field(i);
if (field.is_required()) {
return Error("Feature field ", field.full_name(),
" is an unsupported required field.");
}
if (field.is_repeated()) {
return Error("Feature field ", field.full_name(),
" is an unsupported repeated field.");
}
if (field.options().targets().empty()) {
return Error("Feature field ", field.full_name(),
" has no target specified.");
}
}
return absl::OkStatus();
}
absl::Status FillDefaults(absl::string_view edition, Message& msg) {
const Descriptor& descriptor = *msg.GetDescriptor();
auto comparator = [](const FieldOptions::EditionDefault& a,
const FieldOptions::EditionDefault& b) {
return EditionsLessThan(a.edition(), b.edition());
};
FieldOptions::EditionDefault edition_lookup;
edition_lookup.set_edition(edition);
for (int i = 0; i < descriptor.field_count(); ++i) {
const FieldDescriptor& field = *descriptor.field(i);
msg.GetReflection()->ClearField(&msg, &field);
ABSL_CHECK(!field.is_repeated());
std::vector<FieldOptions::EditionDefault> defaults{
field.options().edition_defaults().begin(),
field.options().edition_defaults().end()};
absl::c_sort(defaults, comparator);
auto first_nonmatch =
absl::c_upper_bound(defaults, edition_lookup, comparator);
if (first_nonmatch == defaults.begin()) {
return Error("No valid default found for edition ", edition,
" in feature field ", field.full_name());
}
if (field.cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
for (auto it = defaults.begin(); it != first_nonmatch; ++it) {
if (!TextFormat::MergeFromString(
it->value(),
msg.GetReflection()->MutableMessage(&msg, &field))) {
return Error("Parsing error in edition_defaults for feature field ",
field.full_name(), ". Could not parse: ", it->value());
}
}
} else {
const std::string& def = std::prev(first_nonmatch)->value();
if (!TextFormat::ParseFieldValueFromString(def, &field, &msg)) {
return Error("Parsing error in edition_defaults for feature field ",
field.full_name(), ". Could not parse: ", def);
}
}
}
return absl::OkStatus();
}
absl::Status ValidateMergedFeatures(const Message& msg) {
const Descriptor& descriptor = *msg.GetDescriptor();
const Reflection& reflection = *msg.GetReflection();
for (int i = 0; i < descriptor.field_count(); ++i) {
const FieldDescriptor& field = *descriptor.field(i);
// Validate enum features.
if (field.enum_type() != nullptr) {
ABSL_DCHECK(reflection.HasField(msg, &field));
int int_value = reflection.GetEnumValue(msg, &field);
const EnumValueDescriptor* value =
field.enum_type()->FindValueByNumber(int_value);
ABSL_DCHECK(value != nullptr);
if (value->number() == 0) {
return Error("Feature field ", field.full_name(),
" must resolve to a known value, found ", value->name());
}
}
}
return absl::OkStatus();
}
} // namespace
absl::StatusOr<FeatureResolver> FeatureResolver::Create(
absl::string_view edition, const Descriptor* descriptor) {
if (descriptor == nullptr) {
return Error(
"Unable to find definition of google.protobuf.FeatureSet in descriptor pool.");
}
RETURN_IF_ERROR(ValidateDescriptor(edition, *descriptor));
auto message_factory = absl::make_unique<DynamicMessageFactory>();
auto defaults =
absl::WrapUnique(message_factory->GetPrototype(descriptor)->New());
RETURN_IF_ERROR(FillDefaults(edition, *defaults));
return FeatureResolver(edition, *descriptor, std::move(message_factory),
std::move(defaults));
}
absl::Status FeatureResolver::RegisterExtension(
const FieldDescriptor& extension) {
if (!extension.is_extension() ||
extension.containing_type() != &descriptor_ ||
extensions_.contains(&extension)) {
// These are valid but irrelevant extensions, just return ok.
return absl::OkStatus();
}
ABSL_CHECK(descriptor_.IsExtensionNumber(extension.number()));
if (extension.message_type() == nullptr) {
return Error("FeatureSet extension ", extension.full_name(),
" is not of message type. Feature extensions should "
"always use messages to allow for evolution.");
}
if (extension.is_repeated()) {
return Error(
"Only singular features extensions are supported. Found "
"repeated extension ",
extension.full_name());
}
if (extension.message_type()->extension_count() > 0 ||
extension.message_type()->extension_range_count() > 0) {
return Error("Nested extensions in feature extension ",
extension.full_name(), " are not supported.");
}
RETURN_IF_ERROR(ValidateDescriptor(edition_, *extension.message_type()));
Message* msg =
defaults_->GetReflection()->MutableMessage(defaults_.get(), &extension);
ABSL_CHECK(msg != nullptr);
RETURN_IF_ERROR(FillDefaults(edition_, *msg));
extensions_.insert(&extension);
return absl::OkStatus();
}
absl::Status FeatureResolver::RegisterExtensions(const FileDescriptor& file) {
for (int i = 0; i < file.extension_count(); ++i) {
RETURN_IF_ERROR(RegisterExtension(*file.extension(i)));
}
for (int i = 0; i < file.message_type_count(); ++i) {
RETURN_IF_ERROR(RegisterExtensions(*file.message_type(i)));
}
return absl::OkStatus();
}
absl::Status FeatureResolver::RegisterExtensions(const Descriptor& message) {
for (int i = 0; i < message.extension_count(); ++i) {
RETURN_IF_ERROR(RegisterExtension(*message.extension(i)));
}
for (int i = 0; i < message.nested_type_count(); ++i) {
RETURN_IF_ERROR(RegisterExtensions(*message.nested_type(i)));
}
return absl::OkStatus();
}
absl::StatusOr<FeatureSet> FeatureResolver::MergeFeatures(
const FeatureSet& merged_parent, const FeatureSet& unmerged_child) const {
FeatureSet merged;
ABSL_CHECK(merged.ParseFromString(defaults_->SerializeAsString()));
merged.MergeFrom(merged_parent);
merged.MergeFrom(unmerged_child);
RETURN_IF_ERROR(ValidateMergedFeatures(merged));
return merged;
}
} // namespace protobuf
} // namespace google
#include "google/protobuf/port_undef.inc"

View File

@ -0,0 +1,99 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_FEATURE_RESOLVER_H__
#define GOOGLE_PROTOBUF_FEATURE_RESOLVER_H__
#include <memory>
#include <string>
#include <utility>
#include "absl/container/flat_hash_set.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/dynamic_message.h"
// Must be included last.
#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
// These helpers implement the unique behaviors of edition features. For more
// details, see go/protobuf-editions-features.
class PROTOBUF_EXPORT FeatureResolver {
public:
FeatureResolver(FeatureResolver&&) = default;
FeatureResolver& operator=(FeatureResolver&&) = delete;
// Creates a new FeatureResolver at a specific edition. This validates the
// built-in features for the given edition, and calculates the default feature
// set.
static absl::StatusOr<FeatureResolver> Create(absl::string_view edition,
const Descriptor* descriptor);
// Registers a potential extension of the FeatureSet proto. Any visible
// extensions will be used during merging. Returns an error if the extension
// is a feature extension but fails validation.
absl::Status RegisterExtensions(const FileDescriptor& file);
// Creates a new feature set using inheritance and default behavior. This is
// designed to be called recursively, and the parent feature set is expected
// to be a fully merged one.
absl::StatusOr<FeatureSet> MergeFeatures(
const FeatureSet& merged_parent, const FeatureSet& unmerged_child) const;
private:
FeatureResolver(absl::string_view edition, const Descriptor& descriptor,
std::unique_ptr<DynamicMessageFactory> message_factory,
std::unique_ptr<Message> defaults)
: edition_(edition),
descriptor_(descriptor),
message_factory_(std::move(message_factory)),
defaults_(std::move(defaults)) {}
absl::Status RegisterExtensions(const Descriptor& message);
absl::Status RegisterExtension(const FieldDescriptor& extension);
std::string edition_;
const Descriptor& descriptor_;
absl::flat_hash_set<const FieldDescriptor*> extensions_;
std::unique_ptr<DynamicMessageFactory> message_factory_;
std::unique_ptr<Message> defaults_;
};
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_FEATURE_RESOLVER_H__
#include "google/protobuf/port_undef.inc"

View File

@ -0,0 +1,857 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "google/protobuf/feature_resolver.h"
#include <vector>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "google/protobuf/compiler/parser.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/io/tokenizer.h"
#include "google/protobuf/test_textproto.h"
#include "google/protobuf/text_format.h"
#include "google/protobuf/unittest_custom_options.pb.h"
#include "google/protobuf/unittest_features.pb.h"
#include "google/protobuf/stubs/status_macros.h"
// Must be included last.
#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
namespace {
using ::testing::AllOf;
using ::testing::ExplainMatchResult;
using ::testing::HasSubstr;
// TODO(b/234474291): Use the gtest versions once that's available in OSS.
absl::Status GetStatus(const absl::Status& s) { return s; }
template <typename T>
absl::Status GetStatus(const absl::StatusOr<T>& s) {
return s.status();
}
MATCHER_P(HasError, msg_matcher, "") {
return GetStatus(arg).code() == absl::StatusCode::kFailedPrecondition &&
ExplainMatchResult(msg_matcher, GetStatus(arg).message(),
result_listener);
}
MATCHER_P(StatusIs, status,
absl::StrCat(".status() is ", testing::PrintToString(status))) {
return GetStatus(arg).code() == status;
}
#define EXPECT_OK(x) EXPECT_THAT(x, StatusIs(absl::StatusCode::kOk))
#define ASSERT_OK(x) ASSERT_THAT(x, StatusIs(absl::StatusCode::kOk))
template <typename ExtensionT>
const FileDescriptor& GetExtensionFile(
const ExtensionT& ext,
const Descriptor* descriptor = FeatureSet::descriptor()) {
return *DescriptorPool::generated_pool()
->FindExtensionByNumber(descriptor, ext.number())
->file();
}
template <typename... Extensions>
absl::StatusOr<FeatureResolver> SetupFeatureResolver(absl::string_view edition,
Extensions... extensions) {
auto resolver = FeatureResolver::Create(edition, FeatureSet::descriptor());
RETURN_IF_ERROR(resolver.status());
std::vector<absl::Status> results{
resolver->RegisterExtensions(GetExtensionFile(extensions))...};
for (absl::Status result : results) {
RETURN_IF_ERROR(result);
}
return resolver;
}
template <typename... Extensions>
absl::StatusOr<FeatureSet> GetDefaults(absl::string_view edition,
Extensions... extensions) {
absl::StatusOr<FeatureResolver> resolver =
SetupFeatureResolver(edition, extensions...);
RETURN_IF_ERROR(resolver.status());
FeatureSet parent, child;
return resolver->MergeFeatures(parent, child);
}
TEST(FeatureResolverTest, DefaultsCore2023) {
absl::StatusOr<FeatureSet> merged = GetDefaults("2023");
ASSERT_OK(merged);
EXPECT_EQ(merged->field_presence(), FeatureSet::EXPLICIT);
EXPECT_EQ(merged->enum_type(), FeatureSet::OPEN);
EXPECT_EQ(merged->repeated_field_encoding(), FeatureSet::PACKED);
EXPECT_EQ(merged->string_field_validation(), FeatureSet::MANDATORY);
EXPECT_EQ(merged->message_encoding(), FeatureSet::LENGTH_PREFIXED);
}
TEST(FeatureResolverTest, DefaultsTest2023) {
absl::StatusOr<FeatureSet> merged = GetDefaults("2023", pb::test);
ASSERT_OK(merged);
EXPECT_EQ(merged->field_presence(), FeatureSet::EXPLICIT);
EXPECT_EQ(merged->enum_type(), FeatureSet::OPEN);
EXPECT_EQ(merged->repeated_field_encoding(), FeatureSet::PACKED);
EXPECT_EQ(merged->string_field_validation(), FeatureSet::MANDATORY);
EXPECT_EQ(merged->message_encoding(), FeatureSet::LENGTH_PREFIXED);
const pb::TestFeatures& ext = merged->GetExtension(pb::test);
EXPECT_EQ(ext.int_file_feature(), 1);
EXPECT_EQ(ext.int_extension_range_feature(), 1);
EXPECT_EQ(ext.int_message_feature(), 1);
EXPECT_EQ(ext.int_field_feature(), 1);
EXPECT_EQ(ext.int_oneof_feature(), 1);
EXPECT_EQ(ext.int_enum_feature(), 1);
EXPECT_EQ(ext.int_enum_entry_feature(), 1);
EXPECT_EQ(ext.int_service_feature(), 1);
EXPECT_EQ(ext.int_method_feature(), 1);
EXPECT_EQ(ext.bool_field_feature(), false);
EXPECT_FLOAT_EQ(ext.float_field_feature(), 1.1);
EXPECT_THAT(ext.message_field_feature(),
EqualsProto("bool_field: true int_field: 1 float_field: 1.5 "
"string_field: '2023'"));
EXPECT_EQ(ext.enum_field_feature(), pb::TestFeatures::ENUM_VALUE1);
}
TEST(FeatureResolverTest, DefaultsTestMessageExtension) {
absl::StatusOr<FeatureSet> merged =
GetDefaults("2023", pb::TestMessage::test_message);
ASSERT_OK(merged);
EXPECT_EQ(merged->field_presence(), FeatureSet::EXPLICIT);
EXPECT_EQ(merged->enum_type(), FeatureSet::OPEN);
EXPECT_EQ(merged->repeated_field_encoding(), FeatureSet::PACKED);
EXPECT_EQ(merged->string_field_validation(), FeatureSet::MANDATORY);
EXPECT_EQ(merged->message_encoding(), FeatureSet::LENGTH_PREFIXED);
const pb::TestFeatures& ext = merged->GetExtension(pb::test);
EXPECT_EQ(ext.int_file_feature(), 1);
EXPECT_EQ(ext.int_extension_range_feature(), 1);
EXPECT_EQ(ext.int_message_feature(), 1);
EXPECT_EQ(ext.int_field_feature(), 1);
EXPECT_EQ(ext.int_oneof_feature(), 1);
EXPECT_EQ(ext.int_enum_feature(), 1);
EXPECT_EQ(ext.int_enum_entry_feature(), 1);
EXPECT_EQ(ext.int_service_feature(), 1);
EXPECT_EQ(ext.int_method_feature(), 1);
EXPECT_EQ(ext.bool_field_feature(), false);
EXPECT_FLOAT_EQ(ext.float_field_feature(), 1.1);
EXPECT_THAT(ext.message_field_feature(),
EqualsProto("bool_field: true int_field: 1 float_field: 1.5 "
"string_field: '2023'"));
EXPECT_EQ(ext.enum_field_feature(), pb::TestFeatures::ENUM_VALUE1);
}
TEST(FeatureResolverTest, DefaultsTestNestedExtension) {
absl::StatusOr<FeatureSet> merged =
GetDefaults("2023", pb::TestMessage::Nested::test_nested);
ASSERT_OK(merged);
EXPECT_EQ(merged->field_presence(), FeatureSet::EXPLICIT);
EXPECT_EQ(merged->enum_type(), FeatureSet::OPEN);
EXPECT_EQ(merged->repeated_field_encoding(), FeatureSet::PACKED);
EXPECT_EQ(merged->string_field_validation(), FeatureSet::MANDATORY);
EXPECT_EQ(merged->message_encoding(), FeatureSet::LENGTH_PREFIXED);
const pb::TestFeatures& ext = merged->GetExtension(pb::test);
EXPECT_EQ(ext.int_file_feature(), 1);
EXPECT_EQ(ext.int_extension_range_feature(), 1);
EXPECT_EQ(ext.int_message_feature(), 1);
EXPECT_EQ(ext.int_field_feature(), 1);
EXPECT_EQ(ext.int_oneof_feature(), 1);
EXPECT_EQ(ext.int_enum_feature(), 1);
EXPECT_EQ(ext.int_enum_entry_feature(), 1);
EXPECT_EQ(ext.int_service_feature(), 1);
EXPECT_EQ(ext.int_method_feature(), 1);
EXPECT_EQ(ext.bool_field_feature(), false);
EXPECT_FLOAT_EQ(ext.float_field_feature(), 1.1);
EXPECT_THAT(ext.message_field_feature(),
EqualsProto("bool_field: true int_field: 1 float_field: 1.5 "
"string_field: '2023'"));
EXPECT_EQ(ext.enum_field_feature(), pb::TestFeatures::ENUM_VALUE1);
}
TEST(FeatureResolverTest, DefaultsTooEarly) {
absl::StatusOr<FeatureSet> merged = GetDefaults("2022", pb::test);
EXPECT_THAT(merged, HasError(AllOf(HasSubstr("No valid default found"),
HasSubstr("2022"))));
}
TEST(FeatureResolverTest, DefaultsFarFuture) {
absl::StatusOr<FeatureSet> merged = GetDefaults("3456", pb::test);
ASSERT_OK(merged);
pb::TestFeatures ext = merged->GetExtension(pb::test);
EXPECT_EQ(ext.int_file_feature(), 5);
EXPECT_THAT(ext.message_field_feature(),
EqualsProto("bool_field: true int_field: 4 float_field: 1.5 "
"string_field: '2025'"));
EXPECT_EQ(ext.enum_field_feature(), pb::TestFeatures::ENUM_VALUE5);
}
TEST(FeatureResolverTest, DefaultsMiddleEdition) {
absl::StatusOr<FeatureSet> merged = GetDefaults("2024.1", pb::test);
ASSERT_OK(merged);
pb::TestFeatures ext = merged->GetExtension(pb::test);
EXPECT_EQ(ext.int_file_feature(), 4);
EXPECT_EQ(ext.enum_field_feature(), pb::TestFeatures::ENUM_VALUE4);
}
TEST(FeatureResolverTest, DefaultsDifferentDigitCount) {
absl::StatusOr<FeatureSet> merged = GetDefaults("2023.90", pb::test);
ASSERT_OK(merged);
pb::TestFeatures ext = merged->GetExtension(pb::test);
EXPECT_EQ(ext.int_file_feature(), 3);
EXPECT_EQ(ext.enum_field_feature(), pb::TestFeatures::ENUM_VALUE3);
}
TEST(FeatureResolverTest, DefaultsMessageMerge) {
{
absl::StatusOr<FeatureSet> merged = GetDefaults("2023", pb::test);
ASSERT_OK(merged);
pb::TestFeatures ext = merged->GetExtension(pb::test);
EXPECT_THAT(ext.message_field_feature(),
EqualsProto(R"pb(bool_field: true
int_field: 1
float_field: 1.5
string_field: '2023')pb"));
}
{
absl::StatusOr<FeatureSet> merged = GetDefaults("2023.1", pb::test);
ASSERT_OK(merged);
pb::TestFeatures ext = merged->GetExtension(pb::test);
EXPECT_THAT(ext.message_field_feature(),
EqualsProto(R"pb(bool_field: true
int_field: 2
float_field: 1.5
string_field: '2023')pb"));
}
{
absl::StatusOr<FeatureSet> merged = GetDefaults("2024", pb::test);
ASSERT_OK(merged);
pb::TestFeatures ext = merged->GetExtension(pb::test);
EXPECT_THAT(ext.message_field_feature(),
EqualsProto(R"pb(bool_field: true
int_field: 2
float_field: 1.5
string_field: '2024')pb"));
}
}
TEST(FeatureResolverTest, InitializePoolMissingDescriptor) {
DescriptorPool pool;
EXPECT_THAT(FeatureResolver::Create("2023", nullptr),
HasError(HasSubstr("find definition of google.protobuf.FeatureSet")));
}
TEST(FeatureResolverTest, RegisterExtensionDifferentContainingType) {
auto resolver = FeatureResolver::Create("2023", FeatureSet::descriptor());
ASSERT_OK(resolver);
EXPECT_OK(resolver->RegisterExtensions(
GetExtensionFile(protobuf_unittest::file_opt1, FileOptions::descriptor())));
}
TEST(FeatureResolverTest, RegisterExtensionTwice) {
auto resolver = FeatureResolver::Create("2023", FeatureSet::descriptor());
ASSERT_OK(resolver);
EXPECT_OK(resolver->RegisterExtensions(GetExtensionFile(pb::test)));
EXPECT_OK(resolver->RegisterExtensions(GetExtensionFile(pb::test)));
}
TEST(FeatureResolverTest, MergeFeaturesChildOverrideCore) {
absl::StatusOr<FeatureResolver> resolver = SetupFeatureResolver("2023");
ASSERT_OK(resolver);
FeatureSet child = ParseTextOrDie(R"pb(
field_presence: IMPLICIT
repeated_field_encoding: EXPANDED
)pb");
absl::StatusOr<FeatureSet> merged =
resolver->MergeFeatures(FeatureSet(), child);
ASSERT_OK(merged);
EXPECT_EQ(merged->field_presence(), FeatureSet::IMPLICIT);
EXPECT_EQ(merged->enum_type(), FeatureSet::OPEN);
EXPECT_EQ(merged->repeated_field_encoding(), FeatureSet::EXPANDED);
EXPECT_EQ(merged->string_field_validation(), FeatureSet::MANDATORY);
EXPECT_EQ(merged->message_encoding(), FeatureSet::LENGTH_PREFIXED);
}
TEST(FeatureResolverTest, MergeFeaturesChildOverrideComplex) {
absl::StatusOr<FeatureResolver> resolver =
SetupFeatureResolver("2023", pb::test);
ASSERT_OK(resolver);
FeatureSet child = ParseTextOrDie(R"pb(
field_presence: IMPLICIT
repeated_field_encoding: EXPANDED
[pb.test] {
int_field_feature: 5
enum_field_feature: ENUM_VALUE4
message_field_feature { int_field: 10 }
}
)pb");
absl::StatusOr<FeatureSet> merged =
resolver->MergeFeatures(FeatureSet(), child);
ASSERT_OK(merged);
EXPECT_EQ(merged->field_presence(), FeatureSet::IMPLICIT);
EXPECT_EQ(merged->enum_type(), FeatureSet::OPEN);
EXPECT_EQ(merged->repeated_field_encoding(), FeatureSet::EXPANDED);
EXPECT_EQ(merged->string_field_validation(), FeatureSet::MANDATORY);
EXPECT_EQ(merged->message_encoding(), FeatureSet::LENGTH_PREFIXED);
pb::TestFeatures ext = merged->GetExtension(pb::test);
EXPECT_EQ(ext.int_file_feature(), 1);
EXPECT_EQ(ext.int_field_feature(), 5);
EXPECT_FLOAT_EQ(ext.float_field_feature(), 1.1);
EXPECT_THAT(ext.message_field_feature(),
EqualsProto("bool_field: true int_field: 10 float_field: 1.5 "
"string_field: '2023'"));
EXPECT_EQ(ext.enum_field_feature(), pb::TestFeatures::ENUM_VALUE4);
}
TEST(FeatureResolverTest, MergeFeaturesParentOverrides) {
absl::StatusOr<FeatureResolver> resolver =
SetupFeatureResolver("2023", pb::test);
ASSERT_OK(resolver);
FeatureSet parent = ParseTextOrDie(R"pb(
field_presence: IMPLICIT
repeated_field_encoding: EXPANDED
[pb.test] {
int_field_feature: 5
enum_field_feature: ENUM_VALUE4
message_field_feature { int_field: 10 string_field: "parent" }
}
)pb");
FeatureSet child = ParseTextOrDie(R"pb(
string_field_validation: NONE
repeated_field_encoding: PACKED
[pb.test] {
int_field_feature: 9
message_field_feature { bool_field: false int_field: 9 }
}
)pb");
absl::StatusOr<FeatureSet> merged = resolver->MergeFeatures(parent, child);
ASSERT_OK(merged);
EXPECT_EQ(merged->field_presence(), FeatureSet::IMPLICIT);
EXPECT_EQ(merged->enum_type(), FeatureSet::OPEN);
EXPECT_EQ(merged->repeated_field_encoding(), FeatureSet::PACKED);
EXPECT_EQ(merged->string_field_validation(), FeatureSet::NONE);
EXPECT_EQ(merged->message_encoding(), FeatureSet::LENGTH_PREFIXED);
pb::TestFeatures ext = merged->GetExtension(pb::test);
EXPECT_EQ(ext.int_file_feature(), 1);
EXPECT_EQ(ext.int_extension_range_feature(), 1);
EXPECT_EQ(ext.int_message_feature(), 1);
EXPECT_EQ(ext.int_field_feature(), 9);
EXPECT_EQ(ext.int_oneof_feature(), 1);
EXPECT_EQ(ext.int_enum_feature(), 1);
EXPECT_EQ(ext.int_enum_entry_feature(), 1);
EXPECT_EQ(ext.int_service_feature(), 1);
EXPECT_EQ(ext.int_method_feature(), 1);
EXPECT_EQ(ext.bool_field_feature(), false);
EXPECT_FLOAT_EQ(ext.float_field_feature(), 1.1);
EXPECT_THAT(ext.message_field_feature(),
EqualsProto("bool_field: false int_field: 9 float_field: 1.5 "
"string_field: 'parent'"));
EXPECT_EQ(ext.enum_field_feature(), pb::TestFeatures::ENUM_VALUE4);
}
TEST(FeatureResolverTest, MergeFeaturesFieldPresenceUnknown) {
absl::StatusOr<FeatureResolver> resolver = SetupFeatureResolver("2023");
ASSERT_OK(resolver);
FeatureSet child = ParseTextOrDie(R"pb(
field_presence: FIELD_PRESENCE_UNKNOWN
)pb");
EXPECT_THAT(
resolver->MergeFeatures(FeatureSet(), child),
HasError(AllOf(HasSubstr("field google.protobuf.FeatureSet.field_presence"),
HasSubstr("FIELD_PRESENCE_UNKNOWN"))));
}
TEST(FeatureResolverTest, MergeFeaturesEnumTypeUnknown) {
absl::StatusOr<FeatureResolver> resolver = SetupFeatureResolver("2023");
ASSERT_OK(resolver);
FeatureSet child = ParseTextOrDie(R"pb(
enum_type: ENUM_TYPE_UNKNOWN
)pb");
EXPECT_THAT(resolver->MergeFeatures(FeatureSet(), child),
HasError(AllOf(HasSubstr("field google.protobuf.FeatureSet.enum_type"),
HasSubstr("ENUM_TYPE_UNKNOWN"))));
}
TEST(FeatureResolverTest, MergeFeaturesRepeatedFieldEncodingUnknown) {
absl::StatusOr<FeatureResolver> resolver = SetupFeatureResolver("2023");
ASSERT_OK(resolver);
FeatureSet child = ParseTextOrDie(R"pb(
repeated_field_encoding: REPEATED_FIELD_ENCODING_UNKNOWN
)pb");
EXPECT_THAT(resolver->MergeFeatures(FeatureSet(), child),
HasError(AllOf(
HasSubstr("field google.protobuf.FeatureSet.repeated_field_encoding"),
HasSubstr("REPEATED_FIELD_ENCODING_UNKNOWN"))));
}
TEST(FeatureResolverTest, MergeFeaturesStringFieldValidationUnknown) {
absl::StatusOr<FeatureResolver> resolver = SetupFeatureResolver("2023");
ASSERT_OK(resolver);
FeatureSet child = ParseTextOrDie(R"pb(
string_field_validation: STRING_FIELD_VALIDATION_UNKNOWN
)pb");
EXPECT_THAT(resolver->MergeFeatures(FeatureSet(), child),
HasError(AllOf(
HasSubstr("field google.protobuf.FeatureSet.string_field_validation"),
HasSubstr("STRING_FIELD_VALIDATION_UNKNOWN"))));
}
TEST(FeatureResolverTest, MergeFeaturesMessageEncodingUnknown) {
absl::StatusOr<FeatureResolver> resolver = SetupFeatureResolver("2023");
ASSERT_OK(resolver);
FeatureSet child = ParseTextOrDie(R"pb(
message_encoding: MESSAGE_ENCODING_UNKNOWN
)pb");
EXPECT_THAT(
resolver->MergeFeatures(FeatureSet(), child),
HasError(AllOf(HasSubstr("field google.protobuf.FeatureSet.message_encoding"),
HasSubstr("MESSAGE_ENCODING_UNKNOWN"))));
}
TEST(FeatureResolverTest, MergeFeaturesExtensionEnumUnknown) {
absl::StatusOr<FeatureResolver> resolver =
SetupFeatureResolver("2023", pb::test);
ASSERT_OK(resolver);
FeatureSet child = ParseTextOrDie(R"pb(
[pb.test] { enum_field_feature: TEST_ENUM_FEATURE_UNKNOWN }
)pb");
absl::StatusOr<FeatureSet> merged =
resolver->MergeFeatures(FeatureSet(), child);
ASSERT_OK(merged);
EXPECT_EQ(merged->GetExtension(pb::test).enum_field_feature(),
pb::TestFeatures::TEST_ENUM_FEATURE_UNKNOWN);
}
// TODO(b/273611177) Move the following tests to descriptor_unittest.cc once
// FeatureResolver is hooked up. These will all fail during the descriptor
// build, invalidating the test setup.
//
// Note: We should make sure to keep coverage over the custom DescriptorPool
// cases. These are the only tests covering issues there (the ones above use
// the generated descriptor pool).
class FakeErrorCollector : public io::ErrorCollector {
public:
FakeErrorCollector() = default;
~FakeErrorCollector() override = default;
void RecordWarning(int line, int column, absl::string_view message) override {
ABSL_LOG(WARNING) << line << ":" << column << ": " << message;
}
void RecordError(int line, int column, absl::string_view message) override {
ABSL_LOG(ERROR) << line << ":" << column << ": " << message;
}
};
class FeatureResolverPoolTest : public testing::Test {
protected:
void SetUp() override {
FileDescriptorProto file;
FileDescriptorProto::GetDescriptor()->file()->CopyTo(&file);
ASSERT_NE(pool_.BuildFile(file), nullptr);
}
const FileDescriptor* ParseSchema(absl::string_view schema) {
FakeErrorCollector error_collector;
io::ArrayInputStream raw_input(schema.data(), schema.size());
io::Tokenizer input(&raw_input, &error_collector);
compiler::Parser parser;
parser.RecordErrorsTo(&error_collector);
FileDescriptorProto file;
ABSL_CHECK(parser.Parse(&input, &file));
file.set_name("foo.proto");
return pool_.BuildFile(file);
}
DescriptorPool pool_;
FileDescriptorProto file_proto_;
};
TEST_F(FeatureResolverPoolTest, RegisterExtensionNonMessage) {
const FileDescriptor* file = ParseSchema(R"schema(
syntax = "proto2";
package test;
import "google/protobuf/descriptor.proto";
message Foo {}
extend google.protobuf.FeatureSet {
optional string bar = 9999;
}
)schema");
ASSERT_NE(file, nullptr);
auto resolver = FeatureResolver::Create(
"2023", pool_.FindMessageTypeByName("google.protobuf.FeatureSet"));
ASSERT_OK(resolver);
EXPECT_THAT(resolver->RegisterExtensions(*file),
HasError(AllOf(HasSubstr("test.bar"),
HasSubstr("is not of message type"))));
}
TEST_F(FeatureResolverPoolTest, RegisterExtensionRepeated) {
const FileDescriptor* file = ParseSchema(R"schema(
syntax = "proto2";
package test;
import "google/protobuf/descriptor.proto";
message Foo {}
extend google.protobuf.FeatureSet {
repeated Foo bar = 9999;
}
)schema");
ASSERT_NE(file, nullptr);
auto resolver = FeatureResolver::Create(
"2023", pool_.FindMessageTypeByName("google.protobuf.FeatureSet"));
ASSERT_OK(resolver);
EXPECT_THAT(
resolver->RegisterExtensions(*file),
HasError(AllOf(HasSubstr("test.bar"), HasSubstr("repeated extension"))));
}
TEST_F(FeatureResolverPoolTest, RegisterExtensionWithExtensions) {
const FileDescriptor* file = ParseSchema(R"schema(
syntax = "proto2";
package test;
import "google/protobuf/descriptor.proto";
message Foo {
extensions 1;
}
extend google.protobuf.FeatureSet {
optional Foo bar = 9999;
}
extend Foo {
optional Foo bar2 = 1 [
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2023", value: "" }
];
}
)schema");
ASSERT_NE(file, nullptr);
auto resolver = FeatureResolver::Create(
"2023", pool_.FindMessageTypeByName("google.protobuf.FeatureSet"));
ASSERT_OK(resolver);
EXPECT_THAT(
resolver->RegisterExtensions(*file),
HasError(AllOf(HasSubstr("test.bar"), HasSubstr("Nested extensions"))));
}
TEST_F(FeatureResolverPoolTest, RegisterExtensionWithOneof) {
const FileDescriptor* file = ParseSchema(R"schema(
syntax = "proto2";
package test;
import "google/protobuf/descriptor.proto";
extend google.protobuf.FeatureSet {
optional Foo bar = 9999;
}
message Foo {
oneof x {
int32 int_field = 1 [
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2023", value: "1" }
];
string string_field = 2 [
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2023", value: "'hello'" }
];
}
}
)schema");
ASSERT_NE(file, nullptr);
auto resolver = FeatureResolver::Create(
"2023", pool_.FindMessageTypeByName("google.protobuf.FeatureSet"));
ASSERT_OK(resolver);
EXPECT_THAT(resolver->RegisterExtensions(*file),
HasError(AllOf(HasSubstr("test.Foo"),
HasSubstr("oneof feature fields"))));
}
TEST_F(FeatureResolverPoolTest, RegisterExtensionWithRequired) {
const FileDescriptor* file = ParseSchema(R"schema(
syntax = "proto2";
package test;
import "google/protobuf/descriptor.proto";
extend google.protobuf.FeatureSet {
optional Foo bar = 9999;
}
message Foo {
required int32 required_field = 1 [
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2023", value: "" }
];
}
)schema");
ASSERT_NE(file, nullptr);
auto resolver = FeatureResolver::Create(
"2023", pool_.FindMessageTypeByName("google.protobuf.FeatureSet"));
ASSERT_OK(resolver);
EXPECT_THAT(resolver->RegisterExtensions(*file),
HasError(AllOf(HasSubstr("test.Foo.required_field"),
HasSubstr("required field"))));
}
TEST_F(FeatureResolverPoolTest, RegisterExtensionWithRepeated) {
const FileDescriptor* file = ParseSchema(R"schema(
syntax = "proto2";
package test;
import "google/protobuf/descriptor.proto";
extend google.protobuf.FeatureSet {
optional Foo bar = 9999;
}
message Foo {
repeated int32 repeated_field = 1 [
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2023", value: "1" }
];
}
)schema");
ASSERT_NE(file, nullptr);
auto resolver = FeatureResolver::Create(
"2023", pool_.FindMessageTypeByName("google.protobuf.FeatureSet"));
ASSERT_OK(resolver);
EXPECT_THAT(resolver->RegisterExtensions(*file),
HasError(AllOf(HasSubstr("test.Foo.repeated_field"),
HasSubstr("repeated field"))));
}
TEST_F(FeatureResolverPoolTest, RegisterExtensionWithMissingTarget) {
const FileDescriptor* file = ParseSchema(R"schema(
syntax = "proto2";
package test;
import "google/protobuf/descriptor.proto";
extend google.protobuf.FeatureSet {
optional Foo bar = 9999;
}
message Foo {
optional int32 int_field = 1 [
edition_defaults = { edition: "2023", value: "1" }
];
}
)schema");
ASSERT_NE(file, nullptr);
auto resolver = FeatureResolver::Create(
"2023", pool_.FindMessageTypeByName("google.protobuf.FeatureSet"));
ASSERT_OK(resolver);
EXPECT_THAT(resolver->RegisterExtensions(*file),
HasError(AllOf(HasSubstr("test.Foo.int_field"),
HasSubstr("no target specified"))));
}
TEST_F(FeatureResolverPoolTest, RegisterExtensionDefaultsMessageParsingError) {
const FileDescriptor* file = ParseSchema(R"schema(
syntax = "proto2";
package test;
import "google/protobuf/descriptor.proto";
extend google.protobuf.FeatureSet {
optional Foo bar = 9999;
}
message Foo {
message MessageFeature {
optional int32 int_field = 1;
}
optional MessageFeature message_field_feature = 12 [
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2023", value: "9987" }
];
}
)schema");
ASSERT_NE(file, nullptr);
auto resolver = FeatureResolver::Create(
"2023", pool_.FindMessageTypeByName("google.protobuf.FeatureSet"));
ASSERT_OK(resolver);
EXPECT_THAT(
resolver->RegisterExtensions(*file),
HasError(AllOf(HasSubstr("in edition_defaults"), HasSubstr("9987"))));
}
TEST_F(FeatureResolverPoolTest,
RegisterExtensionDefaultsMessageParsingErrorMerged) {
const FileDescriptor* file = ParseSchema(R"schema(
syntax = "proto2";
package test;
import "google/protobuf/descriptor.proto";
extend google.protobuf.FeatureSet {
optional Foo bar = 9999;
}
message Foo {
message MessageFeature {
optional int32 int_field = 1;
}
optional MessageFeature message_field_feature = 12 [
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2025", value: "int_field: 2" },
edition_defaults = { edition: "2024", value: "int_field: 1" },
edition_defaults = { edition: "2023", value: "9987" }
];
}
)schema");
ASSERT_NE(file, nullptr);
auto resolver = FeatureResolver::Create(
"2024", pool_.FindMessageTypeByName("google.protobuf.FeatureSet"));
ASSERT_OK(resolver);
EXPECT_THAT(
resolver->RegisterExtensions(*file),
HasError(AllOf(HasSubstr("in edition_defaults"), HasSubstr("9987"))));
}
TEST_F(FeatureResolverPoolTest,
RegisterExtensionDefaultsMessageParsingErrorSkipped) {
const FileDescriptor* file = ParseSchema(R"schema(
syntax = "proto2";
package test;
import "google/protobuf/descriptor.proto";
extend google.protobuf.FeatureSet {
optional Foo bar = 9999;
}
message Foo {
message MessageFeature {
optional int32 int_field = 1;
}
optional MessageFeature message_field_feature = 12 [
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2024", value: "int_field: 2" },
edition_defaults = { edition: "2023", value: "int_field: 1" },
edition_defaults = { edition: "2025", value: "9987" }
];
}
)schema");
ASSERT_NE(file, nullptr);
auto resolver = FeatureResolver::Create(
"2024", pool_.FindMessageTypeByName("google.protobuf.FeatureSet"));
ASSERT_OK(resolver);
EXPECT_OK(resolver->RegisterExtensions(*file));
FeatureSet parent, child;
EXPECT_OK(resolver->MergeFeatures(parent, child));
}
TEST_F(FeatureResolverPoolTest, RegisterExtensionDefaultsScalarParsingError) {
const FileDescriptor* file = ParseSchema(R"schema(
syntax = "proto2";
package test;
import "google/protobuf/descriptor.proto";
extend google.protobuf.FeatureSet {
optional Foo bar = 9999;
}
message Foo {
optional int32 int_field_feature = 12 [
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2023", value: "1.23" }
];
}
)schema");
ASSERT_NE(file, nullptr);
auto resolver = FeatureResolver::Create(
"2023", pool_.FindMessageTypeByName("google.protobuf.FeatureSet"));
ASSERT_OK(resolver);
EXPECT_THAT(
resolver->RegisterExtensions(*file),
HasError(AllOf(HasSubstr("in edition_defaults"), HasSubstr("1.23"))));
}
TEST_F(FeatureResolverPoolTest,
RegisterExtensionDefaultsScalarParsingErrorSkipped) {
const FileDescriptor* file = ParseSchema(R"schema(
syntax = "proto2";
package test;
import "google/protobuf/descriptor.proto";
extend google.protobuf.FeatureSet {
optional Foo bar = 9999;
}
message Foo {
optional int32 int_field_feature = 12 [
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2024", value: "1.5" },
edition_defaults = { edition: "2023", value: "1" }
];
}
)schema");
ASSERT_NE(file, nullptr);
auto resolver = FeatureResolver::Create(
"2023", pool_.FindMessageTypeByName("google.protobuf.FeatureSet"));
ASSERT_OK(resolver);
EXPECT_OK(resolver->RegisterExtensions(*file));
FeatureSet parent, child;
EXPECT_OK(resolver->MergeFeatures(parent, child));
}
} // namespace
} // namespace protobuf
} // namespace google
#include "google/protobuf/port_undef.inc"

View File

@ -224,6 +224,10 @@ static_assert(PROTOBUF_CPLUSPLUS_MIN(201402L), "Protobuf only supports C++14 and
static_assert(PROTOBUF_ABSL_MIN(20230125, 3),
"Protobuf only supports Abseil version 20230125.3 and newer.");
// Enable editions infrastructure by default. This should be a no-op without
// the --experimental_editions protoc flag.
#define PROTOBUF_FUTURE_EDITIONS 1
// Future versions of protobuf will include breaking changes to some APIs.
// This macro can be set to enable these API changes ahead of time, so that
// user code can be updated before upgrading versions of protobuf.
@ -242,10 +246,6 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3),
// Owner: ezb@
#define PROTOBUF_FUTURE_REMOVE_CONST_REPEATEDFIELD_GETARENA_API 1
// Used to remove Protobuf editions feature.
// Owner: mkruskal@
#define PROTOBUF_FUTURE_EDITIONS 1
// Used to make ExtensionRange into a fully-fledged descriptor class.
// Owner: mkruskal@
#define PROTOBUF_FUTURE_EXTENSION_RANGE_CLASS 1

View File

@ -0,0 +1,167 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
package pb;
import "google/protobuf/descriptor.proto";
extend google.protobuf.FeatureSet {
optional TestFeatures test = 9999;
}
message TestMessage {
extend google.protobuf.FeatureSet {
optional TestFeatures test_message = 9998;
}
message Nested {
extend google.protobuf.FeatureSet {
optional TestFeatures test_nested = 9997;
}
}
}
message TestFeatures {
optional int32 int_file_feature = 1 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FILE,
edition_defaults = { edition: "2025", value: "5" },
edition_defaults = { edition: "2023.1.2", value: "3" },
edition_defaults = { edition: "2023", value: "1" },
edition_defaults = { edition: "2023.1", value: "2" },
edition_defaults = { edition: "2024", value: "4" }
];
optional int32 int_extension_range_feature = 2 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_EXTENSION_RANGE,
edition_defaults = { edition: "2023", value: "1" }
];
optional int32 int_message_feature = 3 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_MESSAGE,
edition_defaults = { edition: "2023", value: "1" }
];
optional int32 int_field_feature = 4 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2023", value: "1" }
];
optional int32 int_oneof_feature = 5 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_ONEOF,
edition_defaults = { edition: "2023", value: "1" }
];
optional int32 int_enum_feature = 6 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_ENUM,
edition_defaults = { edition: "2023", value: "1" }
];
optional int32 int_enum_entry_feature = 7 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_ENUM_ENTRY,
edition_defaults = { edition: "2023", value: "1" }
];
optional int32 int_service_feature = 8 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_SERVICE,
edition_defaults = { edition: "2023", value: "1" }
];
optional int32 int_method_feature = 9 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_METHOD,
edition_defaults = { edition: "2023", value: "1" }
];
optional int32 int_multiple_feature = 10 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FILE,
targets = TARGET_TYPE_FIELD,
targets = TARGET_TYPE_MESSAGE,
targets = TARGET_TYPE_ENUM,
targets = TARGET_TYPE_ENUM_ENTRY,
targets = TARGET_TYPE_SERVICE,
targets = TARGET_TYPE_METHOD,
targets = TARGET_TYPE_ONEOF,
targets = TARGET_TYPE_EXTENSION_RANGE,
edition_defaults = { edition: "2023", value: "1" }
];
optional bool bool_field_feature = 11 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2023", value: "false" },
edition_defaults = { edition: "2023.1", value: "true" }
];
optional float float_field_feature = 12 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2023", value: "1.1" },
edition_defaults = { edition: "2023.1", value: "1.2" }
];
message MessageFeature {
optional bool bool_field = 1;
optional int32 int_field = 2;
optional float float_field = 3;
optional string string_field = 4;
}
optional MessageFeature message_field_feature = 13 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2023.1", value: "int_field: 2" },
edition_defaults = { edition: "2024", value: "string_field: '2024'" },
edition_defaults = {
edition: "2023",
value: "bool_field: true int_field: 1 float_field: 1.5 string_field: '2023'"
},
edition_defaults = {
edition: "2025",
value: "int_field: 4 string_field: '2025'"
}
];
enum EnumFeature {
TEST_ENUM_FEATURE_UNKNOWN = 0;
ENUM_VALUE1 = 1;
ENUM_VALUE2 = 2;
ENUM_VALUE3 = 3;
ENUM_VALUE4 = 4;
ENUM_VALUE5 = 5;
}
optional EnumFeature enum_field_feature = 14 [
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FIELD,
edition_defaults = { edition: "2023.10", value: "ENUM_VALUE3" },
edition_defaults = { edition: "2023.9", value: "ENUM_VALUE2" },
edition_defaults = { edition: "2025", value: "ENUM_VALUE5" },
edition_defaults = { edition: "2023", value: "ENUM_VALUE1" },
edition_defaults = { edition: "2024", value: "ENUM_VALUE4" }
];
}

View File

@ -0,0 +1,41 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
package pb;
import "google/protobuf/descriptor.proto";
message TestInvalid {
extend .google.protobuf.FeatureSet {
optional string scalar_extension = 9996;
}
}

View File

@ -2,6 +2,7 @@
global:
extern "C++" {
*google*;
pb::*;
};
scc_info_*;
descriptor_table_*;

View File

@ -2,6 +2,7 @@
global:
extern "C++" {
*google*;
pb::*;
};
scc_info_*;
descriptor_table_*;

View File

@ -2,6 +2,7 @@
global:
extern "C++" {
*google*;
pb::*;
};
scc_info_*;
descriptor_table_*;