Skip to content

Commit 4f2f5c8

Browse files
Rachel Goldfingercopybara-github
authored andcommitted
Add edition unstable for development work.
PiperOrigin-RevId: 828497841
1 parent 49d04b3 commit 4f2f5c8

File tree

8 files changed

+202
-27
lines changed

8 files changed

+202
-27
lines changed

editions/defaults_test.cc

Lines changed: 27 additions & 11 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,20 +92,28 @@ TEST(DefaultsTest, CheckFuture) {
9292
.GetExtension(pb::test)
9393
.file_feature(),
9494
pb::VALUE3);
95-
EXPECT_EQ(defaults->defaults()[4].edition(), EDITION_99997_TEST_ONLY);
95+
EXPECT_EQ(defaults->defaults()[4].edition(), EDITION_UNSTABLE);
9696
EXPECT_EQ(defaults->defaults()[4].overridable_features().field_presence(),
9797
FeatureSet::EXPLICIT);
9898
EXPECT_EQ(defaults->defaults()[4]
9999
.overridable_features()
100100
.GetExtension(pb::test)
101101
.file_feature(),
102+
pb::VALUE3);
103+
EXPECT_EQ(defaults->defaults()[5].edition(), EDITION_99997_TEST_ONLY);
104+
EXPECT_EQ(defaults->defaults()[5].overridable_features().field_presence(),
105+
FeatureSet::EXPLICIT);
106+
EXPECT_EQ(defaults->defaults()[5]
107+
.overridable_features()
108+
.GetExtension(pb::test)
109+
.file_feature(),
102110
pb::VALUE4);
103111
}
104112

105113
TEST(DefaultsTest, CheckFarFuture) {
106114
auto defaults = ReadDefaults("test_defaults_far_future");
107115
ASSERT_OK(defaults);
108-
ASSERT_EQ(defaults->defaults().size(), 7);
116+
ASSERT_EQ(defaults->defaults().size(), 8);
109117
ASSERT_EQ(defaults->minimum_edition(), EDITION_99997_TEST_ONLY);
110118
ASSERT_EQ(defaults->maximum_edition(), EDITION_99999_TEST_ONLY);
111119

@@ -127,21 +135,29 @@ TEST(DefaultsTest, CheckFarFuture) {
127135
.GetExtension(pb::test)
128136
.file_feature(),
129137
pb::VALUE3);
130-
EXPECT_EQ(defaults->defaults()[4].edition(), EDITION_99997_TEST_ONLY);
138+
EXPECT_EQ(defaults->defaults()[4].edition(), EDITION_UNSTABLE);
131139
EXPECT_EQ(defaults->defaults()[4].overridable_features().field_presence(),
132140
FeatureSet::EXPLICIT);
133141
EXPECT_EQ(defaults->defaults()[4]
134142
.overridable_features()
135143
.GetExtension(pb::test)
136144
.file_feature(),
137-
pb::VALUE4);
138-
EXPECT_EQ(defaults->defaults()[5].edition(), EDITION_99998_TEST_ONLY);
145+
pb::VALUE3);
146+
EXPECT_EQ(defaults->defaults()[5].edition(), EDITION_99997_TEST_ONLY);
139147
EXPECT_EQ(defaults->defaults()[5].overridable_features().field_presence(),
140148
FeatureSet::EXPLICIT);
141149
EXPECT_EQ(defaults->defaults()[5]
142150
.overridable_features()
143151
.GetExtension(pb::test)
144152
.file_feature(),
153+
pb::VALUE4);
154+
EXPECT_EQ(defaults->defaults()[6].edition(), EDITION_99998_TEST_ONLY);
155+
EXPECT_EQ(defaults->defaults()[6].overridable_features().field_presence(),
156+
FeatureSet::EXPLICIT);
157+
EXPECT_EQ(defaults->defaults()[6]
158+
.overridable_features()
159+
.GetExtension(pb::test)
160+
.file_feature(),
145161
pb::VALUE5);
146162
}
147163

@@ -150,7 +166,7 @@ TEST(DefaultsTest, Embedded) {
150166
ASSERT_TRUE(defaults.ParseFromString(absl::string_view(
151167
DEFAULTS_TEST_EMBEDDED, sizeof(DEFAULTS_TEST_EMBEDDED) - 1)))
152168
<< "Could not parse embedded data";
153-
ASSERT_EQ(defaults.defaults().size(), 3);
169+
ASSERT_EQ(defaults.defaults().size(), 4);
154170
ASSERT_EQ(defaults.minimum_edition(), EDITION_2023);
155171
ASSERT_EQ(defaults.maximum_edition(), EDITION_2023);
156172

@@ -174,7 +190,7 @@ TEST(DefaultsTest, EmbeddedBase64) {
174190
sizeof(DEFAULTS_TEST_EMBEDDED_BASE64) - 1},
175191
&data));
176192
ASSERT_TRUE(defaults.ParseFromString(data));
177-
ASSERT_EQ(defaults.defaults().size(), 3);
193+
ASSERT_EQ(defaults.defaults().size(), 4);
178194
ASSERT_EQ(defaults.minimum_edition(), EDITION_2023);
179195
ASSERT_EQ(defaults.maximum_edition(), EDITION_2023);
180196

@@ -195,7 +211,7 @@ TEST(DefaultsTest, EmbeddedDecimalArray) {
195211
ASSERT_TRUE(defaults.ParseFromArray(kDefaultTestEmbeddedDecimalArray.data(),
196212
kDefaultTestEmbeddedDecimalArray.size()))
197213
<< "Could not parse embedded data";
198-
ASSERT_EQ(defaults.defaults().size(), 3);
214+
ASSERT_EQ(defaults.defaults().size(), 4);
199215
ASSERT_EQ(defaults.minimum_edition(), EDITION_2023);
200216
ASSERT_EQ(defaults.maximum_edition(), EDITION_2023);
201217

@@ -216,7 +232,7 @@ TEST(DefaultsTest, EmbeddedHexArray) {
216232
ASSERT_TRUE(defaults.ParseFromArray(kDefaultTestEmbeddedHexArray.data(),
217233
kDefaultTestEmbeddedHexArray.size()))
218234
<< "Could not parse embedded data";
219-
ASSERT_EQ(defaults.defaults().size(), 3);
235+
ASSERT_EQ(defaults.defaults().size(), 4);
220236
ASSERT_EQ(defaults.minimum_edition(), EDITION_2023);
221237
ASSERT_EQ(defaults.maximum_edition(), EDITION_2023);
222238

src/google/protobuf/compiler/code_generator_unittest.cc

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,51 @@ TEST_F(CodeGeneratorTest, BuildFeatureSetDefaults) {
470470
)pb")));
471471
}
472472

473+
TEST_F(CodeGeneratorTest, BuildFeatureSetDefaultsWithUnstable) {
474+
TestGenerator generator;
475+
auto result = generator.BuildFeatureSetDefaults();
476+
ASSERT_OK(result);
477+
EXPECT_THAT(result->defaults(result->defaults_size() - 1), EqualsProto(R"pb(
478+
edition: EDITION_UNSTABLE
479+
overridable_features {
480+
field_presence: EXPLICIT
481+
enum_type: OPEN
482+
repeated_field_encoding: PACKED
483+
utf8_validation: VERIFY
484+
message_encoding: LENGTH_PREFIXED
485+
json_format: ALLOW
486+
enforce_naming_style: STYLE2024
487+
default_symbol_visibility: EXPORT_TOP_LEVEL
488+
[pb.test] {
489+
file_feature: VALUE3
490+
extension_range_feature: VALUE1
491+
message_feature: VALUE1
492+
field_feature: VALUE1
493+
oneof_feature: VALUE1
494+
enum_feature: VALUE1
495+
enum_entry_feature: VALUE1
496+
service_feature: VALUE1
497+
method_feature: VALUE1
498+
multiple_feature: VALUE1
499+
bool_field_feature: false
500+
source_feature: VALUE1
501+
source_feature2: VALUE1
502+
future_feature: VALUE2
503+
value_lifetime_feature: VALUE_LIFETIME_FUTURE
504+
unstable_feature_new: VALUE2
505+
unstable_feature_existing: VALUE3
506+
}
507+
}
508+
fixed_features {
509+
[pb.test] {
510+
removed_feature: VALUE3
511+
legacy_feature: VALUE2
512+
same_edition_removed_feature: VALUE1
513+
}
514+
}
515+
)pb"));
516+
}
517+
473518
TEST_F(CodeGeneratorTest, BuildFeatureSetDefaultsUnsupported) {
474519
TestGenerator generator;
475520
generator.set_supported_features(0);

src/google/protobuf/compiler/command_line_interface.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2777,7 +2777,7 @@ bool CommandLineInterface::EnforceEditionsSupport(
27772777
fd->name(), codegen_name, edition, minimum_edition);
27782778
return false;
27792779
}
2780-
if (edition > maximum_edition) {
2780+
if (edition > maximum_edition && edition != EDITION_UNSTABLE) {
27812781
std::cerr << absl::Substitute(
27822782
"$0: is a file using edition $2, which isn't supported by code "
27832783
"generator $1. Please ask the owner of this code generator to add "
@@ -2803,7 +2803,7 @@ bool CommandLineInterface::EnforceProtocEditionsSupport(
28032803
continue;
28042804
}
28052805

2806-
if (edition > ProtocMaximumEdition()) {
2806+
if (edition > ProtocMaximumEdition() && edition != EDITION_UNSTABLE) {
28072807
std::cerr << absl::Substitute(
28082808
"$0: is a file using edition $1, which is later than "
28092809
"the protoc "

src/google/protobuf/compiler/command_line_interface_unittest.cc

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2166,8 +2166,23 @@ TEST_F(CommandLineInterfaceTest,
21662166
Run("protocol_compiler --experimental_editions --proto_path=$tmpdir "
21672167
"--test_out=$tmpdir foo.proto");
21682168
ExpectErrorSubstring(
2169-
"foo.proto:2:5: Edition 99997_TEST_ONLY is later than the maximum "
2170-
"supported edition 2024\n");
2169+
absl::StrCat("Edition 99997_TEST_ONLY is later than the maximum "
2170+
"supported edition ",
2171+
ProtocMaximumEdition()));
2172+
}
2173+
2174+
TEST_F(CommandLineInterfaceTest, UnstableEdition) {
2175+
CreateTempFile("foo.proto",
2176+
R"schema(
2177+
edition = "UNSTABLE";
2178+
package foo;
2179+
message Foo {
2180+
}
2181+
)schema");
2182+
2183+
Run("protocol_compiler --proto_path=$tmpdir "
2184+
"--test_out=$tmpdir foo.proto");
2185+
ExpectNoErrors();
21712186
}
21722187

21732188
TEST_F(CommandLineInterfaceTest, EditionDefaults) {
@@ -2315,6 +2330,32 @@ TEST_F(CommandLineInterfaceTest, EditionDefaultsWithMaximum) {
23152330
)pb"));
23162331
}
23172332

2333+
TEST_F(CommandLineInterfaceTest, EditionDefaultsWithUnstable) {
2334+
CreateTempFile("google/protobuf/descriptor.proto",
2335+
google::protobuf::DescriptorProto::descriptor()->file()->DebugString());
2336+
CreateTempFile("google/protobuf/unittest_features.proto",
2337+
pb::TestFeatures::descriptor()->file()->DebugString());
2338+
Run("protocol_compiler --proto_path=$tmpdir "
2339+
"--edition_defaults_out=$tmpdir/defaults "
2340+
"google/protobuf/unittest_features.proto "
2341+
"google/protobuf/descriptor.proto");
2342+
ExpectNoErrors();
2343+
2344+
FeatureSetDefaults defaults = ReadEditionDefaults("defaults");
2345+
EXPECT_EQ(defaults.defaults_size(), 5);
2346+
EXPECT_EQ(defaults.defaults(4).edition(), EDITION_UNSTABLE);
2347+
EXPECT_EQ(defaults.defaults(4)
2348+
.overridable_features()
2349+
.GetExtension(pb::test)
2350+
.unstable_feature_new(),
2351+
pb::EnumFeature::VALUE2);
2352+
EXPECT_EQ(defaults.defaults(4)
2353+
.overridable_features()
2354+
.GetExtension(pb::test)
2355+
.unstable_feature_existing(),
2356+
pb::EnumFeature::VALUE3);
2357+
}
2358+
23182359
TEST_F(CommandLineInterfaceTest, EditionDefaultsWithMinimum) {
23192360
CreateTempFile("google/protobuf/descriptor.proto",
23202361
google::protobuf::DescriptorProto::descriptor()->file()->DebugString());
@@ -2404,12 +2445,13 @@ TEST_F(CommandLineInterfaceTest, EditionDefaultsWithExtension) {
24042445
FeatureSetDefaults defaults = ReadEditionDefaults("defaults");
24052446
EXPECT_EQ(defaults.minimum_edition(), EDITION_PROTO2);
24062447
EXPECT_EQ(defaults.maximum_edition(), EDITION_99999_TEST_ONLY);
2407-
ASSERT_EQ(defaults.defaults_size(), 7);
2448+
ASSERT_EQ(defaults.defaults_size(), 8);
24082449
EXPECT_EQ(defaults.defaults(0).edition(), EDITION_LEGACY);
24092450
EXPECT_EQ(defaults.defaults(2).edition(), EDITION_2023);
24102451
EXPECT_EQ(defaults.defaults(3).edition(), EDITION_2024);
2411-
EXPECT_EQ(defaults.defaults(4).edition(), EDITION_99997_TEST_ONLY);
2412-
EXPECT_EQ(defaults.defaults(5).edition(), EDITION_99998_TEST_ONLY);
2452+
EXPECT_EQ(defaults.defaults(4).edition(), EDITION_UNSTABLE);
2453+
EXPECT_EQ(defaults.defaults(5).edition(), EDITION_99997_TEST_ONLY);
2454+
EXPECT_EQ(defaults.defaults(6).edition(), EDITION_99998_TEST_ONLY);
24132455
EXPECT_EQ(defaults.defaults(0)
24142456
.fixed_features()
24152457
.GetExtension(pb::test)
@@ -2429,11 +2471,16 @@ TEST_F(CommandLineInterfaceTest, EditionDefaultsWithExtension) {
24292471
.overridable_features()
24302472
.GetExtension(pb::test)
24312473
.file_feature(),
2432-
pb::EnumFeature::VALUE4);
2474+
pb::EnumFeature::VALUE3);
24332475
EXPECT_EQ(defaults.defaults(5)
24342476
.overridable_features()
24352477
.GetExtension(pb::test)
24362478
.file_feature(),
2479+
pb::EnumFeature::VALUE4);
2480+
EXPECT_EQ(defaults.defaults(6)
2481+
.overridable_features()
2482+
.GetExtension(pb::test)
2483+
.file_feature(),
24372484
pb::EnumFeature::VALUE5);
24382485
}
24392486

src/google/protobuf/descriptor_unittest.cc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12337,6 +12337,33 @@ TEST_F(FeaturesTest, FutureFeatureDefault) {
1233712337
pb::VALUE1);
1233812338
}
1233912339

12340+
TEST_F(FeaturesTest, NewUnstableFeatureDefault) {
12341+
BuildDescriptorMessagesInTestPool();
12342+
BuildFileInTestPool(pb::TestFeatures::descriptor()->file());
12343+
const FileDescriptor* file = BuildFile(R"pb(
12344+
name: "foo.proto"
12345+
syntax: "editions"
12346+
edition: EDITION_UNSTABLE
12347+
)pb");
12348+
ASSERT_THAT(file, NotNull());
12349+
EXPECT_EQ(GetFeatures(file).GetExtension(pb::test).unstable_feature_new(),
12350+
pb::VALUE2);
12351+
}
12352+
12353+
TEST_F(FeaturesTest, ExistingUnstableFeatureDefault) {
12354+
BuildDescriptorMessagesInTestPool();
12355+
BuildFileInTestPool(pb::TestFeatures::descriptor()->file());
12356+
const FileDescriptor* file = BuildFile(R"pb(
12357+
name: "foo.proto"
12358+
syntax: "editions"
12359+
edition: EDITION_UNSTABLE
12360+
)pb");
12361+
ASSERT_THAT(file, NotNull());
12362+
EXPECT_EQ(
12363+
GetFeatures(file).GetExtension(pb::test).unstable_feature_existing(),
12364+
pb::VALUE3);
12365+
}
12366+
1234012367
// Test that the result of FileDescriptor::DebugString() can be used to create
1234112368
// the original descriptors.
1234212369
class FeaturesDebugStringTest

src/google/protobuf/feature_resolver.cc

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

255255
void MaybeInsertEdition(Edition edition, Edition maximum_edition,
256256
absl::btree_set<Edition>& editions) {
257-
if (edition <= maximum_edition) {
257+
if (edition <= maximum_edition || edition == EDITION_UNSTABLE) {
258258
editions.insert(edition);
259259
}
260260
}
@@ -504,12 +504,14 @@ absl::StatusOr<FeatureSetDefaults> FeatureResolver::CompileDefaults(
504504

505505
absl::StatusOr<FeatureResolver> FeatureResolver::Create(
506506
Edition edition, const FeatureSetDefaults& compiled_defaults) {
507-
if (edition < compiled_defaults.minimum_edition()) {
507+
if (edition < compiled_defaults.minimum_edition() &&
508+
edition != EDITION_UNSTABLE) {
508509
return Error("Edition ", edition,
509510
" is earlier than the minimum supported edition ",
510511
compiled_defaults.minimum_edition());
511512
}
512-
if (compiled_defaults.maximum_edition() < edition) {
513+
if (compiled_defaults.maximum_edition() < edition &&
514+
edition != EDITION_UNSTABLE) {
513515
return Error("Edition ", edition,
514516
" is later than the maximum supported edition ",
515517
compiled_defaults.maximum_edition());

0 commit comments

Comments
 (0)