Remove edition getter from C++ descriptor APIs

PiperOrigin-RevId: 597686725
pull/15415/head
Mike Kruskal 2024-01-11 16:44:25 -08:00 committed by Copybara-Service
parent e6d8669958
commit 93b219f4e8
20 changed files with 143 additions and 80 deletions

View File

@ -145,6 +145,7 @@ cc_library(
deps = [
":conformance_cc_proto",
"//src/google/protobuf",
"//src/google/protobuf:descriptor_legacy",
"//src/google/protobuf:protobuf_lite",
"//src/google/protobuf/util:differencer",
"//src/google/protobuf/util:json_util",

View File

@ -24,6 +24,7 @@
#include "absl/strings/string_view.h"
#include "conformance/conformance.pb.h"
#include "conformance/conformance.pb.h"
#include "google/protobuf/descriptor_legacy.h"
#include "google/protobuf/message.h"
#include "google/protobuf/text_format.h"
@ -142,7 +143,8 @@ ConformanceTestSuite::ConformanceRequestSetting::NewTestMessage() const {
std::string
ConformanceTestSuite::ConformanceRequestSetting::GetSyntaxIdentifier() const {
switch (prototype_message_.GetDescriptor()->file()->edition()) {
switch (FileDescriptorLegacy(prototype_message_.GetDescriptor()->file())
.edition()) {
case Edition::EDITION_PROTO3:
return "Proto3";
case Edition::EDITION_PROTO2:

View File

@ -237,6 +237,7 @@ cc_dist_library(
],
tags = ["manual"],
deps = [
"//src/google/protobuf:descriptor_legacy",
"//src/google/protobuf:internal_visibility_for_testing",
"//src/google/protobuf:test_textproto",
"//src/google/protobuf/compiler:command_line_interface_tester",

View File

@ -649,6 +649,18 @@ cc_library(
],
)
cc_library(
name = "descriptor_legacy",
hdrs = ["descriptor_legacy.h"],
copts = COPTS,
linkopts = LINK_OPTS,
strip_include_prefix = "/src",
visibility = ["//:__subpackages__"],
deps = [
":protobuf",
],
)
filegroup(
name = "well_known_type_protos",
srcs = [
@ -1110,6 +1122,7 @@ cc_test(
deps = [
":any_cc_proto",
":cc_test_protos",
":descriptor_legacy",
":port",
":protobuf",
":test_textproto",

View File

@ -156,6 +156,11 @@ class PROTOC_EXPORT CodeGenerator {
return ::google::protobuf::internal::InternalFeatureHelper::GetUnresolvedFeatures(
descriptor, extension);
}
// Retrieves the edition of a built file descriptor.
static Edition GetEdition(const FileDescriptor& file) {
return ::google::protobuf::internal::InternalFeatureHelper::GetEdition(file);
}
};
// CodeGenerators generate one or more files in a given directory. This

View File

@ -991,8 +991,8 @@ bool ContainsProto3Optional(const Descriptor* desc) {
return false;
}
bool ContainsProto3Optional(const FileDescriptor* file) {
if (file->edition() == Edition::EDITION_PROTO3) {
bool ContainsProto3Optional(Edition edition, const FileDescriptor* file) {
if (edition == Edition::EDITION_PROTO3) {
for (int i = 0; i < file->message_type_count(); i++) {
if (ContainsProto3Optional(file->message_type(i))) {
return true;
@ -1600,7 +1600,8 @@ bool CommandLineInterface::ParseInputFiles(
if (!experimental_editions_ &&
!absl::StartsWith(parsed_file->name(), "google/protobuf/") &&
!absl::StartsWith(parsed_file->name(), "upb/")) {
if (parsed_file->edition() >= Edition::EDITION_2023) {
if (::google::protobuf::internal::InternalFeatureHelper::GetEdition(*parsed_file) >=
Edition::EDITION_2023) {
std::cerr
<< parsed_file->name()
<< ": This file uses editions, but --experimental_editions has not "
@ -2533,7 +2534,8 @@ bool CommandLineInterface::EnforceProto3OptionalSupport(
supported_features & CodeGenerator::FEATURE_PROTO3_OPTIONAL;
if (!supports_proto3_optional) {
for (const auto fd : parsed_files) {
if (ContainsProto3Optional(fd)) {
if (ContainsProto3Optional(
::google::protobuf::internal::InternalFeatureHelper::GetEdition(*fd), fd)) {
std::cerr << fd->name()
<< ": is a proto3 file that contains optional fields, but "
"code generator "
@ -2558,7 +2560,9 @@ bool CommandLineInterface::EnforceEditionsSupport(
return true;
}
for (const auto* fd : parsed_files) {
if (fd->edition() < Edition::EDITION_2023) {
Edition edition =
::google::protobuf::internal::InternalFeatureHelper::GetEdition(*fd);
if (edition < Edition::EDITION_2023) {
// Legacy proto2/proto3 files don't need any checks.
continue;
}
@ -2576,19 +2580,19 @@ bool CommandLineInterface::EnforceEditionsSupport(
fd->name(), codegen_name);
return false;
}
if (fd->edition() < minimum_edition) {
if (edition < minimum_edition) {
std::cerr << absl::Substitute(
"$0: is a file using edition $2, which isn't supported by code "
"generator $1. Please upgrade your file to at least edition $3.",
fd->name(), codegen_name, fd->edition(), minimum_edition);
fd->name(), codegen_name, edition, minimum_edition);
return false;
}
if (fd->edition() > maximum_edition) {
if (edition > maximum_edition) {
std::cerr << absl::Substitute(
"$0: is a file using edition $2, which isn't supported by code "
"generator $1. Please ask the owner of this code generator to add "
"support or switch back to a maximum of edition $3.",
fd->name(), codegen_name, fd->edition(), maximum_edition);
fd->name(), codegen_name, edition, maximum_edition);
return false;
}
}

View File

@ -58,6 +58,7 @@ class PROTOC_EXPORT JavaGenerator : public CodeGenerator {
opensource_runtime_ = opensource;
}
using CodeGenerator::GetEdition;
using CodeGenerator::GetResolvedSourceFeatures;
private:

View File

@ -25,6 +25,7 @@
#include "google/protobuf/compiler/java/doc_comment.h"
#include "google/protobuf/compiler/java/enum_lite.h"
#include "google/protobuf/compiler/java/extension_lite.h"
#include "google/protobuf/compiler/java/generator.h"
#include "google/protobuf/compiler/java/generator_factory.h"
#include "google/protobuf/compiler/java/helpers.h"
#include "google/protobuf/compiler/java/message_builder.h"
@ -476,9 +477,11 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuildMessageInfo(
flags |= 0x2;
}
if (!context_->options().strip_nonfunctional_codegen) {
if (descriptor_->file()->edition() == Edition::EDITION_PROTO2) {
if (JavaGenerator::GetEdition(*descriptor_->file()) ==
Edition::EDITION_PROTO2) {
flags |= 0x1;
} else if (descriptor_->file()->edition() >= Edition::EDITION_2023) {
} else if (JavaGenerator::GetEdition(*descriptor_->file()) >=
Edition::EDITION_2023) {
flags |= 0x4;
}
}

View File

@ -215,7 +215,7 @@ bool MockCodeGenerator::Generate(const FileDescriptor* file,
maximum_edition_ = Edition::EDITION_PROTO2;
}
if (file->edition() >= Edition::EDITION_2023 &&
if (GetEdition(*file) >= Edition::EDITION_2023 &&
(suppressed_features_ & CodeGenerator::FEATURE_SUPPORTS_EDITIONS) == 0) {
internal::VisitDescriptors(*file, [&](const auto& descriptor) {
const FeatureSet& features = GetResolvedSourceFeatures(descriptor);

View File

@ -264,10 +264,11 @@ FileGenerator::CommonState::CollectMinimalFileDepsContainingExtensions(
return result;
}
FileGenerator::FileGenerator(const FileDescriptor* file,
FileGenerator::FileGenerator(Edition edition, const FileDescriptor* file,
const GenerationOptions& generation_options,
CommonState& common_state)
: file_(file),
: edition_(edition),
file_(file),
generation_options_(generation_options),
common_state_(&common_state),
root_class_name_(FileClassName(file)),
@ -777,7 +778,7 @@ void FileGenerator::EmitFileDescription(io::Printer* p) const {
// mode.
syntax = "GPBFileSyntaxUnknown";
} else {
switch (file_->edition()) {
switch (edition_) {
case Edition::EDITION_UNKNOWN:
syntax = "GPBFileSyntaxUnknown";
break;

View File

@ -55,7 +55,7 @@ class FileGenerator {
const bool include_custom_options;
};
FileGenerator(const FileDescriptor* file,
FileGenerator(Edition edition, const FileDescriptor* file,
const GenerationOptions& generation_options,
CommonState& common_state);
~FileGenerator() = default;
@ -114,6 +114,7 @@ class FileGenerator {
generation_options_.headers_use_forward_declarations;
}
const Edition edition_;
const FileDescriptor* file_;
const GenerationOptions& generation_options_;
mutable CommonState* common_state_;

View File

@ -341,7 +341,8 @@ bool ObjectiveCGenerator::GenerateAll(
FileGenerator::CommonState state(!generation_options.strip_custom_options);
for (const auto& file : files) {
const FileGenerator file_generator(file, generation_options, state);
const FileGenerator file_generator(GetEdition(*file), file,
generation_options, state);
std::string filepath = FilePath(file);
// Generate header.

View File

@ -544,8 +544,8 @@ void Generator::PrintFileDescriptor() const {
m["descriptor_name"] = kDescriptorKey;
m["name"] = file_->name();
m["package"] = file_->package();
m["syntax"] = GetLegacySyntaxName(file_->edition());
m["edition"] = Edition_Name(file_->edition());
m["syntax"] = GetLegacySyntaxName(GetEdition(*file_));
m["edition"] = Edition_Name(GetEdition(*file_));
m["options"] = OptionsValue(proto_.options().SerializeAsString());
m["serialized_descriptor"] = absl::CHexEscape(file_descriptor_serialized_);
if (GeneratingDescriptorProto()) {

View File

@ -1164,22 +1164,8 @@ const FeatureSet& GetParentFeatures(const MethodDescriptor* method) {
return internal::InternalFeatureHelper::GetFeatures(*method->service());
}
bool IsLegacyEdition(const FileDescriptor* file) {
return file->edition() < Edition::EDITION_2023;
}
template <class DescriptorT>
bool IsLegacyEdition(const DescriptorT* descriptor) {
return IsLegacyEdition(descriptor->file());
}
Edition GetDescriptorEdition(const FileDescriptor* descriptor) {
return descriptor->edition();
}
template <class DescriptorT>
Edition GetDescriptorEdition(const DescriptorT* descriptor) {
return GetDescriptorEdition(descriptor->file());
bool IsLegacyEdition(Edition edition) {
return edition < Edition::EDITION_2023;
}
} // anonymous namespace
@ -2759,7 +2745,7 @@ void FileDescriptor::CopyHeadingTo(FileDescriptorProto* proto) const {
if (edition() == Edition::EDITION_PROTO3) {
proto->set_syntax("proto3");
} else if (!IsLegacyEdition(this)) {
} else if (!IsLegacyEdition(edition())) {
proto->set_syntax("editions");
proto->set_edition(edition());
}
@ -2857,7 +2843,7 @@ void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const {
}
// Some compilers do not allow static_cast directly between two enum types,
// so we must cast to int first.
if (is_required() && !IsLegacyEdition(this)) {
if (is_required() && !IsLegacyEdition(file()->edition())) {
// Editions files have no required keyword, and we only set this label
// during descriptor build.
proto->set_label(static_cast<FieldDescriptorProto::Label>(
@ -2866,7 +2852,7 @@ void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const {
proto->set_label(static_cast<FieldDescriptorProto::Label>(
absl::implicit_cast<int>(label())));
}
if (type() == TYPE_GROUP && !IsLegacyEdition(this)) {
if (type() == TYPE_GROUP && !IsLegacyEdition(file()->edition())) {
// Editions files have no group keyword, and we only set this label
// during descriptor build.
proto->set_type(static_cast<FieldDescriptorProto::Type>(
@ -3002,8 +2988,9 @@ void MethodDescriptor::CopyTo(MethodDescriptorProto* proto) const {
namespace {
bool IsGroupSyntax(const FieldDescriptor* desc) {
return IsLegacyEdition(desc) && desc->type() == FieldDescriptor::TYPE_GROUP;
bool IsGroupSyntax(Edition edition, const FieldDescriptor* desc) {
return IsLegacyEdition(edition) &&
desc->type() == FieldDescriptor::TYPE_GROUP;
}
template <typename OptionsT>
@ -3117,8 +3104,8 @@ bool FormatLineOptions(int depth, const Message& options,
return !all_options.empty();
}
static std::string GetLegacySyntaxName(const FileDescriptor* file) {
if (file->edition() == Edition::EDITION_PROTO3) {
static std::string GetLegacySyntaxName(Edition edition) {
if (edition == Edition::EDITION_PROTO3) {
return "proto3";
}
return "proto2";
@ -3201,9 +3188,9 @@ std::string FileDescriptor::DebugStringWithOptions(
SourceLocationCommentPrinter syntax_comment(this, path, "",
debug_string_options);
syntax_comment.AddPreComment(&contents);
if (IsLegacyEdition(this)) {
if (IsLegacyEdition(edition())) {
absl::SubstituteAndAppend(&contents, "syntax = \"$0\";\n\n",
GetLegacySyntaxName(this));
GetLegacySyntaxName(edition()));
} else {
absl::SubstituteAndAppend(&contents, "edition = \"$0\";\n\n", edition());
}
@ -3256,7 +3243,7 @@ std::string FileDescriptor::DebugStringWithOptions(
// definitions (those will be done with their group field descriptor).
absl::flat_hash_set<const Descriptor*> groups;
for (int i = 0; i < extension_count(); i++) {
if (IsGroupSyntax(extension(i))) {
if (IsGroupSyntax(edition(), extension(i))) {
groups.insert(extension(i)->message_type());
}
}
@ -3331,12 +3318,12 @@ void Descriptor::DebugString(int depth, std::string* contents,
// descriptor).
absl::flat_hash_set<const Descriptor*> groups;
for (int i = 0; i < field_count(); i++) {
if (IsGroupSyntax(field(i))) {
if (IsGroupSyntax(file()->edition(), field(i))) {
groups.insert(field(i)->message_type());
}
}
for (int i = 0; i < extension_count(); i++) {
if (IsGroupSyntax(extension(i))) {
if (IsGroupSyntax(file()->edition(), extension(i))) {
groups.insert(extension(i)->message_type());
}
}
@ -3447,7 +3434,7 @@ std::string FieldDescriptor::FieldTypeNameDebugString() const {
switch (type()) {
case TYPE_MESSAGE:
case TYPE_GROUP:
if (IsGroupSyntax(this)) {
if (IsGroupSyntax(file()->edition(), this)) {
return kTypeToName[type()];
}
return absl::StrCat(".", message_type()->full_name());
@ -3482,7 +3469,7 @@ void FieldDescriptor::DebugString(
label.clear();
}
// Label is omitted for optional and required fields under editions.
if ((is_optional() || is_required()) && !IsLegacyEdition(this)) {
if ((is_optional() || is_required()) && !IsLegacyEdition(file()->edition())) {
label.clear();
}
@ -3492,7 +3479,8 @@ void FieldDescriptor::DebugString(
absl::SubstituteAndAppend(
contents, "$0$1$2 $3 = $4", prefix, label, field_type,
IsGroupSyntax(this) ? message_type()->name() : name(), number());
IsGroupSyntax(file()->edition(), this) ? message_type()->name() : name(),
number());
bool bracketed = false;
if (has_default_value()) {
@ -3526,7 +3514,7 @@ void FieldDescriptor::DebugString(
contents->append("]");
}
if (IsGroupSyntax(this)) {
if (IsGroupSyntax(file()->edition(), this)) {
if (debug_string_options.elide_group_body) {
contents->append(" { ... };\n");
} else {
@ -4201,8 +4189,8 @@ class DescriptorBuilder {
internal::FlatAllocator& alloc);
template <class DescriptorT>
void ResolveFeaturesImpl(
const typename DescriptorT::Proto& proto, DescriptorT* descriptor,
typename DescriptorT::OptionsType* options,
Edition edition, const typename DescriptorT::Proto& proto,
DescriptorT* descriptor, typename DescriptorT::OptionsType* options,
internal::FlatAllocator& alloc,
DescriptorPool::ErrorCollector::ErrorLocation error_location,
bool force_merge = false);
@ -5305,8 +5293,9 @@ static void InferLegacyProtoFeatures(const FieldDescriptorProto& proto,
template <class DescriptorT>
void DescriptorBuilder::ResolveFeaturesImpl(
const typename DescriptorT::Proto& proto, DescriptorT* descriptor,
typename DescriptorT::OptionsType* options, internal::FlatAllocator& alloc,
Edition edition, const typename DescriptorT::Proto& proto,
DescriptorT* descriptor, typename DescriptorT::OptionsType* options,
internal::FlatAllocator& alloc,
DescriptorPool::ErrorCollector::ErrorLocation error_location,
bool force_merge) {
const FeatureSet& parent_features = GetParentFeatures(descriptor);
@ -5326,13 +5315,12 @@ void DescriptorBuilder::ResolveFeaturesImpl(
FeatureSet base_features = *descriptor->proto_features_;
// Handle feature inference from proto2/proto3.
if (IsLegacyEdition(descriptor)) {
if (IsLegacyEdition(edition)) {
if (descriptor->proto_features_ != &FeatureSet::default_instance()) {
AddError(descriptor->name(), proto, error_location,
"Features are only valid under editions.");
}
InferLegacyProtoFeatures(proto, *options, GetDescriptorEdition(descriptor),
base_features);
InferLegacyProtoFeatures(proto, *options, edition, base_features);
}
if (base_features.ByteSizeLong() == 0 && !force_merge) {
@ -5358,8 +5346,8 @@ void DescriptorBuilder::ResolveFeatures(
const typename DescriptorT::Proto& proto, DescriptorT* descriptor,
typename DescriptorT::OptionsType* options,
internal::FlatAllocator& alloc) {
ResolveFeaturesImpl(proto, descriptor, options, alloc,
DescriptorPool::ErrorCollector::NAME);
ResolveFeaturesImpl(descriptor->file()->edition(), proto, descriptor, options,
alloc, DescriptorPool::ErrorCollector::NAME);
}
void DescriptorBuilder::ResolveFeatures(const FileDescriptorProto& proto,
@ -5368,7 +5356,7 @@ void DescriptorBuilder::ResolveFeatures(const FileDescriptorProto& proto,
internal::FlatAllocator& alloc) {
// File descriptors always need their own merged feature set, even without
// any explicit features.
ResolveFeaturesImpl(proto, descriptor, options, alloc,
ResolveFeaturesImpl(descriptor->edition(), proto, descriptor, options, alloc,
DescriptorPool::ErrorCollector::EDITIONS,
/*force_merge=*/true);
}
@ -5444,11 +5432,11 @@ void DescriptorBuilder::AddImportError(const FileDescriptorProto& proto,
}
PROTOBUF_NOINLINE static bool ExistingFileMatchesProto(
const FileDescriptor* existing_file, const FileDescriptorProto& proto) {
Edition edition, const FileDescriptor* existing_file,
const FileDescriptorProto& proto) {
FileDescriptorProto existing_proto;
existing_file->CopyTo(&existing_proto);
if (existing_file->edition() == Edition::EDITION_PROTO2 &&
proto.has_syntax()) {
if (edition == Edition::EDITION_PROTO2 && proto.has_syntax()) {
existing_proto.set_syntax("proto2");
}
@ -5593,7 +5581,8 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
const FileDescriptor* existing_file = tables_->FindFile(filename_);
if (existing_file != nullptr) {
// File already in pool. Compare the existing one to the input.
if (ExistingFileMatchesProto(existing_file, proto)) {
if (ExistingFileMatchesProto(existing_file->edition(), existing_file,
proto)) {
// They're identical. Return the existing descriptor.
return existing_file;
}
@ -7882,7 +7871,7 @@ static bool IsStringMapType(const FieldDescriptor& field) {
void DescriptorBuilder::ValidateFileFeatures(const FileDescriptor* file,
const FileDescriptorProto& proto) {
// Rely on our legacy validation for proto2/proto3 files.
if (IsLegacyEdition(file)) {
if (IsLegacyEdition(file->edition())) {
return;
}
@ -9589,6 +9578,9 @@ namespace internal {
absl::string_view ShortEditionName(Edition edition) {
return absl::StripPrefix(Edition_Name(edition), "EDITION_");
}
Edition InternalFeatureHelper::GetEdition(const FileDescriptor& desc) {
return desc.edition();
}
} // namespace internal
} // namespace protobuf

View File

@ -277,6 +277,11 @@ class PROTOBUF_EXPORT InternalFeatureHelper {
FeatureSet, TypeTraitsT, field_type, is_packed>& extension) {
return descriptor.proto_features_->GetExtension(extension);
}
// Provides a restricted view exclusively to code generators to query the
// edition of files being processed. While most people should never write
// edition-dependent code, generators frequently will need to.
static Edition GetEdition(const FileDescriptor& desc);
};
PROTOBUF_EXPORT absl::string_view ShortEditionName(Edition edition);
@ -1853,11 +1858,6 @@ class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase {
// descriptor.proto, and any available extensions of that message.
const FileOptions& options() const;
public:
// Returns edition of this file. For legacy proto2/proto3 files, special
// EDITION_PROTO2 and EDITION_PROTO3 values are used.
Edition edition() const;
// Find a top-level message type by name (not full_name). Returns nullptr if
// not found.
const Descriptor* FindMessageTypeByName(absl::string_view name) const;
@ -1924,8 +1924,15 @@ class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase {
bool GetSourceLocation(const std::vector<int>& path,
SourceLocation* out_location) const;
private:
// Returns edition of this file. For legacy proto2/proto3 files, special
// EDITION_PROTO2 and EDITION_PROTO3 values are used.
Edition edition() const;
private:
friend class Symbol;
friend class FileDescriptorLegacy;
typedef FileOptions OptionsType;
bool is_placeholder_;

View File

@ -0,0 +1,25 @@
#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_EDITION_H__
#define GOOGLE_PROTOBUF_DESCRIPTOR_EDITION_H__
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/descriptor.h"
namespace google {
namespace protobuf {
// TODO Remove this deprecated API entirely.
class FileDescriptorLegacy {
public:
explicit FileDescriptorLegacy(const FileDescriptor* file) : file_(file) {}
// Edition shouldn't be depended on unless dealing with raw unbuilt
// descriptors, which will expose it via FileDescriptorProto.edition.
Edition edition() const { return file_->edition(); }
private:
const FileDescriptor* file_;
};
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_DESCRIPTOR_EDITION_H__

View File

@ -47,6 +47,7 @@
#include "google/protobuf/compiler/parser.h"
#include "google/protobuf/cpp_features.pb.h"
#include "google/protobuf/descriptor_database.h"
#include "google/protobuf/descriptor_legacy.h"
#include "google/protobuf/dynamic_message.h"
#include "google/protobuf/feature_resolver.h"
#include "google/protobuf/io/tokenizer.h"
@ -480,7 +481,7 @@ TEST_F(FileDescriptorTest, Edition) {
DescriptorPool pool;
const FileDescriptor* file = pool.BuildFile(proto);
ASSERT_TRUE(file != nullptr);
EXPECT_EQ(file->edition(), Edition::EDITION_PROTO2);
EXPECT_EQ(FileDescriptorLegacy(file).edition(), Edition::EDITION_PROTO2);
FileDescriptorProto other;
file->CopyTo(&other);
EXPECT_EQ("", other.syntax());
@ -491,7 +492,7 @@ TEST_F(FileDescriptorTest, Edition) {
DescriptorPool pool;
const FileDescriptor* file = pool.BuildFile(proto);
ASSERT_TRUE(file != nullptr);
EXPECT_EQ(file->edition(), Edition::EDITION_PROTO3);
EXPECT_EQ(FileDescriptorLegacy(file).edition(), Edition::EDITION_PROTO3);
FileDescriptorProto other;
file->CopyTo(&other);
EXPECT_EQ("proto3", other.syntax());
@ -503,8 +504,7 @@ TEST_F(FileDescriptorTest, Edition) {
DescriptorPool pool;
const FileDescriptor* file = pool.BuildFile(proto);
ASSERT_TRUE(file != nullptr);
EXPECT_EQ(file->edition(), Edition::EDITION_2023);
EXPECT_EQ(file->edition(), EDITION_2023);
EXPECT_EQ(FileDescriptorLegacy(file).edition(), Edition::EDITION_2023);
FileDescriptorProto other;
file->CopyTo(&other);
EXPECT_EQ("editions", other.syntax());

View File

@ -201,6 +201,7 @@ cc_library(
visibility = ["//:__subpackages__"],
deps = [
"//src/google/protobuf",
"//src/google/protobuf:descriptor_legacy",
"//src/google/protobuf:port",
"//src/google/protobuf:source_context_cc_proto",
"//src/google/protobuf:type_cc_proto",
@ -226,6 +227,7 @@ cc_test(
"//src/google/protobuf",
"//src/google/protobuf:any_cc_proto",
"//src/google/protobuf:cc_test_protos",
"//src/google/protobuf:descriptor_legacy",
"//src/google/protobuf:test_util",
"//src/google/protobuf:type_cc_proto",
"//src/google/protobuf:wrappers_cc_proto",

View File

@ -20,6 +20,7 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
#include "google/protobuf/descriptor_legacy.h"
#include "google/protobuf/io/strtod.h"
#include "google/protobuf/util/type_resolver.h"
@ -260,7 +261,8 @@ Syntax ConvertSyntax(Edition edition) {
void ConvertEnumDescriptor(const EnumDescriptor& descriptor, Enum* enum_type) {
enum_type->Clear();
enum_type->set_syntax(ConvertSyntax(descriptor.file()->edition()));
enum_type->set_syntax(
ConvertSyntax(FileDescriptorLegacy(descriptor.file()).edition()));
enum_type->set_name(descriptor.full_name());
enum_type->mutable_source_context()->set_file_name(descriptor.file()->name());
@ -281,7 +283,8 @@ void ConvertDescriptor(absl::string_view url_prefix,
const Descriptor& descriptor, Type* type) {
type->Clear();
type->set_name(descriptor.full_name());
type->set_syntax(ConvertSyntax(descriptor.file()->edition()));
type->set_syntax(
ConvertSyntax(FileDescriptorLegacy(descriptor.file()).edition()));
for (int i = 0; i < descriptor.field_count(); ++i) {
ConvertFieldDescriptor(url_prefix, *descriptor.field(i),
type->add_fields());

View File

@ -21,6 +21,7 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor_legacy.h"
#include "google/protobuf/util/json_format_proto3.pb.h"
#include "google/protobuf/map_unittest.pb.h"
#include "google/protobuf/unittest.pb.h"
@ -443,7 +444,7 @@ class DescriptorPoolTypeResolverSyntaxTest : public testing::Test {
TEST_F(DescriptorPoolTypeResolverSyntaxTest, SyntaxProto2) {
const FileDescriptor* file = BuildFile("proto2");
ASSERT_EQ(file->edition(), Edition::EDITION_PROTO2);
ASSERT_EQ(FileDescriptorLegacy(file).edition(), Edition::EDITION_PROTO2);
Type type;
ASSERT_TRUE(
@ -454,7 +455,7 @@ TEST_F(DescriptorPoolTypeResolverSyntaxTest, SyntaxProto2) {
TEST_F(DescriptorPoolTypeResolverSyntaxTest, SyntaxProto3) {
const FileDescriptor* file = BuildFile("proto3");
ASSERT_EQ(file->edition(), Edition::EDITION_PROTO3);
ASSERT_EQ(FileDescriptorLegacy(file).edition(), Edition::EDITION_PROTO3);
Type type;
ASSERT_TRUE(