Fixed a bug in enum layout generation.

pull/13171/head
Joshua Haberman 3 years ago
parent 65a85a63c8
commit 85072ce04e
  1. 10
      upb/def.c
  2. 10
      upb/def.h
  3. 16
      upb/util/def_to_proto_test.cc
  4. 4
      upb/util/def_to_proto_test.proto
  5. 2
      upbc/protoc-gen-upb.cc

@ -2411,7 +2411,7 @@ upb_MiniTable_Enum* create_enumlayout(symtab_addctx* ctx,
for (int i = 0; i < e->value_count; i++) {
uint32_t val = (uint32_t)e->values[i].number;
if (val < 64) {
mask |= 1 << val;
mask |= 1ULL << val;
} else {
n++;
}
@ -3102,7 +3102,8 @@ const upb_FileDef* upb_DefPool_AddFile(
/* Include here since we want most of this file to be stdio-free. */
#include <stdio.h>
bool _upb_DefPool_LoadDefInit(upb_DefPool* s, const _upb_DefPool_Init* init) {
bool _upb_DefPool_LoadDefInitEx(upb_DefPool* s, const _upb_DefPool_Init* init,
bool rebuild_minitable) {
/* Since this function should never fail (it would indicate a bug in upb) we
* print errors to stderr instead of returning error status to the user. */
_upb_DefPool_Init** deps = init->deps;
@ -3119,7 +3120,7 @@ bool _upb_DefPool_LoadDefInit(upb_DefPool* s, const _upb_DefPool_Init* init) {
arena = upb_Arena_New();
for (; *deps; deps++) {
if (!_upb_DefPool_LoadDefInit(s, *deps)) goto err;
if (!_upb_DefPool_LoadDefInitEx(s, *deps, rebuild_minitable)) goto err;
}
file = google_protobuf_FileDescriptorProto_parse_ex(
@ -3136,7 +3137,8 @@ bool _upb_DefPool_LoadDefInit(upb_DefPool* s, const _upb_DefPool_Init* init) {
goto err;
}
if (!_upb_DefPool_AddFile(s, file, init->layout, &status)) {
const upb_MiniTable_File* mt = rebuild_minitable ? NULL : init->layout;
if (!_upb_DefPool_AddFile(s, file, mt, &status)) {
goto err;
}

@ -389,7 +389,15 @@ typedef struct _upb_DefPool_Init {
upb_StringView descriptor; /* Serialized descriptor. */
} _upb_DefPool_Init;
bool _upb_DefPool_LoadDefInit(upb_DefPool* s, const _upb_DefPool_Init* init);
// Should only be directly called by tests. This varant lets us suppress
// the use of compiled-in tables, forcing a rebuild of the tables at runtime.
bool _upb_DefPool_LoadDefInitEx(upb_DefPool* s, const _upb_DefPool_Init* init,
bool rebuild_minitable);
UPB_INLINE bool _upb_DefPool_LoadDefInit(upb_DefPool* s,
const _upb_DefPool_Init* init) {
return _upb_DefPool_LoadDefInitEx(s, init, false);
}
#include "upb/port_undef.inc"

@ -125,3 +125,19 @@ TEST(DefToProto, Test) {
upb::FileDefPtr file = msgdef.file();
CheckFile(file, file_desc);
}
// Like the previous test, but uses a message layout built at runtime.
TEST(DefToProto, TestRuntimeReflection) {
upb::Arena arena;
upb::SymbolTable symtab;
upb_StringView test_file_desc =
upb_util_def_to_proto_test_proto_upbdefinit.descriptor;
const auto* file_desc = google_protobuf_FileDescriptorProto_parse(
test_file_desc.data, test_file_desc.size, arena.ptr());
_upb_DefPool_LoadDefInitEx(
symtab.ptr(), &upb_util_def_to_proto_test_proto_upbdefinit, true);
upb::FileDefPtr file = symtab.FindFileByName(
upb_util_def_to_proto_test_proto_upbdefinit.filename);
CheckFile(file, file_desc);
}

@ -97,6 +97,10 @@ extend Message {
optional int32 ext = 1001;
}
enum Has31 {
VALUE_31 = 31;
}
message PretendMessageSet {
option message_set_wire_format = true;
// Since this is message_set_wire_format, "max" here means INT32_MAX.

@ -1314,7 +1314,7 @@ int WriteEnums(const protobuf::FileDescriptor* file, Output& output) {
absl::flat_hash_set<int32_t> values;
for (auto number : SortedUniqueEnumNumbers(e)) {
if (static_cast<uint32_t>(number) < 64) {
mask |= 1 << number;
mask |= 1ULL << number;
} else {
values.insert(number);
}

Loading…
Cancel
Save