Skip to content

Commit 90e1b49

Browse files
zhangskzcopybara-github
authored andcommitted
Use Editions features in Java, Kotlin, and Java Lite code generators.
This uses C++ feature resolution. Note that JVM runtimes are not fully Editions compatible yet. PiperOrigin-RevId: 573905581
1 parent 6424bca commit 90e1b49

16 files changed

Lines changed: 156 additions & 22 deletions

src/google/protobuf/compiler/java/BUILD.bazel

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ cc_library(
2626
"names.cc",
2727
],
2828
hdrs = [
29+
"generator.h",
2930
"helpers.h",
3031
"name_resolver.h",
3132
"names.h",
@@ -35,13 +36,25 @@ cc_library(
3536
include_prefix = "google/protobuf/compiler/java",
3637
visibility = ["//pkg:__pkg__"],
3738
deps = [
39+
":java_features_bootstrap",
3840
"//src/google/protobuf:descriptor_legacy",
3941
"//src/google/protobuf:protobuf_nowkt",
4042
"//src/google/protobuf/compiler:code_generator",
4143
"@com_google_absl//absl/container:flat_hash_set",
4244
],
4345
)
4446

47+
cc_library(
48+
name = "java_features_bootstrap",
49+
srcs = ["java_features.pb.cc"],
50+
hdrs = ["java_features.pb.h"],
51+
include_prefix = "google/protobuf/compiler/java",
52+
deps = [
53+
"//src/google/protobuf:arena",
54+
"//src/google/protobuf:protobuf_nowkt",
55+
],
56+
)
57+
4558
cc_library(
4659
name = "java",
4760
srcs = [
@@ -57,7 +70,6 @@ cc_library(
5770
"file.cc",
5871
"generator.cc",
5972
"generator_factory.cc",
60-
"java_features.pb.cc",
6173
"kotlin_generator.cc",
6274
"map_field.cc",
6375
"map_field_lite.cc",
@@ -113,6 +125,7 @@ cc_library(
113125
"//src/google/protobuf/compiler:__pkg__",
114126
],
115127
deps = [
128+
":java_features_bootstrap",
116129
":names",
117130
":names_internal",
118131
"//src/google/protobuf:arena",

src/google/protobuf/compiler/java/doc_comment.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ static std::string FirstLineOf(const std::string& value) {
191191
static void WriteDebugString(io::Printer* printer, const FieldDescriptor* field,
192192
const Options options, const bool kdoc) {
193193
std::string field_comment = FirstLineOf(field->DebugString());
194+
if (options.strip_nonfunctional_codegen) {
195+
field_comment = field->name();
196+
}
194197
if (kdoc) {
195198
printer->Print(" * `$def$`\n", "def", EscapeKdoc(field_comment));
196199
} else {

src/google/protobuf/compiler/java/file.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,13 @@ void FileGenerator::GenerateDescriptorInitializationCodeForImmutable(
442442
FieldDescriptorSet extensions;
443443
CollectExtensions(file_proto, *file_->pool(), &extensions, file_data);
444444

445+
if (options_.strip_nonfunctional_codegen) {
446+
// Skip feature extensions, which are a visible (but non-functional)
447+
// deviation between editions and legacy syntax.
448+
absl::erase_if(extensions, [](const FieldDescriptor* field) {
449+
return field->containing_type()->full_name() == "google.protobuf.FeatureSet";
450+
});
451+
}
445452
if (!extensions.empty()) {
446453
// Must construct an ExtensionRegistry containing all existing extensions
447454
// and use it to parse the descriptor data again to recognize extensions.
@@ -744,6 +751,13 @@ void FileGenerator::GenerateKotlinSiblings(
744751

745752
bool FileGenerator::ShouldIncludeDependency(const FileDescriptor* descriptor,
746753
bool immutable_api) {
754+
// Skip feature imports, which are a visible (but non-functional) deviation
755+
// between editions and legacy syntax.
756+
if (options_.strip_nonfunctional_codegen &&
757+
IsKnownFeatureProto(descriptor->name())) {
758+
return false;
759+
}
760+
747761
return true;
748762
}
749763

src/google/protobuf/compiler/java/generator.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include <utility>
1515
#include <vector>
1616

17+
#include "google/protobuf/compiler/code_generator.h"
18+
1719

1820
#include <memory>
1921

@@ -36,7 +38,8 @@ JavaGenerator::JavaGenerator() {}
3638
JavaGenerator::~JavaGenerator() {}
3739

3840
uint64_t JavaGenerator::GetSupportedFeatures() const {
39-
return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL;
41+
return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL |
42+
CodeGenerator::Feature::FEATURE_SUPPORTS_EDITIONS;
4043
}
4144

4245
bool JavaGenerator::Generate(const FileDescriptor* file,
@@ -69,6 +72,8 @@ bool JavaGenerator::Generate(const FileDescriptor* file,
6972
file_options.annotate_code = true;
7073
} else if (option.first == "annotation_list_file") {
7174
file_options.annotation_list_file = option.second;
75+
} else if (option.first == "experimental_strip_nonfunctional_codegen") {
76+
file_options.strip_nonfunctional_codegen = true;
7277
} else {
7378
*error = absl::StrCat("Unknown generator option: ", option.first);
7479
return false;

src/google/protobuf/compiler/java/generator.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@
1414
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
1515
#define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
1616

17+
#include <cstdint>
1718
#include <string>
19+
#include <vector>
1820

1921
#include "google/protobuf/compiler/code_generator.h"
22+
#include "google/protobuf/compiler/java/java_features.pb.h"
23+
#include "google/protobuf/descriptor.pb.h"
2024

2125
// Must be included last.
2226
#include "google/protobuf/port_def.inc"
@@ -43,10 +47,19 @@ class PROTOC_EXPORT JavaGenerator : public CodeGenerator {
4347

4448
uint64_t GetSupportedFeatures() const override;
4549

50+
Edition GetMinimumEdition() const override { return Edition::EDITION_PROTO2; }
51+
Edition GetMaximumEdition() const override { return Edition::EDITION_2023; }
52+
53+
std::vector<const FieldDescriptor*> GetFeatureExtensions() const override {
54+
return {GetExtensionReflection(pb::java)};
55+
}
56+
4657
void set_opensource_runtime(bool opensource) {
4758
opensource_runtime_ = opensource;
4859
}
4960

61+
using CodeGenerator::GetResolvedSourceFeatures;
62+
5063
private:
5164
bool opensource_runtime_ = PROTO2_IS_OSS;
5265
};

src/google/protobuf/compiler/java/helpers.h

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <string>
1717

1818
#include "absl/strings/string_view.h"
19+
#include "google/protobuf/compiler/java/generator.h"
20+
#include "google/protobuf/compiler/java/java_features.pb.h"
1921
#include "google/protobuf/compiler/java/names.h"
2022
#include "google/protobuf/compiler/java/options.h"
2123
#include "google/protobuf/descriptor.h"
@@ -349,10 +351,12 @@ inline bool ExposePublicParser(const FileDescriptor* descriptor) {
349351
// but in the message and can be queried using additional getters that return
350352
// ints.
351353
inline bool SupportUnknownEnumValue(const FieldDescriptor* field) {
352-
// TODO: Check Java legacy_enum_field_treated_as_closed feature.
353-
return field->type() != FieldDescriptor::TYPE_ENUM ||
354-
FileDescriptorLegacy(field->file()).syntax() ==
355-
FileDescriptorLegacy::SYNTAX_PROTO3;
354+
if (JavaGenerator::GetResolvedSourceFeatures(*field)
355+
.GetExtension(pb::java)
356+
.legacy_closed_enum()) {
357+
return false;
358+
}
359+
return field->enum_type() != nullptr && !field->enum_type()->is_closed();
356360
}
357361

358362
// Check whether a message has repeated fields.
@@ -375,7 +379,14 @@ inline bool IsWrappersProtoFile(const FileDescriptor* descriptor) {
375379
}
376380

377381
inline bool CheckUtf8(const FieldDescriptor* descriptor) {
378-
return descriptor->requires_utf8_validation() ||
382+
if (JavaGenerator::GetResolvedSourceFeatures(*descriptor)
383+
.GetExtension(pb::java)
384+
.utf8_validation() == pb::JavaFeatures::VERIFY) {
385+
return true;
386+
}
387+
return JavaGenerator::GetResolvedSourceFeatures(*descriptor)
388+
.utf8_validation() == FeatureSet::VERIFY ||
389+
// For legacy syntax. This is not allowed under Editions.
379390
descriptor->file()->options().java_string_check_utf8();
380391
}
381392

src/google/protobuf/compiler/java/kotlin_generator.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ KotlinGenerator::KotlinGenerator() {}
2222
KotlinGenerator::~KotlinGenerator() {}
2323

2424
uint64_t KotlinGenerator::GetSupportedFeatures() const {
25-
return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL;
25+
return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL |
26+
CodeGenerator::Feature::FEATURE_SUPPORTS_EDITIONS;
2627
}
2728

2829
bool KotlinGenerator::Generate(const FileDescriptor* file,
@@ -54,6 +55,8 @@ bool KotlinGenerator::Generate(const FileDescriptor* file,
5455
file_options.annotate_code = true;
5556
} else if (option.first == "annotation_list_file") {
5657
file_options.annotation_list_file = option.second;
58+
} else if (option.first == "experimental_strip_nonfunctional_codegen") {
59+
file_options.strip_nonfunctional_codegen = true;
5760
} else {
5861
*error = absl::StrCat("Unknown generator option: ", option.first);
5962
return false;

src/google/protobuf/compiler/java/kotlin_generator.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include <string>
1414

1515
#include "google/protobuf/compiler/code_generator.h"
16+
#include "google/protobuf/compiler/java/java_features.pb.h"
17+
#include "google/protobuf/descriptor.pb.h"
1618

1719
// Must be included last.
1820
#include "google/protobuf/port_def.inc"
@@ -38,6 +40,15 @@ class PROTOC_EXPORT KotlinGenerator : public CodeGenerator {
3840
GeneratorContext* context, std::string* error) const override;
3941

4042
uint64_t GetSupportedFeatures() const override;
43+
44+
Edition GetMinimumEdition() const override { return Edition::EDITION_PROTO2; }
45+
Edition GetMaximumEdition() const override { return Edition::EDITION_2023; }
46+
47+
std::vector<const FieldDescriptor*> GetFeatureExtensions() const override {
48+
return {GetExtensionReflection(pb::java)};
49+
}
50+
51+
using CodeGenerator::GetResolvedSourceFeatures;
4152
};
4253

4354
} // namespace java

src/google/protobuf/compiler/java/message_lite.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,14 +487,18 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuildMessageInfo(
487487
int flags = 0;
488488
if (FileDescriptorLegacy(descriptor_->file()).syntax() ==
489489
FileDescriptorLegacy::Syntax::SYNTAX_PROTO2) {
490-
flags |= 0x1;
490+
if (!context_->options().strip_nonfunctional_codegen) {
491+
flags |= 0x1;
492+
}
491493
}
492494
if (descriptor_->options().message_set_wire_format()) {
493495
flags |= 0x2;
494496
}
495497
if (FileDescriptorLegacy(descriptor_->file()).syntax() ==
496498
FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS) {
497-
flags |= 0x4;
499+
if (!context_->options().strip_nonfunctional_codegen) {
500+
flags |= 0x4;
501+
}
498502
}
499503

500504
WriteIntToUtf16CharSequence(flags, &chars);

src/google/protobuf/compiler/java/message_serialization_unittest.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,11 @@ int CompileJavaProto(std::string proto_file_name) {
4747
"protoc",
4848
proto_path.c_str(),
4949
java_out.c_str(),
50+
"--experimental_editions",
5051
proto_file_name.c_str(),
5152
};
5253

53-
return cli.Run(4, argv);
54+
return cli.Run(5, argv);
5455
}
5556

5657
TEST(MessageSerializationTest, CollapseAdjacentExtensionRanges) {

0 commit comments

Comments
 (0)