@@ -4904,6 +4904,154 @@ TEST(CustomOptions, DebugString) {
49044904 descriptor->DebugString());
49054905}
49064906
4907+ TEST(CustomOptions, FeatureSupportInvalidDeprecatedAfterRemoved) {
4908+ DescriptorPool pool;
4909+ pool.EnforceFeatureSupportValidation(true);
4910+
4911+ FileDescriptorProto file_proto;
4912+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
4913+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
4914+
4915+ ASSERT_TRUE(TextFormat::ParseFromString(
4916+ R"pb(
4917+ name: "foo.proto"
4918+ edition: EDITION_2024
4919+ package: "proto2_unittest"
4920+ dependency: "google/protobuf/descriptor.proto"
4921+ extension {
4922+ name: "file_opt1"
4923+ number: 7739974
4924+ label: LABEL_OPTIONAL
4925+ type: TYPE_UINT64
4926+ extendee: ".google.protobuf.FieldOptions"
4927+ options {
4928+ feature_support {
4929+ edition_introduced: EDITION_2023
4930+ edition_deprecated: EDITION_2024
4931+ deprecation_warning: "warning"
4932+ edition_removed: EDITION_2024
4933+ removal_error: "Custom feature removal error"
4934+ }
4935+ }
4936+ })pb",
4937+ &file_proto));
4938+
4939+ MockErrorCollector error_collector;
4940+ EXPECT_FALSE(pool.BuildFileCollectingErrors(file_proto, &error_collector));
4941+ EXPECT_EQ(error_collector.text_,
4942+ "foo.proto: proto2_unittest.file_opt1: OPTION_NAME: proto"
4943+ "2_unittest.file_opt1 was deprecated after it was removed.\n");
4944+ }
4945+
4946+ TEST(CustomOptions, FeatureSupportInvalidValueDeprecatedAfterOption) {
4947+ DescriptorPool pool;
4948+ pool.EnforceFeatureSupportValidation(true);
4949+
4950+ FileDescriptorProto file_proto;
4951+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
4952+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
4953+
4954+ ASSERT_TRUE(TextFormat::ParseFromString(
4955+ R"pb(
4956+ name: "foo.proto"
4957+ edition: EDITION_2024
4958+ package: "proto2_unittest"
4959+ dependency: "google/protobuf/descriptor.proto"
4960+ enum_type {
4961+ name: "Foo"
4962+ value { name: "UNKNOWN" number: 0 }
4963+ value {
4964+ name: "VALUE"
4965+ number: 1
4966+ options {
4967+ feature_support {
4968+ edition_deprecated: EDITION_99997_TEST_ONLY
4969+ deprecation_warning: "warning"
4970+ }
4971+ }
4972+ }
4973+ }
4974+ message_type {
4975+ name: "Bar"
4976+ extension {
4977+ name: "bool_field"
4978+ number: 7739973
4979+ label: LABEL_OPTIONAL
4980+ type: TYPE_ENUM
4981+ type_name: "Foo"
4982+ extendee: ".google.protobuf.FieldOptions"
4983+ options {
4984+ feature_support {
4985+ edition_introduced: EDITION_2023
4986+ edition_deprecated: EDITION_2024
4987+ deprecation_warning: "warning"
4988+ }
4989+ }
4990+ }
4991+ })pb",
4992+ &file_proto));
4993+
4994+ MockErrorCollector error_collector;
4995+ EXPECT_FALSE(pool.BuildFileCollectingErrors(file_proto, &error_collector));
4996+ EXPECT_THAT(error_collector.text_,
4997+ testing::HasSubstr(
4998+ "foo.proto: proto2_unittest.Bar.bool_field: "
4999+ "OPTION_NAME: value proto2_unittest.VALUE was "
5000+ "deprecated after proto2_unittest.Bar.bool_field was.\n"));
5001+ }
5002+
5003+ TEST(CustomOptions, FeatureSupportValid) {
5004+ DescriptorPool pool;
5005+ pool.EnforceFeatureSupportValidation(true);
5006+
5007+ FileDescriptorProto file_proto;
5008+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
5009+ ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
5010+
5011+ ASSERT_TRUE(TextFormat::ParseFromString(
5012+ R"pb(
5013+ name: "foo.proto"
5014+ edition: EDITION_2024
5015+ package: "proto2_unittest"
5016+ dependency: "google/protobuf/descriptor.proto"
5017+ enum_type {
5018+ name: "Foo"
5019+ value { name: "UNKNOWN" number: 0 }
5020+ value {
5021+ name: "VALUE"
5022+ number: 1
5023+ options {
5024+ feature_support {
5025+ edition_introduced: EDITION_2024
5026+ edition_deprecated: EDITION_99997_TEST_ONLY
5027+ deprecation_warning: "warning"
5028+ }
5029+ }
5030+ }
5031+ }
5032+ message_type {
5033+ name: "Bar"
5034+ extension {
5035+ name: "bool_field"
5036+ number: 7739971
5037+ label: LABEL_OPTIONAL
5038+ type: TYPE_ENUM
5039+ type_name: "Foo"
5040+ extendee: ".google.protobuf.FieldOptions"
5041+ options {
5042+ feature_support {
5043+ edition_introduced: EDITION_2023
5044+ edition_removed: EDITION_99998_TEST_ONLY
5045+ removal_error: "removed"
5046+ }
5047+ }
5048+ }
5049+ })pb",
5050+ &file_proto));
5051+
5052+ EXPECT_NE(pool.BuildFile(file_proto), nullptr);
5053+ }
5054+
49075055// ===================================================================
49085056
49095057TEST_F(ValidationErrorTest, AlreadyDefined) {
0 commit comments