(NFC) Refactored upbc header generation into smaller methods.

This is in anticipation of a larger upcoming refactor.
pull/13171/head
Joshua Haberman 3 years ago
parent 237e3bf51d
commit 7c541f0ba6
  1. 156
      upbc/protoc-gen-upb.cc

@ -418,14 +418,8 @@ void GenerateExtensionInHeader(const protobuf::FieldDescriptor* ext,
} }
} }
void GenerateMessageInHeader(const protobuf::Descriptor* message, void GenerateMessageFunctionsInHeader(const protobuf::Descriptor* message,
Output& output) { Output& output) {
MessageLayout layout(message);
output("/* $0 */\n\n", message->full_name());
std::string msg_name = ToCIdent(message->full_name());
if (!message->options().map_entry()) {
output( output(
R"cc( R"cc(
UPB_INLINE $0* $0_new(upb_Arena* arena) { UPB_INLINE $0* $0_new(upb_Arena* arena) {
@ -461,8 +455,9 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message,
MessageName(message), MessageInit(message)); MessageName(message), MessageInit(message));
} }
for (int i = 0; i < message->real_oneof_decl_count(); i++) { void GenerateOneofInHeader(const protobuf::OneofDescriptor* oneof,
const protobuf::OneofDescriptor* oneof = message->oneof_decl(i); const MessageLayout& layout,
absl::string_view msg_name, Output& output) {
std::string fullname = ToCIdent(oneof->full_name()); std::string fullname = ToCIdent(oneof->full_name());
output("typedef enum {\n"); output("typedef enum {\n");
for (int j = 0; j < oneof->field_count(); j++) { for (int j = 0; j < oneof->field_count(); j++) {
@ -481,10 +476,9 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message,
GetSizeInit(layout.GetOneofCaseOffset(oneof))); GetSizeInit(layout.GetOneofCaseOffset(oneof)));
} }
// Generate const methods. void GenerateHazzer(const protobuf::FieldDescriptor* field,
const MessageLayout& layout, absl::string_view msg_name,
for (auto field : FieldNumberOrder(message)) { Output& output) {
// Generate hazzer (if any).
if (layout.HasHasbit(field)) { if (layout.HasHasbit(field)) {
output( output(
"UPB_INLINE bool $0_has_$1(const $0 *msg) { " "UPB_INLINE bool $0_has_$1(const $0 *msg) { "
@ -495,8 +489,7 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message,
"UPB_INLINE bool $0_has_$1(const $0 *msg) { " "UPB_INLINE bool $0_has_$1(const $0 *msg) { "
"return _upb_getoneofcase(msg, $2) == $3; }\n", "return _upb_getoneofcase(msg, $2) == $3; }\n",
msg_name, field->name(), msg_name, field->name(),
GetSizeInit( GetSizeInit(layout.GetOneofCaseOffset(field->real_containing_oneof())),
layout.GetOneofCaseOffset(field->real_containing_oneof())),
field->number()); field->number());
} else if (field->message_type()) { } else if (field->message_type()) {
output( output(
@ -504,9 +497,11 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message,
"return _upb_has_submsg_nohasbit(msg, $2); }\n", "return _upb_has_submsg_nohasbit(msg, $2); }\n",
msg_name, field->name(), GetSizeInit(layout.GetFieldOffset(field))); msg_name, field->name(), GetSizeInit(layout.GetFieldOffset(field)));
} }
}
// Generate getter. void GenerateMapGetters(const protobuf::FieldDescriptor* field,
if (field->is_map()) { const MessageLayout& layout, absl::string_view msg_name,
Output& output) {
const protobuf::Descriptor* entry = field->message_type(); const protobuf::Descriptor* entry = field->message_type();
const protobuf::FieldDescriptor* key = entry->FindFieldByNumber(1); const protobuf::FieldDescriptor* key = entry->FindFieldByNumber(1);
const protobuf::FieldDescriptor* val = entry->FindFieldByNumber(2); const protobuf::FieldDescriptor* val = entry->FindFieldByNumber(2);
@ -530,7 +525,10 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message,
"return ($0)_upb_msg_map_next(msg, $3, iter); }\n", "return ($0)_upb_msg_map_next(msg, $3, iter); }\n",
CTypeConst(field), msg_name, field->name(), CTypeConst(field), msg_name, field->name(),
GetSizeInit(layout.GetFieldOffset(field))); GetSizeInit(layout.GetFieldOffset(field)));
} else if (message->options().map_entry()) { }
void GenerateMapEntryGetters(const protobuf::FieldDescriptor* field,
absl::string_view msg_name, Output& output) {
output( output(
"UPB_INLINE $0 $1_$2(const $1 *msg) {\n" "UPB_INLINE $0 $1_$2(const $1 *msg) {\n"
" $3 ret;\n" " $3 ret;\n"
@ -541,22 +539,33 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message,
field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_STRING field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_STRING
? "0" ? "0"
: "sizeof(ret)"); : "sizeof(ret)");
} else if (field->is_repeated()) { }
void GenerateRepeatedGetters(const protobuf::FieldDescriptor* field,
const MessageLayout& layout,
absl::string_view msg_name, Output& output) {
output( output(
"UPB_INLINE $0 const* $1_$2(const $1 *msg, size_t *len) { " "UPB_INLINE $0 const* $1_$2(const $1 *msg, size_t *len) { "
"return ($0 const*)_upb_array_accessor(msg, $3, len); }\n", "return ($0 const*)_upb_array_accessor(msg, $3, len); }\n",
CTypeConst(field), msg_name, field->name(), CTypeConst(field), msg_name, field->name(),
GetSizeInit(layout.GetFieldOffset(field))); GetSizeInit(layout.GetFieldOffset(field)));
} else if (field->real_containing_oneof()) { }
void GenerateOneofGetters(const protobuf::FieldDescriptor* field,
const MessageLayout& layout,
absl::string_view msg_name, Output& output) {
output( output(
"UPB_INLINE $0 $1_$2(const $1 *msg) { " "UPB_INLINE $0 $1_$2(const $1 *msg) { "
"return UPB_READ_ONEOF(msg, $0, $3, $4, $5, $6); }\n", "return UPB_READ_ONEOF(msg, $0, $3, $4, $5, $6); }\n",
CTypeConst(field), msg_name, field->name(), CTypeConst(field), msg_name, field->name(),
GetSizeInit(layout.GetFieldOffset(field)), GetSizeInit(layout.GetFieldOffset(field)),
GetSizeInit( GetSizeInit(layout.GetOneofCaseOffset(field->real_containing_oneof())),
layout.GetOneofCaseOffset(field->real_containing_oneof())),
field->number(), FieldDefault(field)); field->number(), FieldDefault(field));
} else { }
void GenerateScalarGetters(const protobuf::FieldDescriptor* field,
const MessageLayout& layout,
absl::string_view msg_name, Output& output) {
if (HasNonZeroDefault(field)) { if (HasNonZeroDefault(field)) {
output( output(
R"cc( R"cc(
@ -577,24 +586,37 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message,
GetSizeInit(layout.GetFieldOffset(field))); GetSizeInit(layout.GetFieldOffset(field)));
} }
} }
}
output("\n"); void GenerateGetters(const protobuf::FieldDescriptor* field,
const MessageLayout& layout, absl::string_view msg_name,
// Generate mutable methods. Output& output) {
for (auto field : FieldNumberOrder(message)) {
if (field->is_map()) { if (field->is_map()) {
// TODO(haberman): add map-based mutators. GenerateMapGetters(field, layout, msg_name, output);
} else if (field->containing_type()->options().map_entry()) {
GenerateMapEntryGetters(field, msg_name, output);
} else if (field->is_repeated()) {
GenerateRepeatedGetters(field, layout, msg_name, output);
} else if (field->real_containing_oneof()) {
GenerateOneofGetters(field, layout, msg_name, output);
} else {
GenerateScalarGetters(field, layout, msg_name, output);
}
}
void GenerateMapSetters(const protobuf::FieldDescriptor* field,
const MessageLayout& layout, absl::string_view msg_name,
Output& output) {
const protobuf::Descriptor* entry = field->message_type(); const protobuf::Descriptor* entry = field->message_type();
const protobuf::FieldDescriptor* key = entry->FindFieldByNumber(1); const protobuf::FieldDescriptor* key = entry->FindFieldByNumber(1);
const protobuf::FieldDescriptor* val = entry->FindFieldByNumber(2); const protobuf::FieldDescriptor* val = entry->FindFieldByNumber(2);
output( output(
"UPB_INLINE void $0_$1_clear($0 *msg) { _upb_msg_map_clear(msg, $2); " "UPB_INLINE void $0_$1_clear($0 *msg) { _upb_msg_map_clear(msg, "
"$2); "
"}\n", "}\n",
msg_name, field->name(), GetSizeInit(layout.GetFieldOffset(field))); msg_name, field->name(), GetSizeInit(layout.GetFieldOffset(field)));
output( output(
"UPB_INLINE bool $0_$1_set($0 *msg, $2 key, $3 val, upb_Arena *a) { " "UPB_INLINE bool $0_$1_set($0 *msg, $2 key, $3 val, upb_Arena *a) "
"{ "
"return _upb_msg_map_set(msg, $4, &key, $5, &val, $6, a); }\n", "return _upb_msg_map_set(msg, $4, &key, $5, &val, $6, a); }\n",
msg_name, field->name(), CType(key), CType(val), msg_name, field->name(), CType(key), CType(val),
GetSizeInit(layout.GetFieldOffset(field)), GetSizeInit(layout.GetFieldOffset(field)),
@ -617,7 +639,11 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message,
"return ($0)_upb_msg_map_next(msg, $3, iter); }\n", "return ($0)_upb_msg_map_next(msg, $3, iter); }\n",
CType(field), msg_name, field->name(), CType(field), msg_name, field->name(),
GetSizeInit(layout.GetFieldOffset(field))); GetSizeInit(layout.GetFieldOffset(field)));
} else if (field->is_repeated()) { }
void GenerateRepeatedSetters(const protobuf::FieldDescriptor* field,
const MessageLayout& layout,
absl::string_view msg_name, Output& output) {
output( output(
"UPB_INLINE $0* $1_mutable_$2($1 *msg, size_t *len) {\n" "UPB_INLINE $0* $1_mutable_$2($1 *msg, size_t *len) {\n"
" return ($0*)_upb_array_mutable_accessor(msg, $3, len);\n" " return ($0*)_upb_array_mutable_accessor(msg, $3, len);\n"
@ -653,19 +679,22 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message,
CType(field), msg_name, field->name(), CType(field), msg_name, field->name(),
GetSizeInit(layout.GetFieldOffset(field)), SizeLg2(field)); GetSizeInit(layout.GetFieldOffset(field)), SizeLg2(field));
} }
} else { }
// Non-repeated field.
if (message->options().map_entry() && field->name() == "key") { void GenerateNonRepeatedSetters(const protobuf::FieldDescriptor* field,
const MessageLayout& layout,
absl::string_view msg_name, Output& output) {
if (field == field->containing_type()->map_key()) {
// Key cannot be mutated. // Key cannot be mutated.
continue; return;
} }
// The common function signature for all setters. Varying implementations // The common function signature for all setters. Varying
// follow. // implementations follow.
output("UPB_INLINE void $0_set_$1($0 *msg, $2 value) {\n", msg_name, output("UPB_INLINE void $0_set_$1($0 *msg, $2 value) {\n", msg_name,
field->name(), CType(field)); field->name(), CType(field));
if (message->options().map_entry()) { if (field == field->containing_type()->map_value()) {
output( output(
" _upb_msg_map_set_value(msg, &value, $0);\n" " _upb_msg_map_set_value(msg, &value, $0);\n"
"}\n", "}\n",
@ -677,8 +706,7 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message,
" UPB_WRITE_ONEOF(msg, $0, $1, value, $2, $3);\n" " UPB_WRITE_ONEOF(msg, $0, $1, value, $2, $3);\n"
"}\n", "}\n",
CType(field), GetSizeInit(layout.GetFieldOffset(field)), CType(field), GetSizeInit(layout.GetFieldOffset(field)),
GetSizeInit( GetSizeInit(layout.GetOneofCaseOffset(field->real_containing_oneof())),
layout.GetOneofCaseOffset(field->real_containing_oneof())),
field->number()); field->number());
} else { } else {
if (MessageLayout::HasHasbit(field)) { if (MessageLayout::HasHasbit(field)) {
@ -690,10 +718,13 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message,
CType(field), GetSizeInit(layout.GetFieldOffset(field))); CType(field), GetSizeInit(layout.GetFieldOffset(field)));
} }
// Message fields also have a Msg_mutable_foo() accessor that will create
// the sub-message if it doesn't already exist.
if (field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE && if (field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE &&
!message->options().map_entry()) { !field->containing_type()->options().map_entry()) {
output( output(
"UPB_INLINE struct $0* $1_mutable_$2($1 *msg, upb_Arena *arena) {\n" "UPB_INLINE struct $0* $1_mutable_$2($1 *msg, upb_Arena *arena) "
"{\n"
" struct $0* sub = (struct $0*)$1_$2(msg);\n" " struct $0* sub = (struct $0*)$1_$2(msg);\n"
" if (sub == NULL) {\n" " if (sub == NULL) {\n"
" sub = (struct $0*)_upb_Message_New(&$3, arena);\n" " sub = (struct $0*)_upb_Message_New(&$3, arena);\n"
@ -706,6 +737,43 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message,
MessageInit(field->message_type())); MessageInit(field->message_type()));
} }
} }
void GenerateSetters(const protobuf::FieldDescriptor* field,
const MessageLayout& layout, absl::string_view msg_name,
Output& output) {
if (field->is_map()) {
GenerateMapSetters(field, layout, msg_name, output);
} else if (field->is_repeated()) {
GenerateRepeatedSetters(field, layout, msg_name, output);
} else {
GenerateNonRepeatedSetters(field, layout, msg_name, output);
}
}
void GenerateMessageInHeader(const protobuf::Descriptor* message,
Output& output) {
MessageLayout layout(message);
output("/* $0 */\n\n", message->full_name());
std::string msg_name = ToCIdent(message->full_name());
if (!message->options().map_entry()) {
GenerateMessageFunctionsInHeader(message, output);
}
for (int i = 0; i < message->real_oneof_decl_count(); i++) {
GenerateOneofInHeader(message->oneof_decl(i), layout, msg_name, output);
}
for (auto field : FieldNumberOrder(message)) {
GenerateHazzer(field, layout, msg_name, output);
GenerateGetters(field, layout, msg_name, output);
}
output("\n");
for (auto field : FieldNumberOrder(message)) {
GenerateSetters(field, layout, msg_name, output);
} }
output("\n"); output("\n");

Loading…
Cancel
Save