@@ -1637,7 +1637,9 @@ class DescriptorPool::DeferredValidation {
16371637 }
16381638
16391639 bool Validate () {
1640- if (lifetimes_info_map_.empty ()) return true ;
1640+ if (lifetimes_info_map_.empty ()) {
1641+ return true ;
1642+ }
16411643
16421644 static absl::string_view feature_set_name = " google.protobuf.FeatureSet" ;
16431645 const Descriptor* feature_set =
@@ -5014,6 +5016,9 @@ class DescriptorBuilder {
50145016 const DescriptorProto::ExtensionRange& proto) {}
50155017 void ValidateExtensionRangeOptions (const DescriptorProto& proto,
50165018 const Descriptor& message);
5019+ void ValidateFeatureSupport (
5020+ const FieldOptions::FeatureSupport& feature_support, const Message& proto,
5021+ absl::string_view full_name);
50175022 void ValidateExtensionDeclaration (
50185023 absl::string_view full_name,
50195024 const RepeatedPtrField<ExtensionRangeOptions_Declaration>& declarations,
@@ -8487,12 +8492,84 @@ void DescriptorBuilder::ValidateOptions(const OneofDescriptor* /*oneof*/,
84878492}
84888493
84898494
8495+ void DescriptorBuilder::ValidateFeatureSupport (
8496+ const FieldOptions::FeatureSupport& feature_support, const Message& proto,
8497+ absl::string_view full_name) {
8498+ std::string feature_support_error (
8499+ FeatureResolver::ValidateFeatureSupport (feature_support, full_name)
8500+ .message ());
8501+ if (!feature_support_error.empty ()) {
8502+ AddError (full_name, proto, DescriptorPool::ErrorCollector::OPTION_NAME,
8503+ feature_support_error.c_str ());
8504+ }
8505+ }
8506+
84908507void DescriptorBuilder::ValidateOptions (const FieldDescriptor* field,
84918508 const FieldDescriptorProto& proto) {
84928509 if (pool_->lazily_build_dependencies_ && (!field || !field->message_type ())) {
84938510 return ;
84948511 }
8512+ if (field->options ().has_feature_support ()) {
8513+ const FieldOptions::FeatureSupport field_feature_support =
8514+ field->options ().feature_support ();
8515+ ValidateFeatureSupport (field_feature_support, proto, field->full_name ());
8516+ if (field->enum_type () != nullptr ) {
8517+ for (int i = 0 ; i < field->enum_type ()->value_count (); i++) {
8518+ const EnumValueDescriptor& value = *field->enum_type ()->value (i);
8519+ // We allow missing support windows on feature values, and they'll
8520+ // inherit from the feature spec.
8521+ if (!value.options ().has_feature_support ()) {
8522+ continue ;
8523+ }
84958524
8525+ FieldOptions::FeatureSupport value_feature_support =
8526+ field_feature_support;
8527+ value_feature_support.MergeFrom (value.options ().feature_support ());
8528+ ValidateFeatureSupport (value_feature_support, proto, value.full_name ());
8529+
8530+ // Make sure enum values don't expand any bounds
8531+ if (field_feature_support.edition_introduced () >
8532+ value_feature_support.edition_introduced ()) {
8533+ AddError (value.full_name (), proto,
8534+ DescriptorPool::ErrorCollector::OPTION_NAME,
8535+ absl::Substitute (" value $0 was introduced before $1 was." ,
8536+ value.full_name (), field->full_name ())
8537+ .c_str ());
8538+ }
8539+ if (field_feature_support.has_edition_removed () &&
8540+ field_feature_support.edition_removed () <
8541+ value_feature_support.edition_removed ()) {
8542+ AddError (value.full_name (), proto,
8543+ DescriptorPool::ErrorCollector::OPTION_NAME,
8544+ absl::Substitute (" value $0 was removed after $1 was." ,
8545+ value.full_name (), field->full_name ())
8546+ .c_str ());
8547+ }
8548+ if (field_feature_support.has_edition_deprecated () &&
8549+ field_feature_support.edition_deprecated () <
8550+ value_feature_support.edition_deprecated ()) {
8551+ AddError (value.full_name (), proto,
8552+ DescriptorPool::ErrorCollector::OPTION_NAME,
8553+ absl::Substitute (" value $0 was deprecated after $1 was." ,
8554+ value.full_name (), field->full_name ())
8555+ .c_str ());
8556+ }
8557+ }
8558+ }
8559+ } else if (field->enum_type () != nullptr ) {
8560+ for (int i = 0 ; i < field->enum_type ()->value_count (); i++) {
8561+ const EnumValueDescriptor& value = *field->enum_type ()->value (i);
8562+ if (value.options ().has_feature_support ()) {
8563+ AddError (value.full_name (), proto,
8564+ DescriptorPool::ErrorCollector::OPTION_NAME,
8565+ absl::Substitute (
8566+ " value $0 is not allowed to have feature support "
8567+ " because its field $1 doesn't have feature support." ,
8568+ value.full_name (), field->full_name ())
8569+ .c_str ());
8570+ }
8571+ }
8572+ }
84968573 ValidateFieldFeatures (field, proto);
84978574
84988575
@@ -8822,10 +8899,12 @@ void DescriptorBuilder::ValidateOptions(const EnumDescriptor* enm,
88228899 }
88238900}
88248901
8825- void DescriptorBuilder::ValidateOptions (
8826- const EnumValueDescriptor* /* enum_value */ ,
8827- const EnumValueDescriptorProto& /* proto */ ) {
8828- // Nothing to do so far.
8902+ void DescriptorBuilder::ValidateOptions (const EnumValueDescriptor* enum_value,
8903+ const EnumValueDescriptorProto& proto) {
8904+ if (enum_value->options ().has_feature_support ()) {
8905+ ValidateFeatureSupport (enum_value->options ().feature_support (), proto,
8906+ enum_value->full_name ());
8907+ }
88298908}
88308909
88318910namespace {
0 commit comments