[Upb C++] Generate class scoped declarations for enumerations.

PiperOrigin-RevId: 512191989
pull/13171/head
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent 9253c42843
commit a35491fa55
  1. 9
      protos_generator/gen_enums.cc
  2. 3
      protos_generator/gen_enums.h
  3. 52
      protos_generator/gen_messages.cc
  4. 1
      protos_generator/gen_messages.h
  5. 3
      protos_generator/protoc-gen-upb-protos.cc
  6. 11
      protos_generator/tests/test_generated.cc

@ -25,6 +25,11 @@
#include "protos_generator/gen_enums.h" #include "protos_generator/gen_enums.h"
#include <algorithm>
#include <limits>
#include <string>
#include <vector>
#include "google/protobuf/descriptor.pb.h" #include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.h"
#include "protos_generator/gen_utils.h" #include "protos_generator/gen_utils.h"
@ -106,10 +111,6 @@ void WriteEnumValues(const protobuf::EnumDescriptor* desc, Output& output) {
for (size_t i = 0; i < values.size(); i++) { for (size_t i = 0; i < values.size(); i++) {
auto value = values[i]; auto value = values[i];
output(" $0", EnumValueSymbolInNameSpace(desc, value)); output(" $0", EnumValueSymbolInNameSpace(desc, value));
if (value->options().deprecated()) {
output(" ABSL_DEPRECATED(\"Proto enum $0\")",
EnumValueSymbolInNameSpace(desc, value));
}
output(" = $0", EnumInt32ToString(value->number())); output(" = $0", EnumInt32ToString(value->number()));
if (i != values.size() - 1) { if (i != values.size() - 1) {
output(","); output(",");

@ -34,6 +34,9 @@ namespace protos_generator {
namespace protobuf = ::google::protobuf; namespace protobuf = ::google::protobuf;
std::string EnumTypeName(const protobuf::EnumDescriptor* enum_descriptor); std::string EnumTypeName(const protobuf::EnumDescriptor* enum_descriptor);
std::string EnumValueSymbolInNameSpace(
const protobuf::EnumDescriptor* desc,
const protobuf::EnumValueDescriptor* value);
void WriteHeaderEnumForwardDecls( void WriteHeaderEnumForwardDecls(
std::vector<const protobuf::EnumDescriptor*>& enums, Output& output); std::vector<const protobuf::EnumDescriptor*>& enums, Output& output);
void WriteEnumDeclarations( void WriteEnumDeclarations(

@ -27,9 +27,13 @@
#include "protos_generator/gen_messages.h" #include "protos_generator/gen_messages.h"
#include <string>
#include <vector>
#include "google/protobuf/descriptor.pb.h" #include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.h"
#include "protos_generator/gen_accessors.h" #include "protos_generator/gen_accessors.h"
#include "protos_generator/gen_enums.h"
#include "protos_generator/gen_extensions.h" #include "protos_generator/gen_extensions.h"
#include "protos_generator/gen_utils.h" #include "protos_generator/gen_utils.h"
#include "protos_generator/output.h" #include "protos_generator/output.h"
@ -45,6 +49,7 @@ void WriteModelAccessDeclaration(const protobuf::Descriptor* descriptor,
void WriteModelPublicDeclaration( void WriteModelPublicDeclaration(
const protobuf::Descriptor* descriptor, const protobuf::Descriptor* descriptor,
const std::vector<const protobuf::FieldDescriptor*>& file_exts, const std::vector<const protobuf::FieldDescriptor*>& file_exts,
const std::vector<const protobuf::EnumDescriptor*>& file_enums,
Output& output); Output& output);
void WriteExtensionIdentifiersInClassHeader( void WriteExtensionIdentifiersInClassHeader(
const protobuf::Descriptor* message, const protobuf::Descriptor* message,
@ -62,6 +67,10 @@ void WriteExtensionIdentifiersImplementation(
const protobuf::Descriptor* message, const protobuf::Descriptor* message,
const std::vector<const protobuf::FieldDescriptor*>& file_exts, const std::vector<const protobuf::FieldDescriptor*>& file_exts,
Output& output); Output& output);
void WriteUsingEnumsInHeader(
const protobuf::Descriptor* message,
const std::vector<const protobuf::EnumDescriptor*>& file_enums,
Output& output);
// Writes message class declarations into .upb.proto.h. // Writes message class declarations into .upb.proto.h.
// //
@ -70,6 +79,7 @@ void WriteExtensionIdentifiersImplementation(
void WriteMessageClassDeclarations( void WriteMessageClassDeclarations(
const protobuf::Descriptor* descriptor, const protobuf::Descriptor* descriptor,
const std::vector<const protobuf::FieldDescriptor*>& file_exts, const std::vector<const protobuf::FieldDescriptor*>& file_exts,
const std::vector<const protobuf::EnumDescriptor*>& file_enums,
Output& output) { Output& output) {
if (IsMapEntryMessage(descriptor)) { if (IsMapEntryMessage(descriptor)) {
// Skip map entry generation. Low level accessors for maps are // Skip map entry generation. Low level accessors for maps are
@ -85,7 +95,7 @@ void WriteMessageClassDeclarations(
WriteInternalForwardDeclarationsInHeader(descriptor, output); WriteInternalForwardDeclarationsInHeader(descriptor, output);
output("\n"); output("\n");
output("} // namespace internal\n"); output("} // namespace internal\n");
WriteModelPublicDeclaration(descriptor, file_exts, output); WriteModelPublicDeclaration(descriptor, file_exts, file_enums, output);
output("namespace internal {\n"); output("namespace internal {\n");
WriteModelProxyDeclaration(descriptor, output); WriteModelProxyDeclaration(descriptor, output);
WriteModelCProxyDeclaration(descriptor, output); WriteModelCProxyDeclaration(descriptor, output);
@ -131,6 +141,7 @@ void WriteModelAccessDeclaration(const protobuf::Descriptor* descriptor,
void WriteModelPublicDeclaration( void WriteModelPublicDeclaration(
const protobuf::Descriptor* descriptor, const protobuf::Descriptor* descriptor,
const std::vector<const protobuf::FieldDescriptor*>& file_exts, const std::vector<const protobuf::FieldDescriptor*>& file_exts,
const std::vector<const protobuf::EnumDescriptor*>& file_enums,
Output& output) { Output& output) {
output( output(
R"cc( R"cc(
@ -157,6 +168,7 @@ void WriteModelPublicDeclaration(
ClassName(descriptor)); ClassName(descriptor));
WriteUsingAccessorsInHeader(descriptor, MessageClassType::kMessage, output); WriteUsingAccessorsInHeader(descriptor, MessageClassType::kMessage, output);
WriteUsingEnumsInHeader(descriptor, file_enums, output);
WriteDefaultInstanceHeader(descriptor, output); WriteDefaultInstanceHeader(descriptor, output);
WriteExtensionIdentifiersInClassHeader(descriptor, file_exts, output); WriteExtensionIdentifiersInClassHeader(descriptor, file_exts, output);
output.Indent(); output.Indent();
@ -376,4 +388,42 @@ void WriteExtensionIdentifiersImplementation(
} }
} }
void WriteUsingEnumsInHeader(
const protobuf::Descriptor* message,
const std::vector<const protobuf::EnumDescriptor*>& file_enums,
Output& output) {
for (auto* enum_descriptor : file_enums) {
std::string enum_type_name = EnumTypeName(enum_descriptor);
std::string enum_resolved_type_name =
enum_descriptor->file()->package().empty() &&
enum_descriptor->containing_type() == nullptr
? absl::StrCat(kNoPackageNamePrefix,
ToCIdent(enum_descriptor->name()))
: enum_type_name;
if (enum_descriptor->containing_type() == nullptr ||
enum_descriptor->containing_type()->full_name() !=
message->full_name()) {
continue;
}
output("using $0", enum_descriptor->name());
if (enum_descriptor->options().deprecated()) {
output(" ABSL_DEPRECATED(\"Proto enum $0\")", enum_descriptor->name());
}
output(" = $0;", enum_resolved_type_name);
output("\n");
int value_count = enum_descriptor->value_count();
for (int i = 0; i < value_count; i++) {
output("static constexpr $0 $1", enum_descriptor->name(),
enum_descriptor->value(i)->name());
if (enum_descriptor->options().deprecated() ||
enum_descriptor->value(i)->options().deprecated()) {
output(" ABSL_DEPRECATED(\"Proto enum value $0\") ",
enum_descriptor->value(i)->name());
}
output(" = $0;\n", EnumValueSymbolInNameSpace(enum_descriptor,
enum_descriptor->value(i)));
}
}
}
} // namespace protos_generator } // namespace protos_generator

@ -37,6 +37,7 @@ namespace protobuf = ::google::protobuf;
void WriteMessageClassDeclarations( void WriteMessageClassDeclarations(
const protobuf::Descriptor* descriptor, const protobuf::Descriptor* descriptor,
const std::vector<const protobuf::FieldDescriptor*>& file_exts, const std::vector<const protobuf::FieldDescriptor*>& file_exts,
const std::vector<const protobuf::EnumDescriptor*>& file_enums,
Output& output); Output& output);
void WriteMessageImplementation( void WriteMessageImplementation(
const protobuf::Descriptor* descriptor, const protobuf::Descriptor* descriptor,

@ -171,7 +171,8 @@ void WriteHeader(const protobuf::FileDescriptor* file, Output& output) {
output("\n"); output("\n");
for (auto message : this_file_messages) { for (auto message : this_file_messages) {
WriteMessageClassDeclarations(message, this_file_exts, output); WriteMessageClassDeclarations(message, this_file_exts, this_file_enums,
output);
} }
output("\n"); output("\n");

@ -36,6 +36,7 @@ using ::protos_generator::test::protos::other_ext;
using ::protos_generator::test::protos::RED; using ::protos_generator::test::protos::RED;
using ::protos_generator::test::protos::TestEnum; using ::protos_generator::test::protos::TestEnum;
using ::protos_generator::test::protos::TestModel; using ::protos_generator::test::protos::TestModel;
using ::protos_generator::test::protos::TestModel_Category;
using ::protos_generator::test::protos::TestModel_Category_IMAGES; using ::protos_generator::test::protos::TestModel_Category_IMAGES;
using ::protos_generator::test::protos::TestModel_Category_NEWS; using ::protos_generator::test::protos::TestModel_Category_NEWS;
using ::protos_generator::test::protos::TestModel_Category_VIDEO; using ::protos_generator::test::protos::TestModel_Category_VIDEO;
@ -52,6 +53,16 @@ TEST(CppGeneratedCode, Enum) { EXPECT_EQ(1, RED); }
TEST(CppGeneratedCode, EnumNoPackage) { EXPECT_EQ(1, ::protos_CELSIUS); } TEST(CppGeneratedCode, EnumNoPackage) { EXPECT_EQ(1, ::protos_CELSIUS); }
TEST(CppGeneratedCode, MessageEnumType) {
TestModel_Category category1 = TestModel_Category_IMAGES;
TestModel::Category category2 = TestModel::IMAGES;
EXPECT_EQ(category1, category2);
}
TEST(CppGeneratedCode, MessageEnumValue) {
EXPECT_EQ(TestModel_Category_IMAGES, TestModel::IMAGES);
}
TEST(CppGeneratedCode, ArenaConstructor) { TEST(CppGeneratedCode, ArenaConstructor) {
::protos::Arena arena; ::protos::Arena arena;
auto testModel = ::protos::CreateMessage<TestModel>(arena); auto testModel = ::protos::CreateMessage<TestModel>(arena);

Loading…
Cancel
Save