|
|
|
@ -536,7 +536,7 @@ void WriteHeader(const protobuf::FileDescriptor* file, Output& output) { |
|
|
|
|
"#endif\n" |
|
|
|
|
"\n"); |
|
|
|
|
|
|
|
|
|
std::vector<const protobuf::Descriptor*> this_file_messages = |
|
|
|
|
const std::vector<const protobuf::Descriptor*> this_file_messages = |
|
|
|
|
SortedMessages(file); |
|
|
|
|
|
|
|
|
|
// Forward-declare types defined in this file.
|
|
|
|
@ -554,7 +554,7 @@ void WriteHeader(const protobuf::FileDescriptor* file, Output& output) { |
|
|
|
|
// Order by full name for consistent ordering.
|
|
|
|
|
std::map<std::string, const protobuf::Descriptor*> forward_messages; |
|
|
|
|
|
|
|
|
|
for (auto message : SortedMessages(file)) { |
|
|
|
|
for (auto message : this_file_messages) { |
|
|
|
|
for (int i = 0; i < message->field_count(); i++) { |
|
|
|
|
const protobuf::FieldDescriptor* field = message->field(i); |
|
|
|
|
if (field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE && |
|
|
|
@ -843,27 +843,54 @@ std::vector<TableEntry> FastDecodeTable(const protobuf::Descriptor* message, |
|
|
|
|
return table; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void WriteSource(const protobuf::FileDescriptor* file, Output& output, |
|
|
|
|
bool fasttable_enabled) { |
|
|
|
|
EmitFileWarning(file, output); |
|
|
|
|
void WriteField(const protobuf::FieldDescriptor* field, |
|
|
|
|
absl::string_view offset, absl::string_view presence, |
|
|
|
|
int submsg_index, Output& output) { |
|
|
|
|
|
|
|
|
|
output( |
|
|
|
|
"#include <stddef.h>\n" |
|
|
|
|
"#include \"upb/msg_internal.h\"\n" |
|
|
|
|
"#include \"$0\"\n", |
|
|
|
|
HeaderFilename(file->name())); |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < file->dependency_count(); i++) { |
|
|
|
|
output("#include \"$0\"\n", HeaderFilename(file->dependency(i)->name())); |
|
|
|
|
std::string label; |
|
|
|
|
if (field->is_map()) { |
|
|
|
|
label = "_UPB_LABEL_MAP"; |
|
|
|
|
} else if (field->is_packed()) { |
|
|
|
|
label = "_UPB_LABEL_PACKED"; |
|
|
|
|
} else { |
|
|
|
|
label = absl::StrCat(field->label()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
output( |
|
|
|
|
"\n" |
|
|
|
|
"#include \"upb/port_def.inc\"\n" |
|
|
|
|
"\n"); |
|
|
|
|
output("{$0, $1, $2, $3, $4, $5}", field->number(), offset, presence, |
|
|
|
|
submsg_index, TableDescriptorType(field), label); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Writes a single field into a .upb.c source file.
|
|
|
|
|
void WriteMessageField(const protobuf::FieldDescriptor* field, |
|
|
|
|
const MessageLayout& layout, int submsg_index, |
|
|
|
|
Output& output) { |
|
|
|
|
std::string presence = "0"; |
|
|
|
|
|
|
|
|
|
for (auto message : SortedMessages(file)) { |
|
|
|
|
if (MessageLayout::HasHasbit(field)) { |
|
|
|
|
int index = layout.GetHasbitIndex(field); |
|
|
|
|
assert(index != 0); |
|
|
|
|
presence = absl::StrCat(index); |
|
|
|
|
} else if (field->real_containing_oneof()) { |
|
|
|
|
MessageLayout::Size case_offset = |
|
|
|
|
layout.GetOneofCaseOffset(field->real_containing_oneof()); |
|
|
|
|
|
|
|
|
|
// We encode as negative to distinguish from hasbits.
|
|
|
|
|
case_offset.size32 = ~case_offset.size32; |
|
|
|
|
case_offset.size64 = ~case_offset.size64; |
|
|
|
|
assert(case_offset.size32 < 0); |
|
|
|
|
assert(case_offset.size64 < 0); |
|
|
|
|
presence = GetSizeInit(case_offset); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
output(" "); |
|
|
|
|
WriteField(field, GetSizeInit(layout.GetFieldOffset(field)), presence, |
|
|
|
|
submsg_index, output); |
|
|
|
|
output(",\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Writes a single message into a .upb.c source file.
|
|
|
|
|
void WriteMessage(const protobuf::Descriptor* message, Output& output, |
|
|
|
|
bool fasttable_enabled) { |
|
|
|
|
std::string msgname = ToCIdent(message->full_name()); |
|
|
|
|
std::string fields_array_ref = "NULL"; |
|
|
|
|
std::string submsgs_array_ref = "NULL"; |
|
|
|
@ -897,7 +924,6 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output, |
|
|
|
|
for (int i = 0; i < static_cast<int>(field_number_order.size()); i++) { |
|
|
|
|
auto field = field_number_order[i]; |
|
|
|
|
int submsg_index = 0; |
|
|
|
|
std::string presence = "0"; |
|
|
|
|
|
|
|
|
|
if (i < dense_below_max && field->number() == i + 1 && |
|
|
|
|
(i == 0 || field_number_order[i - 1]->number() == i)) { |
|
|
|
@ -908,38 +934,7 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output, |
|
|
|
|
submsg_index = submsg_array.GetIndex(field); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (MessageLayout::HasHasbit(field)) { |
|
|
|
|
int index = layout.GetHasbitIndex(field); |
|
|
|
|
assert(index != 0); |
|
|
|
|
presence = absl::StrCat(index); |
|
|
|
|
} else if (field->real_containing_oneof()) { |
|
|
|
|
MessageLayout::Size case_offset = |
|
|
|
|
layout.GetOneofCaseOffset(field->real_containing_oneof()); |
|
|
|
|
|
|
|
|
|
// We encode as negative to distinguish from hasbits.
|
|
|
|
|
case_offset.size32 = ~case_offset.size32; |
|
|
|
|
case_offset.size64 = ~case_offset.size64; |
|
|
|
|
assert(case_offset.size32 < 0); |
|
|
|
|
assert(case_offset.size64 < 0); |
|
|
|
|
presence = GetSizeInit(case_offset); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::string label; |
|
|
|
|
if (field->is_map()) { |
|
|
|
|
label = "_UPB_LABEL_MAP"; |
|
|
|
|
} else if (field->is_packed()) { |
|
|
|
|
label = "_UPB_LABEL_PACKED"; |
|
|
|
|
} else { |
|
|
|
|
label = absl::StrCat(field->label()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
output(" {$0, $1, $2, $3, $4, $5},\n", |
|
|
|
|
field->number(), |
|
|
|
|
GetSizeInit(layout.GetFieldOffset(field)), |
|
|
|
|
presence, |
|
|
|
|
submsg_index, |
|
|
|
|
TableDescriptorType(field), |
|
|
|
|
label); |
|
|
|
|
WriteMessageField(field, layout, submsg_index, output); |
|
|
|
|
} |
|
|
|
|
output("};\n\n"); |
|
|
|
|
} |
|
|
|
@ -974,8 +969,37 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output, |
|
|
|
|
output(" }),\n"); |
|
|
|
|
} |
|
|
|
|
output("};\n\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void WriteMessages(const protobuf::FileDescriptor* file, Output& output, |
|
|
|
|
bool fasttable_enabled) { |
|
|
|
|
for (auto message : SortedMessages(file)) { |
|
|
|
|
WriteMessage(message, output, fasttable_enabled); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Writes a .upb.c source file.
|
|
|
|
|
void WriteSource(const protobuf::FileDescriptor* file, Output& output, |
|
|
|
|
bool fasttable_enabled) { |
|
|
|
|
EmitFileWarning(file, output); |
|
|
|
|
|
|
|
|
|
output( |
|
|
|
|
"#include <stddef.h>\n" |
|
|
|
|
"#include \"upb/msg_internal.h\"\n" |
|
|
|
|
"#include \"$0\"\n", |
|
|
|
|
HeaderFilename(file->name())); |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < file->dependency_count(); i++) { |
|
|
|
|
output("#include \"$0\"\n", HeaderFilename(file->dependency(i)->name())); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
output( |
|
|
|
|
"\n" |
|
|
|
|
"#include \"upb/port_def.inc\"\n" |
|
|
|
|
"\n"); |
|
|
|
|
|
|
|
|
|
WriteMessages(file, output, fasttable_enabled); |
|
|
|
|
|
|
|
|
|
output("#include \"upb/port_undef.inc\"\n"); |
|
|
|
|
output("\n"); |
|
|
|
|
} |
|
|
|
|