Skip to content

Commit 44e090c

Browse files
Rachel Goldfingerkarenwuz
authored andcommitted
Add edition unstable for development work.
PiperOrigin-RevId: 834395706
1 parent a79f5f5 commit 44e090c

File tree

7 files changed

+293
-31
lines changed

7 files changed

+293
-31
lines changed

editions/defaults_test.cc

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ absl::StatusOr<FeatureSetDefaults> ReadDefaults(absl::string_view name) {
5151
TEST(DefaultsTest, Check2023) {
5252
auto defaults = ReadDefaults("test_defaults_2023");
5353
ASSERT_OK(defaults);
54-
ASSERT_EQ(defaults->defaults().size(), 3);
54+
ASSERT_EQ(defaults->defaults().size(), 4);
5555
ASSERT_EQ(defaults->minimum_edition(), EDITION_2023);
5656
ASSERT_EQ(defaults->maximum_edition(), EDITION_2023);
5757

@@ -70,7 +70,7 @@ TEST(DefaultsTest, Check2023) {
7070
TEST(DefaultsTest, CheckFuture) {
7171
auto defaults = ReadDefaults("test_defaults_future");
7272
ASSERT_OK(defaults);
73-
ASSERT_EQ(defaults->defaults().size(), 5);
73+
ASSERT_EQ(defaults->defaults().size(), 6);
7474
ASSERT_EQ(defaults->minimum_edition(), EDITION_2023);
7575
ASSERT_EQ(defaults->maximum_edition(), EDITION_99997_TEST_ONLY);
7676

@@ -92,10 +92,16 @@ TEST(DefaultsTest, CheckFuture) {
9292
.GetExtension(pb::test)
9393
.file_feature(),
9494
pb::VALUE3);
95-
EXPECT_EQ(defaults->defaults()[4].edition(), EDITION_99997_TEST_ONLY);
96-
EXPECT_EQ(defaults->defaults()[4].overridable_features().field_presence(),
97-
FeatureSet::EXPLICIT);
95+
EXPECT_EQ(defaults->defaults()[4].edition(), EDITION_UNSTABLE);
9896
EXPECT_EQ(defaults->defaults()[4]
97+
.overridable_features()
98+
.GetExtension(pb::test)
99+
.new_unstable_feature(),
100+
pb::UNSTABLE2);
101+
EXPECT_EQ(defaults->defaults()[5].edition(), EDITION_99997_TEST_ONLY);
102+
EXPECT_EQ(defaults->defaults()[5].overridable_features().field_presence(),
103+
FeatureSet::EXPLICIT);
104+
EXPECT_EQ(defaults->defaults()[5]
99105
.overridable_features()
100106
.GetExtension(pb::test)
101107
.file_feature(),
@@ -105,7 +111,7 @@ TEST(DefaultsTest, CheckFuture) {
105111
TEST(DefaultsTest, CheckFarFuture) {
106112
auto defaults = ReadDefaults("test_defaults_far_future");
107113
ASSERT_OK(defaults);
108-
ASSERT_EQ(defaults->defaults().size(), 7);
114+
ASSERT_EQ(defaults->defaults().size(), 8);
109115
ASSERT_EQ(defaults->minimum_edition(), EDITION_99997_TEST_ONLY);
110116
ASSERT_EQ(defaults->maximum_edition(), EDITION_99999_TEST_ONLY);
111117

@@ -127,21 +133,27 @@ TEST(DefaultsTest, CheckFarFuture) {
127133
.GetExtension(pb::test)
128134
.file_feature(),
129135
pb::VALUE3);
130-
EXPECT_EQ(defaults->defaults()[4].edition(), EDITION_99997_TEST_ONLY);
131-
EXPECT_EQ(defaults->defaults()[4].overridable_features().field_presence(),
132-
FeatureSet::EXPLICIT);
136+
EXPECT_EQ(defaults->defaults()[4].edition(), EDITION_UNSTABLE);
133137
EXPECT_EQ(defaults->defaults()[4]
134138
.overridable_features()
135139
.GetExtension(pb::test)
136-
.file_feature(),
137-
pb::VALUE4);
138-
EXPECT_EQ(defaults->defaults()[5].edition(), EDITION_99998_TEST_ONLY);
140+
.new_unstable_feature(),
141+
pb::UNSTABLE2);
142+
EXPECT_EQ(defaults->defaults()[5].edition(), EDITION_99997_TEST_ONLY);
139143
EXPECT_EQ(defaults->defaults()[5].overridable_features().field_presence(),
140144
FeatureSet::EXPLICIT);
141145
EXPECT_EQ(defaults->defaults()[5]
142146
.overridable_features()
143147
.GetExtension(pb::test)
144148
.file_feature(),
149+
pb::VALUE4);
150+
EXPECT_EQ(defaults->defaults()[6].edition(), EDITION_99998_TEST_ONLY);
151+
EXPECT_EQ(defaults->defaults()[6].overridable_features().field_presence(),
152+
FeatureSet::EXPLICIT);
153+
EXPECT_EQ(defaults->defaults()[6]
154+
.overridable_features()
155+
.GetExtension(pb::test)
156+
.file_feature(),
145157
pb::VALUE5);
146158
}
147159

@@ -150,7 +162,7 @@ TEST(DefaultsTest, Embedded) {
150162
ASSERT_TRUE(defaults.ParseFromArray(DEFAULTS_TEST_EMBEDDED,
151163
sizeof(DEFAULTS_TEST_EMBEDDED) - 1))
152164
<< "Could not parse embedded data";
153-
ASSERT_EQ(defaults.defaults().size(), 3);
165+
ASSERT_EQ(defaults.defaults().size(), 4);
154166
ASSERT_EQ(defaults.minimum_edition(), EDITION_2023);
155167
ASSERT_EQ(defaults.maximum_edition(), EDITION_2023);
156168

@@ -174,7 +186,7 @@ TEST(DefaultsTest, EmbeddedBase64) {
174186
sizeof(DEFAULTS_TEST_EMBEDDED_BASE64) - 1},
175187
&data));
176188
ASSERT_TRUE(defaults.ParseFromString(data));
177-
ASSERT_EQ(defaults.defaults().size(), 3);
189+
ASSERT_EQ(defaults.defaults().size(), 4);
178190
ASSERT_EQ(defaults.minimum_edition(), EDITION_2023);
179191
ASSERT_EQ(defaults.maximum_edition(), EDITION_2023);
180192

@@ -195,7 +207,7 @@ TEST(DefaultsTest, EmbeddedDecimalArray) {
195207
ASSERT_TRUE(defaults.ParseFromArray(kDefaultTestEmbeddedDecimalArray.data(),
196208
kDefaultTestEmbeddedDecimalArray.size()))
197209
<< "Could not parse embedded data";
198-
ASSERT_EQ(defaults.defaults().size(), 3);
210+
ASSERT_EQ(defaults.defaults().size(), 4);
199211
ASSERT_EQ(defaults.minimum_edition(), EDITION_2023);
200212
ASSERT_EQ(defaults.maximum_edition(), EDITION_2023);
201213

@@ -216,7 +228,7 @@ TEST(DefaultsTest, EmbeddedHexArray) {
216228
ASSERT_TRUE(defaults.ParseFromArray(kDefaultTestEmbeddedHexArray.data(),
217229
kDefaultTestEmbeddedHexArray.size()))
218230
<< "Could not parse embedded data";
219-
ASSERT_EQ(defaults.defaults().size(), 3);
231+
ASSERT_EQ(defaults.defaults().size(), 4);
220232
ASSERT_EQ(defaults.minimum_edition(), EDITION_2023);
221233
ASSERT_EQ(defaults.maximum_edition(), EDITION_2023);
222234

src/google/protobuf/compiler/code_generator_unittest.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ class SimpleErrorCollector : public io::ErrorCollector {
8686
}
8787
};
8888

89+
const FeatureSetDefaults::FeatureSetEditionDefault* FindEditionDefault(
90+
const FeatureSetDefaults& defaults, Edition edition) {
91+
for (const auto& edition_default : defaults.defaults()) {
92+
if (edition_default.edition() == edition) {
93+
return &edition_default;
94+
}
95+
}
96+
return nullptr;
97+
}
98+
8999
class CodeGeneratorTest : public ::testing::Test {
90100
protected:
91101
const FileDescriptor* BuildFile(absl::string_view schema) {
@@ -433,6 +443,21 @@ MATCHER_P(IsOkAndHolds, matcher, "") {
433443
return arg.ok() && ExplainMatchResult(matcher, *arg, result_listener);
434444
}
435445

446+
TEST_F(CodeGeneratorTest, FindEditionDefault) {
447+
TestGenerator generator;
448+
auto result = generator.BuildFeatureSetDefaults();
449+
ASSERT_TRUE(result.ok()) << result.status().message();
450+
const auto* edition_defaults = FindEditionDefault(*result, EDITION_2023);
451+
ASSERT_THAT(edition_defaults, NotNull());
452+
EXPECT_EQ(edition_defaults->edition(), EDITION_2023);
453+
EXPECT_EQ(edition_defaults->overridable_features()
454+
.GetExtension(pb::test)
455+
.file_feature(),
456+
pb::EnumFeature::VALUE3);
457+
EXPECT_NE(edition_defaults->edition(), EDITION_2024);
458+
EXPECT_EQ(FindEditionDefault(*result, EDITION_99999_TEST_ONLY), nullptr);
459+
}
460+
436461
TEST_F(CodeGeneratorTest, BuildFeatureSetDefaultsInvalidExtension) {
437462
TestGenerator generator;
438463
generator.set_feature_extensions({nullptr});
@@ -509,6 +534,22 @@ TEST_F(CodeGeneratorTest, BuildFeatureSetDefaults) {
509534
)pb")));
510535
}
511536

537+
TEST_F(CodeGeneratorTest, BuildFeatureSetDefaultsWithUnstable) {
538+
TestGenerator generator;
539+
auto result = generator.BuildFeatureSetDefaults();
540+
ASSERT_TRUE(result.ok()) << result.status().message();
541+
const auto* unstable_defaults = FindEditionDefault(*result, EDITION_UNSTABLE);
542+
ASSERT_THAT(unstable_defaults, NotNull());
543+
EXPECT_EQ(unstable_defaults->overridable_features()
544+
.GetExtension(pb::test)
545+
.new_unstable_feature(),
546+
pb::UnstableEnumFeature::UNSTABLE2);
547+
EXPECT_EQ(unstable_defaults->overridable_features()
548+
.GetExtension(pb::test)
549+
.unstable_existing_feature(),
550+
pb::UnstableEnumFeature::UNSTABLE3);
551+
}
552+
512553
TEST_F(CodeGeneratorTest, BuildFeatureSetDefaultsUnsupported) {
513554
TestGenerator generator;
514555
generator.set_supported_features(0);

src/google/protobuf/compiler/command_line_interface_unittest.cc

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2147,8 +2147,39 @@ TEST_F(CommandLineInterfaceTest,
21472147
Run("protocol_compiler --experimental_editions --proto_path=$tmpdir "
21482148
"--test_out=$tmpdir foo.proto");
21492149
ExpectErrorSubstring(
2150-
"foo.proto:2:5: Edition 99997_TEST_ONLY is later than the maximum "
2151-
"supported edition 2024\n");
2150+
absl::StrCat("Edition 99997_TEST_ONLY is later than the maximum "
2151+
"supported edition ",
2152+
ProtocMaximumEdition()));
2153+
}
2154+
2155+
TEST_F(CommandLineInterfaceTest, UnstableEditionWithFlag) {
2156+
CreateTempFile("foo.proto",
2157+
R"schema(
2158+
edition = "UNSTABLE";
2159+
package foo;
2160+
message Foo {
2161+
}
2162+
)schema");
2163+
2164+
Run("protocol_compiler --proto_path=$tmpdir --experimental_editions "
2165+
"--test_out=$tmpdir foo.proto");
2166+
ExpectNoErrors();
2167+
}
2168+
2169+
TEST_F(CommandLineInterfaceTest, UnstableEditionWithoutFlag) {
2170+
CreateTempFile("foo.proto",
2171+
R"schema(
2172+
edition = "UNSTABLE";
2173+
package foo;
2174+
message Foo {
2175+
}
2176+
)schema");
2177+
2178+
Run("protocol_compiler --proto_path=$tmpdir "
2179+
"--test_out=$tmpdir foo.proto");
2180+
ExpectErrorSubstring(
2181+
"foo.proto: is a file using edition UNSTABLE, which is later than "
2182+
"the protoc maximum supported edition 2024.");
21522183
}
21532184

21542185
TEST_F(CommandLineInterfaceTest, EditionDefaults) {
@@ -2296,6 +2327,32 @@ TEST_F(CommandLineInterfaceTest, EditionDefaultsWithMaximum) {
22962327
)pb"));
22972328
}
22982329

2330+
TEST_F(CommandLineInterfaceTest, EditionDefaultsWithUnstable) {
2331+
CreateTempFile("google/protobuf/descriptor.proto",
2332+
google::protobuf::DescriptorProto::descriptor()->file()->DebugString());
2333+
CreateTempFile("google/protobuf/unittest_features.proto",
2334+
pb::TestFeatures::descriptor()->file()->DebugString());
2335+
Run("protocol_compiler --proto_path=$tmpdir "
2336+
"--edition_defaults_out=$tmpdir/defaults "
2337+
"google/protobuf/unittest_features.proto "
2338+
"google/protobuf/descriptor.proto");
2339+
ExpectNoErrors();
2340+
2341+
FeatureSetDefaults defaults = ReadEditionDefaults("defaults");
2342+
EXPECT_EQ(defaults.defaults_size(), 5);
2343+
EXPECT_EQ(defaults.defaults(4).edition(), EDITION_UNSTABLE);
2344+
EXPECT_EQ(defaults.defaults(4)
2345+
.overridable_features()
2346+
.GetExtension(pb::test)
2347+
.new_unstable_feature(),
2348+
pb::UnstableEnumFeature::UNSTABLE2);
2349+
EXPECT_EQ(defaults.defaults(4)
2350+
.overridable_features()
2351+
.GetExtension(pb::test)
2352+
.unstable_existing_feature(),
2353+
pb::UnstableEnumFeature::UNSTABLE3);
2354+
}
2355+
22992356
TEST_F(CommandLineInterfaceTest, EditionDefaultsWithMinimum) {
23002357
CreateTempFile("google/protobuf/descriptor.proto",
23012358
google::protobuf::DescriptorProto::descriptor()->file()->DebugString());
@@ -2385,12 +2442,13 @@ TEST_F(CommandLineInterfaceTest, EditionDefaultsWithExtension) {
23852442
FeatureSetDefaults defaults = ReadEditionDefaults("defaults");
23862443
EXPECT_EQ(defaults.minimum_edition(), EDITION_PROTO2);
23872444
EXPECT_EQ(defaults.maximum_edition(), EDITION_99999_TEST_ONLY);
2388-
ASSERT_EQ(defaults.defaults_size(), 7);
2445+
ASSERT_EQ(defaults.defaults_size(), 8);
23892446
EXPECT_EQ(defaults.defaults(0).edition(), EDITION_LEGACY);
23902447
EXPECT_EQ(defaults.defaults(2).edition(), EDITION_2023);
23912448
EXPECT_EQ(defaults.defaults(3).edition(), EDITION_2024);
2392-
EXPECT_EQ(defaults.defaults(4).edition(), EDITION_99997_TEST_ONLY);
2393-
EXPECT_EQ(defaults.defaults(5).edition(), EDITION_99998_TEST_ONLY);
2449+
EXPECT_EQ(defaults.defaults(4).edition(), EDITION_UNSTABLE);
2450+
EXPECT_EQ(defaults.defaults(5).edition(), EDITION_99997_TEST_ONLY);
2451+
EXPECT_EQ(defaults.defaults(6).edition(), EDITION_99998_TEST_ONLY);
23942452
EXPECT_EQ(defaults.defaults(0)
23952453
.fixed_features()
23962454
.GetExtension(pb::test)
@@ -2407,11 +2465,16 @@ TEST_F(CommandLineInterfaceTest, EditionDefaultsWithExtension) {
24072465
.file_feature(),
24082466
pb::EnumFeature::VALUE3);
24092467
EXPECT_EQ(defaults.defaults(4)
2468+
.overridable_features()
2469+
.GetExtension(pb::test)
2470+
.new_unstable_feature(),
2471+
pb::UnstableEnumFeature::UNSTABLE2);
2472+
EXPECT_EQ(defaults.defaults(5)
24102473
.overridable_features()
24112474
.GetExtension(pb::test)
24122475
.file_feature(),
24132476
pb::EnumFeature::VALUE4);
2414-
EXPECT_EQ(defaults.defaults(5)
2477+
EXPECT_EQ(defaults.defaults(6)
24152478
.overridable_features()
24162479
.GetExtension(pb::test)
24172480
.file_feature(),

src/google/protobuf/descriptor_unittest.cc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12492,6 +12492,33 @@ TEST_F(FeaturesTest, FutureFeatureDefault) {
1249212492
pb::VALUE1);
1249312493
}
1249412494

12495+
TEST_F(FeaturesTest, NewUnstableFeatureDefault) {
12496+
BuildDescriptorMessagesInTestPool();
12497+
BuildFileInTestPool(pb::TestFeatures::descriptor()->file());
12498+
const FileDescriptor* file = BuildFile(R"pb(
12499+
name: "foo.proto"
12500+
syntax: "editions"
12501+
edition: EDITION_UNSTABLE
12502+
)pb");
12503+
ASSERT_THAT(file, NotNull());
12504+
EXPECT_EQ(GetFeatures(file).GetExtension(pb::test).new_unstable_feature(),
12505+
pb::UNSTABLE2);
12506+
}
12507+
12508+
TEST_F(FeaturesTest, ExistingUnstableFeatureDefault) {
12509+
BuildDescriptorMessagesInTestPool();
12510+
BuildFileInTestPool(pb::TestFeatures::descriptor()->file());
12511+
const FileDescriptor* file = BuildFile(R"pb(
12512+
name: "foo.proto"
12513+
syntax: "editions"
12514+
edition: EDITION_UNSTABLE
12515+
)pb");
12516+
ASSERT_THAT(file, NotNull());
12517+
EXPECT_EQ(
12518+
GetFeatures(file).GetExtension(pb::test).unstable_existing_feature(),
12519+
pb::UNSTABLE3);
12520+
}
12521+
1249512522
// Test that the result of FileDescriptor::DebugString() can be used to create
1249612523
// the original descriptors.
1249712524
class FeaturesDebugStringTest

src/google/protobuf/feature_resolver.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ absl::Status ValidateExtension(const Descriptor& feature_set,
253253

254254
void MaybeInsertEdition(Edition edition, Edition maximum_edition,
255255
absl::btree_set<Edition>& editions) {
256-
if (edition <= maximum_edition) {
256+
if (edition <= maximum_edition || edition == EDITION_UNSTABLE) {
257257
editions.insert(edition);
258258
}
259259
}
@@ -498,7 +498,8 @@ absl::StatusOr<FeatureResolver> FeatureResolver::Create(
498498
" is earlier than the minimum supported edition ",
499499
compiled_defaults.minimum_edition());
500500
}
501-
if (compiled_defaults.maximum_edition() < edition) {
501+
if (compiled_defaults.maximum_edition() < edition &&
502+
edition != EDITION_UNSTABLE) {
502503
return Error("Edition ", edition,
503504
" is later than the maximum supported edition ",
504505
compiled_defaults.maximum_edition());

0 commit comments

Comments
 (0)