From e9d79d2441732264e2b990a5b2dc76d13724db07 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Wed, 16 Mar 2016 18:07:32 -0700 Subject: Added upb::FileDef, which represents the file defs are declared in. It is entirely optional: MessageDef/EnumDef can still exist on their own. But this can represent a def's file when it is desirable to do so (eg. for code generators). This approach will require that we change the way we handle extensions. But I think it will be a good change overall. Specifically, we previously handled extensions by duplicating the extended message and then adding the extension as a regular field to the duplicated message. This required also duplicating any messages that could reach the extended message. In the new world we will need a way of declaring and looking up extensions separately from the message being extended. This change also involves some notable changes to the generated code: - files are now called foo.upbdefs.h instead of foo.upb.h. This reflects the fact that we might possibly generate several different output files for a .proto file, and this one is just for defs. - we no longer generate selectors in the .h file. - the upbdefs.c no longer vends a SymbolTable. Now it vends the individual messages (and possibly a FileDef later). I think this will compose better once we can generate files where one generated files imports another. We also make the descriptor reader vend a list of FileDefs now. This is the best conceptual match for parsing a FileDescriptorSet. --- upb/bindings/lua/upb.c | 174 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 161 insertions(+), 13 deletions(-) (limited to 'upb/bindings/lua/upb.c') diff --git a/upb/bindings/lua/upb.c b/upb/bindings/lua/upb.c index 2d7b1b3..531967c 100644 --- a/upb/bindings/lua/upb.c +++ b/upb/bindings/lua/upb.c @@ -36,6 +36,7 @@ #define LUPB_MSGDEF "lupb.msgdef" #define LUPB_ENUMDEF "lupb.enumdef" #define LUPB_FIELDDEF "lupb.fielddef" +#define LUPB_FILEDEF "lupb.filedef" #define LUPB_SYMTAB "lupb.symtab" /* Other table constants. */ @@ -485,6 +486,12 @@ static int lupb_def_fullname(lua_State *L) { return 1; } +static int lupb_def_name(lua_State *L) { + const upb_def *def = lupb_def_check(L, 1); + lua_pushstring(L, upb_def_name(def)); + return 1; +} + static int lupb_def_setfullname(lua_State *L) { const char *name = lupb_checkname(L, 2); CHK(upb_def_setfullname(lupb_def_checkmutable(L, 1), name, &status)); @@ -496,6 +503,7 @@ static int lupb_def_setfullname(lua_State *L) { {"full_name", lupb_def_fullname}, \ {"freeze", lupb_def_freeze}, \ {"is_frozen", lupb_def_isfrozen}, \ + {"name", lupb_def_name}, \ {"set_full_name", lupb_def_setfullname}, \ @@ -1056,6 +1064,128 @@ static const struct luaL_Reg lupb_enumdef_m[] = { }; +/* lupb_filedef ***************************************************************/ + +void lupb_filedef_pushwrapper(lua_State *L, const upb_filedef *f, + const void *ref_donor) { + lupb_refcounted_pushwrapper(L, upb_filedef_upcast(f), LUPB_FILEDEF, ref_donor, + sizeof(void *)); +} + +void lupb_filedef_pushnewrapper(lua_State *L, const upb_filedef *f, + const void *ref_donor) { + lupb_refcounted_pushnewrapper(L, upb_filedef_upcast(f), LUPB_FILEDEF, + ref_donor); +} + +const upb_filedef *lupb_filedef_check(lua_State *L, int narg) { + return lupb_refcounted_check(L, narg, LUPB_FILEDEF); +} + +static upb_filedef *lupb_filedef_checkmutable(lua_State *L, int narg) { + const upb_filedef *f = lupb_filedef_check(L, narg); + if (upb_filedef_isfrozen(f)) + luaL_error(L, "not allowed on frozen value"); + return (upb_filedef*)f; +} + +static int lupb_filedef_new(lua_State *L) { + upb_filedef *f = upb_filedef_new(&f); + lupb_filedef_pushnewrapper(L, f, &f); + return 1; +} + +static int lupb_filedef_def(lua_State *L) { + const upb_filedef *f = lupb_filedef_check(L, 1); + int index = luaL_checkint(L, 2); + const upb_def *def = upb_filedef_def(f, index); + + if (!def) { + return luaL_error(L, "index out of range"); + } + + lupb_def_pushwrapper(L, def, NULL); + return 1; +} + +static int lupb_filedef_name(lua_State *L) { + const upb_filedef *f = lupb_filedef_check(L, 1); + lua_pushstring(L, upb_filedef_name(f)); + return 1; +} + +static int lupb_filedef_package(lua_State *L) { + const upb_filedef *f = lupb_filedef_check(L, 1); + lua_pushstring(L, upb_filedef_package(f)); + return 1; +} + +static int lupb_filedef_len(lua_State *L) { + const upb_filedef *f = lupb_filedef_check(L, 1); + lua_pushinteger(L, upb_filedef_defcount(f)); + return 1; +} + +static int lupb_filedef_setname(lua_State *L) { + upb_filedef *f = lupb_filedef_checkmutable(L, 1); + CHK(upb_filedef_setname(f, lupb_checkname(L, 2), &status)); + return 0; +} + +static int lupb_filedef_setpackage(lua_State *L) { + upb_filedef *f = lupb_filedef_checkmutable(L, 1); + CHK(upb_filedef_setpackage(f, lupb_checkname(L, 2), &status)); + return 0; +} + +static int lupb_filedefiter_next(lua_State *L) { + const upb_filedef *f = lupb_filedef_check(L, lua_upvalueindex(1)); + int type = lua_tointeger(L, lua_upvalueindex(2)); + size_t i = lua_tointeger(L, lua_upvalueindex(3)); + size_t n = upb_filedef_defcount(f); + + for (; i < n; i++) { + const upb_def *def; + + def = upb_filedef_def(f, i); + assert(def); + + if (type == UPB_DEF_ANY || upb_def_type(def) == type) { + lua_pushinteger(L, i + 1); + lua_replace(L, lua_upvalueindex(3)); + lupb_def_pushwrapper(L, def, NULL); + return 1; + } + } + + return 0; +} + +static int lupb_filedef_defs(lua_State *L) { + lupb_filedef_check(L, 1); + luaL_checkinteger(L, 2); /* Def type. Could make this optional. */ + lua_pushnumber(L, 0); /* Index, starts at zero. */ + lua_pushcclosure(L, &lupb_filedefiter_next, 3); + return 1; +} + +static const struct luaL_Reg lupb_filedef_mm[] = { + {"__len", lupb_filedef_len}, + {NULL, NULL} +}; + +static const struct luaL_Reg lupb_filedef_m[] = { + {"def", lupb_filedef_def}, + {"defs", lupb_filedef_defs}, + {"name", lupb_filedef_name}, + {"package", lupb_filedef_package}, + + {"set_name", lupb_filedef_setname}, + {"set_package", lupb_filedef_setpackage}, + + {NULL, NULL} +}; + /* lupb_symtab ****************************************************************/ /* Inherits a ref on the symtab. @@ -1128,6 +1258,13 @@ static int lupb_symtab_add(lua_State *L) { return 0; } +static int lupb_symtab_addfile(lua_State *L) { + upb_symtab *s = lupb_symtab_checkmutable(L, 1); + upb_filedef *f = lupb_filedef_checkmutable(L, 2); + CHK(upb_symtab_addfile(s, f, &status)); + return 0; +} + static int lupb_symtab_lookup(lua_State *L) { const upb_symtab *s = lupb_symtab_check(L, 1); int i; @@ -1158,24 +1295,13 @@ static int lupb_symtab_defs(lua_State *L) { return 1; } -/* This is a *temporary* API that will be removed once pending refactorings are - * complete (it does not belong here in core because it depends on both - * the descriptor.proto schema and the protobuf binary format. */ -static int lupb_symtab_load_descriptor(lua_State *L) { - size_t len; - upb_symtab *s = lupb_symtab_checkmutable(L, 1); - const char *str = luaL_checklstring(L, 2, &len); - CHK(upb_load_descriptor_into_symtab(s, str, len, &status)); - return 0; -} - static const struct luaL_Reg lupb_symtab_m[] = { {"add", lupb_symtab_add}, + {"add_file", lupb_symtab_addfile}, {"defs", lupb_symtab_defs}, {"freeze", lupb_symtab_freeze}, {"is_frozen", lupb_symtab_isfrozen}, {"lookup", lupb_symtab_lookup}, - {"load_descriptor", lupb_symtab_load_descriptor}, {NULL, NULL} }; @@ -1287,7 +1413,7 @@ static const struct luaL_Reg lupb_array_mm[] = { /* lupb_msg **************************************************************/ /* A lupb_msg is a userdata where: - * + * * - the userdata's memory contains hasbits and primitive fields. * - the userdata's environment table / uservalue contains references to string * fields, submessage fields, and array fields. */ @@ -1734,14 +1860,35 @@ static int lupb_freeze(lua_State *L) { return 0; } +/* This is a *temporary* API that will be removed once pending refactorings are + * complete (it does not belong here in core because it depends on both + * the descriptor.proto schema and the protobuf binary format. */ +static int lupb_loaddescriptor(lua_State *L) { + size_t len; + const char *str = luaL_checklstring(L, 1, &len); + size_t i; + upb_filedef **files = NULL; + CHK(files = upb_loaddescriptor(str, len, &files, &status)); + + lua_newtable(L); + for (i = 1; *files; i++, files++) { + lupb_filedef_pushnewrapper(L, *files, &files); + lua_rawseti(L, -2, i); + } + + return 1; +} + static const struct luaL_Reg lupb_toplevel_m[] = { {"Array", lupb_array_new}, {"EnumDef", lupb_enumdef_new}, {"FieldDef", lupb_fielddef_new}, + {"FileDef", lupb_filedef_new}, {"Message", lupb_msg_new}, {"MessageDef", lupb_msgdef_new}, {"SymbolTable", lupb_symtab_new}, {"freeze", lupb_freeze}, + {"load_descriptor", lupb_loaddescriptor}, {NULL, NULL} }; @@ -1791,6 +1938,7 @@ int luaopen_upb_c(lua_State *L) { /* Refcounted types. */ lupb_register_type(L, LUPB_ENUMDEF, lupb_enumdef_m, lupb_enumdef_mm, true); lupb_register_type(L, LUPB_FIELDDEF, lupb_fielddef_m, NULL, true); + lupb_register_type(L, LUPB_FILEDEF, lupb_filedef_m, lupb_filedef_mm, true); lupb_register_type(L, LUPB_SYMTAB, lupb_symtab_m, NULL, true); /* Refcounted but with custom __gc. */ -- cgit v1.2.3