Skip to content

Commit 41287bd

Browse files
Implement "reserved" for extension declaration.
This can be useful when an extension field/declaration is deleted in schema to avoid data corruption. It also adds a check for duplicate numbers in the declarations. PiperOrigin-RevId: 523269837
1 parent 11d9cd9 commit 41287bd

File tree

8 files changed

+599
-458
lines changed

8 files changed

+599
-458
lines changed

php/ext/google/protobuf/php-upb.c

Lines changed: 284 additions & 282 deletions
Large diffs are not rendered by default.

php/ext/google/protobuf/php-upb.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4873,6 +4873,21 @@ UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_has_is_repeate
48734873
const upb_MiniTableField field = {4, 8, 4, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)};
48744874
return _upb_Message_HasNonExtensionField(msg, &field);
48754875
}
4876+
UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_clear_reserved(google_protobuf_ExtensionRangeOptions_Declaration* msg) {
4877+
const upb_MiniTableField field = {5, 9, 5, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)};
4878+
_upb_Message_ClearNonExtensionField(msg, &field);
4879+
}
4880+
UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_reserved(const google_protobuf_ExtensionRangeOptions_Declaration* msg) {
4881+
bool default_val = false;
4882+
bool ret;
4883+
const upb_MiniTableField field = {5, 9, 5, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)};
4884+
_upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret);
4885+
return ret;
4886+
}
4887+
UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_has_reserved(const google_protobuf_ExtensionRangeOptions_Declaration* msg) {
4888+
const upb_MiniTableField field = {5, 9, 5, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)};
4889+
return _upb_Message_HasNonExtensionField(msg, &field);
4890+
}
48764891

48774892
UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_set_number(google_protobuf_ExtensionRangeOptions_Declaration *msg, int32_t value) {
48784893
const upb_MiniTableField field = {1, 4, 1, kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)};
@@ -4890,6 +4905,10 @@ UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_set_is_repeate
48904905
const upb_MiniTableField field = {4, 8, 4, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)};
48914906
_upb_Message_SetNonExtensionField(msg, &field, &value);
48924907
}
4908+
UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_set_reserved(google_protobuf_ExtensionRangeOptions_Declaration *msg, bool value) {
4909+
const upb_MiniTableField field = {5, 9, 5, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)};
4910+
_upb_Message_SetNonExtensionField(msg, &field, &value);
4911+
}
48934912

48944913
/* google.protobuf.FieldDescriptorProto */
48954914

ruby/ext/google/protobuf_c/ruby-upb.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -926,24 +926,25 @@ const upb_MiniTable google_protobuf_ExtensionRangeOptions_msg_init = {
926926
})
927927
};
928928

929-
static const upb_MiniTableField google_protobuf_ExtensionRangeOptions_Declaration__fields[4] = {
929+
static const upb_MiniTableField google_protobuf_ExtensionRangeOptions_Declaration__fields[5] = {
930930
{1, 4, 1, kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
931931
{2, UPB_SIZE(12, 16), 2, kUpb_NoSub, 12, kUpb_FieldMode_Scalar | kUpb_LabelFlags_IsAlternate | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
932932
{3, UPB_SIZE(20, 32), 3, kUpb_NoSub, 12, kUpb_FieldMode_Scalar | kUpb_LabelFlags_IsAlternate | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
933933
{4, 8, 4, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
934+
{5, 9, 5, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
934935
};
935936

936937
const upb_MiniTable google_protobuf_ExtensionRangeOptions_Declaration_msg_init = {
937938
NULL,
938939
&google_protobuf_ExtensionRangeOptions_Declaration__fields[0],
939-
UPB_SIZE(32, 48), 4, kUpb_ExtMode_NonExtendable, 4, UPB_FASTTABLE_MASK(56), 0,
940+
UPB_SIZE(32, 48), 5, kUpb_ExtMode_NonExtendable, 5, UPB_FASTTABLE_MASK(56), 0,
940941
UPB_FASTTABLE_INIT({
941942
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
942943
{0x0004000001000008, &upb_psv4_1bt},
943944
{0x0010000002000012, &upb_psb_1bt},
944945
{0x002000000300001a, &upb_psb_1bt},
945946
{0x0008000004000020, &upb_psb1_1bt},
946-
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
947+
{0x0009000005000028, &upb_psb1_1bt},
947948
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
948949
{0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
949950
})

ruby/ext/google/protobuf_c/ruby-upb.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4875,6 +4875,21 @@ UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_has_is_repeate
48754875
const upb_MiniTableField field = {4, 8, 4, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)};
48764876
return _upb_Message_HasNonExtensionField(msg, &field);
48774877
}
4878+
UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_clear_reserved(google_protobuf_ExtensionRangeOptions_Declaration* msg) {
4879+
const upb_MiniTableField field = {5, 9, 5, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)};
4880+
_upb_Message_ClearNonExtensionField(msg, &field);
4881+
}
4882+
UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_reserved(const google_protobuf_ExtensionRangeOptions_Declaration* msg) {
4883+
bool default_val = false;
4884+
bool ret;
4885+
const upb_MiniTableField field = {5, 9, 5, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)};
4886+
_upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret);
4887+
return ret;
4888+
}
4889+
UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_has_reserved(const google_protobuf_ExtensionRangeOptions_Declaration* msg) {
4890+
const upb_MiniTableField field = {5, 9, 5, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)};
4891+
return _upb_Message_HasNonExtensionField(msg, &field);
4892+
}
48784893

48794894
UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_set_number(google_protobuf_ExtensionRangeOptions_Declaration *msg, int32_t value) {
48804895
const upb_MiniTableField field = {1, 4, 1, kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)};
@@ -4892,6 +4907,10 @@ UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_set_is_repeate
48924907
const upb_MiniTableField field = {4, 8, 4, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)};
48934908
_upb_Message_SetNonExtensionField(msg, &field, &value);
48944909
}
4910+
UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_set_reserved(google_protobuf_ExtensionRangeOptions_Declaration *msg, bool value) {
4911+
const upb_MiniTableField field = {5, 9, 5, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)};
4912+
_upb_Message_SetNonExtensionField(msg, &field, &value);
4913+
}
48954914

48964915
/* google.protobuf.FieldDescriptorProto */
48974916

src/google/protobuf/descriptor.cc

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7333,6 +7333,17 @@ void DescriptorBuilder::ValidateFieldOptions(
73337333

73347334
for (const auto& declaration : extension_range->options_->declaration()) {
73357335
if (declaration.number() != field->number()) continue;
7336+
if (declaration.reserved()) {
7337+
AddError(field->full_name(), proto,
7338+
DescriptorPool::ErrorCollector::EXTENDEE, [&] {
7339+
return absl::Substitute(
7340+
"Cannot use number $0 for extension field $1, as it is "
7341+
"reserved in the extension declarations for message $2.",
7342+
field->number(), field->full_name(),
7343+
field->containing_type()->full_name());
7344+
});
7345+
return;
7346+
}
73367347
CheckExtensionDeclaration(*field, proto, declaration.full_name(),
73377348
declaration.type(), declaration.is_repeated());
73387349
return;
@@ -7415,6 +7426,7 @@ void DescriptorBuilder::ValidateExtensionDeclaration(
74157426
const RepeatedPtrField<ExtensionRangeOptions_Declaration>& declarations,
74167427
const DescriptorProto_ExtensionRange& proto,
74177428
absl::flat_hash_set<absl::string_view>& full_name_set) {
7429+
absl::flat_hash_set<int> extension_number_set;
74187430
for (const auto& declaration : declarations) {
74197431
if (declaration.number() < proto.start() ||
74207432
declaration.number() >= proto.end()) {
@@ -7426,7 +7438,15 @@ void DescriptorBuilder::ValidateExtensionDeclaration(
74267438
});
74277439
}
74287440

7429-
if (!declaration.has_full_name() || !declaration.has_type()) {
7441+
if (!extension_number_set.insert(declaration.number()).second) {
7442+
AddError(full_name, proto, DescriptorPool::ErrorCollector::NUMBER, [&] {
7443+
return absl::Substitute(
7444+
"Extension declaration number $0 is declared multiple times.",
7445+
declaration.number());
7446+
});
7447+
}
7448+
7449+
if (declaration.has_full_name() != declaration.has_type()) {
74307450
AddError(full_name, proto, DescriptorPool::ErrorCollector::EXTENDEE, [&] {
74317451
return absl::StrCat(
74327452
"Extension declaration #", declaration.number(),

0 commit comments

Comments
 (0)