summaryrefslogtreecommitdiff
path: root/upb
diff options
context:
space:
mode:
authorJoshua Haberman <jhaberman@gmail.com>2018-12-10 10:18:48 -0800
committerJoshua Haberman <jhaberman@gmail.com>2018-12-10 10:18:48 -0800
commit336402b4d7251d37239d2f7ff8259174525baa38 (patch)
treec3ed0af3e6bbd58b35fc370794c5d7732aea5bab /upb
parentbfa3c015bb8de950d0e6b0076be89df4bc37fba7 (diff)
WIP, core library compiles now.
Diffstat (limited to 'upb')
-rw-r--r--upb/bindings/lua/def.c780
-rw-r--r--upb/def.c722
-rw-r--r--upb/def.h13
-rw-r--r--upb/handlers.c4
-rw-r--r--upb/json/parser.c126
-rw-r--r--upb/json/parser.h3
-rw-r--r--upb/json/parser.rl20
-rw-r--r--upb/json/printer.c2
-rw-r--r--upb/msg.h9
-rw-r--r--upb/pb/textprinter.c4
-rw-r--r--upb/structdefs.int.h196
11 files changed, 591 insertions, 1288 deletions
diff --git a/upb/bindings/lua/def.c b/upb/bindings/lua/def.c
index 7b3f612..1fde212 100644
--- a/upb/bindings/lua/def.c
+++ b/upb/bindings/lua/def.c
@@ -22,22 +22,6 @@
} while (0)
-const char *lupb_checkname(lua_State *L, int narg) {
- size_t len;
- const char *name = luaL_checklstring(L, narg, &len);
- if (strlen(name) != len)
- luaL_error(L, "names cannot have embedded NULLs");
- return name;
-}
-
-upb_fieldtype_t lupb_checkfieldtype(lua_State *L, int narg) {
- int type = luaL_checkint(L, narg);
- if (!upb_fielddef_checktype(type))
- luaL_argerror(L, narg, "invalid field type");
- return type;
-}
-
-
/* lupb_refcounted ************************************************************/
/* All upb objects that use upb_refcounted have a userdata that begins with a
@@ -49,12 +33,12 @@ upb_fieldtype_t lupb_checkfieldtype(lua_State *L, int narg) {
* long as it begins with a pointer. */
/* Checks type; if it matches, pulls the pointer out of the wrapper. */
-void *lupb_refcounted_check(lua_State *L, int narg, const char *type) {
+void *lupb_checkwrapper(lua_State *L, int narg, const char *type) {
void *ud = lua_touserdata(L, narg);
void *ret;
if (!ud) {
- luaL_typerror(L, narg, "refcounted");
+ luaL_typerror(L, narg, "upb wrapper");
}
memcpy(&ret, ud, sizeof(ret));
@@ -66,15 +50,12 @@ void *lupb_refcounted_check(lua_State *L, int narg, const char *type) {
return ret;
}
-bool lupb_refcounted_pushwrapper(lua_State *L, const upb_refcounted *obj,
- const char *type, const void *ref_donor,
- size_t size) {
- bool create;
+void lupb_pushwrapper(lua_State *L, const void *obj, const char *type) {
void *ud;
if (obj == NULL) {
lua_pushnil(L);
- return false;
+ return;
}
/* Lookup our cache in the registry (we don't put our objects in the registry
@@ -85,34 +66,11 @@ bool lupb_refcounted_pushwrapper(lua_State *L, const upb_refcounted *obj,
lua_rawget(L, -2);
/* Stack is now: objcache, cached value. */
- create = false;
-
if (lua_isnil(L, -1)) {
- create = true;
- } else {
- void *ud = lua_touserdata(L, -1);
- void *ud_obj;
- lupb_assert(L, ud);
- memcpy(&ud_obj, ud, sizeof(void*));
-
- /* A corner case: it is possible for the value to be GC'd
- * already, in which case we should evict this entry and create
- * a new one. */
- if (ud_obj == NULL) {
- create = true;
- }
- }
-
- ud = NULL;
-
- if (create) {
/* Remove bad cached value and push new value. */
lua_pop(L, 1);
-
- /* All of our userdata begin with a pointer to the obj. */
- ud = lua_newuserdata(L, size);
- memcpy(ud, &obj, sizeof(void*));
- upb_refcounted_donateref(obj, ref_donor, ud);
+ ud = lua_newuserdata(L, sizeof(*ud));
+ memcpy(ud, &obj, sizeof(*ud));
luaL_getmetatable(L, type);
/* Should have been created by luaopen_upb. */
@@ -123,207 +81,36 @@ bool lupb_refcounted_pushwrapper(lua_State *L, const upb_refcounted *obj,
lua_pushlightuserdata(L, (void*)obj);
lua_pushvalue(L, -2);
lua_rawset(L, -4);
- } else {
- /* Existing wrapper obj already has a ref. */
- ud = lua_touserdata(L, -1);
- upb_refcounted_checkref(obj, ud);
- if (ref_donor)
- upb_refcounted_unref(obj, ref_donor);
}
lua_insert(L, -2);
lua_pop(L, 1);
- return create;
-}
-
-void lupb_refcounted_pushnewrapper(lua_State *L, const upb_refcounted *obj,
- const char *type, const void *ref_donor) {
- bool created =
- lupb_refcounted_pushwrapper(L, obj, type, ref_donor, sizeof(void *));
- UPB_ASSERT(created == true);
-}
-
-int lupb_refcounted_gc(lua_State *L) {
- void *ud = lua_touserdata(L, 1);
- void *nullp;
- upb_refcounted *obj;
- memcpy(&obj, ud, sizeof(obj));
- upb_refcounted_unref(obj, ud);
-
- /* Zero out pointer so we can detect a call into a GC'd object. */
- nullp = NULL;
- memcpy(ud, &nullp, sizeof(nullp));
-
- return 0;
-}
-
-
-/* lupb_def *******************************************************************/
-
-static const upb_def *lupb_def_check(lua_State *L, int narg) {
- upb_def *ret;
- void *ud, *ud2;
-
- ud = lua_touserdata(L, narg);
- if (!ud) {
- luaL_typerror(L, narg, "upb def");
- }
-
- memcpy(&ret, ud, sizeof(ret));
- if (!ret) {
- luaL_error(L, "called into dead object");
- }
-
- ud2 = luaL_testudata(L, narg, LUPB_MSGDEF);
- if (!ud2) ud2 = luaL_testudata(L, narg, LUPB_ENUMDEF);
- if (!ud2) ud2 = luaL_testudata(L, narg, LUPB_FIELDDEF);
- if (!ud2) luaL_typerror(L, narg, "upb def");
-
- return ret;
-}
-
-static upb_def *lupb_def_checkmutable(lua_State *L, int narg) {
- const upb_def *def = lupb_def_check(L, narg);
- if (upb_def_isfrozen(def))
- luaL_error(L, "not allowed on frozen value");
- return (upb_def*)def;
-}
-
-bool lupb_def_pushwrapper(lua_State *L, const upb_def *def,
- const void *ref_donor) {
- const char *type = NULL;
- bool created;
-
- if (def == NULL) {
- lua_pushnil(L);
- return false;
- }
-
- switch (upb_def_type(def)) {
- case UPB_DEF_MSG:
- type = LUPB_MSGDEF;
- break;
- case UPB_DEF_FIELD:
- type = LUPB_FIELDDEF;
- break;
- case UPB_DEF_ENUM:
- type = LUPB_ENUMDEF;
- break;
- default:
- printf("Def type: %d\n", (int)upb_def_type(def));
- UPB_UNREACHABLE();
- }
-
- created = lupb_refcounted_pushwrapper(L, upb_def_upcast(def), type, ref_donor,
- sizeof(void *));
- return created;
-}
-
-void lupb_def_pushnewrapper(lua_State *L, const upb_def *def,
- const void *ref_donor) {
- bool created = lupb_def_pushwrapper(L, def, ref_donor);
- UPB_ASSERT(created == true);
-}
-
-static int lupb_def_type(lua_State *L) {
- const upb_def *def = lupb_def_check(L, 1);
- lua_pushinteger(L, upb_def_type(def));
- return 1;
-}
-
-void lupb_filedef_pushwrapper(lua_State *L, const upb_filedef *f,
- const void *ref_donor);
-
-static int lupb_def_file(lua_State *L) {
- const upb_def *def = lupb_def_check(L, 1);
- lupb_filedef_pushwrapper(L, upb_def_file(def), NULL);
- return 1;
-}
-
-static int lupb_def_freeze(lua_State *L) {
- upb_def *def = lupb_def_checkmutable(L, 1);
- CHK(upb_def_freeze(&def, 1, &status));
- return 0;
-}
-
-static int lupb_def_isfrozen(lua_State *L) {
- const upb_def *def = lupb_def_check(L, 1);
- lua_pushboolean(L, upb_def_isfrozen(def));
- return 1;
-}
-
-static int lupb_def_fullname(lua_State *L) {
- const upb_def *def = lupb_def_check(L, 1);
- lua_pushstring(L, upb_def_fullname(def));
- 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));
- return 0;
-}
-
-#define LUPB_COMMON_DEF_METHODS \
- {"def_type", lupb_def_type}, \
- {"file", lupb_def_file}, \
- {"full_name", lupb_def_fullname}, \
- {"freeze", lupb_def_freeze}, \
- {"is_frozen", lupb_def_isfrozen}, \
- {"name", lupb_def_name}, \
- {"set_full_name", lupb_def_setfullname}, \
+void lupb_msgdef_pushwrapper(lua_State *L, const upb_msgdef *m);
+void lupb_oneofdef_pushwrapper(lua_State *L, const upb_oneofdef *o);
+static void lupb_enumdef_pushwrapper(lua_State *L, const upb_enumdef *e);
/* lupb_fielddef **************************************************************/
-void lupb_fielddef_pushwrapper(lua_State *L, const upb_fielddef *f,
- const void *ref_donor) {
- lupb_def_pushwrapper(L, upb_fielddef_upcast(f), ref_donor);
+void lupb_fielddef_pushwrapper(lua_State *L, const upb_fielddef *f) {
+ lupb_pushwrapper(L, f, LUPB_FIELDDEF);
}
const upb_fielddef *lupb_fielddef_check(lua_State *L, int narg) {
- return lupb_refcounted_check(L, narg, LUPB_FIELDDEF);
+ return lupb_checkwrapper(L, narg, LUPB_FIELDDEF);
}
-static upb_fielddef *lupb_fielddef_checkmutable(lua_State *L, int narg) {
- const upb_fielddef *f = lupb_fielddef_check(L, narg);
- if (upb_fielddef_isfrozen(f))
- luaL_error(L, "not allowed on frozen value");
- return (upb_fielddef*)f;
-}
-
-static int lupb_fielddef_new(lua_State *L) {
- upb_fielddef *f = upb_fielddef_new(&f);
- lupb_def_pushnewrapper(L, upb_fielddef_upcast(f), &f);
- return 1;
-}
-
-/* Getters */
-
-void lupb_oneofdef_pushwrapper(lua_State *L, const upb_oneofdef *o,
- const void *ref_donor);
-
static int lupb_fielddef_containingoneof(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
- lupb_oneofdef_pushwrapper(L, upb_fielddef_containingoneof(f), NULL);
+ lupb_oneofdef_pushwrapper(L, upb_fielddef_containingoneof(f));
return 1;
}
static int lupb_fielddef_containingtype(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
- lupb_msgdef_pushwrapper(L, upb_fielddef_containingtype(f), NULL);
- return 1;
-}
-
-static int lupb_fielddef_containingtypename(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- lua_pushstring(L, upb_fielddef_containingtypename(f));
+ lupb_msgdef_pushwrapper(L, upb_fielddef_containingtype(f));
return 1;
}
@@ -331,7 +118,7 @@ static int lupb_fielddef_default(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
switch (upb_fielddef_type(f)) {
case UPB_TYPE_INT32:
- int32:
+ case UPB_TYPE_ENUM:
lupb_pushint32(L, upb_fielddef_defaultint32(f)); break;
case UPB_TYPE_INT64:
lupb_pushint64(L, upb_fielddef_defaultint64(f)); break;
@@ -345,18 +132,8 @@ static int lupb_fielddef_default(lua_State *L) {
lua_pushnumber(L, upb_fielddef_defaultfloat(f)); break;
case UPB_TYPE_BOOL:
lua_pushboolean(L, upb_fielddef_defaultbool(f)); break;
- case UPB_TYPE_ENUM:
- if (upb_fielddef_enumhasdefaultstr(f)) {
- goto str;
- } else if (upb_fielddef_enumhasdefaultint32(f)) {
- goto int32;
- } else {
- lua_pushnil(L);
- }
- break;
case UPB_TYPE_STRING:
- case UPB_TYPE_BYTES:
- str: {
+ case UPB_TYPE_BYTES: {
size_t len;
const char *data = upb_fielddef_defaultstr(f, &len);
lua_pushlstring(L, data, len);
@@ -397,24 +174,12 @@ static int lupb_fielddef_index(lua_State *L) {
return 1;
}
-static int lupb_fielddef_intfmt(lua_State *L) {
- const upb_fielddef *f = lupb_fielddef_check(L, 1);
- lua_pushinteger(L, upb_fielddef_intfmt(f));
- return 1;
-}
-
static int lupb_fielddef_isextension(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
lua_pushboolean(L, upb_fielddef_isextension(f));
return 1;
}
-static int lupb_fielddef_istagdelim(lua_State *L) {
- const upb_fielddef *f = lupb_fielddef_check(L, 1);
- lua_pushboolean(L, upb_fielddef_istagdelim(f));
- return 1;
-}
-
static int lupb_fielddef_label(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
lua_pushinteger(L, upb_fielddef_label(f));
@@ -449,22 +214,15 @@ static int lupb_fielddef_packed(lua_State *L) {
return 1;
}
-static int lupb_fielddef_subdef(lua_State *L) {
+static int lupb_fielddef_msgsubdef(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
- const upb_def *def;
-
- if (!upb_fielddef_hassubdef(f))
- luaL_error(L, "Tried to get subdef of non-message field");
- def = upb_fielddef_subdef(f);
- lupb_def_pushwrapper(L, def, NULL);
+ lupb_msgdef_pushwrapper(L, upb_fielddef_msgsubdef(f));
return 1;
}
-static int lupb_fielddef_subdefname(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- if (!upb_fielddef_hassubdef(f))
- luaL_error(L, "Tried to get subdef name of non-message field");
- lua_pushstring(L, upb_fielddef_subdefname(f));
+static int lupb_fielddef_enumsubdef(lua_State *L) {
+ const upb_fielddef *f = lupb_fielddef_check(L, 1);
+ lupb_enumdef_pushwrapper(L, upb_fielddef_enumsubdef(f));
return 1;
}
@@ -477,216 +235,40 @@ static int lupb_fielddef_type(lua_State *L) {
return 1;
}
-/* Setters */
-
-static int lupb_fielddef_setcontainingtypename(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- const char *name = NULL;
- if (!lua_isnil(L, 2))
- name = lupb_checkname(L, 2);
- CHK(upb_fielddef_setcontainingtypename(f, name, &status));
- return 0;
-}
-
-static int lupb_fielddef_setdefault(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
-
- switch (upb_fielddef_type(f)) {
- case UPB_TYPE_INT32:
- upb_fielddef_setdefaultint32(f, lupb_checkint32(L, 2));
- break;
- case UPB_TYPE_INT64:
- upb_fielddef_setdefaultint64(f, lupb_checkint64(L, 2));
- break;
- case UPB_TYPE_UINT32:
- upb_fielddef_setdefaultuint32(f, lupb_checkuint32(L, 2));
- break;
- case UPB_TYPE_UINT64:
- upb_fielddef_setdefaultuint64(f, lupb_checkuint64(L, 2));
- break;
- case UPB_TYPE_DOUBLE:
- upb_fielddef_setdefaultdouble(f, lupb_checkdouble(L, 2));
- break;
- case UPB_TYPE_FLOAT:
- upb_fielddef_setdefaultfloat(f, lupb_checkfloat(L, 2));
- break;
- case UPB_TYPE_BOOL:
- upb_fielddef_setdefaultbool(f, lupb_checkbool(L, 2));
- break;
- case UPB_TYPE_MESSAGE:
- return luaL_error(L, "Message types cannot have defaults.");
- case UPB_TYPE_ENUM:
- if (lua_type(L, 2) != LUA_TSTRING) {
- upb_fielddef_setdefaultint32(f, lupb_checkint32(L, 2));
- break;
- }
- /* Else fall through and set string default. */
- case UPB_TYPE_BYTES:
- case UPB_TYPE_STRING: {
- size_t len;
- const char *str = lua_tolstring(L, 2, &len);
- CHK(upb_fielddef_setdefaultstr(f, str, len, &status));
- }
- }
- return 0;
-}
-
-static int lupb_fielddef_setisextension(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- CHK(upb_fielddef_setisextension(f, lupb_checkbool(L, 2)));
- return 0;
-}
-
-static int lupb_fielddef_setlabel(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- int label = luaL_checkint(L, 2);
- if (!upb_fielddef_checklabel(label))
- luaL_argerror(L, 2, "invalid field label");
- upb_fielddef_setlabel(f, label);
- return 0;
-}
-
-static int lupb_fielddef_setlazy(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- upb_fielddef_setlazy(f, lupb_checkbool(L, 2));
- return 0;
-}
-
-static int lupb_fielddef_setname(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- CHK(upb_fielddef_setname(f, lupb_checkname(L, 2), &status));
- return 0;
-}
-
-static int lupb_fielddef_setnumber(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- CHK(upb_fielddef_setnumber(f, luaL_checkint(L, 2), &status));
- return 0;
-}
-
-static int lupb_fielddef_setpacked(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- upb_fielddef_setpacked(f, lupb_checkbool(L, 2));
- return 0;
-}
-
-static int lupb_fielddef_setsubdef(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- const upb_def *def = NULL;
- if (!lua_isnil(L, 2))
- def = lupb_def_check(L, 2);
- CHK(upb_fielddef_setsubdef(f, def, &status));
- return 0;
-}
-
-static int lupb_fielddef_setsubdefname(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- const char *name = NULL;
- if (!lua_isnil(L, 2))
- name = lupb_checkname(L, 2);
- CHK(upb_fielddef_setsubdefname(f, name, &status));
- return 0;
-}
-
-static int lupb_fielddef_settype(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- upb_fielddef_settype(f, lupb_checkfieldtype(L, 2));
- return 0;
-}
-
-static int lupb_fielddef_setintfmt(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- int32_t intfmt = luaL_checknumber(L, 2);
- if (!upb_fielddef_checkintfmt(intfmt))
- luaL_argerror(L, 2, "invalid intfmt");
- upb_fielddef_setintfmt(f, intfmt);
- return 0;
-}
-
-static int lupb_fielddef_settagdelim(lua_State *L) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 1);
- bool is_tag_delim = lupb_checkbool(L, 2);
- CHK(upb_fielddef_settagdelim(f, is_tag_delim));
- return 0;
-}
-
-static const struct luaL_Reg lupb_fielddef_mm[] = {
- {"__gc", lupb_refcounted_gc},
- {NULL, NULL}
-};
-
static const struct luaL_Reg lupb_fielddef_m[] = {
- LUPB_COMMON_DEF_METHODS
-
{"containing_oneof", lupb_fielddef_containingoneof},
{"containing_type", lupb_fielddef_containingtype},
- {"containing_type_name", lupb_fielddef_containingtypename},
{"default", lupb_fielddef_default},
{"descriptor_type", lupb_fielddef_descriptortype},
{"getsel", lupb_fielddef_getsel},
{"has_subdef", lupb_fielddef_hassubdef},
{"index", lupb_fielddef_index},
- {"intfmt", lupb_fielddef_intfmt},
{"is_extension", lupb_fielddef_isextension},
- {"istagdelim", lupb_fielddef_istagdelim},
{"label", lupb_fielddef_label},
{"lazy", lupb_fielddef_lazy},
{"name", lupb_fielddef_name},
{"number", lupb_fielddef_number},
{"packed", lupb_fielddef_packed},
- {"subdef", lupb_fielddef_subdef},
- {"subdef_name", lupb_fielddef_subdefname},
+ {"msgsubdef", lupb_fielddef_msgsubdef},
+ {"enumsubdef", lupb_fielddef_enumsubdef},
{"type", lupb_fielddef_type},
-
- {"set_containing_type_name", lupb_fielddef_setcontainingtypename},
- {"set_default", lupb_fielddef_setdefault},
- {"set_is_extension", lupb_fielddef_setisextension},
- {"set_label", lupb_fielddef_setlabel},
- {"set_lazy", lupb_fielddef_setlazy},
- {"set_name", lupb_fielddef_setname},
- {"set_number", lupb_fielddef_setnumber},
- {"set_packed", lupb_fielddef_setpacked},
- {"set_subdef", lupb_fielddef_setsubdef},
- {"set_subdef_name", lupb_fielddef_setsubdefname},
- {"set_type", lupb_fielddef_settype},
- {"set_intfmt", lupb_fielddef_setintfmt},
- {"set_tagdelim", lupb_fielddef_settagdelim},
-
{NULL, NULL}
};
/* lupb_oneofdef **************************************************************/
-void lupb_oneofdef_pushwrapper(lua_State *L, const upb_oneofdef *o,
- const void *ref_donor) {
- lupb_refcounted_pushwrapper(L, upb_oneofdef_upcast(o), LUPB_ONEOFDEF,
- ref_donor, sizeof(void *));
+void lupb_oneofdef_pushwrapper(lua_State *L, const upb_oneofdef *o) {
+ lupb_pushwrapper(L, o, LUPB_ONEOFDEF);
}
const upb_oneofdef *lupb_oneofdef_check(lua_State *L, int narg) {
return lupb_refcounted_check(L, narg, LUPB_ONEOFDEF);
}
-static upb_oneofdef *lupb_oneofdef_checkmutable(lua_State *L, int narg) {
- const upb_oneofdef *o = lupb_oneofdef_check(L, narg);
- if (upb_oneofdef_isfrozen(o))
- luaL_error(L, "not allowed on frozen value");
- return (upb_oneofdef*)o;
-}
-
-static int lupb_oneofdef_new(lua_State *L) {
- upb_oneofdef *o = upb_oneofdef_new(&o);
- lupb_refcounted_pushnewrapper(L, upb_oneofdef_upcast(o), LUPB_ONEOFDEF, &o);
- return 1;
-}
-
-/* Getters */
-
static int lupb_oneofdef_containingtype(lua_State *L) {
const upb_oneofdef *o = lupb_oneofdef_check(L, 1);
- lupb_def_pushwrapper(L, upb_msgdef_upcast(upb_oneofdef_containingtype(o)),
- NULL);
+ lupb_msgdef_pushwrapper(L, upb_oneofdef_containingtype(o));
return 1;
}
@@ -704,14 +286,14 @@ static int lupb_oneofdef_field(lua_State *L) {
return luaL_argerror(L, 2, msg);
}
- lupb_def_pushwrapper(L, upb_fielddef_upcast(f), NULL);
+ lupb_fielddef_pushwrapper(L, f);
return 1;
}
static int lupb_oneofiter_next(lua_State *L) {
upb_oneof_iter *i = lua_touserdata(L, lua_upvalueindex(1));
if (upb_oneof_done(i)) return 0;
- lupb_fielddef_pushwrapper(L, upb_oneof_iter_field(i), NULL);
+ lupb_fielddef_pushwrapper(L, upb_oneof_iter_field(i));
upb_oneof_next(i);
return 1;
}
@@ -738,35 +320,15 @@ static int lupb_oneofdef_name(lua_State *L) {
return 1;
}
-/* Setters */
-
-static int lupb_oneofdef_add(lua_State *L) {
- upb_oneofdef *o = lupb_oneofdef_checkmutable(L, 1);
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 2);
- CHK(upb_oneofdef_addfield(o, f, NULL, &status));
- return 0;
-}
-
-static int lupb_oneofdef_setname(lua_State *L) {
- upb_oneofdef *o = lupb_oneofdef_checkmutable(L, 1);
- CHK(upb_oneofdef_setname(o, lupb_checkname(L, 2), &status));
- return 0;
-}
-
static const struct luaL_Reg lupb_oneofdef_m[] = {
{"containing_type", lupb_oneofdef_containingtype},
{"field", lupb_oneofdef_field},
{"fields", lupb_oneofdef_fields},
{"name", lupb_oneofdef_name},
-
- {"add", lupb_oneofdef_add},
- {"set_name", lupb_oneofdef_setname},
-
{NULL, NULL}
};
static const struct luaL_Reg lupb_oneofdef_mm[] = {
- {"__gc", lupb_refcounted_gc},
{"__len", lupb_oneofdef_len},
{NULL, NULL}
};
@@ -778,42 +340,14 @@ typedef struct {
const upb_msgdef *md;
} lupb_msgdef;
-void lupb_msgdef_pushwrapper(lua_State *L, const upb_msgdef *m,
- const void *ref_donor) {
- lupb_def_pushwrapper(L, upb_msgdef_upcast(m), ref_donor);
+void lupb_msgdef_pushwrapper(lua_State *L, const upb_msgdef *m) {
+ lupb_pushwrapper(L, m, LUPB_MSGDEF);
}
const upb_msgdef *lupb_msgdef_check(lua_State *L, int narg) {
return lupb_refcounted_check(L, narg, LUPB_MSGDEF);
}
-static upb_msgdef *lupb_msgdef_checkmutable(lua_State *L, int narg) {
- const upb_msgdef *m = lupb_msgdef_check(L, narg);
- if (upb_msgdef_isfrozen(m))
- luaL_error(L, "not allowed on frozen value");
- return (upb_msgdef*)m;
-}
-
-static int lupb_msgdef_new(lua_State *L) {
- upb_msgdef *md = upb_msgdef_new(&md);
- lupb_def_pushnewrapper(L, upb_msgdef_upcast(md), &md);
- return 1;
-}
-
-static int lupb_msgdef_add(lua_State *L) {
- upb_msgdef *m = lupb_msgdef_checkmutable(L, 1);
-
- /* Both oneofs and fields can be added. */
- if (luaL_testudata(L, 2, LUPB_FIELDDEF)) {
- upb_fielddef *f = lupb_fielddef_checkmutable(L, 2);
- CHK(upb_msgdef_addfield(m, f, NULL, &status));
- } else if (luaL_testudata(L, 2, LUPB_ONEOFDEF)) {
- upb_oneofdef *o = lupb_oneofdef_checkmutable(L, 2);
- CHK(upb_msgdef_addoneof(m, o, NULL, &status));
- }
- return 0;
-}
-
static int lupb_msgdef_len(lua_State *L) {
const upb_msgdef *m = lupb_msgdef_check(L, 1);
lua_pushinteger(L, upb_msgdef_numfields(m));
@@ -834,7 +368,7 @@ static int lupb_msgdef_field(lua_State *L) {
return luaL_argerror(L, 2, msg);
}
- lupb_def_pushwrapper(L, upb_fielddef_upcast(f), NULL);
+ lupb_fielddef_pushwrapper(L, f);
return 1;
}
@@ -845,9 +379,9 @@ static int lupb_msgdef_lookupname(lua_State *L) {
if (!upb_msgdef_lookupnamez(m, lua_tostring(L, 2), &f, &o)) {
lua_pushnil(L);
} else if (o) {
- lupb_oneofdef_pushwrapper(L, o, NULL);
+ lupb_oneofdef_pushwrapper(L, o);
} else {
- lupb_fielddef_pushwrapper(L, f, NULL);
+ lupb_fielddef_pushwrapper(L, f);
}
return 1;
}
@@ -855,7 +389,7 @@ static int lupb_msgdef_lookupname(lua_State *L) {
static int lupb_msgfielditer_next(lua_State *L) {
upb_msg_field_iter *i = lua_touserdata(L, lua_upvalueindex(1));
if (upb_msg_field_done(i)) return 0;
- lupb_def_pushwrapper(L, upb_fielddef_upcast(upb_msg_iter_field(i)), NULL);
+ lupb_fielddef_pushwrapper(L, upb_msg_iter_field(i));
upb_msg_field_next(i);
return 1;
}
@@ -873,7 +407,7 @@ static int lupb_msgdef_fields(lua_State *L) {
static int lupb_msgoneofiter_next(lua_State *L) {
upb_msg_oneof_iter *i = lua_touserdata(L, lua_upvalueindex(1));
if (upb_msg_oneof_done(i)) return 0;
- lupb_oneofdef_pushwrapper(L, upb_msg_iter_oneof(i), NULL);
+ lupb_oneofdef_pushwrapper(L, upb_msg_iter_oneof(i));
upb_msg_oneof_next(i);
return 1;
}
@@ -902,20 +436,16 @@ static int lupb_msgdef_syntax(lua_State *L) {
static const struct luaL_Reg lupb_msgdef_mm[] = {
{"__len", lupb_msgdef_len},
- {"__gc", lupb_refcounted_gc},
{NULL, NULL}
};
static const struct luaL_Reg lupb_msgdef_m[] = {
- LUPB_COMMON_DEF_METHODS
- {"add", lupb_msgdef_add},
{"field", lupb_msgdef_field},
{"fields", lupb_msgdef_fields},
{"lookup_name", lupb_msgdef_lookupname},
{"oneofs", lupb_msgdef_oneofs},
{"syntax", lupb_msgdef_syntax},
{"_map_entry", lupb_msgdef_mapentry},
-
{NULL, NULL}
};
@@ -926,25 +456,8 @@ const upb_enumdef *lupb_enumdef_check(lua_State *L, int narg) {
return lupb_refcounted_check(L, narg, LUPB_ENUMDEF);
}
-static upb_enumdef *lupb_enumdef_checkmutable(lua_State *L, int narg) {
- const upb_enumdef *f = lupb_enumdef_check(L, narg);
- if (upb_enumdef_isfrozen(f))
- luaL_error(L, "not allowed on frozen value");
- return (upb_enumdef*)f;
-}
-
-static int lupb_enumdef_new(lua_State *L) {
- upb_enumdef *e = upb_enumdef_new(&e);
- lupb_def_pushnewrapper(L, upb_enumdef_upcast(e), &e);
- return 1;
-}
-
-static int lupb_enumdef_add(lua_State *L) {
- upb_enumdef *e = lupb_enumdef_checkmutable(L, 1);
- const char *name = lupb_checkname(L, 2);
- int32_t val = lupb_checkint32(L, 3);
- CHK(upb_enumdef_addval(e, name, val, &status));
- return 0;
+static void lupb_enumdef_pushwrapper(lua_State *L, const upb_enumdef *e) {
+ lupb_pushwrapper(L, e, LUPB_ENUMDEF);
}
static int lupb_enumdef_len(lua_State *L) {
@@ -996,14 +509,11 @@ static int lupb_enumdef_values(lua_State *L) {
}
static const struct luaL_Reg lupb_enumdef_mm[] = {
- {"__gc", lupb_refcounted_gc},
{"__len", lupb_enumdef_len},
{NULL, NULL}
};
static const struct luaL_Reg lupb_enumdef_m[] = {
- LUPB_COMMON_DEF_METHODS
- {"add", lupb_enumdef_add},
{"value", lupb_enumdef_value},
{"values", lupb_enumdef_values},
{NULL, NULL}
@@ -1012,68 +522,50 @@ 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);
+void lupb_filedef_pushwrapper(lua_State *L, const upb_filedef *f) {
+ lupb_pushwrapper(L, f, LUPB_FILEDEF);
}
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_dep(lua_State *L) {
+ const upb_filedef *f = lupb_filedef_check(L, 1);
+ int index = luaL_checkint(L, 2);
+ lupb_filedef_pushwrapper(L, upb_filedef_dep(f, index));
+ return 1;
}
-static int lupb_filedef_new(lua_State *L) {
- upb_filedef *f = upb_filedef_new(&f);
- lupb_filedef_pushnewrapper(L, f, &f);
+static int lupb_filedef_depcount(lua_State *L) {
+ const upb_filedef *f = lupb_filedef_check(L, 1);
+ lua_pushnumber(L, upb_filedef_depcount(f));
return 1;
}
-static int lupb_filedef_def(lua_State *L) {
+static int lupb_filedef_enum(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);
+ lupb_enumdef_pushwrapper(L, upb_filedef_enum(f, index));
return 1;
}
-static int lupb_filedefdepiter_next(lua_State *L) {
- const upb_filedef *f = lupb_filedef_check(L, lua_upvalueindex(1));
- size_t i = lua_tointeger(L, lua_upvalueindex(2));
-
- if (i >= upb_filedef_depcount(f)) {
- return 0;
- }
-
- lupb_filedef_pushwrapper(L, upb_filedef_dep(f, i), NULL);
- lua_pushinteger(L, i + 1);
- lua_replace(L, lua_upvalueindex(2));
+static int lupb_filedef_enumcount(lua_State *L) {
+ const upb_filedef *f = lupb_filedef_check(L, 1);
+ lua_pushnumber(L, upb_filedef_enumcount(f));
return 1;
}
+static int lupb_filedef_msg(lua_State *L) {
+ const upb_filedef *f = lupb_filedef_check(L, 1);
+ int index = luaL_checkint(L, 2);
+ lupb_msgdef_pushwrapper(L, upb_filedef_msg(f, index));
+ return 1;
+}
-static int lupb_filedef_dependencies(lua_State *L) {
- lupb_filedef_check(L, 1);
- lua_pushvalue(L, 1);
- lua_pushnumber(L, 0); /* Index, starts at zero. */
- lua_pushcclosure(L, &lupb_filedefdepiter_next, 2);
+static int lupb_filedef_msgcount(lua_State *L) {
+ const upb_filedef *f = lupb_filedef_check(L, 1);
+ lua_pushnumber(L, upb_filedef_msgcount(f));
return 1;
}
@@ -1095,72 +587,16 @@ static int lupb_filedef_syntax(lua_State *L) {
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);
- UPB_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[] = {
- {"__gc", lupb_refcounted_gc},
- {"__len", lupb_filedef_len},
- {NULL, NULL}
-};
-
static const struct luaL_Reg lupb_filedef_m[] = {
- {"def", lupb_filedef_def},
- {"defs", lupb_filedef_defs},
- {"dependencies", lupb_filedef_dependencies},
+ {"dep", lupb_filedef_dep},
+ {"depcount", lupb_filedef_depcount},
+ {"enum", lupb_filedef_enum},
+ {"enumcount", lupb_filedef_enumcount},
+ {"msg", lupb_filedef_msg},
+ {"msgcount", lupb_filedef_msgcount},
{"name", lupb_filedef_name},
{"package", lupb_filedef_package},
{"syntax", lupb_filedef_syntax},
-
- {"set_name", lupb_filedef_setname},
- {"set_package", lupb_filedef_setpackage},
-
{NULL, NULL}
};
@@ -1194,15 +630,23 @@ static int lupb_symtab_gc(lua_State *L) {
return 0;
}
+/* TODO(haberman): perhaps this should take a message object instead of a
+ * serialized string once we have a good story for vending compiled-in
+ * messages. */
static int lupb_symtab_add(lua_State *L) {
size_t len;
- upb_symtab *s = lupb_symtab_check(L, 1);
- const char *str = luaL_checklstring(L, 2, &len);
- google_protobuf_FileDescriptorSet *set =
- google_protobuf_FileDescriptorSet_parsenew(upb_stringview_make(str, len),
- upb_symtab_arena(s));
+ upb_arena *arena;
size_t i;
upb_array *file_arr;
+ google_protobuf_FileDescriptorSet *set;
+ upb_symtab *s = lupb_symtab_check(L, 1);
+ const char *str = luaL_checklstring(L, 2, &len);
+
+ lupb_arena_new(L);
+ arena = lupb_arena_check(L, -1);
+
+ set = google_protobuf_FileDescriptorSet_parsenew(
+ upb_stringview_make(str, len), arena);
if (!set) {
luaL_argerror(L, 2, "failed to parse descriptor");
@@ -1219,40 +663,24 @@ static int lupb_symtab_add(lua_State *L) {
return 0;
}
-static int lupb_symtab_lookup(lua_State *L) {
+static int lupb_symtab_lookupmsg(lua_State *L) {
const upb_symtab *s = lupb_symtab_check(L, 1);
- int i;
- for (i = 2; i <= lua_gettop(L); i++) {
- const upb_def *def = upb_symtab_lookup(s, luaL_checkstring(L, i));
- lupb_def_pushwrapper(L, def, NULL);
- lua_replace(L, i);
- }
- return lua_gettop(L) - 1;
-}
-
-static int lupb_symtabiter_next(lua_State *L) {
- upb_symtab_iter *i = lua_touserdata(L, lua_upvalueindex(1));
- if (upb_symtab_done(i)) return 0;
- lupb_def_pushwrapper(L, upb_symtab_iter_def(i), NULL);
- upb_symtab_next(i);
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, luaL_checkstring(L, 2));
+ lupb_msgdef_pushwrapper(L, m);
return 1;
}
-static int lupb_symtab_defs(lua_State *L) {
+static int lupb_symtab_lookupenum(lua_State *L) {
const upb_symtab *s = lupb_symtab_check(L, 1);
- upb_deftype_t type = lua_gettop(L) > 1 ? luaL_checkint(L, 2) : UPB_DEF_ANY;
- upb_symtab_iter *i = lua_newuserdata(L, sizeof(upb_symtab_iter));
- upb_symtab_begin(i, s, type);
- /* Need to guarantee that the symtab outlives the iter. */
- lua_pushvalue(L, 1);
- lua_pushcclosure(L, &lupb_symtabiter_next, 2);
+ const upb_enumdef *e = upb_symtab_lookupenum(s, luaL_checkstring(L, 2));
+ lupb_enumdef_pushwrapper(L, e);
return 1;
}
static const struct luaL_Reg lupb_symtab_m[] = {
{"add", lupb_symtab_add},
- {"defs", lupb_symtab_defs},
- {"lookup", lupb_symtab_lookup},
+ {"lookup_msg", lupb_symtab_lookupmsg},
+ {"lookup_enum", lupb_symtab_lookupenum},
{NULL, NULL}
};
@@ -1263,35 +691,13 @@ static const struct luaL_Reg lupb_symtab_mm[] = {
/* lupb toplevel **************************************************************/
-static int lupb_freeze(lua_State *L) {
- int n = lua_gettop(L);
- int i;
- /* Scratch memory; lua_newuserdata() anchors it as a GC root in case any Lua
- * functions fail. */
- upb_def **defs = lua_newuserdata(L, n * sizeof(upb_def*));
-
- for (i = 0; i < n; i++) {
- /* Could allow an array of defs here also. */
- defs[i] = lupb_def_checkmutable(L, i + 1);
- }
- CHK(upb_def_freeze(defs, n, &status));
- return 0;
-}
-
static void lupb_setfieldi(lua_State *L, const char *field, int i) {
lua_pushinteger(L, i);
lua_setfield(L, -2, field);
}
static const struct luaL_Reg lupbdef_toplevel_m[] = {
- {"EnumDef", lupb_enumdef_new},
- {"FieldDef", lupb_fielddef_new},
- {"FileDef", lupb_filedef_new},
- {"MessageDef", lupb_msgdef_new},
- {"OneofDef", lupb_oneofdef_new},
{"SymbolTable", lupb_symtab_new},
- {"freeze", lupb_freeze},
-
{NULL, NULL}
};
@@ -1300,8 +706,8 @@ void lupb_def_registertypes(lua_State *L) {
/* Refcounted types. */
lupb_register_type(L, LUPB_ENUMDEF, lupb_enumdef_m, lupb_enumdef_mm);
- lupb_register_type(L, LUPB_FIELDDEF, lupb_fielddef_m, lupb_fielddef_mm);
- lupb_register_type(L, LUPB_FILEDEF, lupb_filedef_m, lupb_filedef_mm);
+ lupb_register_type(L, LUPB_FIELDDEF, lupb_fielddef_m, NULL);
+ lupb_register_type(L, LUPB_FILEDEF, lupb_filedef_m, NULL);
lupb_register_type(L, LUPB_MSGDEF, lupb_msgdef_m, lupb_msgdef_mm);
lupb_register_type(L, LUPB_ONEOFDEF, lupb_oneofdef_m, lupb_oneofdef_mm);
lupb_register_type(L, LUPB_SYMTAB, lupb_symtab_m, lupb_symtab_mm);
@@ -1354,12 +760,6 @@ void lupb_def_registertypes(lua_State *L) {
lupb_setfieldi(L, "DESCRIPTOR_TYPE_SINT32", UPB_DESCRIPTOR_TYPE_SINT32);
lupb_setfieldi(L, "DESCRIPTOR_TYPE_SINT64", UPB_DESCRIPTOR_TYPE_SINT64);
- lupb_setfieldi(L, "DEF_MSG", UPB_DEF_MSG);
- lupb_setfieldi(L, "DEF_FIELD", UPB_DEF_FIELD);
- lupb_setfieldi(L, "DEF_ENUM", UPB_DEF_ENUM);
- lupb_setfieldi(L, "DEF_SERVICE", UPB_DEF_SERVICE);
- lupb_setfieldi(L, "DEF_ANY", UPB_DEF_ANY);
-
lupb_setfieldi(L, "HANDLER_INT32", UPB_HANDLER_INT32);
lupb_setfieldi(L, "HANDLER_INT64", UPB_HANDLER_INT64);
lupb_setfieldi(L, "HANDLER_UINT32", UPB_HANDLER_UINT32);
diff --git a/upb/def.c b/upb/def.c
index c800319..3167222 100644
--- a/upb/def.c
+++ b/upb/def.c
@@ -2,8 +2,10 @@
#include "upb/def.h"
#include <ctype.h>
+#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include "google/protobuf/descriptor.upb.h"
#include "upb/handlers.h"
typedef struct {
@@ -29,6 +31,7 @@ struct upb_fielddef {
uint64_t uint;
double dbl;
float flt;
+ bool boolean;
str_t *str;
} defaultval;
const upb_msgdef *msgdef;
@@ -48,14 +51,11 @@ struct upb_fielddef {
};
struct upb_msgdef {
- upb_filedef *file;
+ const upb_filedef *file;
const char *full_name;
uint32_t selector_count;
uint32_t submsg_field_count;
- upb_fielddef **fields;
- upb_oneofdef **oneofs;
-
/* Tables for looking up fields by number and name. */
upb_inttable itof;
upb_strtable ntof;
@@ -82,11 +82,6 @@ struct upb_oneofdef {
upb_inttable itof;
};
-struct upb_symtab {
- upb_arena arena;
- upb_strtable symtab;
-};
-
struct upb_filedef {
const char *name;
const char *package;
@@ -94,8 +89,37 @@ struct upb_filedef {
const char *phpnamespace;
upb_syntax_t syntax;
- upb_inttable defs;
- upb_inttable deps;
+ const upb_msgdef **msgs;
+ const upb_enumdef **enums;
+ const upb_filedef **deps;
+
+ int msgcount;
+ int enumcount;
+ int depcount;
+};
+
+/* Inside a symtab we store tagged pointers to specific def types. */
+typedef enum {
+ UPB_DEFTYPE_MSG = 0,
+ UPB_DEFTYPE_ENUM = 1,
+ UPB_DEFTYPE_FIELD = 2,
+ UPB_DEFTYPE_ONEOF = 3
+} upb_deftype_t;
+
+static const void *unpack_def(upb_value v, upb_deftype_t type) {
+ uintptr_t num = (uintptr_t)upb_value_getconstptr(v);
+ return (num & 3) == type ? (const void*)(num & ~3) : NULL;
+}
+
+static upb_value pack_def(const void *ptr, upb_deftype_t type) {
+ uintptr_t num = (uintptr_t)ptr | type;
+ return upb_value_constptr((const void*)num);
+}
+
+struct upb_symtab {
+ upb_arena arena;
+ upb_strtable syms; /* full_name -> packed def ptr */
+ upb_strtable files; /* file_name -> upb_filedef* */
};
/* isalpha() etc. from <ctype.h> are locale-dependent, which we don't want. */
@@ -111,7 +135,9 @@ static bool upb_isalphanum(char c) {
return upb_isletter(c) || upb_isbetween(c, '0', '9');
}
-static bool upb_isident(const char *str, size_t len, bool full, upb_status *s) {
+static bool upb_isident(upb_stringview name, bool full, upb_status *s) {
+ const char *str = name.data;
+ size_t len = name.size;
bool start = true;
size_t i;
for (i = 0; i < len; i++) {
@@ -141,7 +167,7 @@ static bool upb_isident(const char *str, size_t len, bool full, upb_status *s) {
return !start;
}
-static const char *shortname(const char *fullname) {
+static const char *shortdefname(const char *fullname) {
const char *p;
if (fullname == NULL) {
@@ -388,22 +414,12 @@ err:
/* upb_enumdef ****************************************************************/
-#if 0
-bool upb_enumdef_init(upb_enumdef *e) {
- upb_def_init(&e->base, UPB_DEF_ENUM);
-
- if (!upb_strtable_init(&e->ntoi, UPB_CTYPE_INT32)) goto err2;
- if (!upb_inttable_init(&e->iton, UPB_CTYPE_CSTR)) goto err1;
- return true;
-}
-#endif
-
const char *upb_enumdef_fullname(const upb_enumdef *e) {
return e->full_name;
}
const char *upb_enumdef_name(const upb_enumdef *e) {
- return shortname(e->full_name);
+ return shortdefname(e->full_name);
}
#if 0
@@ -499,43 +515,10 @@ int32_t upb_enum_iter_number(upb_enum_iter *iter) {
/* upb_fielddef ***************************************************************/
-static void upb_fielddef_init_default(upb_fielddef *f);
-
const char *upb_fielddef_fullname(const upb_fielddef *f) {
return f->full_name;
}
-#if 0
-upb_fielddef *upb_fielddef_new(const void *o) {
- upb_fielddef *f = upb_gmalloc(sizeof(*f));
- if (!f) return NULL;
- upb_def_init(&f->base, UPB_DEF_FIELD);
- f->msg.def = NULL;
- f->sub.def = NULL;
- f->oneof = NULL;
- f->subdef_is_symbolic = false;
- f->label_ = UPB_LABEL_OPTIONAL;
- f->type_ = UPB_TYPE_INT32;
- f->number_ = 0;
- f->type_is_set_ = false;
- f->tagdelim = false;
- f->is_extension_ = false;
- f->lazy_ = false;
- f->packed_ = true;
-
- /* For the moment we default this to UPB_INTFMT_VARIABLE, since it will work
- * with all integer types and is in some since more "default" since the most
- * normal-looking proto2 types int32/int64/uint32/uint64 use variable.
- *
- * Other options to consider:
- * - there is no default; users must set this manually (like type).
- * - default signed integers to UPB_INTFMT_ZIGZAG, since it's more likely to
- * be an optimal default for signed integers. */
- f->intfmt = UPB_INTFMT_VARIABLE;
- return f;
-}
-#endif
-
upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f) {
switch (f->type_) {
case UPB_DESCRIPTOR_TYPE_DOUBLE:
@@ -699,32 +682,6 @@ const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len) {
return str->str;
}
-#if 0
-static void upb_fielddef_init_default(upb_fielddef *f) {
- f->default_is_string = false;
- switch (upb_fielddef_type(f)) {
- case UPB_TYPE_DOUBLE: f->defaultval.dbl = 0; break;
- case UPB_TYPE_FLOAT: f->defaultval.flt = 0; break;
- case UPB_TYPE_INT32:
- case UPB_TYPE_INT64: f->defaultval.sint = 0; break;
- case UPB_TYPE_UINT64:
- case UPB_TYPE_UINT32:
- case UPB_TYPE_BOOL: f->defaultval.uint = 0; break;
- case UPB_TYPE_STRING:
- case UPB_TYPE_BYTES:
- f->defaultval.bytes = newstr("", 0);
- f->default_is_string = true;
- break;
- case UPB_TYPE_MESSAGE: break;
- case UPB_TYPE_ENUM:
- /* This is our special sentinel that indicates "not set" for an enum. */
- f->default_is_string = true;
- f->defaultval.bytes = NULL;
- break;
- }
-}
-#endif
-
const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f) {
UPB_ASSERT(upb_fielddef_type(f) == UPB_TYPE_MESSAGE);
return f->sub.msgdef;
@@ -735,38 +692,6 @@ const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f) {
return f->sub.enumdef;
}
-#if 0
-bool upb_fielddef_setnumber(upb_fielddef *f, uint32_t number, upb_status *s) {
- if (upb_fielddef_containingtype(f)) {
- upb_status_seterrmsg(
- s, "cannot change field number after adding to a message");
- return false;
- }
- if (number == 0 || number > UPB_MAX_FIELDNUMBER) {
- upb_status_seterrf(s, "invalid field number (%u)", number);
- return false;
- }
- f->number_ = number;
- return true;
-}
-
-static bool upb_subdef_typecheck(upb_fielddef *f, const upb_def *subdef,
- upb_status *s) {
- if (f->type_ == UPB_TYPE_MESSAGE) {
- if (upb_dyncast_msgdef(subdef)) return true;
- upb_status_seterrmsg(s, "invalid subdef type for this submessage field");
- return false;
- } else if (f->type_ == UPB_TYPE_ENUM) {
- if (upb_dyncast_enumdef(subdef)) return true;
- upb_status_seterrmsg(s, "invalid subdef type for this enum field");
- return false;
- } else {
- upb_status_seterrmsg(s, "only message and enum fields can have a subdef");
- return false;
- }
-}
-#endif
-
bool upb_fielddef_issubmsg(const upb_fielddef *f) {
return upb_fielddef_type(f) == UPB_TYPE_MESSAGE;
}
@@ -812,7 +737,7 @@ const char *upb_msgdef_fullname(const upb_msgdef *m) {
}
const char *upb_msgdef_name(const upb_msgdef *m) {
- return shortname(m->full_name);
+ return shortdefname(m->full_name);
}
upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m) {
@@ -827,16 +752,6 @@ static bool check_field_add(const upb_msgdef *m, const upb_fielddef *f,
if (upb_fielddef_containingtype(f) != NULL) {
upb_status_seterrmsg(s, "fielddef already belongs to a message");
return false;
- } else if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
- upb_status_seterrmsg(s, "field name or number were not set");
- return false;
- } else if (upb_msgdef_itof(m, upb_fielddef_number(f))) {
- upb_status_seterrmsg(s, "duplicate field number");
- return false;
- } else if (upb_strtable_lookup(&m->ntof, upb_fielddef_name(f), NULL)) {
- upb_status_seterrmsg(s, "name conflicts with existing field or oneof");
- return false;
- }
return true;
}
@@ -1156,38 +1071,6 @@ void upb_oneof_iter_setdone(upb_oneof_iter *iter) {
/* upb_filedef ****************************************************************/
-upb_filedef *upb_filedef_new(const void *owner) {
- upb_filedef *f = upb_gmalloc(sizeof(*f));
-
- if (!f) {
- return NULL;
- }
-
- f->package = NULL;
- f->name = NULL;
- f->phpprefix = NULL;
- f->phpnamespace = NULL;
- f->syntax = UPB_SYNTAX_PROTO2;
-
- if (!upb_inttable_init(&f->defs, UPB_CTYPE_CONSTPTR)) {
- goto err;
- }
-
- if (!upb_inttable_init(&f->deps, UPB_CTYPE_CONSTPTR)) {
- goto err2;
- }
-
- return f;
-
-
-err2:
- upb_inttable_uninit(&f->defs);
-
-err:
- upb_gfree(f);
- return NULL;
-}
-
const char *upb_filedef_name(const upb_filedef *f) {
return f->name;
}
@@ -1208,32 +1091,28 @@ upb_syntax_t upb_filedef_syntax(const upb_filedef *f) {
return f->syntax;
}
-size_t upb_filedef_defcount(const upb_filedef *f) {
- return upb_inttable_count(&f->defs);
+int upb_filedef_msgcount(const upb_filedef *f) {
+ return f->msgcount;
}
-size_t upb_filedef_depcount(const upb_filedef *f) {
- return upb_inttable_count(&f->deps);
+int upb_filedef_depcount(const upb_filedef *f) {
+ return f->depcount;
}
-const upb_def *upb_filedef_def(const upb_filedef *f, size_t i) {
- upb_value v;
+int upb_filedef_enumcount(const upb_filedef *f) {
+ return f->enumcount;
+}
- if (upb_inttable_lookup32(&f->defs, i, &v)) {
- return upb_value_getconstptr(v);
- } else {
- return NULL;
- }
+const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i) {
+ return i < 0 || i >= f->depcount ? NULL : f->deps[i];
}
-const upb_filedef *upb_filedef_dep(const upb_filedef *f, size_t i) {
- upb_value v;
+const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i) {
+ return i < 0 || i >= f->msgcount ? NULL : f->msgs[i];
+}
- if (upb_inttable_lookup32(&f->deps, i, &v)) {
- return upb_value_getconstptr(v);
- } else {
- return NULL;
- }
+const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) {
+ return i < 0 || i >= f->enumcount ? NULL : f->enums[i];
}
void upb_symtab_free(upb_symtab *s) {
@@ -1243,53 +1122,44 @@ void upb_symtab_free(upb_symtab *s) {
upb_symtab *upb_symtab_new() {
upb_symtab *s = upb_gmalloc(sizeof(*s));
+ upb_alloc *alloc;
+
if (!s) {
return NULL;
}
- if (!upb_arena_init(&s->arena)) goto err2;
- if (!upb_strtable_init2(&s->symtab, UPB_CTYPE_PTR,
- upb_arena_alloc(&s->arena))) {
- goto err1;
- }
- return s;
+ upb_arena_init(&s->arena);
+ alloc = upb_arena_alloc(&s->arena);
-err1:
- upb_arena_uninit(&s->arena);
-err2:
- upb_gfree(s);
+ if (!upb_strtable_init2(&s->syms, UPB_CTYPE_CONSTPTR, alloc) ||
+ !upb_strtable_init2(&s->files, UPB_CTYPE_CONSTPTR, alloc)) {
+ upb_arena_uninit(&s->arena);
+ upb_gfree(s);
+ s = NULL;
+ }
return s;
}
-const upb_def *upb_symtab_lookup(const upb_symtab *s, const char *sym) {
- upb_value v;
- upb_def *ret = upb_strtable_lookup(&s->symtab, sym, &v) ?
- upb_value_getptr(v) : NULL;
- return ret;
-}
-
const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
upb_value v;
- upb_def *def = upb_strtable_lookup(&s->symtab, sym, &v) ?
- upb_value_getptr(v) : NULL;
- return def ? upb_dyncast_msgdef(def) : NULL;
+ return upb_strtable_lookup(&s->syms, sym, &v) ?
+ unpack_def(v, UPB_DEFTYPE_MSG) : NULL;
}
const upb_msgdef *upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym,
size_t len) {
upb_value v;
- upb_def *def = upb_strtable_lookup2(&s->symtab, sym, len, &v) ?
- upb_value_getptr(v) : NULL;
- return def ? upb_dyncast_msgdef(def) : NULL;
+ return upb_strtable_lookup2(&s->syms, sym, len, &v) ?
+ unpack_def(v, UPB_DEFTYPE_MSG) : NULL;
}
const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) {
upb_value v;
- upb_def *def = upb_strtable_lookup(&s->symtab, sym, &v) ?
- upb_value_getptr(v) : NULL;
- return def ? upb_dyncast_enumdef(def) : NULL;
+ return upb_strtable_lookup(&s->syms, sym, &v) ?
+ unpack_def(v, UPB_DEFTYPE_ENUM) : NULL;
}
+#if 0
/* Given a symbol and the base symbol inside which it is defined, find the
* symbol's definition in t. */
static upb_def *upb_resolvename(const upb_strtable *t,
@@ -1311,11 +1181,10 @@ static upb_def *upb_resolvename(const upb_strtable *t,
const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base,
const char *sym) {
- upb_def *ret = upb_resolvename(&s->symtab, base, sym);
+ upb_def *ret = upb_resolvename(&s->syms, base, sym);
return ret;
}
-#if 0
/* Now using the table, resolve symbolic references for subdefs. */
upb_strtable_begin(&iter, &addtab);
for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
@@ -1338,7 +1207,7 @@ const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base,
* there, try existing defs. */
upb_def *subdef = upb_resolvename(&addtab, base, name);
if (subdef == NULL) {
- subdef = upb_resolvename(&s->symtab, base, name);
+ subdef = upb_resolvename(&s->syms, base, name);
}
if (subdef == NULL) {
upb_status_seterrf(
@@ -1352,76 +1221,258 @@ const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base,
}
#endif
+
+/* Code to build defs from descriptor protos. *********************************/
+
+/* There is a question of how much validation to do here. It will be difficult
+ * to perfectly match the amount of validation performed by proto2. But since
+ * this code is used to directly build defs from Ruby (for example) we do need
+ * to validate important constraints like uniqueness of names and numbers. */
+
+#define CHK(x) if (!(x)) return false
+#define CHK_OOM(x) if (!(x)) { upb_upberr_setoom(ctx->status); return false; }
+
+typedef struct {
+ const upb_symtab *symtab;
+ const upb_filedef *file; /* File we are building. */
+ upb_alloc *alloc; /* Allocate defs here. */
+ upb_alloc *tmp; /* Alloc for addtab and any other tmp data. */
+ upb_strtable *addtab; /* full_name -> packed def ptr for new defs. */
+ upb_status *status; /* Record errors here. */
+} symtab_addctx;
+
+static const char *makefullname(const char *prefix, upb_stringview name) {
+ return NULL;
+}
+
+static bool symtab_add(const symtab_addctx *ctx, const char *name,
+ upb_value v) {
+ upb_value tmp;
+ if (upb_strtable_lookup(ctx->addtab, name, &tmp) ||
+ upb_strtable_lookup(&ctx->symtab->syms, name, &tmp)) {
+ upb_status_seterrf(ctx->status, "Duplicate symbol '%s'", name);
+ return false;
+ }
+
+ CHK_OOM(upb_strtable_insert3(ctx->addtab, name, strlen(name), v, ctx->tmp));
+ return true;
+}
+
static bool create_oneofdef(
- upb_symtab *s, const google_protobuf_OneofDescriptorProto *oneof_proto,
- upb_msgdef *m, upb_status *s) {
- upb_alloc *alloc = upb_arena_alloc(&s->arena);
- upb_oneofdef *o = upb_malloc(alloc, sizeof(upb_oneofdef));
+ const symtab_addctx *ctx, upb_msgdef *m,
+ const google_protobuf_OneofDescriptorProto *oneof_proto) {
+ upb_oneofdef *o = upb_malloc(ctx->alloc, sizeof(*o));
upb_stringview name = google_protobuf_OneofDescriptorProto_name(oneof_proto);
upb_value o_ptr = upb_value_ptr(o);
- CHK(o);
- CHK(upb_inttable_init2(&o->itof, UPB_CTYPE_PTR, alloc));
- CHK(upb_strtable_init2(&o->ntof, UPB_CTYPE_PTR, alloc));
+ CHK_OOM(o);
+ CHK_OOM(upb_inttable_init2(&o->itof, UPB_CTYPE_PTR, ctx->alloc));
+ CHK_OOM(upb_strtable_init2(&o->ntof, UPB_CTYPE_PTR, ctx->alloc));
o->index = upb_strtable_count(&m->ntof);
- o->name = upb_strdup2(name.data, name.size, alloc);
+ o->name = upb_strdup2(name.data, name.size, ctx->alloc);
o->parent = m;
- CHK(upb_strtable_insert3(&m->ntof, name.data, name.size, o_ptr, alloc));
+ CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, o_ptr,
+ ctx->alloc));
return true;
}
-static bool create_field(
- upb_symtab *s, const google_protobuf_FieldDescriptorProto *field_proto,
- upb_msgdef *m, upb_status *s) {
- upb_alloc *alloc = upb_arena_alloc(&s->arena);
- upb_fielddef *f = upb_malloc(alloc, sizeof(upb_fielddef));
- const google_protobuf_MessageOptions *options;
+static bool parse_default(const char *str, size_t len, upb_fielddef *f) {
+ char *end;
+ switch (upb_fielddef_type(f)) {
+ case UPB_TYPE_INT32: {
+ long val = strtol(str, &end, 0);
+ CHK(val <= INT32_MAX && val >= INT32_MIN && errno != ERANGE && !*end);
+ f->defaultval.sint = val;
+ break;
+ }
+ case UPB_TYPE_ENUM:
+ case UPB_TYPE_INT64: {
+ /* XXX: Need to write our own strtoll, since it's not available in c89. */
+ long long val = strtol(str, &end, 0);
+ CHK(val <= INT64_MAX && val >= INT64_MIN && errno != ERANGE && !*end);
+ f->defaultval.sint = val;
+ break;
+ }
+ case UPB_TYPE_UINT32: {
+ unsigned long val = strtoul(str, &end, 0);
+ CHK(val <= UINT32_MAX && errno != ERANGE && !*end);
+ f->defaultval.uint = val;
+ break;
+ }
+ case UPB_TYPE_UINT64: {
+ /* XXX: Need to write our own strtoull, since it's not available in c89. */
+ unsigned long long val = strtoul(str, &end, 0);
+ CHK(val <= UINT64_MAX && errno != ERANGE && !*end);
+ f->defaultval.uint = val;
+ break;
+ }
+ case UPB_TYPE_DOUBLE: {
+ double val = strtod(str, &end);
+ CHK(errno != ERANGE && !*end);
+ f->defaultval.dbl = val;
+ break;
+ }
+ case UPB_TYPE_FLOAT: {
+ /* XXX: Need to write our own strtof, since it's not available in c89. */
+ float val = strtod(str, &end);
+ CHK(errno != ERANGE && !*end);
+ f->defaultval.dbl = val;
+ break;
+ }
+ case UPB_TYPE_BOOL: {
+ if (strcmp(str, "false") == 0) {
+ f->defaultval.boolean = false;
+ } else if (strcmp(str, "true") == 0) {
+ f->defaultval.boolean = true;
+ } else {
+ return false;
+ }
+ }
+ case UPB_TYPE_STRING:
+ f->defaultval.str = newstr(str, len);
+ break;
+ case UPB_TYPE_BYTES:
+ /* XXX: need to interpret the C-escaped value. */
+ f->defaultval.str = newstr(str, len);
+ case UPB_TYPE_MESSAGE:
+ /* Should not have a default value. */
+ return false;
+ }
+ return true;
+}
+
+static bool create_fielddef(
+ const symtab_addctx *ctx, const char *prefix, upb_msgdef *m,
+ const google_protobuf_FieldDescriptorProto *field_proto) {
+ upb_alloc *alloc = ctx->alloc;
+ upb_fielddef *f = upb_malloc(ctx->alloc, sizeof(*f));
+ const google_protobuf_FieldOptions *options;
+ upb_stringview defaultval, name;
+ upb_value packed_v = pack_def(f, UPB_DEFTYPE_FIELD);
+ upb_value v = upb_value_constptr(f);
+ const char *shortname;
+
+ CHK_OOM(f);
+ memset(f, 0, sizeof(*f));
+
+ name = google_protobuf_FieldDescriptorProto_name(field_proto);
+
+ /* TODO(haberman): use hazzers. */
+ if (name.size == 0 || f->number_ == 0) {
+ upb_status_seterrmsg(ctx->status, "field name or number were not set");
+ return false;
+ }
+
+ CHK(upb_isident(name, false, ctx->status));
+
+ f->full_name = makefullname(prefix, name);
+ f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto);
+ f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto);
+ f->number_ = google_protobuf_FieldDescriptorProto_number(field_proto);
+ shortname = shortdefname(f->full_name);
+
+ if (f->number_ == 0 || f->number_ > UPB_MAX_FIELDNUMBER) {
+ upb_status_seterrf(ctx->status, "invalid field number (%u)", f->number_);
+ return false;
+ }
+#if 0
+ //f->oneof
+ //f->sub
+#endif
+
+ defaultval = google_protobuf_FieldDescriptorProto_default_value(field_proto);
+
+ if (defaultval.data) {
+ CHK(parse_default(defaultval.data, defaultval.size, f));
+ }
+
+ options = google_protobuf_FieldDescriptorProto_options(field_proto);
+
+ if (options) {
+ f->lazy_ = google_protobuf_FieldOptions_lazy(options);
+ f->packed_ = google_protobuf_FieldOptions_packed(options);
+ }
+
+ if (m) {
+ /* direct message field. */
+ if (!upb_strtable_insert3(&m->ntof, name.data, name.size, packed_v, alloc)) {
+ upb_status_seterrf(ctx->status, "duplicate name (%s)", shortname);
+ return false;
+ }
+
+ if (!upb_inttable_insert2(&m->itof, f->number_, v, alloc)) {
+ upb_status_seterrf(ctx->status, "duplicate field number (%u)", f->number_);
+ return false;
+ }
+
+ f->msgdef = m;
+ f->is_extension_ = false;
+ } else {
+ /* extension field. */
+ f->is_extension_ = true;
+ }
+
+ return true;
+}
+
+static bool create_enumdef(
+ const symtab_addctx *ctx, const char *prefix,
+ const google_protobuf_EnumDescriptorProto *enum_proto) {
+ upb_enumdef *e = upb_malloc(ctx->alloc, sizeof(*e));
const upb_array *arr;
+ upb_stringview name;
+ size_t i;
- CHK(f);
+ name = google_protobuf_EnumDescriptorProto_name(enum_proto);
+ CHK(upb_isident(name, false, ctx->status));
- f->msgdef = m;
+ e->full_name = makefullname(prefix, name);
+ e->defaultval = 0;
- union {
- int64_t sint;
- uint64_t uint;
- double dbl;
- float flt;
- void *bytes;
- } defaultval;
- const upb_msgdef *msgdef;
- union {
- const upb_msgdef *msgdef;
- const upb_msgdef *enumdef;
- } sub;
- const upb_oneofdef *oneof;
- bool is_extension_;
- bool lazy_;
- bool packed_;
- upb_intfmt_t intfmt;
- bool tagdelim;
- upb_fieldtype_t type_;
- upb_label_t label_;
- uint32_t number_;
- uint32_t selector_base; /* Used to index into a upb::Handlers table. */
- uint32_t index_;
+ CHK_OOM(e);
+ CHK_OOM(upb_strtable_init2(&e->ntoi, UPB_CTYPE_INT32, ctx->alloc));
+ CHK_OOM(upb_inttable_init2(&e->iton, UPB_CTYPE_CSTR, ctx->alloc));
+
+ arr = google_protobuf_EnumDescriptorProto_value(enum_proto);
+
+ for (i = 0; i < upb_array_size(arr); i++) {
+ const google_protobuf_EnumValueDescriptorProto *value =
+ upb_msgval_getptr(upb_array_get(arr, i));
+ upb_stringview name = google_protobuf_EnumValueDescriptorProto_name(value);
+ char *name2 = upb_strdup2(name.data, name.size, ctx->alloc);
+ int32_t num = google_protobuf_EnumValueDescriptorProto_number(value);
+ upb_value v = upb_value_int32(num);
+
+ CHK_OOM(name2 && upb_strtable_insert(&e->ntoi, name2, v));
+
+ if (!upb_inttable_lookup(&e->iton, num, NULL)) {
+ CHK_OOM(upb_inttable_insert(&e->iton, num, upb_value_cstr(name2)));
+ }
+ }
+
+ return true;
}
-static bool create_msgdef(upb_symtab *s,
- const google_protobuf_DescriptorProto *msg_proto,
- upb_symtab *addtab, upb_status *status) {
- upb_alloc *alloc = upb_arena_alloc(&s->arena);
- upb_msgdef *m = upb_malloc(alloc, sizeof(upb_msgdef));
+static bool create_msgdef(const symtab_addctx *ctx, const char *prefix,
+ const google_protobuf_DescriptorProto *msg_proto) {
+ upb_msgdef *m = upb_malloc(ctx->alloc, sizeof(upb_msgdef));
const google_protobuf_MessageOptions *options;
const upb_array *arr;
+ size_t i;
+ upb_stringview name;
- CHK(m);
- CHK(upb_inttable_init2(&m->itof, UPB_CTYPE_PTR, alloc));
- CHK(upb_strtable_init2(&m->ntof, UPB_CTYPE_PTR, alloc));
+ CHK_OOM(m);
+ CHK_OOM(upb_inttable_init2(&m->itof, UPB_CTYPE_PTR, ctx->alloc));
+ CHK_OOM(upb_strtable_init2(&m->ntof, UPB_CTYPE_PTR, ctx->alloc));
+ name = google_protobuf_DescriptorProto_name(msg_proto);
+ CHK(upb_isident(name, false, ctx->status));
+
+ m->file = ctx->file;
+ m->full_name = makefullname(prefix, name);
m->map_entry = false;
options = google_protobuf_DescriptorProto_options(msg_proto);
@@ -1434,118 +1485,181 @@ static bool create_msgdef(upb_symtab *s,
for (i = 0; i < upb_array_size(arr); i++) {
const google_protobuf_OneofDescriptorProto *oneof_proto =
- (const void *)upb_array_get(arr, i);
- CHK(create_oneofdef(s, oneof_proto, m, status));
+ upb_msgval_getptr(upb_array_get(arr, i));
+ CHK(create_oneofdef(ctx, m, oneof_proto));
}
arr = google_protobuf_DescriptorProto_field(msg_proto);
for (i = 0; i < upb_array_size(arr); i++) {
const google_protobuf_FieldDescriptorProto *field_proto =
- (const void *)upb_array_get(arr, i);
- CHK(create_fielddef(s, field_proto, m, status));
+ upb_msgval_getptr(upb_array_get(arr, i));
+ CHK(create_fielddef(ctx, m->full_name, m, field_proto));
}
+ CHK(assign_msg_indices(m, ctx->status));
+ assign_msg_wellknowntype(m);
+ symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG));
+
+ /* This message is built. Now build nested messages and enums. */
+
arr = google_protobuf_DescriptorProto_enum_type(msg_proto);
for (i = 0; i < upb_array_size(arr); i++) {
const google_protobuf_EnumDescriptorProto *enum_proto =
- (const void *)upb_array_get(arr, i);
- CHK(create_enumdef(s, enum_proto, addtab, status));
+ upb_msgval_getptr(upb_array_get(arr, i));
+ CHK(create_enumdef(ctx, m->full_name, enum_proto));
}
arr = google_protobuf_DescriptorProto_nested_type(msg_proto);
for (i = 0; i < upb_array_size(arr); i++) {
const google_protobuf_DescriptorProto *msg_proto2 =
- (const void *)upb_array_get(arr, i);
- CHK(create_msgdef(s, msg_proto2, addtab, status));
+ upb_msgval_getptr(upb_array_get(arr, i));
+ CHK(create_msgdef(ctx, m->full_name, msg_proto2));
}
return true;
}
-static char* strviewdup(upb_symtab *symtab, upb_stringview view) {
+static char* strviewdup(const symtab_addctx *ctx, upb_stringview view) {
if (view.size == 0) {
return NULL;
}
- return upb_strdup2(view.data, view.size, upb_arena_alloc(&symtab->arena));
+ return upb_strdup2(view.data, view.size, ctx->alloc);
}
-bool upb_symtab_addfile(upb_symtab *s, const char *buf, size_t len,
- upb_status *status) {
- upb_arena tmparena;
- upb_strtable addtab;
- upb_alloc *alloc = upb_arena_alloc(&s->arena);
- upb_stringview serialized = upb_stringview_make(buf, len);
- const google_protobuf_FileDescriptorProto *file_proto;
+static bool build_filedef(
+ const symtab_addctx *ctx, upb_filedef *file,
+ const google_protobuf_FileDescriptorProto *file_proto) {
const google_protobuf_FileOptions *file_options_proto;
- upb_filedef *file = upb_malloc(alloc, sizeof(*file));
- const upb_array *arr;
upb_strtable_iter iter;
- size_t i;
-
- upb_arena_init(&tmparena);
- upb_strtable_init2(&addtab, UPB_CTYPE_PTR, upb_arena_alloc(&tmparena));
- file_proto =
- google_protobuf_FileDescriptorProto_parsenew(serialized, &tmparena);
-
+ const upb_array *arr;
+ size_t i, n;
+ upb_stringview syntax, package;
- if (!file_proto || !file) goto err;
+ package = google_protobuf_FileDescriptorProto_package(file_proto);
+ CHK(upb_isident(package, true, ctx->status));
file->name =
- strviewdup(s, google_protobuf_FileDescriptorProto_name(file_proto));
- file->package =
- strviewdup(s, google_protobuf_FileDescriptorProto_package(file_proto));
+ strviewdup(ctx, google_protobuf_FileDescriptorProto_name(file_proto));
+ file->package = strviewdup(ctx, package);
file->phpprefix = NULL;
file->phpnamespace = NULL;
+ syntax = google_protobuf_FileDescriptorProto_syntax(file_proto);
+
+ if (upb_stringview_eql(syntax, upb_stringview_makez("proto2"))) {
+ file->syntax = UPB_SYNTAX_PROTO2;
+ } else if (upb_stringview_eql(syntax, upb_stringview_makez("proto3"))) {
+ file->syntax = UPB_SYNTAX_PROTO3;
+ } else {
+ upb_status_seterrf(ctx->status, "Invalid syntax '%s'", syntax);
+ return false;
+ }
+
+ /* Read options. */
+
file_options_proto = google_protobuf_FileDescriptorProto_options(file_proto);
+
if (file_options_proto) {
- file->phpprefix =
- strviewdup(s, google_protobuf_FileOptions_php_class_prefix(file_proto));
- file->phpnamespace =
- strviewdup(s, google_protobuf_FileOptions_php_namespace(file_proto));
+ file->phpprefix = strviewdup(
+ ctx, google_protobuf_FileOptions_php_class_prefix(file_options_proto));
+ file->phpnamespace = strviewdup(
+ ctx, google_protobuf_FileOptions_php_namespace(file_options_proto));
}
- arr = google_protobuf_FileDescriptorProto_message_type(file_proto);
+ /* Resolve dependencies. */
+
+ arr = google_protobuf_FileDescriptorProto_dependency(file_proto);
+ n = upb_array_size(arr);
+ file->deps = upb_malloc(ctx->alloc, sizeof(*file->deps) * n) ;
+ CHK_OOM(file->deps);
+ for (i = 0; i < n; i++) {
+ upb_stringview dep_name = upb_msgval_getstr(upb_array_get(arr, i));
+ upb_value v;
+ if (!upb_strtable_lookup2(&ctx->symtab->files, dep_name.data,
+ dep_name.size, &v)) {
+ upb_status_seterrf(ctx->status,
+ "Depends on file '%s', but it has not been loaded",
+ dep_name.data);
+ return false;
+ }
+ file->deps[i] = upb_value_getconstptr(v);
+ }
+ /* Create messages. */
+
+ arr = google_protobuf_FileDescriptorProto_message_type(file_proto);
for (i = 0; i < upb_array_size(arr); i++) {
const google_protobuf_DescriptorProto *msg_proto =
- (const void *)upb_array_get(arr, i);
- if (!create_msgdef(s, msg_proto, &addtab, status)) goto err;
+ upb_msgval_getptr(upb_array_get(arr, i));
+ CHK(create_msgdef(ctx, file->package, msg_proto));
}
- arr = google_protobuf_FileDescriptorProto_enum_type(file_proto);
+ /* Create enums. */
+ arr = google_protobuf_FileDescriptorProto_enum_type(file_proto);
for (i = 0; i < upb_array_size(arr); i++) {
const google_protobuf_EnumDescriptorProto *enum_proto =
- (const void *)upb_array_get(arr, i);
- if (!create_enumdef(s, enum_proto, &addtab, status)) goto err;
+ upb_msgval_getptr(upb_array_get(arr, i));
+ CHK(create_enumdef(ctx, file->package, enum_proto));
}
/* Now that all names are in the table, resolve references. */
- upb_strtable_begin(&iter, &addtab);
+ upb_strtable_begin(&iter, ctx->addtab);
for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
}
- /* Success; add addtab to symtab. */
- upb_strtable_begin(&iter, &addtab);
+ return true;
+}
+
+static bool upb_symtab_addtotabs(upb_symtab *s, symtab_addctx *ctx,
+ upb_status *status) {
+ const upb_filedef *file = ctx->file;
+ upb_alloc *alloc = upb_arena_alloc(&s->arena);
+ upb_strtable_iter iter;
+
+ CHK_OOM(upb_strtable_insert3(&s->files, file->name, strlen(file->name),
+ upb_value_constptr(file), alloc));
+
+ upb_strtable_begin(&iter, ctx->addtab);
for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
const char *key = upb_strtable_iter_key(&iter);
- size_t keylen = upb_strtable_iter_keylen(&iter);
+ size_t keylen = upb_strtable_iter_keylength(&iter);
upb_value value = upb_strtable_iter_value(&iter);
- upb_strtable_insert3(&s->symtab, key, keylen, value, alloc);
+ CHK_OOM(upb_strtable_insert3(&s->syms, key, keylen, value, alloc));
}
return true;
+}
+
+bool upb_symtab_addfile(upb_symtab *s,
+ const google_protobuf_FileDescriptorProto *file_proto,
+ upb_status *status) {
+ upb_arena tmparena;
+ upb_strtable addtab;
+ symtab_addctx ctx;
+ upb_alloc *alloc = upb_arena_alloc(&s->arena);
+ upb_filedef *file = upb_malloc(alloc, sizeof(*file));
+ bool ok;
+
+ ctx.file = file;
+ ctx.alloc = alloc;
+ ctx.tmp = upb_arena_alloc(&tmparena);
+ ctx.addtab = &addtab;
+ ctx.status = status;
+
+ upb_arena_init(&tmparena);
+
+ ok = file &&
+ upb_strtable_init2(&addtab, UPB_CTYPE_PTR, ctx.tmp) &&
+ build_filedef(&ctx, file, file_proto) &&
+ upb_symtab_addtotabs(s, &ctx, status);
-err:
upb_arena_uninit(&tmparena);
- return false;
+ return ok;
}
-bool upb_symtab_addset(upb_symtab *s, const char *buf, size_t len,
- upb_status *status) {
- return true;
-}
+#undef CHK
+#undef CHK_OOM
diff --git a/upb/def.h b/upb/def.h
index 2551c86..4a7342e 100644
--- a/upb/def.h
+++ b/upb/def.h
@@ -19,6 +19,7 @@
#include "upb/upb.h"
#include "upb/table.int.h"
+#include "google/protobuf/descriptor.upb.h"
#ifdef __cplusplus
#include <cstring>
@@ -665,6 +666,13 @@ const char *upb_filedef_package(const upb_filedef *f);
const char *upb_filedef_phpprefix(const upb_filedef *f);
const char *upb_filedef_phpnamespace(const upb_filedef *f);
upb_syntax_t upb_filedef_syntax(const upb_filedef *f);
+int upb_filedef_depcount(const upb_filedef *f);
+int upb_filedef_msgcount(const upb_filedef *f);
+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);
+
UPB_END_EXTERN_C
@@ -708,10 +716,9 @@ const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym);
const upb_msgdef *upb_symtab_lookupmsg2(
const upb_symtab *s, const char *sym, size_t len);
const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym);
-bool upb_symtab_addfile(upb_symtab *s, const char *buf, size_t len,
+bool upb_symtab_addfile(upb_symtab *s,
+ const google_protobuf_FileDescriptorProto* file,
upb_status *status);
-bool upb_symtab_addset(upb_symtab *s, const char *buf, size_t len,
- upb_status *status);
UPB_END_EXTERN_C
diff --git a/upb/handlers.c b/upb/handlers.c
index 7382e0c..fa75a48 100644
--- a/upb/handlers.c
+++ b/upb/handlers.c
@@ -84,7 +84,7 @@ static upb_handlers *newformsg(const upb_msgdef *m, const void *owner,
if (!upb_fielddef_issubmsg(f)) continue;
- subdef = upb_downcast_msgdef(upb_fielddef_subdef(f));
+ subdef = upb_fielddef_msgsubdef(f);
if (upb_inttable_lookupptr(&s->tab, subdef, &subm_ent)) {
upb_handlers_setsubhandlers(h, f, upb_value_getptr(subm_ent));
} else {
@@ -392,7 +392,7 @@ bool upb_handlers_setsubhandlers(upb_handlers *h, const upb_fielddef *f,
UPB_ASSERT(!upb_handlers_isfrozen(h));
UPB_ASSERT(upb_fielddef_issubmsg(f));
if (SUBH_F(h, f)) return false; /* Can't reset. */
- if (upb_msgdef_upcast(upb_handlers_msgdef(sub)) != upb_fielddef_subdef(f)) {
+ if (upb_handlers_msgdef(sub) != upb_fielddef_msgsubdef(f)) {
return false;
}
SUBH_F(h, f) = sub;
diff --git a/upb/json/parser.c b/upb/json/parser.c
index 83590a1..85919e7 100644
--- a/upb/json/parser.c
+++ b/upb/json/parser.c
@@ -264,10 +264,6 @@ struct upb_json_parsermethod {
upb_byteshandler input_handler_;
- /* Mainly for the purposes of refcounting, so all the fielddefs we point
- * to stay alive. */
- const upb_msgdef *msg;
-
/* Keys are upb_msgdef*, values are upb_strtable (json_name -> fielddef) */
upb_inttable name_tables;
};
@@ -1327,8 +1323,7 @@ static bool end_stringval_nontop(upb_json_parser *p) {
case UPB_TYPE_ENUM: {
/* Resolve enum symbolic name to integer value. */
- const upb_enumdef *enumdef =
- (const upb_enumdef*)upb_fielddef_subdef(p->top->f);
+ const upb_enumdef *enumdef = upb_fielddef_enumsubdef(p->top->f);
size_t len;
const char *buf = accumulate_getptr(p, &len);
@@ -2414,11 +2409,11 @@ static bool is_string_wrapper_object(upb_json_parser *p) {
* final state once, when the closing '"' is seen. */
-#line 2576 "upb/json/parser.rl"
+#line 2571 "upb/json/parser.rl"
-#line 2422 "upb/json/parser.c"
+#line 2417 "upb/json/parser.c"
static const char _json_actions[] = {
0, 1, 0, 1, 1, 1, 3, 1,
4, 1, 6, 1, 7, 1, 8, 1,
@@ -2665,7 +2660,7 @@ static const int json_en_value_machine = 75;
static const int json_en_main = 1;
-#line 2579 "upb/json/parser.rl"
+#line 2574 "upb/json/parser.rl"
size_t parse(void *closure, const void *hd, const char *buf, size_t size,
const upb_bufhandle *handle) {
@@ -2688,7 +2683,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size,
capture_resume(parser, buf);
-#line 2692 "upb/json/parser.c"
+#line 2687 "upb/json/parser.c"
{
int _klen;
unsigned int _trans;
@@ -2763,83 +2758,83 @@ _match:
switch ( *_acts++ )
{
case 1:
-#line 2427 "upb/json/parser.rl"
+#line 2422 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
case 2:
-#line 2429 "upb/json/parser.rl"
+#line 2424 "upb/json/parser.rl"
{ p--; {stack[top++] = cs; cs = 23;goto _again;} }
break;
case 3:
-#line 2433 "upb/json/parser.rl"
+#line 2428 "upb/json/parser.rl"
{ start_text(parser, p); }
break;
case 4:
-#line 2434 "upb/json/parser.rl"
+#line 2429 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_text(parser, p)); }
break;
case 5:
-#line 2440 "upb/json/parser.rl"
+#line 2435 "upb/json/parser.rl"
{ start_hex(parser); }
break;
case 6:
-#line 2441 "upb/json/parser.rl"
+#line 2436 "upb/json/parser.rl"
{ hexdigit(parser, p); }
break;
case 7:
-#line 2442 "upb/json/parser.rl"
+#line 2437 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_hex(parser)); }
break;
case 8:
-#line 2448 "upb/json/parser.rl"
+#line 2443 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(escape(parser, p)); }
break;
case 9:
-#line 2454 "upb/json/parser.rl"
+#line 2449 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
case 10:
-#line 2466 "upb/json/parser.rl"
+#line 2461 "upb/json/parser.rl"
{ start_duration_base(parser, p); }
break;
case 11:
-#line 2467 "upb/json/parser.rl"
+#line 2462 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_duration_base(parser, p)); }
break;
case 12:
-#line 2469 "upb/json/parser.rl"
+#line 2464 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
case 13:
-#line 2474 "upb/json/parser.rl"
+#line 2469 "upb/json/parser.rl"
{ start_timestamp_base(parser, p); }
break;
case 14:
-#line 2475 "upb/json/parser.rl"
+#line 2470 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_timestamp_base(parser, p)); }
break;
case 15:
-#line 2477 "upb/json/parser.rl"
+#line 2472 "upb/json/parser.rl"
{ start_timestamp_fraction(parser, p); }
break;
case 16:
-#line 2478 "upb/json/parser.rl"
+#line 2473 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_timestamp_fraction(parser, p)); }
break;
case 17:
-#line 2480 "upb/json/parser.rl"
+#line 2475 "upb/json/parser.rl"
{ start_timestamp_zone(parser, p); }
break;
case 18:
-#line 2481 "upb/json/parser.rl"
+#line 2476 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_timestamp_zone(parser, p)); }
break;
case 19:
-#line 2483 "upb/json/parser.rl"
+#line 2478 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
case 20:
-#line 2488 "upb/json/parser.rl"
+#line 2483 "upb/json/parser.rl"
{
if (is_wellknown_msg(parser, UPB_WELLKNOWN_TIMESTAMP)) {
{stack[top++] = cs; cs = 47;goto _again;}
@@ -2851,11 +2846,11 @@ _match:
}
break;
case 21:
-#line 2499 "upb/json/parser.rl"
+#line 2494 "upb/json/parser.rl"
{ p--; {stack[top++] = cs; cs = 75;goto _again;} }
break;
case 22:
-#line 2504 "upb/json/parser.rl"
+#line 2499 "upb/json/parser.rl"
{
if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) {
start_any_member(parser, p);
@@ -2865,11 +2860,11 @@ _match:
}
break;
case 23:
-#line 2511 "upb/json/parser.rl"
+#line 2506 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_membername(parser)); }
break;
case 24:
-#line 2514 "upb/json/parser.rl"
+#line 2509 "upb/json/parser.rl"
{
if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) {
end_any_member(parser, p);
@@ -2879,7 +2874,7 @@ _match:
}
break;
case 25:
-#line 2525 "upb/json/parser.rl"
+#line 2520 "upb/json/parser.rl"
{
if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) {
start_any_object(parser, p);
@@ -2889,7 +2884,7 @@ _match:
}
break;
case 26:
-#line 2534 "upb/json/parser.rl"
+#line 2529 "upb/json/parser.rl"
{
if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) {
CHECK_RETURN_TOP(end_any_object(parser, p));
@@ -2899,54 +2894,54 @@ _match:
}
break;
case 27:
-#line 2546 "upb/json/parser.rl"
+#line 2541 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(start_array(parser)); }
break;
case 28:
-#line 2550 "upb/json/parser.rl"
+#line 2545 "upb/json/parser.rl"
{ end_array(parser); }
break;
case 29:
-#line 2555 "upb/json/parser.rl"
+#line 2550 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(start_number(parser, p)); }
break;
case 30:
-#line 2556 "upb/json/parser.rl"
+#line 2551 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_number(parser, p)); }
break;
case 31:
-#line 2558 "upb/json/parser.rl"
+#line 2553 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(start_stringval(parser)); }
break;
case 32:
-#line 2559 "upb/json/parser.rl"
+#line 2554 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_stringval(parser)); }
break;
case 33:
-#line 2561 "upb/json/parser.rl"
+#line 2556 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_bool(parser, true)); }
break;
case 34:
-#line 2563 "upb/json/parser.rl"
+#line 2558 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_bool(parser, false)); }
break;
case 35:
-#line 2565 "upb/json/parser.rl"
+#line 2560 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_null(parser)); }
break;
case 36:
-#line 2567 "upb/json/parser.rl"
+#line 2562 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(start_subobject_full(parser)); }
break;
case 37:
-#line 2568 "upb/json/parser.rl"
+#line 2563 "upb/json/parser.rl"
{ end_subobject_full(parser); }
break;
case 38:
-#line 2573 "upb/json/parser.rl"
+#line 2568 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
-#line 2950 "upb/json/parser.c"
+#line 2945 "upb/json/parser.c"
}
}
@@ -2963,32 +2958,32 @@ _again:
while ( __nacts-- > 0 ) {
switch ( *__acts++ ) {
case 0:
-#line 2425 "upb/json/parser.rl"
+#line 2420 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; if ( p == pe )
goto _test_eof;
goto _again;} }
break;
case 30:
-#line 2556 "upb/json/parser.rl"
+#line 2551 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_number(parser, p)); }
break;
case 33:
-#line 2561 "upb/json/parser.rl"
+#line 2556 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_bool(parser, true)); }
break;
case 34:
-#line 2563 "upb/json/parser.rl"
+#line 2558 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_bool(parser, false)); }
break;
case 35:
-#line 2565 "upb/json/parser.rl"
+#line 2560 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_null(parser)); }
break;
case 37:
-#line 2568 "upb/json/parser.rl"
+#line 2563 "upb/json/parser.rl"
{ end_subobject_full(parser); }
break;
-#line 2992 "upb/json/parser.c"
+#line 2987 "upb/json/parser.c"
}
}
}
@@ -2996,7 +2991,7 @@ goto _again;} }
_out: {}
}
-#line 2601 "upb/json/parser.rl"
+#line 2596 "upb/json/parser.rl"
if (p != pe) {
upb_status_seterrf(&parser->status, "Parse error at '%.*s'\n", pe - p, p);
@@ -3044,13 +3039,13 @@ static void json_parser_reset(upb_json_parser *p) {
/* Emit Ragel initialization of the parser. */
-#line 3048 "upb/json/parser.c"
+#line 3043 "upb/json/parser.c"
{
cs = json_start;
top = 0;
}
-#line 2648 "upb/json/parser.rl"
+#line 2643 "upb/json/parser.rl"
p->current_state = cs;
p->parser_top = top;
accumulate_clear(p);
@@ -3060,13 +3055,6 @@ static void json_parser_reset(upb_json_parser *p) {
upb_status_clear(&p->status);
}
-static void visit_json_parsermethod(const upb_refcounted *r,
- upb_refcounted_visit *visit,
- void *closure) {
- const upb_json_parsermethod *method = (upb_json_parsermethod*)r;
- visit(r, upb_msgdef_upcast2(method->msg), closure);
-}
-
static void free_json_parsermethod(upb_refcounted *r) {
upb_json_parsermethod *method = (upb_json_parsermethod*)r;
@@ -3183,14 +3171,10 @@ upb_bytessink *upb_json_parser_input(upb_json_parser *p) {
upb_json_parsermethod *upb_json_parsermethod_new(const upb_msgdef* md,
const void* owner) {
- static const struct upb_refcounted_vtbl vtbl = {visit_json_parsermethod,
- free_json_parsermethod};
+ static const struct upb_refcounted_vtbl vtbl = {NULL, free_json_parsermethod};
upb_json_parsermethod *ret = upb_gmalloc(sizeof(*ret));
upb_refcounted_init(upb_json_parsermethod_upcast_mutable(ret), &vtbl, owner);
- ret->msg = md;
- upb_ref2(md, ret);
-
upb_byteshandler_init(&ret->input_handler_);
upb_byteshandler_setstring(&ret->input_handler_, parse, ret);
upb_byteshandler_setendstr(&ret->input_handler_, end, ret);
diff --git a/upb/json/parser.h b/upb/json/parser.h
index fb5fd2f..91b08d8 100644
--- a/upb/json/parser.h
+++ b/upb/json/parser.h
@@ -52,7 +52,8 @@ class upb::json::ParserMethod {
/* Include base methods from upb::ReferenceCounted. */
UPB_REFCOUNTED_CPPMETHODS
- /* Returns handlers for parsing according to the specified schema. */
+ /* Returns handlers for parsing according to the specified schema.
+ * The MessageDef must outlive the ParserMethod. */
static reffed_ptr<const ParserMethod> New(const upb::MessageDef* md);
/* The destination handlers that are statically bound to this method.
diff --git a/upb/json/parser.rl b/upb/json/parser.rl
index a7bdb3f..9ceb816 100644
--- a/upb/json/parser.rl
+++ b/upb/json/parser.rl
@@ -262,10 +262,6 @@ struct upb_json_parsermethod {
upb_byteshandler input_handler_;
- /* Mainly for the purposes of refcounting, so all the fielddefs we point
- * to stay alive. */
- const upb_msgdef *msg;
-
/* Keys are upb_msgdef*, values are upb_strtable (json_name -> fielddef) */
upb_inttable name_tables;
};
@@ -1325,8 +1321,7 @@ static bool end_stringval_nontop(upb_json_parser *p) {
case UPB_TYPE_ENUM: {
/* Resolve enum symbolic name to integer value. */
- const upb_enumdef *enumdef =
- (const upb_enumdef*)upb_fielddef_subdef(p->top->f);
+ const upb_enumdef *enumdef = upb_fielddef_enumsubdef(p->top->f);
size_t len;
const char *buf = accumulate_getptr(p, &len);
@@ -2654,13 +2649,6 @@ static void json_parser_reset(upb_json_parser *p) {
upb_status_clear(&p->status);
}
-static void visit_json_parsermethod(const upb_refcounted *r,
- upb_refcounted_visit *visit,
- void *closure) {
- const upb_json_parsermethod *method = (upb_json_parsermethod*)r;
- visit(r, upb_msgdef_upcast2(method->msg), closure);
-}
-
static void free_json_parsermethod(upb_refcounted *r) {
upb_json_parsermethod *method = (upb_json_parsermethod*)r;
@@ -2777,14 +2765,10 @@ upb_bytessink *upb_json_parser_input(upb_json_parser *p) {
upb_json_parsermethod *upb_json_parsermethod_new(const upb_msgdef* md,
const void* owner) {
- static const struct upb_refcounted_vtbl vtbl = {visit_json_parsermethod,
- free_json_parsermethod};
+ static const struct upb_refcounted_vtbl vtbl = {NULL, free_json_parsermethod};
upb_json_parsermethod *ret = upb_gmalloc(sizeof(*ret));
upb_refcounted_init(upb_json_parsermethod_upcast_mutable(ret), &vtbl, owner);
- ret->msg = md;
- upb_ref2(md, ret);
-
upb_byteshandler_init(&ret->input_handler_);
upb_byteshandler_setstring(&ret->input_handler_, parse, ret);
upb_byteshandler_setendstr(&ret->input_handler_, end, ret);
diff --git a/upb/json/printer.c b/upb/json/printer.c
index fe306d4..00438aa 100644
--- a/upb/json/printer.c
+++ b/upb/json/printer.c
@@ -585,7 +585,7 @@ static void set_enum_hd(upb_handlers *h,
bool preserve_fieldnames,
upb_handlerattr *attr) {
EnumHandlerData *hd = upb_gmalloc(sizeof(EnumHandlerData));
- hd->enumdef = (const upb_enumdef *)upb_fielddef_subdef(f);
+ hd->enumdef = upb_fielddef_enumsubdef(f);
hd->keyname = newstrpc(h, f, preserve_fieldnames);
upb_handlers_addcleanup(h, hd, upb_gfree);
upb_handlerattr_sethandlerdata(attr, hd);
diff --git a/upb/msg.h b/upb/msg.h
index 3f0aa0b..f707795 100644
--- a/upb/msg.h
+++ b/upb/msg.h
@@ -22,6 +22,7 @@
#define UPB_MSG_H_
#include <stdint.h>
+#include <string.h>
#include "upb/upb.h"
#ifdef __cplusplus
@@ -86,6 +87,14 @@ UPB_INLINE upb_stringview upb_stringview_make(const char *data, size_t size) {
return ret;
}
+UPB_INLINE upb_stringview upb_stringview_makez(const char *data) {
+ return upb_stringview_make(data, strlen(data));
+}
+
+UPB_INLINE bool upb_stringview_eql(upb_stringview a, upb_stringview b) {
+ return a.size == b.size && memcmp(a.data, b.data, a.size) == 0;
+}
+
#define UPB_STRINGVIEW_INIT(ptr, len) {ptr, len}
diff --git a/upb/pb/textprinter.c b/upb/pb/textprinter.c
index abfc2eb..e8033f8 100644
--- a/upb/pb/textprinter.c
+++ b/upb/pb/textprinter.c
@@ -183,7 +183,7 @@ static bool textprinter_putenum(void *closure, const void *handler_data,
int32_t val) {
upb_textprinter *p = closure;
const upb_fielddef *f = handler_data;
- const upb_enumdef *enum_def = upb_downcast_enumdef(upb_fielddef_subdef(f));
+ const upb_enumdef *enum_def = upb_fielddef_enumsubdef(f);
const char *label = upb_enumdef_iton(enum_def, val);
if (label) {
indent(p);
@@ -292,7 +292,7 @@ static void onmreg(const void *c, upb_handlers *h) {
break;
case UPB_TYPE_MESSAGE: {
const char *name =
- upb_fielddef_istagdelim(f)
+ upb_fielddef_descriptortype(f) == UPB_DESCRIPTOR_TYPE_GROUP
? shortname(upb_msgdef_fullname(upb_fielddef_msgsubdef(f)))
: upb_fielddef_name(f);
upb_handlerattr_sethandlerdata(&attr, name);
diff --git a/upb/structdefs.int.h b/upb/structdefs.int.h
deleted file mode 100644
index cf8bd1d..0000000
--- a/upb/structdefs.int.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
-** This file contains definitions of structs that should be considered private
-** and NOT stable across versions of upb.
-**
-** The only reason they are declared here and not in .c files is to allow upb
-** and the application (if desired) to embed statically-initialized instances
-** of structures like defs.
-**
-** If you include this file, all guarantees of ABI compatibility go out the
-** window! Any code that includes this file needs to recompile against the
-** exact same version of upb that they are linking against.
-**
-** You also need to recompile if you change the value of the UPB_DEBUG_REFS
-** flag.
-*/
-
-#include "upb/def.h"
-
-#ifndef UPB_STATICINIT_H_
-#define UPB_STATICINIT_H_
-
-#ifdef __cplusplus
-/* Because of how we do our typedefs, this header can't be included from C++. */
-#error This file cannot be included from C++
-#endif
-
-/* upb_refcounted *************************************************************/
-
-
-/* upb_def ********************************************************************/
-
-struct upb_def {
- upb_refcounted base;
-
- const char *fullname;
- const upb_filedef* file;
- char type; /* A upb_deftype_t (char to save space) */
-
- /* Used as a flag during the def's mutable stage. Must be false unless
- * it is currently being used by a function on the stack. This allows
- * us to easily determine which defs were passed into the function's
- * current invocation. */
- bool came_from_user;
-};
-
-#define UPB_DEF_INIT(name, type, vtbl, refs, ref2s) \
- { UPB_REFCOUNT_INIT(vtbl, refs, ref2s), name, NULL, type, false }
-
-
-/* upb_fielddef ***************************************************************/
-
-struct upb_fielddef {
- upb_def base;
-
- union {
- int64_t sint;
- uint64_t uint;
- double dbl;
- float flt;
- void *bytes;
- } defaultval;
- union {
- const upb_msgdef *def; /* If !msg_is_symbolic. */
- char *name; /* If msg_is_symbolic. */
- } msg;
- union {
- const upb_def *def; /* If !subdef_is_symbolic. */
- char *name; /* If subdef_is_symbolic. */
- } sub; /* The msgdef or enumdef for this field, if upb_hassubdef(f). */
- bool subdef_is_symbolic;
- bool msg_is_symbolic;
- const upb_oneofdef *oneof;
- bool default_is_string;
- bool type_is_set_; /* False until type is explicitly set. */
- bool is_extension_;
- bool lazy_;
- bool packed_;
- upb_intfmt_t intfmt;
- bool tagdelim;
- upb_fieldtype_t type_;
- upb_label_t label_;
- uint32_t number_;
- uint32_t selector_base; /* Used to index into a upb::Handlers table. */
- uint32_t index_;
-};
-
-extern const struct upb_refcounted_vtbl upb_fielddef_vtbl;
-
-#define UPB_FIELDDEF_INIT(label, type, intfmt, tagdelim, is_extension, lazy, \
- packed, name, num, msgdef, subdef, selector_base, \
- index, defaultval, refs, ref2s) \
- { \
- UPB_DEF_INIT(name, UPB_DEF_FIELD, &upb_fielddef_vtbl, refs, ref2s), \
- defaultval, {msgdef}, {subdef}, NULL, false, false, \
- type == UPB_TYPE_STRING || type == UPB_TYPE_BYTES, true, is_extension, \
- lazy, packed, intfmt, tagdelim, type, label, num, selector_base, index \
- }
-
-
-/* upb_msgdef *****************************************************************/
-
-struct upb_msgdef {
- upb_def base;
-
- size_t selector_count;
- uint32_t submsg_field_count;
-
- /* Tables for looking up fields by number and name. */
- upb_inttable itof; /* int to field */
- upb_strtable ntof; /* name to field/oneof */
-
- /* Is this a map-entry message? */
- bool map_entry;
-
- /* Whether this message has proto2 or proto3 semantics. */
- upb_syntax_t syntax;
-
- /* Type of well known type message. UPB_WELLKNOWN_UNSPECIFIED for
- * non-well-known message. */
- upb_wellknowntype_t well_known_type;
-
- /* TODO(haberman): proper extension ranges (there can be multiple). */
-};
-
-extern const struct upb_refcounted_vtbl upb_msgdef_vtbl;
-
-/* TODO: also support static initialization of the oneofs table. This will be
- * needed if we compile in descriptors that contain oneofs. */
-#define UPB_MSGDEF_INIT(name, selector_count, submsg_field_count, itof, ntof, \
- map_entry, syntax, well_known_type, refs, ref2s) \
- { \
- UPB_DEF_INIT(name, UPB_DEF_MSG, &upb_fielddef_vtbl, refs, ref2s), \
- selector_count, submsg_field_count, itof, ntof, map_entry, syntax, \
- well_known_type \
- }
-
-
-/* upb_enumdef ****************************************************************/
-
-struct upb_enumdef {
- upb_def base;
-
- upb_strtable ntoi;
- upb_inttable iton;
- int32_t defaultval;
-};
-
-extern const struct upb_refcounted_vtbl upb_enumdef_vtbl;
-
-#define UPB_ENUMDEF_INIT(name, ntoi, iton, defaultval, refs, ref2s) \
- { UPB_DEF_INIT(name, UPB_DEF_ENUM, &upb_enumdef_vtbl, refs, ref2s), ntoi, \
- iton, defaultval }
-
-
-/* upb_oneofdef ***************************************************************/
-
-struct upb_oneofdef {
- upb_refcounted base;
-
- uint32_t index; /* Index within oneofs. */
- const char *name;
- upb_strtable ntof;
- upb_inttable itof;
- const upb_msgdef *parent;
-};
-
-extern const struct upb_refcounted_vtbl upb_oneofdef_vtbl;
-
-#define UPB_ONEOFDEF_INIT(name, ntof, itof, refs, ref2s) \
- { UPB_REFCOUNT_INIT(&upb_oneofdef_vtbl, refs, ref2s), 0, name, ntof, itof }
-
-
-/* upb_symtab *****************************************************************/
-
-struct upb_symtab {
- upb_refcounted base;
-
- upb_strtable symtab;
-};
-
-struct upb_filedef {
- upb_refcounted base;
-
- const char *name;
- const char *package;
- const char *phpprefix;
- const char *phpnamespace;
- upb_syntax_t syntax;
-
- upb_inttable defs;
- upb_inttable deps;
-};
-
-extern const struct upb_refcounted_vtbl upb_filedef_vtbl;
-
-#endif /* UPB_STATICINIT_H_ */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback