Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
541 lines
19 KiB
541 lines
19 KiB
1 year ago
|
// Protocol Buffers - Google's data interchange format
|
||
|
// Copyright 2023 Google LLC. All rights reserved.
|
||
|
//
|
||
1 year ago
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file or at
|
||
|
// https://developers.google.com/open-source/licenses/bsd
|
||
2 years ago
|
|
||
6 months ago
|
#include "hpb_generator/gen_messages.h"
|
||
2 years ago
|
|
||
7 months ago
|
#include <cstddef>
|
||
2 years ago
|
#include <string>
|
||
|
#include <vector>
|
||
|
|
||
2 years ago
|
#include "google/protobuf/descriptor.pb.h"
|
||
7 months ago
|
#include "absl/strings/ascii.h"
|
||
1 year ago
|
#include "absl/strings/str_cat.h"
|
||
7 months ago
|
#include "absl/strings/string_view.h"
|
||
2 years ago
|
#include "google/protobuf/descriptor.h"
|
||
6 months ago
|
#include "hpb_generator/gen_accessors.h"
|
||
|
#include "hpb_generator/gen_enums.h"
|
||
|
#include "hpb_generator/gen_extensions.h"
|
||
|
#include "hpb_generator/gen_utils.h"
|
||
|
#include "hpb_generator/names.h"
|
||
|
#include "hpb_generator/output.h"
|
||
1 year ago
|
#include "upb_generator/common.h"
|
||
|
#include "upb_generator/file_layout.h"
|
||
2 years ago
|
|
||
|
namespace protos_generator {
|
||
|
|
||
|
namespace protobuf = ::google::protobuf;
|
||
|
|
||
|
void WriteModelAccessDeclaration(const protobuf::Descriptor* descriptor,
|
||
|
Output& output);
|
||
|
void WriteModelPublicDeclaration(
|
||
|
const protobuf::Descriptor* descriptor,
|
||
|
const std::vector<const protobuf::FieldDescriptor*>& file_exts,
|
||
2 years ago
|
const std::vector<const protobuf::EnumDescriptor*>& file_enums,
|
||
2 years ago
|
Output& output);
|
||
|
void WriteExtensionIdentifiersInClassHeader(
|
||
|
const protobuf::Descriptor* message,
|
||
|
const std::vector<const protobuf::FieldDescriptor*>& file_exts,
|
||
|
Output& output);
|
||
|
void WriteModelProxyDeclaration(const protobuf::Descriptor* descriptor,
|
||
|
Output& output);
|
||
|
void WriteModelCProxyDeclaration(const protobuf::Descriptor* descriptor,
|
||
|
Output& output);
|
||
|
void WriteInternalForwardDeclarationsInHeader(
|
||
|
const protobuf::Descriptor* message, Output& output);
|
||
|
void WriteDefaultInstanceHeader(const protobuf::Descriptor* message,
|
||
|
Output& output);
|
||
|
void WriteExtensionIdentifiersImplementation(
|
||
|
const protobuf::Descriptor* message,
|
||
|
const std::vector<const protobuf::FieldDescriptor*>& file_exts,
|
||
|
Output& output);
|
||
2 years ago
|
void WriteUsingEnumsInHeader(
|
||
|
const protobuf::Descriptor* message,
|
||
|
const std::vector<const protobuf::EnumDescriptor*>& file_enums,
|
||
|
Output& output);
|
||
2 years ago
|
|
||
|
// Writes message class declarations into .upb.proto.h.
|
||
|
//
|
||
|
// For each proto Foo, FooAccess and FooProxy/FooCProxy are generated
|
||
|
// that are exposed to users as Foo , Ptr<Foo> and Ptr<const Foo>.
|
||
|
void WriteMessageClassDeclarations(
|
||
|
const protobuf::Descriptor* descriptor,
|
||
|
const std::vector<const protobuf::FieldDescriptor*>& file_exts,
|
||
2 years ago
|
const std::vector<const protobuf::EnumDescriptor*>& file_enums,
|
||
2 years ago
|
Output& output) {
|
||
|
if (IsMapEntryMessage(descriptor)) {
|
||
|
// Skip map entry generation. Low level accessors for maps are
|
||
|
// generated that don't require a separate map type.
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Forward declaration of Proto Class for GCC handling of free friend method.
|
||
2 years ago
|
output("class $0;\n", ClassName(descriptor));
|
||
|
output("namespace internal {\n\n");
|
||
2 years ago
|
WriteModelAccessDeclaration(descriptor, output);
|
||
|
output("\n");
|
||
|
WriteInternalForwardDeclarationsInHeader(descriptor, output);
|
||
|
output("\n");
|
||
2 years ago
|
output("} // namespace internal\n\n");
|
||
2 years ago
|
WriteModelPublicDeclaration(descriptor, file_exts, file_enums, output);
|
||
2 years ago
|
output("namespace internal {\n");
|
||
|
WriteModelCProxyDeclaration(descriptor, output);
|
||
2 years ago
|
WriteModelProxyDeclaration(descriptor, output);
|
||
2 years ago
|
output("} // namespace internal\n\n");
|
||
2 years ago
|
}
|
||
|
|
||
|
void WriteModelAccessDeclaration(const protobuf::Descriptor* descriptor,
|
||
|
Output& output) {
|
||
|
output(
|
||
|
R"cc(
|
||
|
class $0Access {
|
||
|
public:
|
||
|
$0Access() {}
|
||
1 year ago
|
$0Access($1* msg, upb_Arena* arena) : msg_(msg), arena_(arena) {
|
||
|
assert(arena != nullptr);
|
||
|
} // NOLINT
|
||
2 years ago
|
$0Access(const $1* msg, upb_Arena* arena)
|
||
1 year ago
|
: msg_(const_cast<$1*>(msg)), arena_(arena) {
|
||
|
assert(arena != nullptr);
|
||
|
} // NOLINT
|
||
2 years ago
|
void* GetInternalArena() const { return arena_; }
|
||
|
)cc",
|
||
|
ClassName(descriptor), MessageName(descriptor));
|
||
|
WriteFieldAccessorsInHeader(descriptor, output);
|
||
2 years ago
|
WriteOneofAccessorsInHeader(descriptor, output);
|
||
2 years ago
|
output.Indent();
|
||
|
output(
|
||
|
R"cc(
|
||
|
private:
|
||
|
friend class $2;
|
||
|
friend class $0Proxy;
|
||
|
friend class $0CProxy;
|
||
1 year ago
|
friend struct ::protos::internal::PrivateAccess;
|
||
2 years ago
|
$1* msg_;
|
||
|
upb_Arena* arena_;
|
||
|
)cc",
|
||
|
ClassName(descriptor), MessageName(descriptor),
|
||
|
QualifiedClassName(descriptor));
|
||
|
output.Outdent();
|
||
|
output("};\n");
|
||
|
}
|
||
|
|
||
7 months ago
|
std::string UnderscoresToCamelCase(absl::string_view input,
|
||
|
bool cap_next_letter) {
|
||
|
std::string result;
|
||
|
|
||
|
for (size_t i = 0; i < input.size(); i++) {
|
||
|
if (absl::ascii_islower(input[i])) {
|
||
|
if (cap_next_letter) {
|
||
|
result += absl::ascii_toupper(input[i]);
|
||
|
} else {
|
||
|
result += input[i];
|
||
|
}
|
||
|
cap_next_letter = false;
|
||
|
} else if (absl::ascii_isupper(input[i])) {
|
||
|
// Capital letters are left as-is.
|
||
|
result += input[i];
|
||
|
cap_next_letter = false;
|
||
|
} else if (absl::ascii_isdigit(input[i])) {
|
||
|
result += input[i];
|
||
|
cap_next_letter = true;
|
||
|
} else {
|
||
|
cap_next_letter = true;
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
std::string FieldConstantName(const protobuf::FieldDescriptor* field) {
|
||
|
std::string field_name = UnderscoresToCamelCase(field->name(), true);
|
||
|
std::string result = absl::StrCat("k", field_name, "FieldNumber");
|
||
|
|
||
|
if (!field->is_extension() &&
|
||
|
field->containing_type()->FindFieldByCamelcaseName(
|
||
|
field->camelcase_name()) != field) {
|
||
|
// This field's camelcase name is not unique, add field number to make it
|
||
|
// unique.
|
||
|
absl::StrAppend(&result, "_", field->number());
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
void WriteConstFieldNumbers(Output& output,
|
||
|
const protobuf::Descriptor* descriptor) {
|
||
|
for (auto field : FieldRange(descriptor)) {
|
||
|
output("static constexpr ::uint32_t $0 = $1;\n", FieldConstantName(field),
|
||
|
field->number());
|
||
|
}
|
||
|
output("\n\n");
|
||
|
}
|
||
|
|
||
2 years ago
|
void WriteModelPublicDeclaration(
|
||
|
const protobuf::Descriptor* descriptor,
|
||
|
const std::vector<const protobuf::FieldDescriptor*>& file_exts,
|
||
2 years ago
|
const std::vector<const protobuf::EnumDescriptor*>& file_enums,
|
||
2 years ago
|
Output& output) {
|
||
|
output(
|
||
|
R"cc(
|
||
|
class $0 final : private internal::$0Access {
|
||
|
public:
|
||
|
using Access = internal::$0Access;
|
||
|
using Proxy = internal::$0Proxy;
|
||
|
using CProxy = internal::$0CProxy;
|
||
2 years ago
|
|
||
2 years ago
|
$0();
|
||
2 years ago
|
|
||
|
$0(const $0& from);
|
||
1 year ago
|
$0& operator=(const $3& from);
|
||
2 years ago
|
$0(const CProxy& from);
|
||
|
$0(const Proxy& from);
|
||
1 year ago
|
$0& operator=(const CProxy& from);
|
||
|
|
||
2 years ago
|
$0($0&& m)
|
||
9 months ago
|
: Access(std::exchange(m.msg_, nullptr),
|
||
|
std::exchange(m.arena_, nullptr)),
|
||
2 years ago
|
owned_arena_(std::move(m.owned_arena_)) {}
|
||
2 years ago
|
|
||
2 years ago
|
$0& operator=($0&& m) {
|
||
9 months ago
|
msg_ = std::exchange(m.msg_, nullptr);
|
||
|
arena_ = std::exchange(m.arena_, nullptr);
|
||
2 years ago
|
owned_arena_ = std::move(m.owned_arena_);
|
||
|
return *this;
|
||
|
}
|
||
|
)cc",
|
||
1 year ago
|
ClassName(descriptor),
|
||
|
::upb::generator::MessageInit(descriptor->full_name()),
|
||
2 years ago
|
MessageName(descriptor), QualifiedClassName(descriptor));
|
||
2 years ago
|
|
||
|
WriteUsingAccessorsInHeader(descriptor, MessageClassType::kMessage, output);
|
||
2 years ago
|
WriteUsingEnumsInHeader(descriptor, file_enums, output);
|
||
2 years ago
|
WriteDefaultInstanceHeader(descriptor, output);
|
||
|
WriteExtensionIdentifiersInClassHeader(descriptor, file_exts, output);
|
||
|
if (descriptor->extension_range_count()) {
|
||
|
// for typetrait checking
|
||
|
output("using ExtendableType = $0;\n", ClassName(descriptor));
|
||
|
}
|
||
|
// Note: free function friends that are templates such as ::protos::Parse
|
||
|
// require explicit <$2> type parameter in declaration to be able to compile
|
||
|
// with gcc otherwise the compiler will fail with
|
||
|
// "has not been declared within namespace" error. Even though there is a
|
||
|
// namespace qualifier, cross namespace matching fails.
|
||
2 years ago
|
output.Indent();
|
||
2 years ago
|
output(
|
||
|
R"cc(
|
||
|
static const upb_MiniTable* minitable();
|
||
|
using $0Access::GetInternalArena;
|
||
2 years ago
|
)cc",
|
||
|
ClassName(descriptor));
|
||
|
output("\n");
|
||
7 months ago
|
WriteConstFieldNumbers(output, descriptor);
|
||
2 years ago
|
output(
|
||
|
R"cc(
|
||
2 years ago
|
private:
|
||
11 months ago
|
const upb_Message* msg() const { return UPB_UPCAST(msg_); }
|
||
|
upb_Message* msg() { return UPB_UPCAST(msg_); }
|
||
1 year ago
|
|
||
2 years ago
|
$0(upb_Message* msg, upb_Arena* arena) : $0Access() {
|
||
|
msg_ = ($1*)msg;
|
||
|
arena_ = owned_arena_.ptr();
|
||
|
upb_Arena_Fuse(arena_, arena);
|
||
|
}
|
||
|
::protos::Arena owned_arena_;
|
||
1 year ago
|
friend struct ::protos::internal::PrivateAccess;
|
||
2 years ago
|
friend Proxy;
|
||
|
friend CProxy;
|
||
|
friend absl::StatusOr<$2>(::protos::Parse<$2>(absl::string_view bytes,
|
||
|
int options));
|
||
|
friend absl::StatusOr<$2>(::protos::Parse<$2>(
|
||
|
absl::string_view bytes,
|
||
|
const ::protos::ExtensionRegistry& extension_registry,
|
||
|
int options));
|
||
1 year ago
|
friend upb_Arena* ::protos::internal::GetArena<$0>($0* message);
|
||
1 year ago
|
friend upb_Arena* ::protos::internal::GetArena<$0>(::protos::Ptr<$0> message);
|
||
2 years ago
|
friend $0(::protos::internal::MoveMessage<$0>(upb_Message* msg,
|
||
|
upb_Arena* arena));
|
||
|
)cc",
|
||
|
ClassName(descriptor), MessageName(descriptor),
|
||
|
QualifiedClassName(descriptor));
|
||
|
output.Outdent();
|
||
|
output("};\n\n");
|
||
|
}
|
||
|
|
||
|
void WriteModelProxyDeclaration(const protobuf::Descriptor* descriptor,
|
||
|
Output& output) {
|
||
|
// Foo::Proxy.
|
||
|
output(
|
||
|
R"cc(
|
||
|
class $0Proxy final : private internal::$0Access {
|
||
|
public:
|
||
|
$0Proxy() = delete;
|
||
|
$0Proxy(const $0Proxy& m) : internal::$0Access() {
|
||
|
msg_ = m.msg_;
|
||
|
arena_ = m.arena_;
|
||
|
}
|
||
1 year ago
|
$0Proxy($0* m) : internal::$0Access() {
|
||
|
msg_ = m->msg_;
|
||
|
arena_ = m->arena_;
|
||
|
}
|
||
2 years ago
|
$0Proxy operator=(const $0Proxy& m) {
|
||
|
msg_ = m.msg_;
|
||
|
arena_ = m.arena_;
|
||
|
return *this;
|
||
|
}
|
||
|
using $0Access::GetInternalArena;
|
||
|
)cc",
|
||
|
ClassName(descriptor));
|
||
|
|
||
|
WriteUsingAccessorsInHeader(descriptor, MessageClassType::kMessageProxy,
|
||
|
output);
|
||
|
output("\n");
|
||
|
output.Indent(1);
|
||
|
output(
|
||
|
R"cc(
|
||
|
private:
|
||
11 months ago
|
upb_Message* msg() const { return UPB_UPCAST(msg_); }
|
||
1 year ago
|
|
||
11 months ago
|
$0Proxy(upb_Message* msg, upb_Arena* arena)
|
||
|
: internal::$0Access(($1*)msg, arena) {}
|
||
2 years ago
|
friend $0::Proxy(::protos::CreateMessage<$0>(::protos::Arena& arena));
|
||
|
friend $0::Proxy(::protos::internal::CreateMessageProxy<$0>(
|
||
|
upb_Message*, upb_Arena*));
|
||
1 year ago
|
friend struct ::protos::internal::PrivateAccess;
|
||
2 years ago
|
friend class RepeatedFieldProxy;
|
||
2 years ago
|
friend class $0CProxy;
|
||
|
friend class $0Access;
|
||
|
friend class ::protos::Ptr<$0>;
|
||
|
friend class ::protos::Ptr<const $0>;
|
||
1 year ago
|
static const upb_MiniTable* minitable() { return $0::minitable(); }
|
||
|
friend const upb_MiniTable* ::protos::internal::GetMiniTable<$0Proxy>(
|
||
|
const $0Proxy* message);
|
||
|
friend const upb_MiniTable* ::protos::internal::GetMiniTable<$0Proxy>(
|
||
|
::protos::Ptr<$0Proxy> message);
|
||
1 year ago
|
friend upb_Arena* ::protos::internal::GetArena<$2>($2* message);
|
||
1 year ago
|
friend upb_Arena* ::protos::internal::GetArena<$2>(::protos::Ptr<$2> message);
|
||
2 years ago
|
static void Rebind($0Proxy& lhs, const $0Proxy& rhs) {
|
||
|
lhs.msg_ = rhs.msg_;
|
||
|
lhs.arena_ = rhs.arena_;
|
||
|
}
|
||
|
)cc",
|
||
|
ClassName(descriptor), MessageName(descriptor),
|
||
|
QualifiedClassName(descriptor));
|
||
|
output.Outdent(1);
|
||
|
output("};\n\n");
|
||
|
}
|
||
|
|
||
|
void WriteModelCProxyDeclaration(const protobuf::Descriptor* descriptor,
|
||
|
Output& output) {
|
||
|
// Foo::CProxy.
|
||
|
output(
|
||
|
R"cc(
|
||
|
class $0CProxy final : private internal::$0Access {
|
||
|
public:
|
||
|
$0CProxy() = delete;
|
||
1 year ago
|
$0CProxy(const $0* m)
|
||
|
: internal::$0Access(m->msg_, ::protos::internal::GetArena(m)) {}
|
||
2 years ago
|
$0CProxy($0Proxy m);
|
||
2 years ago
|
using $0Access::GetInternalArena;
|
||
|
)cc",
|
||
|
ClassName(descriptor), MessageName(descriptor));
|
||
|
|
||
1 year ago
|
WriteUsingAccessorsInHeader(descriptor, MessageClassType::kMessageCProxy,
|
||
2 years ago
|
output);
|
||
|
|
||
|
output.Indent(1);
|
||
|
output(
|
||
|
R"cc(
|
||
|
private:
|
||
1 year ago
|
using AsNonConst = $0Proxy;
|
||
11 months ago
|
const upb_Message* msg() const { return UPB_UPCAST(msg_); }
|
||
1 year ago
|
|
||
11 months ago
|
$0CProxy(const upb_Message* msg, upb_Arena* arena)
|
||
1 year ago
|
: internal::$0Access(($1*)msg, arena){};
|
||
1 year ago
|
friend struct ::protos::internal::PrivateAccess;
|
||
2 years ago
|
friend class RepeatedFieldProxy;
|
||
2 years ago
|
friend class ::protos::Ptr<$0>;
|
||
|
friend class ::protos::Ptr<const $0>;
|
||
1 year ago
|
static const upb_MiniTable* minitable() { return $0::minitable(); }
|
||
|
friend const upb_MiniTable* ::protos::internal::GetMiniTable<$0CProxy>(
|
||
|
const $0CProxy* message);
|
||
|
friend const upb_MiniTable* ::protos::internal::GetMiniTable<$0CProxy>(
|
||
|
::protos::Ptr<$0CProxy> message);
|
||
|
|
||
2 years ago
|
static void Rebind($0CProxy& lhs, const $0CProxy& rhs) {
|
||
|
lhs.msg_ = rhs.msg_;
|
||
|
lhs.arena_ = rhs.arena_;
|
||
|
}
|
||
|
)cc",
|
||
|
ClassName(descriptor), MessageName(descriptor));
|
||
|
output.Outdent(1);
|
||
|
output("};\n\n");
|
||
|
}
|
||
|
|
||
|
void WriteDefaultInstanceHeader(const protobuf::Descriptor* message,
|
||
|
Output& output) {
|
||
|
output(" static ::protos::Ptr<const $0> default_instance();\n",
|
||
|
ClassName(message));
|
||
|
}
|
||
|
|
||
|
void WriteMessageImplementation(
|
||
|
const protobuf::Descriptor* descriptor,
|
||
|
const std::vector<const protobuf::FieldDescriptor*>& file_exts,
|
||
|
Output& output) {
|
||
|
bool message_is_map_entry = descriptor->options().map_entry();
|
||
|
if (!message_is_map_entry) {
|
||
|
// Constructor.
|
||
|
output(
|
||
|
R"cc(
|
||
|
$0::$0() : $0Access() {
|
||
|
arena_ = owned_arena_.ptr();
|
||
|
msg_ = $1_new(arena_);
|
||
|
}
|
||
2 years ago
|
$0::$0(const $0& from) : $0Access() {
|
||
|
arena_ = owned_arena_.ptr();
|
||
11 months ago
|
msg_ = ($1*)::protos::internal::DeepClone(UPB_UPCAST(from.msg_), &$2, arena_);
|
||
2 years ago
|
}
|
||
|
$0::$0(const CProxy& from) : $0Access() {
|
||
|
arena_ = owned_arena_.ptr();
|
||
1 year ago
|
msg_ = ($1*)::protos::internal::DeepClone(
|
||
1 year ago
|
::protos::internal::GetInternalMsg(&from), &$2, arena_);
|
||
2 years ago
|
}
|
||
|
$0::$0(const Proxy& from) : $0(static_cast<const CProxy&>(from)) {}
|
||
|
internal::$0CProxy::$0CProxy($0Proxy m) : $0Access() {
|
||
|
arena_ = m.arena_;
|
||
1 year ago
|
msg_ = ($1*)::protos::internal::GetInternalMsg(&m);
|
||
2 years ago
|
}
|
||
1 year ago
|
$0& $0::operator=(const $3& from) {
|
||
|
arena_ = owned_arena_.ptr();
|
||
11 months ago
|
msg_ = ($1*)::protos::internal::DeepClone(UPB_UPCAST(from.msg_), &$2, arena_);
|
||
1 year ago
|
return *this;
|
||
|
}
|
||
|
$0& $0::operator=(const CProxy& from) {
|
||
|
arena_ = owned_arena_.ptr();
|
||
1 year ago
|
msg_ = ($1*)::protos::internal::DeepClone(
|
||
1 year ago
|
::protos::internal::GetInternalMsg(&from), &$2, arena_);
|
||
|
return *this;
|
||
|
}
|
||
2 years ago
|
)cc",
|
||
2 years ago
|
ClassName(descriptor), MessageName(descriptor),
|
||
1 year ago
|
::upb::generator::MessageInit(descriptor->full_name()),
|
||
2 years ago
|
QualifiedClassName(descriptor));
|
||
|
output("\n");
|
||
2 years ago
|
// Minitable
|
||
|
output(
|
||
|
R"cc(
|
||
|
const upb_MiniTable* $0::minitable() { return &$1; }
|
||
|
)cc",
|
||
1 year ago
|
ClassName(descriptor),
|
||
|
::upb::generator::MessageInit(descriptor->full_name()));
|
||
2 years ago
|
output("\n");
|
||
2 years ago
|
}
|
||
|
|
||
2 years ago
|
WriteAccessorsInSource(descriptor, output);
|
||
2 years ago
|
|
||
|
if (!message_is_map_entry) {
|
||
|
output(
|
||
|
R"cc(
|
||
|
struct $0DefaultTypeInternal {
|
||
|
$1* msg;
|
||
1 year ago
|
upb_Arena* arena;
|
||
2 years ago
|
};
|
||
1 year ago
|
static $0DefaultTypeInternal _$0DefaultTypeBuilder() {
|
||
|
upb_Arena* arena = upb_Arena_New();
|
||
|
return $0DefaultTypeInternal{$1_new(arena), arena};
|
||
|
}
|
||
|
$0DefaultTypeInternal _$0_default_instance_ = _$0DefaultTypeBuilder();
|
||
2 years ago
|
)cc",
|
||
|
ClassName(descriptor), MessageName(descriptor));
|
||
|
|
||
|
output(
|
||
|
R"cc(
|
||
|
::protos::Ptr<const $0> $0::default_instance() {
|
||
|
return ::protos::internal::CreateMessage<$0>(
|
||
1 year ago
|
(upb_Message *)_$0_default_instance_.msg,
|
||
|
_$0_default_instance_.arena);
|
||
2 years ago
|
}
|
||
|
)cc",
|
||
|
ClassName(descriptor));
|
||
2 years ago
|
|
||
|
WriteExtensionIdentifiersImplementation(descriptor, file_exts, output);
|
||
2 years ago
|
}
|
||
|
}
|
||
|
|
||
|
void WriteInternalForwardDeclarationsInHeader(
|
||
|
const protobuf::Descriptor* message, Output& output) {
|
||
|
// Write declaration for internal re-usable default_instance without
|
||
|
// leaking implementation.
|
||
|
output(
|
||
|
R"cc(
|
||
|
struct $0DefaultTypeInternal;
|
||
|
extern $0DefaultTypeInternal _$0_default_instance_;
|
||
|
)cc",
|
||
|
ClassName(message));
|
||
|
}
|
||
|
|
||
|
void WriteExtensionIdentifiersInClassHeader(
|
||
|
const protobuf::Descriptor* message,
|
||
|
const std::vector<const protobuf::FieldDescriptor*>& file_exts,
|
||
|
Output& output) {
|
||
|
for (auto* ext : file_exts) {
|
||
|
if (ext->extension_scope() &&
|
||
|
ext->extension_scope()->full_name() == message->full_name()) {
|
||
|
WriteExtensionIdentifierHeader(ext, output);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void WriteExtensionIdentifiersImplementation(
|
||
|
const protobuf::Descriptor* message,
|
||
|
const std::vector<const protobuf::FieldDescriptor*>& file_exts,
|
||
|
Output& output) {
|
||
|
for (auto* ext : file_exts) {
|
||
|
if (ext->extension_scope() &&
|
||
|
ext->extension_scope()->full_name() == message->full_name()) {
|
||
|
WriteExtensionIdentifier(ext, output);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
2 years ago
|
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)));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
2 years ago
|
} // namespace protos_generator
|