summaryrefslogtreecommitdiff
path: root/upb/bindings
diff options
context:
space:
mode:
authorJosh Haberman <jhaberman@gmail.com>2016-03-16 18:07:32 -0700
committerJosh Haberman <jhaberman@gmail.com>2016-04-05 17:52:21 -0700
commite9d79d2441732264e2b990a5b2dc76d13724db07 (patch)
tree7faaccbd62043ef5652f891e61577a218a74adbc /upb/bindings
parentd0b9d0a9b782e46a483d4d72515f9ab4f72e402a (diff)
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.
Diffstat (limited to 'upb/bindings')
-rw-r--r--upb/bindings/lua/upb.c174
1 files changed, 161 insertions, 13 deletions
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. */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback