Added an accessor to get the symtab from a filedef.

This matches an API already present in proto2
(const DescriptorPool* FileDescriptor::pool()).
However there is a slightly subtle implication here.

In proto2, the relationship between Descriptor and
MessageFactory is 1:many. You can create as many
DynamicMessageFactory instances as you want, and
each one will have its own independent DynamicMessage
prototype and computed layout for the same underlying
Descriptor. In practice the layouts will all be the same,
but one thing that could be distinct is that each can
have its own extension pool, which is a DescriptorPool
that will be searched for extensions when parsing.

In contrast, upb does not have a separate "message
factory" abstraction. That means that each upb_msgdef
has a single distinct layout, in other words a 1:1
correspondence between descriptor and layout. This means
that there is no way to create multiple message types
for the same descriptor that have distinct extension
pools. If you want a different set of extensions, you
must create a separate upb_symtab with a distinct set
of descriptors.

This change further entrenches that upb_filedef:upb_symtab
is a 1:1 relationship. A single upb_filedef cannot be a
member of multiple symbol tables. In practice this was
already true (there is no way to add a single filedef to
multiple symbol tables) but this change codifies this
1:1 relationship.
pull/13171/head
Joshua Haberman 4 years ago
parent a81b47025a
commit ee49a8d7df
  1. 14
      tests/bindings/lua/test_upb.lua
  2. 12
      upb/bindings/lua/def.c
  3. 8
      upb/def.c
  4. 1
      upb/def.h

@ -651,6 +651,20 @@ function test_foo()
assert_equal(set.file[1].name, "google/protobuf/descriptor.proto")
end
function test_descriptor()
local symtab = upb.SymbolTable()
local file_proto = descriptor.FileDescriptorProto {
name = "test.proto",
message_type = upb.Array(descriptor.DescriptorProto, {
descriptor.DescriptorProto{
name = "ABC",
},
})
}
local file = symtab:add_file(upb.encode(file_proto))
assert_equal(file:symtab(), symtab)
end
function test_descriptor_error()
local symtab = upb.SymbolTable()
local file = descriptor.FileDescriptorProto()

@ -668,6 +668,13 @@ static int lupb_filedef_package(lua_State *L) {
return 1;
}
static int lupb_filedef_symtab(lua_State *L) {
const upb_filedef *f = lupb_filedef_check(L, 1);
const upb_symtab *symtab = upb_filedef_symtab(f);
lupb_wrapper_pushwrapper(L, 1, symtab, LUPB_SYMTAB);
return 1;
}
static int lupb_filedef_syntax(lua_State *L) {
const upb_filedef *f = lupb_filedef_check(L, 1);
lua_pushnumber(L, upb_filedef_syntax(f));
@ -683,6 +690,7 @@ static const struct luaL_Reg lupb_filedef_m[] = {
{"msgcount", lupb_filedef_msgcount},
{"name", lupb_filedef_name},
{"package", lupb_filedef_package},
{"symtab", lupb_filedef_symtab},
{"syntax", lupb_filedef_syntax},
{NULL, NULL}
};
@ -761,6 +769,10 @@ static int lupb_symtab_new(lua_State *L) {
lua_setfield(L, -2, "__mode");
lua_setmetatable(L, -2);
/* Put the symtab itself in the cache metatable. */
lua_pushvalue(L, -2);
lua_rawsetp(L, -2, lsymtab->symtab);
/* Set the cache as our userval. */
lua_setiuservalue(L, -2, LUPB_CACHE_INDEX);

@ -93,17 +93,18 @@ struct upb_filedef {
const char *package;
const char *phpprefix;
const char *phpnamespace;
upb_syntax_t syntax;
const upb_filedef **deps;
const upb_msgdef *msgs;
const upb_enumdef *enums;
const upb_fielddef *exts;
const upb_symtab *symtab;
int dep_count;
int msg_count;
int enum_count;
int ext_count;
upb_syntax_t syntax;
};
struct upb_symtab {
@ -823,6 +824,10 @@ const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) {
return i < 0 || i >= f->enum_count ? NULL : &f->enums[i];
}
const upb_symtab *upb_filedef_symtab(const upb_filedef *f) {
return f->symtab;
}
void upb_symtab_free(upb_symtab *s) {
upb_arena_free(s->arena);
upb_gfree(s);
@ -2093,6 +2098,7 @@ static const upb_filedef *_upb_symtab_addfile(
file->msg_count = 0;
file->enum_count = 0;
file->ext_count = 0;
file->symtab = s;
if (UPB_UNLIKELY(UPB_SETJMP(ctx.err))) {
UPB_ASSERT(!upb_ok(status));

@ -277,6 +277,7 @@ int upb_filedef_enumcount(const upb_filedef *f);
const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i);
const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i);
const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i);
const upb_symtab *upb_filedef_symtab(const upb_filedef *f);
/* upb_symtab *****************************************************************/

Loading…
Cancel
Save