diff options
Diffstat (limited to 'upb')
-rw-r--r-- | upb/bindings/lua/def.c | 780 | ||||
-rw-r--r-- | upb/def.c | 722 | ||||
-rw-r--r-- | upb/def.h | 13 | ||||
-rw-r--r-- | upb/handlers.c | 4 | ||||
-rw-r--r-- | upb/json/parser.c | 126 | ||||
-rw-r--r-- | upb/json/parser.h | 3 | ||||
-rw-r--r-- | upb/json/parser.rl | 20 | ||||
-rw-r--r-- | upb/json/printer.c | 2 | ||||
-rw-r--r-- | upb/msg.h | 9 | ||||
-rw-r--r-- | upb/pb/textprinter.c | 4 | ||||
-rw-r--r-- | upb/structdefs.int.h | 196 |
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); @@ -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 @@ -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); @@ -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_ */ |